This commit is contained in:
Lana Steuck 2014-09-25 16:21:30 -07:00
commit 187e5e2014
21 changed files with 515 additions and 299 deletions

View File

@ -124,8 +124,7 @@ public abstract class Attribute implements AnnotationValue {
: types.erasure(type); : types.erasure(type);
return new Type.ClassType(types.syms.classType.getEnclosingType(), return new Type.ClassType(types.syms.classType.getEnclosingType(),
List.of(arg), List.of(arg),
types.syms.classType.tsym, types.syms.classType.tsym);
Type.noAnnotations);
} }
@DefinedBy(Api.LANGUAGE_MODEL) @DefinedBy(Api.LANGUAGE_MODEL)
public String toString() { public String toString() {

View File

@ -970,7 +970,7 @@ public abstract class Symbol extends AnnoConstruct implements Element {
this( this(
flags, flags,
name, name,
new ClassType(Type.noType, null, null, Type.noAnnotations), new ClassType(Type.noType, null, null),
owner); owner);
this.type.tsym = this; this.type.tsym = this;
} }
@ -1007,7 +1007,7 @@ public abstract class Symbol extends AnnoConstruct implements Element {
if (erasure_field == null) if (erasure_field == null)
erasure_field = new ClassType(types.erasure(type.getEnclosingType()), erasure_field = new ClassType(types.erasure(type.getEnclosingType()),
List.<Type>nil(), this, List.<Type>nil(), this,
type.getAnnotationMirrors()); type.getMetadata());
return erasure_field; return erasure_field;
} }

View File

@ -72,6 +72,24 @@ import static com.sun.tools.javac.code.TypeTag.*;
*/ */
public abstract class Type extends AnnoConstruct implements TypeMirror { public abstract class Type extends AnnoConstruct implements TypeMirror {
/**
* Type metadata, Should be {@code null} for the default value.
*
* Note: it is an invariant that for any {@code TypeMetadata}
* class, a given {@code Type} may have at most one metadata array
* entry of that class.
*/
protected final TypeMetadata metadata;
public TypeMetadata getMetadata() {
return metadata;
}
public TypeMetadata.Element getMetadataOfKind(final TypeMetadata.Element.Kind kind) {
return metadata != null ? metadata.get(kind) : null;
}
/** Constant type: no type at all. */ /** Constant type: no type at all. */
public static final JCNoType noType = new JCNoType() { public static final JCNoType noType = new JCNoType() {
@Override @DefinedBy(Api.LANGUAGE_MODEL) @Override @DefinedBy(Api.LANGUAGE_MODEL)
@ -96,9 +114,6 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
} }
}; };
public static final List<Attribute.TypeCompound> noAnnotations =
List.nil();
/** If this switch is turned on, the names of type variables /** If this switch is turned on, the names of type variables
* and anonymous classes are printed with hashcodes appended. * and anonymous classes are printed with hashcodes appended.
*/ */
@ -108,10 +123,6 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
*/ */
public TypeSymbol tsym; public TypeSymbol tsym;
/** The type annotations on this type.
*/
protected final List<Attribute.TypeCompound> annos;
/** /**
* Checks if the current type tag is equal to the given tag. * Checks if the current type tag is equal to the given tag.
* @return true if tag is equal to the current type tag. * @return true if tag is equal to the current type tag.
@ -198,13 +209,11 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
/** Define a type given its tag, type symbol, and type annotations /** Define a type given its tag, type symbol, and type annotations
*/ */
public Type(TypeSymbol tsym, List<Attribute.TypeCompound> annos) {
if(annos == null) {
Assert.error("Attempting to create type " + tsym + " with null type annotations");
}
public Type(TypeSymbol tsym, TypeMetadata metadata) {
Assert.checkNonNull(metadata);
this.tsym = tsym; this.tsym = tsym;
this.annos = annos; this.metadata = metadata;
} }
/** An abstract class for mappings from types to types /** An abstract class for mappings from types to types
@ -253,15 +262,39 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
return this; return this;
} }
public abstract Type annotatedType(List<Attribute.TypeCompound> annos); /**
* Create a new type with exactly the given metadata. The
* argument is guaranteed to always be non-empty, and should have
* already been copied/combined with the current type's metadata.
* This is used internally by other methods.
*
*/
public abstract Type clone(TypeMetadata md);
public Type combineMetadata(final TypeMetadata.Element md) {
return clone(metadata.combine(md));
}
public Type annotatedType(final List<Attribute.TypeCompound> annos) {
final TypeMetadata.Element annoMetadata = new TypeMetadata.Annotations(annos);
return combineMetadata(annoMetadata);
}
public boolean isAnnotated() { public boolean isAnnotated() {
return !annos.isEmpty(); final TypeMetadata.Annotations metadata =
(TypeMetadata.Annotations)getMetadataOfKind(TypeMetadata.Element.Kind.ANNOTATIONS);
return null != metadata && !metadata.getAnnotations().isEmpty();
} }
private static final List<Attribute.TypeCompound> noAnnotations = List.nil();
@Override @DefinedBy(Api.LANGUAGE_MODEL) @Override @DefinedBy(Api.LANGUAGE_MODEL)
public List<Attribute.TypeCompound> getAnnotationMirrors() { public List<Attribute.TypeCompound> getAnnotationMirrors() {
return annos; final TypeMetadata.Annotations metadata =
(TypeMetadata.Annotations)getMetadataOfKind(TypeMetadata.Element.Kind.ANNOTATIONS);
return metadata == null ? noAnnotations : metadata.getAnnotations();
} }
@ -296,7 +329,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
if (prefix) { if (prefix) {
sb.append(" "); sb.append(" ");
} }
sb.append(annos); sb.append(getAnnotationMirrors());
sb.append(" "); sb.append(" ");
} }
} }
@ -524,19 +557,19 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
TypeTag tag; TypeTag tag;
public JCPrimitiveType(TypeTag tag, TypeSymbol tsym) { public JCPrimitiveType(TypeTag tag, TypeSymbol tsym) {
this(tag, tsym, noAnnotations); this(tag, tsym, TypeMetadata.empty);
} }
public JCPrimitiveType(TypeTag tag, TypeSymbol tsym, private JCPrimitiveType(TypeTag tag, TypeSymbol tsym,
List<Attribute.TypeCompound> annos) { TypeMetadata metadata) {
super(tsym, annos); super(tsym, metadata);
this.tag = tag; this.tag = tag;
Assert.check(tag.isPrimitive); Assert.check(tag.isPrimitive);
} }
@Override @Override
public Type annotatedType(List<Attribute.TypeCompound> annos) { public JCPrimitiveType clone(TypeMetadata md) {
return new JCPrimitiveType(tag, tsym, annos); return new JCPrimitiveType(tag, tsym, md);
} }
@Override @Override
@ -565,7 +598,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
@Override @Override
public Type constType(Object constValue) { public Type constType(Object constValue) {
final Object value = constValue; final Object value = constValue;
return new JCPrimitiveType(tag, tsym, annos) { return new JCPrimitiveType(tag, tsym, metadata) {
@Override @Override
public Object constValue() { public Object constValue() {
return value; return value;
@ -649,35 +682,30 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
} }
public WildcardType(Type type, BoundKind kind, TypeSymbol tsym) { public WildcardType(Type type, BoundKind kind, TypeSymbol tsym) {
this(type, kind, tsym, null, noAnnotations); this(type, kind, tsym, null, TypeMetadata.empty);
} }
public WildcardType(Type type, BoundKind kind, TypeSymbol tsym, public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
List<Attribute.TypeCompound> annos) { TypeMetadata metadata) {
this(type, kind, tsym, null, annos); this(type, kind, tsym, null, metadata);
}
public WildcardType(WildcardType t, TypeVar bound,
List<Attribute.TypeCompound> annos) {
this(t.type, t.kind, t.tsym, bound, annos);
} }
public WildcardType(Type type, BoundKind kind, TypeSymbol tsym, public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
TypeVar bound) { TypeVar bound) {
this(type, kind, tsym, noAnnotations); this(type, kind, tsym, bound, TypeMetadata.empty);
} }
public WildcardType(Type type, BoundKind kind, TypeSymbol tsym, public WildcardType(Type type, BoundKind kind, TypeSymbol tsym,
TypeVar bound, List<Attribute.TypeCompound> annos) { TypeVar bound, TypeMetadata metadata) {
super(tsym, annos); super(tsym, metadata);
this.type = Assert.checkNonNull(type); this.type = Assert.checkNonNull(type);
this.kind = kind; this.kind = kind;
this.bound = bound; this.bound = bound;
} }
@Override @Override
public WildcardType annotatedType(List<Attribute.TypeCompound> annos) { public WildcardType clone(TypeMetadata md) {
return new WildcardType(type, kind, tsym, bound, annos); return new WildcardType(type, kind, tsym, bound, md);
} }
@Override @Override
@ -747,7 +775,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
if (t == type) if (t == type)
return this; return this;
else else
return new WildcardType(t, kind, tsym, bound, annos); return new WildcardType(t, kind, tsym, bound, metadata);
} }
@DefinedBy(Api.LANGUAGE_MODEL) @DefinedBy(Api.LANGUAGE_MODEL)
@ -808,31 +836,23 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
public List<Type> all_interfaces_field; public List<Type> all_interfaces_field;
public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym) { public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym) {
this(outer, typarams, tsym, noAnnotations); this(outer, typarams, tsym, TypeMetadata.empty);
} }
public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym, public ClassType(Type outer, List<Type> typarams, TypeSymbol tsym,
List<Attribute.TypeCompound> annos) { TypeMetadata metadata) {
super(tsym, annos); super(tsym, metadata);
this.outer_field = outer; this.outer_field = outer;
this.typarams_field = typarams; this.typarams_field = typarams;
this.allparams_field = null; this.allparams_field = null;
this.supertype_field = null; this.supertype_field = null;
this.interfaces_field = null; this.interfaces_field = null;
/*
// this can happen during error recovery
assert
outer.isParameterized() ?
typarams.length() == tsym.type.typarams().length() :
outer.isRaw() ?
typarams.length() == 0 :
true;
*/
} }
@Override @Override
public ClassType annotatedType(List<Attribute.TypeCompound> annos) { public ClassType clone(TypeMetadata md) {
final ClassType out = new ClassType(outer_field, typarams_field, tsym, annos); final ClassType out =
new ClassType(outer_field, typarams_field, tsym, md);
out.allparams_field = allparams_field; out.allparams_field = allparams_field;
out.supertype_field = supertype_field; out.supertype_field = supertype_field;
out.interfaces_field = interfaces_field; out.interfaces_field = interfaces_field;
@ -851,7 +871,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
public Type constType(Object constValue) { public Type constType(Object constValue) {
final Object value = constValue; final Object value = constValue;
return new ClassType(getEnclosingType(), typarams_field, tsym, annos) { return new ClassType(getEnclosingType(), typarams_field, tsym, metadata) {
@Override @Override
public Object constValue() { public Object constValue() {
return value; return value;
@ -987,7 +1007,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
List<Type> typarams = getTypeArguments(); List<Type> typarams = getTypeArguments();
List<Type> typarams1 = map(typarams, f); List<Type> typarams1 = map(typarams, f);
if (outer1 == outer && typarams1 == typarams) return this; if (outer1 == outer && typarams1 == typarams) return this;
else return new ClassType(outer1, typarams1, tsym, annos); else return new ClassType(outer1, typarams1, tsym, metadata);
} }
public boolean contains(Type elem) { public boolean contains(Type elem) {
@ -1016,12 +1036,12 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
public static class ErasedClassType extends ClassType { public static class ErasedClassType extends ClassType {
public ErasedClassType(Type outer, TypeSymbol tsym) { public ErasedClassType(Type outer, TypeSymbol tsym) {
this(outer, tsym, noAnnotations); super(outer, List.<Type>nil(), tsym);
} }
public ErasedClassType(Type outer, TypeSymbol tsym, public ErasedClassType(Type outer, TypeSymbol tsym,
List<Attribute.TypeCompound> annos) { TypeMetadata metadata) {
super(outer, List.<Type>nil(), tsym, annos); super(outer, List.<Type>nil(), tsym, metadata);
} }
@Override @Override
@ -1037,7 +1057,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
public UnionClassType(ClassType ct, List<? extends Type> alternatives) { public UnionClassType(ClassType ct, List<? extends Type> alternatives) {
// Presently no way to refer to this type directly, so we // Presently no way to refer to this type directly, so we
// cannot put annotations directly on it. // cannot put annotations directly on it.
super(ct.outer_field, ct.typarams_field, ct.tsym, noAnnotations); super(ct.outer_field, ct.typarams_field, ct.tsym);
allparams_field = ct.allparams_field; allparams_field = ct.allparams_field;
supertype_field = ct.supertype_field; supertype_field = ct.supertype_field;
interfaces_field = ct.interfaces_field; interfaces_field = ct.interfaces_field;
@ -1045,6 +1065,11 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
alternatives_field = alternatives; alternatives_field = alternatives;
} }
@Override
public UnionClassType clone(TypeMetadata md) {
throw new AssertionError("Cannot add metadata to a union type");
}
public Type getLub() { public Type getLub() {
return tsym.type; return tsym.type;
} }
@ -1077,7 +1102,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
public IntersectionClassType(List<Type> bounds, ClassSymbol csym, boolean allInterfaces) { public IntersectionClassType(List<Type> bounds, ClassSymbol csym, boolean allInterfaces) {
// Presently no way to refer to this type directly, so we // Presently no way to refer to this type directly, so we
// cannot put annotations directly on it. // cannot put annotations directly on it.
super(Type.noType, List.<Type>nil(), csym, noAnnotations); super(Type.noType, List.<Type>nil(), csym);
this.allInterfaces = allInterfaces; this.allInterfaces = allInterfaces;
Assert.check((csym.flags() & COMPOUND) != 0); Assert.check((csym.flags() & COMPOUND) != 0);
supertype_field = bounds.head; supertype_field = bounds.head;
@ -1086,6 +1111,11 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
!supertype_field.isInterface(), supertype_field); !supertype_field.isInterface(), supertype_field);
} }
@Override
public IntersectionClassType clone(TypeMetadata md) {
throw new AssertionError("Cannot add metadata to an intersection type");
}
@DefinedBy(Api.LANGUAGE_MODEL) @DefinedBy(Api.LANGUAGE_MODEL)
public java.util.List<? extends TypeMirror> getBounds() { public java.util.List<? extends TypeMirror> getBounds() {
return Collections.unmodifiableList(getExplicitComponents()); return Collections.unmodifiableList(getExplicitComponents());
@ -1118,18 +1148,18 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
public Type elemtype; public Type elemtype;
public ArrayType(Type elemtype, TypeSymbol arrayClass) { public ArrayType(Type elemtype, TypeSymbol arrayClass) {
this(elemtype, arrayClass, noAnnotations); this(elemtype, arrayClass, TypeMetadata.empty);
} }
public ArrayType(Type elemtype, TypeSymbol arrayClass, public ArrayType(Type elemtype, TypeSymbol arrayClass,
List<Attribute.TypeCompound> annos) { TypeMetadata metadata) {
super(arrayClass, annos); super(arrayClass, metadata);
this.elemtype = elemtype; this.elemtype = elemtype;
} }
@Override @Override
public ArrayType annotatedType(List<Attribute.TypeCompound> annos) { public ArrayType clone(TypeMetadata md) {
return new ArrayType(elemtype, tsym, annos); return new ArrayType(elemtype, tsym, md);
} }
@Override @Override
@ -1192,7 +1222,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
} }
public ArrayType makeVarargs() { public ArrayType makeVarargs() {
return new ArrayType(elemtype, tsym, annos) { return new ArrayType(elemtype, tsym, metadata) {
@Override @Override
public boolean isVarargs() { public boolean isVarargs() {
return true; return true;
@ -1203,7 +1233,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
public Type map(Mapping f) { public Type map(Mapping f) {
Type elemtype1 = f.apply(elemtype); Type elemtype1 = f.apply(elemtype);
if (elemtype1 == elemtype) return this; if (elemtype1 == elemtype) return this;
else return new ArrayType(elemtype1, tsym, annos); else return new ArrayType(elemtype1, tsym, metadata);
} }
public boolean contains(Type elem) { public boolean contains(Type elem) {
@ -1246,15 +1276,15 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
TypeSymbol methodClass) { TypeSymbol methodClass) {
// Presently no way to refer to a method type directly, so // Presently no way to refer to a method type directly, so
// we cannot put type annotations on it. // we cannot put type annotations on it.
super(methodClass, noAnnotations); super(methodClass, TypeMetadata.empty);
this.argtypes = argtypes; this.argtypes = argtypes;
this.restype = restype; this.restype = restype;
this.thrown = thrown; this.thrown = thrown;
} }
@Override @Override
public MethodType annotatedType(List<Attribute.TypeCompound> annos) { public MethodType clone(TypeMetadata md) {
throw new AssertionError("Cannot annotate a method type"); throw new AssertionError("Cannot add metadata to a method type");
} }
@Override @Override
@ -1346,12 +1376,12 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
PackageType(TypeSymbol tsym) { PackageType(TypeSymbol tsym) {
// Package types cannot be annotated // Package types cannot be annotated
super(tsym, noAnnotations); super(tsym, TypeMetadata.empty);
} }
@Override @Override
public PackageType annotatedType(List<Attribute.TypeCompound> annos) { public PackageType clone(TypeMetadata md) {
throw new AssertionError("Cannot annotate a package type"); throw new AssertionError("Cannot add metadata to a package type");
} }
@Override @Override
@ -1402,26 +1432,26 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
public Type lower; public Type lower;
public TypeVar(Name name, Symbol owner, Type lower) { public TypeVar(Name name, Symbol owner, Type lower) {
this(name, owner, lower, noAnnotations); super(null, TypeMetadata.empty);
}
public TypeVar(Name name, Symbol owner, Type lower,
List<Attribute.TypeCompound> annos) {
super(null, annos);
tsym = new TypeVariableSymbol(0, name, this, owner); tsym = new TypeVariableSymbol(0, name, this, owner);
this.bound = bound;
this.lower = lower; this.lower = lower;
} }
public TypeVar(TypeSymbol tsym, Type bound, Type lower) {
this(tsym, bound, lower, TypeMetadata.empty);
}
public TypeVar(TypeSymbol tsym, Type bound, Type lower, public TypeVar(TypeSymbol tsym, Type bound, Type lower,
List<Attribute.TypeCompound> annos) { TypeMetadata metadata) {
super(tsym, annos); super(tsym, metadata);
this.bound = bound; this.bound = bound;
this.lower = lower; this.lower = lower;
} }
@Override @Override
public TypeVar annotatedType(List<Attribute.TypeCompound> annos) { public TypeVar clone(TypeMetadata md) {
return new TypeVar(tsym, bound, lower, annos); return new TypeVar(tsym, bound, lower, md);
} }
@Override @Override
@ -1486,9 +1516,8 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
Symbol owner, Symbol owner,
Type upper, Type upper,
Type lower, Type lower,
WildcardType wildcard, WildcardType wildcard) {
List<Attribute.TypeCompound> annos) { super(name, owner, lower);
super(name, owner, lower, annos);
this.lower = Assert.checkNonNull(lower); this.lower = Assert.checkNonNull(lower);
this.bound = upper; this.bound = upper;
this.wildcard = wildcard; this.wildcard = wildcard;
@ -1499,14 +1528,14 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
Type upper, Type upper,
Type lower, Type lower,
WildcardType wildcard, WildcardType wildcard,
List<Attribute.TypeCompound> annos) { TypeMetadata metadata) {
super(tsym, bound, lower, annos); super(tsym, bound, lower, metadata);
this.wildcard = wildcard; this.wildcard = wildcard;
} }
@Override @Override
public CapturedType annotatedType(List<Attribute.TypeCompound> annos) { public CapturedType clone(TypeMetadata md) {
return new CapturedType(tsym, bound, bound, lower, wildcard, annos); return new CapturedType(tsym, bound, bound, lower, wildcard, md);
} }
@Override @Override
@ -1534,12 +1563,18 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
public static abstract class DelegatedType extends Type { public static abstract class DelegatedType extends Type {
public Type qtype; public Type qtype;
public TypeTag tag; public TypeTag tag;
public DelegatedType(TypeTag tag, Type qtype) {
this(tag, qtype, TypeMetadata.empty);
}
public DelegatedType(TypeTag tag, Type qtype, public DelegatedType(TypeTag tag, Type qtype,
List<Attribute.TypeCompound> annos) { TypeMetadata metadata) {
super(qtype.tsym, annos); super(qtype.tsym, metadata);
this.tag = tag; this.tag = tag;
this.qtype = qtype; this.qtype = qtype;
} }
public TypeTag getTag() { return tag; } public TypeTag getTag() { return tag; }
@DefinedBy(Api.LANGUAGE_MODEL) @DefinedBy(Api.LANGUAGE_MODEL)
public String toString() { return qtype.toString(); } public String toString() { return qtype.toString(); }
@ -1563,13 +1598,13 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
public List<Type> tvars; public List<Type> tvars;
public ForAll(List<Type> tvars, Type qtype) { public ForAll(List<Type> tvars, Type qtype) {
super(FORALL, (MethodType)qtype, noAnnotations); super(FORALL, (MethodType)qtype);
this.tvars = tvars; this.tvars = tvars;
} }
@Override @Override
public ForAll annotatedType(List<Attribute.TypeCompound> annos) { public ForAll clone(TypeMetadata md) {
throw new AssertionError("Cannot annotate forall type"); throw new AssertionError("Cannot add metadata to a forall type");
} }
@Override @Override
@ -1685,7 +1720,7 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
public UndetVar(TypeVar origin, Types types) { public UndetVar(TypeVar origin, Types types) {
// This is a synthesized internal type, so we cannot annotate it. // This is a synthesized internal type, so we cannot annotate it.
super(UNDETVAR, origin, noAnnotations); super(UNDETVAR, origin);
bounds = new EnumMap<>(InferenceBound.class); bounds = new EnumMap<>(InferenceBound.class);
List<Type> declaredBounds = types.getBounds(origin); List<Type> declaredBounds = types.getBounds(origin);
declaredCount = declaredBounds.length(); declaredCount = declaredBounds.length();
@ -1722,8 +1757,8 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
} }
@Override @Override
public UndetVar annotatedType(List<Attribute.TypeCompound> annos) { public UndetVar clone(TypeMetadata md) {
throw new AssertionError("Cannot annotate an UndetVar type"); throw new AssertionError("Cannot add metadata to an UndetVar type");
} }
@Override @Override
@ -1882,12 +1917,12 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
// Need to use List.nil(), because JCNoType constructor // Need to use List.nil(), because JCNoType constructor
// gets called in static initializers in Type, where // gets called in static initializers in Type, where
// noAnnotations is also defined. // noAnnotations is also defined.
super(null, List.<Attribute.TypeCompound>nil()); super(null, TypeMetadata.empty);
} }
@Override @Override
public JCNoType annotatedType(List<Attribute.TypeCompound> annos) { public JCNoType clone(TypeMetadata md) {
throw new AssertionError("Cannot annotate JCNoType"); throw new AssertionError("Cannot add metadata to a JCNoType");
} }
@Override @Override
@ -1915,12 +1950,12 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
public JCVoidType() { public JCVoidType() {
// Void cannot be annotated // Void cannot be annotated
super(null, noAnnotations); super(null, TypeMetadata.empty);
} }
@Override @Override
public JCVoidType annotatedType(List<Attribute.TypeCompound> annos) { public JCVoidType clone(TypeMetadata md) {
throw new AssertionError("Cannot annotate void type"); throw new AssertionError("Cannot add metadata to a void type");
} }
@Override @Override
@ -1950,12 +1985,12 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
static class BottomType extends Type implements NullType { static class BottomType extends Type implements NullType {
public BottomType() { public BottomType() {
// Bottom is a synthesized internal type, so it cannot be annotated // Bottom is a synthesized internal type, so it cannot be annotated
super(null, noAnnotations); super(null, TypeMetadata.empty);
} }
@Override @Override
public BottomType annotatedType(List<Attribute.TypeCompound> annos) { public BottomType clone(TypeMetadata md) {
throw new AssertionError("Cannot annotate bottom type"); throw new AssertionError("Cannot add metadata to a bottom type");
} }
@Override @Override
@ -1998,17 +2033,6 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
private Type originalType = null; private Type originalType = null;
public ErrorType(Type originalType, TypeSymbol tsym) {
this(originalType, tsym, noAnnotations);
}
public ErrorType(Type originalType, TypeSymbol tsym,
List<Attribute.TypeCompound> typeAnnotations) {
super(noType, List.<Type>nil(), null, typeAnnotations);
this.tsym = tsym;
this.originalType = (originalType == null ? noType : originalType);
}
public ErrorType(ClassSymbol c, Type originalType) { public ErrorType(ClassSymbol c, Type originalType) {
this(originalType, c); this(originalType, c);
c.type = this; c.type = this;
@ -2016,9 +2040,22 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
c.members_field = new Scope.ErrorScope(c); c.members_field = new Scope.ErrorScope(c);
} }
public ErrorType(Type originalType, TypeSymbol tsym) {
super(noType, List.<Type>nil(), null);
this.tsym = tsym;
this.originalType = (originalType == null ? noType : originalType);
}
private ErrorType(Type originalType, TypeSymbol tsym,
TypeMetadata metadata) {
super(noType, List.<Type>nil(), null, metadata);
this.tsym = tsym;
this.originalType = (originalType == null ? noType : originalType);
}
@Override @Override
public ErrorType annotatedType(List<Attribute.TypeCompound> annos) { public ErrorType clone(TypeMetadata md) {
return new ErrorType(originalType, tsym, annos); return new ErrorType(originalType, tsym, md);
} }
@Override @Override
@ -2086,12 +2123,12 @@ public abstract class Type extends AnnoConstruct implements TypeMirror {
public UnknownType() { public UnknownType() {
// Unknown is a synthesized internal type, so it cannot be // Unknown is a synthesized internal type, so it cannot be
// annotated. // annotated.
super(null, noAnnotations); super(null, TypeMetadata.empty);
} }
@Override @Override
public UnknownType annotatedType(List<Attribute.TypeCompound> annos) { public UnknownType clone(TypeMetadata md) {
throw new AssertionError("Cannot annotate unknown type"); throw new AssertionError("Cannot add metadata to an unknown type");
} }
@Override @Override

View File

@ -396,8 +396,7 @@ public class TypeAnnotations {
} }
if (type.hasTag(TypeTag.ARRAY)) { if (type.hasTag(TypeTag.ARRAY)) {
Type.ArrayType arType = (Type.ArrayType) type; Type.ArrayType arType = (Type.ArrayType) type;
Type.ArrayType tomodify = new Type.ArrayType(null, arType.tsym, Type.ArrayType tomodify = new Type.ArrayType(null, arType.tsym);
Type.noAnnotations);
Type toreturn; Type toreturn;
if (type.isAnnotated()) { if (type.isAnnotated()) {
toreturn = tomodify.annotatedType(type.getAnnotationMirrors()); toreturn = tomodify.annotatedType(type.getAnnotationMirrors());
@ -414,13 +413,11 @@ public class TypeAnnotations {
Type aelemtype = arType.elemtype; Type aelemtype = arType.elemtype;
arType = (Type.ArrayType) aelemtype; arType = (Type.ArrayType) aelemtype;
ArrayType prevToMod = tomodify; ArrayType prevToMod = tomodify;
tomodify = new Type.ArrayType(null, arType.tsym, tomodify = new Type.ArrayType(null, arType.tsym);
Type.noAnnotations);
prevToMod.elemtype = tomodify.annotatedType(arType.elemtype.getAnnotationMirrors()); prevToMod.elemtype = tomodify.annotatedType(arType.elemtype.getAnnotationMirrors());
} else { } else {
arType = (Type.ArrayType) arType.elemtype; arType = (Type.ArrayType) arType.elemtype;
tomodify.elemtype = new Type.ArrayType(null, arType.tsym, tomodify.elemtype = new Type.ArrayType(null, arType.tsym);
Type.noAnnotations);
tomodify = (Type.ArrayType) tomodify.elemtype; tomodify = (Type.ArrayType) tomodify.elemtype;
} }
arTree = arrayTypeTree(arTree.elemtype); arTree = arrayTypeTree(arTree.elemtype);
@ -582,7 +579,7 @@ public class TypeAnnotations {
} else { } else {
ClassType ret = new ClassType(t.getEnclosingType().accept(this, s), ClassType ret = new ClassType(t.getEnclosingType().accept(this, s),
t.typarams_field, t.tsym, t.typarams_field, t.tsym,
t.getAnnotationMirrors()); t.getMetadata());
ret.all_interfaces_field = t.all_interfaces_field; ret.all_interfaces_field = t.all_interfaces_field;
ret.allparams_field = t.allparams_field; ret.allparams_field = t.allparams_field;
ret.interfaces_field = t.interfaces_field; ret.interfaces_field = t.interfaces_field;
@ -600,7 +597,7 @@ public class TypeAnnotations {
@Override @Override
public Type visitArrayType(ArrayType t, List<TypeCompound> s) { public Type visitArrayType(ArrayType t, List<TypeCompound> s) {
ArrayType ret = new ArrayType(t.elemtype.accept(this, s), t.tsym, ArrayType ret = new ArrayType(t.elemtype.accept(this, s), t.tsym,
t.getAnnotationMirrors()); t.getMetadata());
return ret; return ret;
} }

View File

@ -0,0 +1,171 @@
/*
* Copyright (c) 2014, Oracle and/or its affiliates. All rights
* reserved. DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE
* HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
package com.sun.tools.javac.code;
import com.sun.tools.javac.util.Assert;
import com.sun.tools.javac.util.List;
import java.util.EnumMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
/**
* A super-interface for all type metadata elements. Metadata classes
* can be created for any metadata on types with the following
* properties:
*
* <ul>
* <li>They have a default value (preferably empty)</li>
* <li>The field is usually the default value</li>
* <li>Different values of the field are visible, and denote distinct
* types</li>
* </ul>
*/
public class TypeMetadata {
public static final TypeMetadata empty = new TypeMetadata();
private final EnumMap<TypeMetadata.Element.Kind, TypeMetadata.Element> contents;
private TypeMetadata() {
contents = new EnumMap<Element.Kind, Element>(Element.Kind.class);
}
public TypeMetadata(final Element elem) {
this();
contents.put(elem.kind(), elem);
}
public TypeMetadata(final TypeMetadata other) {
contents = other.contents.clone();
}
public TypeMetadata copy() {
return new TypeMetadata(this);
}
public TypeMetadata combine(final Element elem) {
final TypeMetadata out = new TypeMetadata(this);
final Element.Kind key = elem.kind();
if (contents.containsKey(key)) {
out.add(key, this.contents.get(key).combine(elem));
} else {
out.add(key, elem);
}
return out;
}
public TypeMetadata combine(final TypeMetadata other) {
final TypeMetadata out = new TypeMetadata();
final Set<Element.Kind> keys = new HashSet<>(this.contents.keySet());
keys.addAll(other.contents.keySet());
for(final Element.Kind key : keys) {
if (this.contents.containsKey(key)) {
if (other.contents.containsKey(key)) {
out.add(key, this.contents.get(key).combine(other.contents.get(key)));
} else {
out.add(key, this.contents.get(key));
}
} else if (other.contents.containsKey(key)) {
out.add(key, other.contents.get(key));
}
}
return out;
}
public Element get(final Element.Kind kind) {
return contents.get(kind);
}
public boolean isEmpty() {
return contents.isEmpty();
}
private void add(final Element.Kind kind, final Element elem) {
contents.put(kind, elem);
}
private void addAll(final Map<? extends Element.Kind,? extends Element> m) {
contents.putAll(m);
}
public interface Element {
public enum Kind {
ANNOTATIONS;
}
/**
* Get the kind of metadata this object represents
*/
public Kind kind();
/**
* Combine this type metadata with another metadata of the
* same kind.
*
* @param other The metadata with which to combine this one.
* @return The combined metadata.
*/
public Element combine(Element other);
}
/**
* A type metadata object holding type annotations.
*/
public static class Annotations implements Element {
private final List<Attribute.TypeCompound> annos;
public Annotations(final List<Attribute.TypeCompound> annos) {
this.annos = annos;
}
/**
* Get the type annotations contained in this metadata.
*
* @return The annotations.
*/
public List<Attribute.TypeCompound> getAnnotations() {
return annos;
}
@Override
public Annotations combine(final Element other) {
// Temporary: we should append the lists, but that won't
// work with type annotations today. Instead, we replace
// the list.
return new Annotations(((Annotations) other).annos);
}
@Override
public Kind kind() { return Kind.ANNOTATIONS; }
@Override
public String toString() { return "ANNOTATIONS { " + annos + " }"; }
}
}

View File

@ -258,8 +258,7 @@ public class Types {
ListBuffer<Type> qs = new ListBuffer<>(); ListBuffer<Type> qs = new ListBuffer<>();
for (List<Type> iter = opens; iter.nonEmpty(); iter = iter.tail) { for (List<Type> iter = opens; iter.nonEmpty(); iter = iter.tail) {
qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND, qs.append(new WildcardType(syms.objectType, BoundKind.UNBOUND,
syms.boundClass, (TypeVar) iter.head, syms.boundClass, (TypeVar) iter.head));
Type.noAnnotations));
} }
res = subst(res, opens, qs.toList()); res = subst(res, opens, qs.toList());
} }
@ -631,8 +630,7 @@ public class Types {
csym.members_field = WriteableScope.create(csym); csym.members_field = WriteableScope.create(csym);
MethodSymbol instDescSym = new MethodSymbol(descSym.flags(), descSym.name, descType, csym); MethodSymbol instDescSym = new MethodSymbol(descSym.flags(), descSym.name, descType, csym);
csym.members_field.enter(instDescSym); csym.members_field.enter(instDescSym);
Type.ClassType ctype = new Type.ClassType(Type.noType, List.<Type>nil(), csym, Type.ClassType ctype = new Type.ClassType(Type.noType, List.<Type>nil(), csym);
Type.noAnnotations);
ctype.supertype_field = syms.objectType; ctype.supertype_field = syms.objectType;
ctype.interfaces_field = targets; ctype.interfaces_field = targets;
csym.type = ctype; csym.type = ctype;
@ -881,13 +879,13 @@ public class Types {
s = new WildcardType(syms.objectType, s = new WildcardType(syms.objectType,
BoundKind.UNBOUND, BoundKind.UNBOUND,
syms.boundClass, syms.boundClass,
s.getAnnotationMirrors()); s.getMetadata());
changed = true; changed = true;
} else if (s != orig) { } else if (s != orig) {
s = new WildcardType(wildUpperBound(s), s = new WildcardType(wildUpperBound(s),
BoundKind.EXTENDS, BoundKind.EXTENDS,
syms.boundClass, syms.boundClass,
s.getAnnotationMirrors()); s.getMetadata());
changed = true; changed = true;
} }
rewrite.append(s); rewrite.append(s);
@ -1916,7 +1914,7 @@ public class Types {
if (t.hasTag(VOID) || t.hasTag(PACKAGE)) { if (t.hasTag(VOID) || t.hasTag(PACKAGE)) {
Assert.error("Type t must not be a VOID or PACKAGE type, " + t.toString()); Assert.error("Type t must not be a VOID or PACKAGE type, " + t.toString());
} }
return new ArrayType(t, syms.arrayClass, Type.noAnnotations); return new ArrayType(t, syms.arrayClass);
} }
// </editor-fold> // </editor-fold>
@ -2182,40 +2180,50 @@ public class Types {
} }
// where // where
private SimpleVisitor<Type, Boolean> erasure = new SimpleVisitor<Type, Boolean>() { private SimpleVisitor<Type, Boolean> erasure = new SimpleVisitor<Type, Boolean>() {
private Type combineMetadata(final Type ty,
final TypeMetadata md) {
if (!md.isEmpty()) {
switch (ty.getKind()) {
default: return ty.clone(ty.metadata.combine(md));
case OTHER:
case UNION:
case INTERSECTION:
case PACKAGE:
case EXECUTABLE:
case NONE:
case VOID:
case ERROR:
return ty;
}
} else {
return ty;
}
}
public Type visitType(Type t, Boolean recurse) { public Type visitType(Type t, Boolean recurse) {
if (t.isPrimitive()) if (t.isPrimitive())
return t; /*fast special case*/ return t; /*fast special case*/
else { else {
final List<Attribute.TypeCompound> annos = t.getAnnotationMirrors();
Type erased = t.map(recurse ? erasureRecFun : erasureFun); Type erased = t.map(recurse ? erasureRecFun : erasureFun);
if (!annos.isEmpty()) { return combineMetadata(erased, t.getMetadata());
erased = erased.annotatedType(annos);
}
return erased;
} }
} }
@Override @Override
public Type visitClassType(ClassType t, Boolean recurse) { public Type visitClassType(ClassType t, Boolean recurse) {
Type erased = t.tsym.erasure(Types.this); Type erased = t.tsym.erasure(Types.this);
List<Attribute.TypeCompound> annos = t.getAnnotationMirrors();
if (recurse) { if (recurse) {
erased = new ErasedClassType(erased.getEnclosingType(),erased.tsym); erased = new ErasedClassType(erased.getEnclosingType(),erased.tsym, t.getMetadata());
}
if (!annos.isEmpty()) {
erased = erased.annotatedType(annos);
}
return erased; return erased;
} else {
return combineMetadata(erased, t.getMetadata());
}
} }
@Override @Override
public Type visitTypeVar(TypeVar t, Boolean recurse) { public Type visitTypeVar(TypeVar t, Boolean recurse) {
final List<Attribute.TypeCompound> annos = t.getAnnotationMirrors();
Type erased = erasure(t.bound, recurse); Type erased = erasure(t.bound, recurse);
if (!annos.isEmpty()) { return combineMetadata(erased, t.getMetadata());
erased = erased.annotatedType(annos);
}
return erased;
} }
@Override @Override
@ -2547,7 +2555,7 @@ public class Types {
Type outer1 = classBound(t.getEnclosingType()); Type outer1 = classBound(t.getEnclosingType());
if (outer1 != t.getEnclosingType()) if (outer1 != t.getEnclosingType())
return new ClassType(outer1, t.getTypeArguments(), t.tsym, return new ClassType(outer1, t.getTypeArguments(), t.tsym,
t.getAnnotationMirrors()); t.getMetadata());
else else
return t; return t;
} }
@ -2967,7 +2975,7 @@ public class Types {
return t; return t;
else else
return new ClassType(outer1, typarams1, t.tsym, return new ClassType(outer1, typarams1, t.tsym,
t.getAnnotationMirrors()); t.getMetadata());
} else { } else {
Type st = subst(supertype(t)); Type st = subst(supertype(t));
List<Type> is = subst(interfaces(t)); List<Type> is = subst(interfaces(t));
@ -2989,7 +2997,7 @@ public class Types {
if (t.isExtendsBound() && bound.isExtendsBound()) if (t.isExtendsBound() && bound.isExtendsBound())
bound = wildUpperBound(bound); bound = wildUpperBound(bound);
return new WildcardType(bound, t.kind, syms.boundClass, return new WildcardType(bound, t.kind, syms.boundClass,
t.bound, t.getAnnotationMirrors()); t.bound, t.getMetadata());
} }
} }
@ -2999,7 +3007,7 @@ public class Types {
if (elemtype == t.elemtype) if (elemtype == t.elemtype)
return t; return t;
else else
return new ArrayType(elemtype, t.tsym, t.getAnnotationMirrors()); return new ArrayType(elemtype, t.tsym, t.getMetadata());
} }
@Override @Override
@ -3050,7 +3058,7 @@ public class Types {
// create new type variables without bounds // create new type variables without bounds
for (Type t : tvars) { for (Type t : tvars) {
newTvars.append(new TypeVar(t.tsym, null, syms.botType, newTvars.append(new TypeVar(t.tsym, null, syms.botType,
t.getAnnotationMirrors())); t.getMetadata()));
} }
// the new bounds should use the new type variables in place // the new bounds should use the new type variables in place
// of the old // of the old
@ -3077,7 +3085,7 @@ public class Types {
else { else {
// create new type variable without bounds // create new type variable without bounds
TypeVar tv = new TypeVar(t.tsym, null, syms.botType, TypeVar tv = new TypeVar(t.tsym, null, syms.botType,
t.getAnnotationMirrors()); t.getMetadata());
// the new bound should use the new type variable in place // the new bound should use the new type variable in place
// of the old // of the old
tv.bound = subst(bound1, List.<Type>of(t), List.<Type>of(tv)); tv.bound = subst(bound1, List.<Type>of(t), List.<Type>of(tv));
@ -3118,7 +3126,7 @@ public class Types {
return tvars1; return tvars1;
} }
private static final Mapping newInstanceFun = new Mapping("newInstanceFun") { private static final Mapping newInstanceFun = new Mapping("newInstanceFun") {
public Type apply(Type t) { return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound(), t.getAnnotationMirrors()); } public Type apply(Type t) { return new TypeVar(t.tsym, t.getUpperBound(), t.getLowerBound(), t.getMetadata()); }
}; };
// </editor-fold> // </editor-fold>
@ -3451,14 +3459,12 @@ public class Types {
m = new WildcardType(lub(wildUpperBound(act1.head), m = new WildcardType(lub(wildUpperBound(act1.head),
wildUpperBound(act2.head)), wildUpperBound(act2.head)),
BoundKind.EXTENDS, BoundKind.EXTENDS,
syms.boundClass, syms.boundClass);
Type.noAnnotations);
mergeCache.remove(pair); mergeCache.remove(pair);
} else { } else {
m = new WildcardType(syms.objectType, m = new WildcardType(syms.objectType,
BoundKind.UNBOUND, BoundKind.UNBOUND,
syms.boundClass, syms.boundClass);
Type.noAnnotations);
} }
merged.append(m.withTypeVar(typarams.head)); merged.append(m.withTypeVar(typarams.head));
} }
@ -3470,7 +3476,7 @@ public class Types {
// There is no spec detailing how type annotations are to // There is no spec detailing how type annotations are to
// be inherited. So set it to noAnnotations for now // be inherited. So set it to noAnnotations for now
return new ClassType(class1.getEnclosingType(), merged.toList(), return new ClassType(class1.getEnclosingType(), merged.toList(),
class1.tsym, Type.noAnnotations); class1.tsym);
} }
/** /**
@ -3588,8 +3594,7 @@ public class Types {
} }
} }
// lub(A[], B[]) is lub(A, B)[] // lub(A[], B[]) is lub(A, B)[]
return new ArrayType(lub(elements), syms.arrayClass, return new ArrayType(lub(elements), syms.arrayClass);
Type.noAnnotations);
case CLASS_BOUND: case CLASS_BOUND:
// calculate lub(A, B) // calculate lub(A, B)
@ -3999,7 +4004,7 @@ public class Types {
if (captured) if (captured)
return new ClassType(cls.getEnclosingType(), S, cls.tsym, return new ClassType(cls.getEnclosingType(), S, cls.tsym,
cls.getAnnotationMirrors()); cls.getMetadata());
else else
return t; return t;
} }
@ -4015,8 +4020,7 @@ public class Types {
syms.noSymbol, syms.noSymbol,
bound, bound,
syms.botType, syms.botType,
(WildcardType)t, (WildcardType)t));
Type.noAnnotations));
} else { } else {
result.append(t); result.append(t);
} }
@ -4375,14 +4379,12 @@ public class Types {
return new WildcardType(syms.objectType, return new WildcardType(syms.objectType,
BoundKind.UNBOUND, BoundKind.UNBOUND,
syms.boundClass, syms.boundClass,
formal, formal);
Type.noAnnotations);
} else { } else {
return new WildcardType(bound, return new WildcardType(bound,
BoundKind.EXTENDS, BoundKind.EXTENDS,
syms.boundClass, syms.boundClass,
formal, formal);
Type.noAnnotations);
} }
} }
@ -4399,14 +4401,12 @@ public class Types {
return new WildcardType(syms.objectType, return new WildcardType(syms.objectType,
BoundKind.UNBOUND, BoundKind.UNBOUND,
syms.boundClass, syms.boundClass,
formal, formal);
Type.noAnnotations);
} else { } else {
return new WildcardType(bound, return new WildcardType(bound,
BoundKind.SUPER, BoundKind.SUPER,
syms.boundClass, syms.boundClass,
formal, formal);
Type.noAnnotations);
} }
} }

View File

@ -1797,10 +1797,9 @@ public class Attr extends JCTree.Visitor {
return new ClassType(restype.getEnclosingType(), return new ClassType(restype.getEnclosingType(),
List.<Type>of(new WildcardType(types.erasure(qualifierType), List.<Type>of(new WildcardType(types.erasure(qualifierType),
BoundKind.EXTENDS, BoundKind.EXTENDS,
syms.boundClass, syms.boundClass)),
Type.noAnnotations)),
restype.tsym, restype.tsym,
restype.getAnnotationMirrors()); restype.getMetadata());
} else { } else {
return restype; return restype;
} }
@ -1970,7 +1969,7 @@ public class Attr extends JCTree.Visitor {
ClassType site = new ClassType(clazztype.getEnclosingType(), ClassType site = new ClassType(clazztype.getEnclosingType(),
clazztype.tsym.type.getTypeArguments(), clazztype.tsym.type.getTypeArguments(),
clazztype.tsym, clazztype.tsym,
clazztype.getAnnotationMirrors()); clazztype.getMetadata());
Env<AttrContext> diamondEnv = localEnv.dup(tree); Env<AttrContext> diamondEnv = localEnv.dup(tree);
diamondEnv.info.selectSuper = cdef != null; diamondEnv.info.selectSuper = cdef != null;
@ -2189,8 +2188,7 @@ public class Attr extends JCTree.Visitor {
owntype = elemtype; owntype = elemtype;
for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) { for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) {
attribExpr(l.head, localEnv, syms.intType); attribExpr(l.head, localEnv, syms.intType);
owntype = new ArrayType(owntype, syms.arrayClass, owntype = new ArrayType(owntype, syms.arrayClass);
Type.noAnnotations);
} }
} else { } else {
// we are seeing an untyped aggregate { ... } // we are seeing an untyped aggregate { ... }
@ -2207,8 +2205,7 @@ public class Attr extends JCTree.Visitor {
} }
if (tree.elems != null) { if (tree.elems != null) {
attribExprs(tree.elems, localEnv, elemtype); attribExprs(tree.elems, localEnv, elemtype);
owntype = new ArrayType(elemtype, syms.arrayClass, owntype = new ArrayType(elemtype, syms.arrayClass);
Type.noAnnotations);
} }
if (!types.isReifiable(elemtype)) if (!types.isReifiable(elemtype))
log.error(tree.pos(), "generic.array.creation"); log.error(tree.pos(), "generic.array.creation");
@ -3195,7 +3192,8 @@ public class Attr extends JCTree.Visitor {
elt = ((ArrayType)elt).elemtype; elt = ((ArrayType)elt).elemtype;
if (elt.hasTag(TYPEVAR)) { if (elt.hasTag(TYPEVAR)) {
log.error(tree.pos(), "type.var.cant.be.deref"); log.error(tree.pos(), "type.var.cant.be.deref");
result = types.createErrorType(tree.type); result = tree.type = types.createErrorType(tree.name, site.tsym, site);
tree.sym = tree.type.tsym;
return ; return ;
} }
} }
@ -3508,7 +3506,7 @@ public class Attr extends JCTree.Visitor {
if (normOuter != ownOuter) if (normOuter != ownOuter)
owntype = new ClassType( owntype = new ClassType(
normOuter, List.<Type>nil(), owntype.tsym, normOuter, List.<Type>nil(), owntype.tsym,
owntype.getAnnotationMirrors()); owntype.getMetadata());
} }
} }
break; break;
@ -3829,7 +3827,7 @@ public class Attr extends JCTree.Visitor {
public void visitTypeArray(JCArrayTypeTree tree) { public void visitTypeArray(JCArrayTypeTree tree) {
Type etype = attribType(tree.elemtype, env); Type etype = attribType(tree.elemtype, env);
Type type = new ArrayType(etype, syms.arrayClass, Type.noAnnotations); Type type = new ArrayType(etype, syms.arrayClass);
result = check(tree, type, TYP, resultInfo); result = check(tree, type, TYP, resultInfo);
} }
@ -3878,7 +3876,7 @@ public class Attr extends JCTree.Visitor {
} }
} }
owntype = new ClassType(clazzOuter, actuals, clazztype.tsym, owntype = new ClassType(clazzOuter, actuals, clazztype.tsym,
clazztype.getAnnotationMirrors()); clazztype.getMetadata());
} else { } else {
if (formals.length() != 0) { if (formals.length() != 0) {
log.error(tree.pos(), "wrong.number.type.args", log.error(tree.pos(), "wrong.number.type.args",
@ -4029,8 +4027,7 @@ public class Attr extends JCTree.Visitor {
: attribType(tree.inner, env); : attribType(tree.inner, env);
result = check(tree, new WildcardType(chk.checkRefType(tree.pos(), type), result = check(tree, new WildcardType(chk.checkRefType(tree.pos(), type),
tree.kind.kind, tree.kind.kind,
syms.boundClass, syms.boundClass),
Type.noAnnotations),
TYP, resultInfo); TYP, resultInfo);
} }

View File

@ -137,15 +137,15 @@ public class DeferredAttr extends JCTree.Visitor {
SpeculativeCache speculativeCache; SpeculativeCache speculativeCache;
DeferredType(JCExpression tree, Env<AttrContext> env) { DeferredType(JCExpression tree, Env<AttrContext> env) {
super(null, noAnnotations); super(null, TypeMetadata.empty);
this.tree = tree; this.tree = tree;
this.env = attr.copyEnv(env); this.env = attr.copyEnv(env);
this.speculativeCache = new SpeculativeCache(); this.speculativeCache = new SpeculativeCache();
} }
@Override @Override
public DeferredType annotatedType(List<Attribute.TypeCompound> typeAnnotations) { public DeferredType clone(TypeMetadata md) {
throw new AssertionError("Cannot annotate a deferred type"); throw new AssertionError("Cannot add metadata to a deferred type");
} }
@Override @Override

View File

@ -418,7 +418,7 @@ public class Infer {
List<Type> upperBounds = uv.getBounds(InferenceBound.UPPER); List<Type> upperBounds = uv.getBounds(InferenceBound.UPPER);
if (Type.containsAny(upperBounds, vars)) { if (Type.containsAny(upperBounds, vars)) {
TypeSymbol fresh_tvar = new TypeVariableSymbol(Flags.SYNTHETIC, uv.qtype.tsym.name, null, uv.qtype.tsym.owner); TypeSymbol fresh_tvar = new TypeVariableSymbol(Flags.SYNTHETIC, uv.qtype.tsym.name, null, uv.qtype.tsym.owner);
fresh_tvar.type = new TypeVar(fresh_tvar, types.makeCompoundType(uv.getBounds(InferenceBound.UPPER)), null, Type.noAnnotations); fresh_tvar.type = new TypeVar(fresh_tvar, types.makeCompoundType(uv.getBounds(InferenceBound.UPPER)), null);
todo.append(uv); todo.append(uv);
uv.inst = fresh_tvar.type; uv.inst = fresh_tvar.type;
} else if (upperBounds.nonEmpty()) { } else if (upperBounds.nonEmpty()) {
@ -1562,8 +1562,7 @@ public class Infer {
infer.syms.botType; infer.syms.botType;
CapturedType prevCaptured = (CapturedType)uv.qtype; CapturedType prevCaptured = (CapturedType)uv.qtype;
return new CapturedType(prevCaptured.tsym.name, prevCaptured.tsym.owner, return new CapturedType(prevCaptured.tsym.name, prevCaptured.tsym.owner,
upper, lower, prevCaptured.wildcard, upper, lower, prevCaptured.wildcard);
Type.noAnnotations);
} }
}; };

View File

@ -451,8 +451,7 @@ public class Lower extends TreeTranslator {
ClassSymbol outerCacheClass = outerCacheClass(); ClassSymbol outerCacheClass = outerCacheClass();
this.mapVar = new VarSymbol(STATIC | SYNTHETIC | FINAL, this.mapVar = new VarSymbol(STATIC | SYNTHETIC | FINAL,
varName, varName,
new ArrayType(syms.intType, syms.arrayClass, new ArrayType(syms.intType, syms.arrayClass),
Type.noAnnotations),
outerCacheClass); outerCacheClass);
enterSynthetic(pos, mapVar, outerCacheClass.members()); enterSynthetic(pos, mapVar, outerCacheClass.members());
} }
@ -493,8 +492,7 @@ public class Lower extends TreeTranslator {
syms.lengthVar); syms.lengthVar);
JCExpression mapVarInit = make JCExpression mapVarInit = make
.NewArray(make.Type(syms.intType), List.of(size), null) .NewArray(make.Type(syms.intType), List.of(size), null)
.setType(new ArrayType(syms.intType, syms.arrayClass, .setType(new ArrayType(syms.intType, syms.arrayClass));
Type.noAnnotations));
// try { $SwitchMap$Color[red.ordinal()] = 1; } catch (java.lang.NoSuchFieldError ex) {} // try { $SwitchMap$Color[red.ordinal()] = 1; } catch (java.lang.NoSuchFieldError ex) {}
ListBuffer<JCStatement> stmts = new ListBuffer<>(); ListBuffer<JCStatement> stmts = new ListBuffer<>();
@ -1966,7 +1964,7 @@ public class Lower extends TreeTranslator {
List.<JCExpression>of(make.Literal(INT, 0).setType(syms.intType)), List.<JCExpression>of(make.Literal(INT, 0).setType(syms.intType)),
null); null);
newcache.type = new ArrayType(types.erasure(outerCacheClass.type), newcache.type = new ArrayType(types.erasure(outerCacheClass.type),
syms.arrayClass, Type.noAnnotations); syms.arrayClass);
// forNameSym := java.lang.Class.forName( // forNameSym := java.lang.Class.forName(
// String s,boolean init,ClassLoader loader) // String s,boolean init,ClassLoader loader)
@ -2506,8 +2504,7 @@ public class Lower extends TreeTranslator {
Name valuesName = names.fromString(target.syntheticNameChar() + "VALUES"); Name valuesName = names.fromString(target.syntheticNameChar() + "VALUES");
while (tree.sym.members().findFirst(valuesName) != null) // avoid name clash while (tree.sym.members().findFirst(valuesName) != null) // avoid name clash
valuesName = names.fromString(valuesName + "" + target.syntheticNameChar()); valuesName = names.fromString(valuesName + "" + target.syntheticNameChar());
Type arrayType = new ArrayType(types.erasure(tree.type), Type arrayType = new ArrayType(types.erasure(tree.type), syms.arrayClass);
syms.arrayClass, Type.noAnnotations);
VarSymbol valuesVar = new VarSymbol(PRIVATE|FINAL|STATIC|SYNTHETIC, VarSymbol valuesVar = new VarSymbol(PRIVATE|FINAL|STATIC|SYNTHETIC,
valuesName, valuesName,
arrayType, arrayType,
@ -3077,8 +3074,7 @@ public class Lower extends TreeTranslator {
JCNewArray boxedArgs = make.NewArray(make.Type(varargsElement), JCNewArray boxedArgs = make.NewArray(make.Type(varargsElement),
List.<JCExpression>nil(), List.<JCExpression>nil(),
elems.toList()); elems.toList());
boxedArgs.type = new ArrayType(varargsElement, syms.arrayClass, boxedArgs.type = new ArrayType(varargsElement, syms.arrayClass);
Type.noAnnotations);
result.append(boxedArgs); result.append(boxedArgs);
} else { } else {
if (args.length() != 1) throw new AssertionError(args); if (args.length() != 1) throw new AssertionError(args);

View File

@ -403,8 +403,7 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
* to the symbol table. * to the symbol table.
*/ */
private void addEnumMembers(JCClassDecl tree, Env<AttrContext> env) { private void addEnumMembers(JCClassDecl tree, Env<AttrContext> env) {
JCExpression valuesType = make.Type(new ArrayType(tree.sym.type, syms.arrayClass, JCExpression valuesType = make.Type(new ArrayType(tree.sym.type, syms.arrayClass));
Type.noAnnotations));
// public static T[] values() { return ???; } // public static T[] values() { return ???; }
JCMethodDecl values = make. JCMethodDecl values = make.
@ -1234,13 +1233,12 @@ public class MemberEnter extends JCTree.Visitor implements Completer {
ClassType ct = (ClassType) sym.type; ClassType ct = (ClassType) sym.type;
Assert.check(ct.typarams_field.isEmpty()); Assert.check(ct.typarams_field.isEmpty());
if (n == 1) { if (n == 1) {
TypeVar v = new TypeVar(names.fromString("T"), sym, syms.botType, TypeVar v = new TypeVar(names.fromString("T"), sym, syms.botType);
Type.noAnnotations);
ct.typarams_field = ct.typarams_field.prepend(v); ct.typarams_field = ct.typarams_field.prepend(v);
} else { } else {
for (int i = n; i > 0; i--) { for (int i = n; i > 0; i--) {
TypeVar v = new TypeVar(names.fromString("T" + i), sym, TypeVar v = new TypeVar(names.fromString("T" + i), sym,
syms.botType, Type.noAnnotations); syms.botType);
ct.typarams_field = ct.typarams_field.prepend(v); ct.typarams_field = ct.typarams_field.prepend(v);
} }
} }

View File

@ -3225,7 +3225,7 @@ public class Resolve {
List<Type> typeargtypes, MethodResolutionPhase maxPhase) { List<Type> typeargtypes, MethodResolutionPhase maxPhase) {
super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase); super(referenceTree, names.init, site, argtypes, typeargtypes, maxPhase);
if (site.isRaw()) { if (site.isRaw()) {
this.site = new ClassType(site.getEnclosingType(), site.tsym.type.getTypeArguments(), site.tsym, site.getAnnotationMirrors()); this.site = new ClassType(site.getEnclosingType(), site.tsym.type.getTypeArguments(), site.tsym, site.getMetadata());
needsInference = true; needsInference = true;
} }
} }

View File

@ -543,18 +543,16 @@ public class ClassReader {
case '+': { case '+': {
sigp++; sigp++;
Type t = sigToType(); Type t = sigToType();
return new WildcardType(t, BoundKind.EXTENDS, syms.boundClass, return new WildcardType(t, BoundKind.EXTENDS, syms.boundClass);
Type.noAnnotations);
} }
case '*': case '*':
sigp++; sigp++;
return new WildcardType(syms.objectType, BoundKind.UNBOUND, return new WildcardType(syms.objectType, BoundKind.UNBOUND,
syms.boundClass, Type.noAnnotations); syms.boundClass);
case '-': { case '-': {
sigp++; sigp++;
Type t = sigToType(); Type t = sigToType();
return new WildcardType(t, BoundKind.SUPER, syms.boundClass, return new WildcardType(t, BoundKind.SUPER, syms.boundClass);
Type.noAnnotations);
} }
case 'B': case 'B':
sigp++; sigp++;
@ -599,8 +597,7 @@ public class ClassReader {
return syms.booleanType; return syms.booleanType;
case '[': case '[':
sigp++; sigp++;
return new ArrayType(sigToType(), syms.arrayClass, return new ArrayType(sigToType(), syms.arrayClass);
Type.noAnnotations);
case '(': case '(':
sigp++; sigp++;
List<Type> argtypes = sigToTypes(')'); List<Type> argtypes = sigToTypes(')');
@ -655,8 +652,7 @@ public class ClassReader {
try { try {
return (outer == Type.noType) ? return (outer == Type.noType) ?
t.erasure(types) : t.erasure(types) :
new ClassType(outer, List.<Type>nil(), t, new ClassType(outer, List.<Type>nil(), t);
Type.noAnnotations);
} finally { } finally {
sbp = startSbp; sbp = startSbp;
} }
@ -666,8 +662,7 @@ public class ClassReader {
ClassSymbol t = syms.enterClass(names.fromUtf(signatureBuffer, ClassSymbol t = syms.enterClass(names.fromUtf(signatureBuffer,
startSbp, startSbp,
sbp - startSbp)); sbp - startSbp));
outer = new ClassType(outer, sigToTypes('>'), t, outer = new ClassType(outer, sigToTypes('>'), t) {
Type.noAnnotations) {
boolean completed = false; boolean completed = false;
@Override @DefinedBy(Api.LANGUAGE_MODEL) @Override @DefinedBy(Api.LANGUAGE_MODEL)
public Type getEnclosingType() { public Type getEnclosingType() {
@ -730,8 +725,7 @@ public class ClassReader {
t = syms.enterClass(names.fromUtf(signatureBuffer, t = syms.enterClass(names.fromUtf(signatureBuffer,
startSbp, startSbp,
sbp - startSbp)); sbp - startSbp));
outer = new ClassType(outer, List.<Type>nil(), t, outer = new ClassType(outer, List.<Type>nil(), t);
Type.noAnnotations);
} }
signatureBuffer[sbp++] = (byte)'$'; signatureBuffer[sbp++] = (byte)'$';
continue; continue;
@ -794,8 +788,7 @@ public class ClassReader {
Name name = names.fromUtf(signature, start, sigp - start); Name name = names.fromUtf(signature, start, sigp - start);
TypeVar tvar; TypeVar tvar;
if (sigEnterPhase) { if (sigEnterPhase) {
tvar = new TypeVar(name, currentOwner, syms.botType, tvar = new TypeVar(name, currentOwner, syms.botType);
Type.noAnnotations);
typevars.enter(tvar.tsym); typevars.enter(tvar.tsym);
} else { } else {
tvar = (TypeVar)findTypeVar(name); tvar = (TypeVar)findTypeVar(name);
@ -834,8 +827,7 @@ public class ClassReader {
// we don't know for sure if this owner is correct. It could // we don't know for sure if this owner is correct. It could
// be a method and there is no way to tell before reading the // be a method and there is no way to tell before reading the
// enclosing method attribute. // enclosing method attribute.
TypeVar t = new TypeVar(name, currentOwner, syms.botType, TypeVar t = new TypeVar(name, currentOwner, syms.botType);
Type.noAnnotations);
missingTypeVariables = missingTypeVariables.prepend(t); missingTypeVariables = missingTypeVariables.prepend(t);
// System.err.println("Missing type var " + name); // System.err.println("Missing type var " + name);
return t; return t;

View File

@ -43,24 +43,24 @@ class UninitializedType extends Type.DelegatedType {
public static UninitializedType uninitializedThis(Type qtype) { public static UninitializedType uninitializedThis(Type qtype) {
return new UninitializedType(UNINITIALIZED_THIS, qtype, -1, return new UninitializedType(UNINITIALIZED_THIS, qtype, -1,
qtype.getAnnotationMirrors()); qtype.getMetadata());
} }
public static UninitializedType uninitializedObject(Type qtype, int offset) { public static UninitializedType uninitializedObject(Type qtype, int offset) {
return new UninitializedType(UNINITIALIZED_OBJECT, qtype, offset, return new UninitializedType(UNINITIALIZED_OBJECT, qtype, offset,
qtype.getAnnotationMirrors()); qtype.getMetadata());
} }
public final int offset; // PC where allocation took place public final int offset; // PC where allocation took place
private UninitializedType(TypeTag tag, Type qtype, int offset, private UninitializedType(TypeTag tag, Type qtype, int offset,
List<Attribute.TypeCompound> typeAnnotations) { TypeMetadata metadata) {
super(tag, qtype, typeAnnotations); super(tag, qtype, metadata);
this.offset = offset; this.offset = offset;
} }
@Override @Override
public UninitializedType annotatedType(List<Attribute.TypeCompound> typeAnnotations) { public UninitializedType clone(final TypeMetadata md) {
return new UninitializedType(tag, qtype, offset, typeAnnotations); return new UninitializedType(tag, qtype, offset, md);
} }
Type initializedType() { Type initializedType() {

View File

@ -184,8 +184,7 @@ public class JavacTypes implements javax.lang.model.util.Types {
case PACKAGE: case PACKAGE:
throw new IllegalArgumentException(componentType.toString()); throw new IllegalArgumentException(componentType.toString());
} }
return new Type.ArrayType((Type) componentType, syms.arrayClass, return new Type.ArrayType((Type) componentType, syms.arrayClass);
Type.noAnnotations);
} }
@DefinedBy(Api.LANGUAGE_MODEL) @DefinedBy(Api.LANGUAGE_MODEL)
@ -211,8 +210,7 @@ public class JavacTypes implements javax.lang.model.util.Types {
case DECLARED: case DECLARED:
case ERROR: case ERROR:
case TYPEVAR: case TYPEVAR:
return new Type.WildcardType(bound, bkind, syms.boundClass, return new Type.WildcardType(bound, bkind, syms.boundClass);
Type.noAnnotations);
default: default:
throw new IllegalArgumentException(bound.toString()); throw new IllegalArgumentException(bound.toString());
} }
@ -264,8 +262,7 @@ public class JavacTypes implements javax.lang.model.util.Types {
} }
// TODO: Would like a way to check that type args match formals. // TODO: Would like a way to check that type args match formals.
return (DeclaredType) new Type.ClassType(outer, targs.toList(), sym, return (DeclaredType) new Type.ClassType(outer, targs.toList(), sym);
Type.noAnnotations);
} }
/** /**

View File

@ -1089,8 +1089,7 @@ public class JavacProcessingEnvironment implements ProcessingEnvironment, Closea
for (ClassSymbol cs : symtab.classes.values()) { for (ClassSymbol cs : symtab.classes.values()) {
if (cs.classfile != null || cs.kind == Kinds.ERR) { if (cs.classfile != null || cs.kind == Kinds.ERR) {
cs.reset(); cs.reset();
cs.type = new ClassType(cs.type.getEnclosingType(), cs.type = new ClassType(cs.type.getEnclosingType(), null, cs);
null, cs, Type.noAnnotations);
if (cs.completer == null) { if (cs.completer == null) {
cs.completer = initialCompleter; cs.completer = initialCompleter;
} }

View File

@ -0,0 +1,12 @@
/**
* @test /nodynamiccopyright/
* @bug 8057794
* @summary The tree for TypeVar.class does not have a type set, which leads to an NPE when
* checking if deferred attribution is needed
* @compile/fail/ref=T8057794.out -XDrawDiagnostics T8057794.java
*/
class T8057794<T> {
void t() {
System.out.println(T.class.getSimpleName());
}
}

View File

@ -0,0 +1,2 @@
T8057794.java:10:29: compiler.err.type.var.cant.be.deref
1 error

View File

@ -255,8 +255,7 @@ public class TypeHarness {
public ClassType Class(long flags, Type... typeArgs) { public ClassType Class(long flags, Type... typeArgs) {
ClassSymbol csym = new ClassSymbol(flags, syntheticName(), predef.noSymbol); ClassSymbol csym = new ClassSymbol(flags, syntheticName(), predef.noSymbol);
csym.type = new ClassType(Type.noType, List.from(typeArgs), csym, csym.type = new ClassType(Type.noType, List.from(typeArgs), csym);
Type.noAnnotations);
((ClassType)csym.type).supertype_field = predef.objectType; ((ClassType)csym.type).supertype_field = predef.objectType;
return (ClassType)csym.type; return (ClassType)csym.type;
} }
@ -302,7 +301,7 @@ public class TypeHarness {
} }
public ArrayType Array(Type elemType) { public ArrayType Array(Type elemType) {
return new ArrayType(elemType, predef.arrayClass, Type.noAnnotations); return new ArrayType(elemType, predef.arrayClass);
} }
public TypeVar TypeVariable() { public TypeVar TypeVariable() {
@ -311,16 +310,16 @@ public class TypeHarness {
public TypeVar TypeVariable(Type bound) { public TypeVar TypeVariable(Type bound) {
TypeSymbol tvsym = new TypeVariableSymbol(0, syntheticName(), null, predef.noSymbol); TypeSymbol tvsym = new TypeVariableSymbol(0, syntheticName(), null, predef.noSymbol);
tvsym.type = new TypeVar(tvsym, bound, null, Type.noAnnotations); tvsym.type = new TypeVar(tvsym, bound, null);
return (TypeVar)tvsym.type; return (TypeVar)tvsym.type;
} }
public WildcardType Wildcard(BoundKind bk, Type bound) { public WildcardType Wildcard(BoundKind bk, Type bound) {
return new WildcardType(bound, bk, predef.boundClass, Type.noAnnotations); return new WildcardType(bound, bk, predef.boundClass);
} }
public CapturedType CapturedVariable(Type upper, Type lower) { public CapturedType CapturedVariable(Type upper, Type lower) {
return new CapturedType(syntheticName(), predef.noSymbol, upper, lower, null, Type.noAnnotations); return new CapturedType(syntheticName(), predef.noSymbol, upper, lower, null);
} }
public ClassType Intersection(Type classBound, Type... intfBounds) { public ClassType Intersection(Type classBound, Type... intfBounds) {

View File

@ -101,11 +101,16 @@ public class Versions {
checksrc19("-target 1.9"); checksrc19("-target 1.9");
checksrc19("-target 9"); checksrc19("-target 9");
fail("-source 7", "-target 1.6", "X.java"); fail("-source 7", "-target 1.6", "Base.java");
fail("-source 8", "-target 1.6", "X.java"); fail("-source 8", "-target 1.6", "Base.java");
fail("-source 8", "-target 1.7", "X.java"); fail("-source 8", "-target 1.7", "Base.java");
fail("-source 9", "-target 1.7", "X.java"); fail("-source 9", "-target 1.7", "Base.java");
fail("-source 9", "-target 1.8", "X.java"); fail("-source 9", "-target 1.8", "Base.java");
fail("-source 1.5", "-target 1.5", "Base.java");
fail("-source 1.4", "-target 1.4", "Base.java");
fail("-source 1.3", "-target 1.3", "Base.java");
fail("-source 1.2", "-target 1.2", "Base.java");
if (failedCases > 0) { if (failedCases > 0) {
System.err.println("failedCases = " + String.valueOf(failedCases)); System.err.println("failedCases = " + String.valueOf(failedCases));
@ -114,8 +119,6 @@ public class Versions {
} }
protected void printargs(String fname,String... args) { protected void printargs(String fname,String... args) {
System.out.printf("test: %s", fname); System.out.printf("test: %s", fname);
for (String onearg : args) { for (String onearg : args) {
@ -148,7 +151,7 @@ public class Versions {
} }
} }
boolean creturn = compile("X.java", jcargs); boolean creturn = compile("Base.java", jcargs);
if (!creturn) { if (!creturn) {
// compilation errors note and return.. assume no class file // compilation errors note and return.. assume no class file
System.err.println("check: Compilation Failed"); System.err.println("check: Compilation Failed");
@ -156,7 +159,7 @@ public class Versions {
System.err.println("\t arguments:\t" + jcargs); System.err.println("\t arguments:\t" + jcargs);
failedCases++; failedCases++;
} else if (!checkClassFileVersion("X.class", major)) { } else if (!checkClassFileVersion("Base.class", major)) {
failedCases++; failedCases++;
} }
} }
@ -166,9 +169,9 @@ public class Versions {
int asize = args.length; int asize = args.length;
String[] newargs = new String[asize + 1]; String[] newargs = new String[asize + 1];
System.arraycopy(args, 0, newargs, 0, asize); System.arraycopy(args, 0, newargs, 0, asize);
newargs[asize] = "X.java"; newargs[asize] = "Base.java";
pass(newargs); pass(newargs);
newargs[asize] = "Y.java"; newargs[asize] = "New17.java";
fail(newargs); fail(newargs);
} }
@ -177,20 +180,26 @@ public class Versions {
int asize = args.length; int asize = args.length;
String[] newargs = new String[asize+1]; String[] newargs = new String[asize+1];
System.arraycopy(args, 0, newargs,0 , asize); System.arraycopy(args, 0, newargs,0 , asize);
newargs[asize] = "X.java"; newargs[asize] = "New17.java";
pass(newargs);
newargs[asize] = "Y.java";
pass(newargs); pass(newargs);
newargs[asize] = "New18.java";
fail(newargs);
} }
protected void checksrc18(String... args) { protected void checksrc18(String... args) {
printargs("checksrc18", args); printargs("checksrc18", args);
checksrc17(args); int asize = args.length;
String[] newargs = new String[asize+1];
System.arraycopy(args, 0, newargs,0 , asize);
newargs[asize] = "New17.java";
pass(newargs);
newargs[asize] = "New18.java";
pass(newargs);
} }
protected void checksrc19(String... args) { protected void checksrc19(String... args) {
printargs("checksrc19", args); printargs("checksrc19", args);
checksrc17(args); checksrc18(args);
} }
protected void pass(String... args) { protected void pass(String... args) {
@ -288,25 +297,36 @@ public class Versions {
} }
} }
protected void writeSourceFile(String fileName, String body) throws IOException{
try (Writer fw = new FileWriter(fileName)) {
fw.write(body);
}
}
protected void genSourceFiles() throws IOException{ protected void genSourceFiles() throws IOException{
/* Create a file that executes with all supported versions. */ /* Create a file that executes with all supported versions. */
File fsource = new File("X.java"); writeSourceFile("Base.java","public class Base { }\n");
try (Writer fw = new FileWriter(fsource)) {
fw.write("public class X { }\n");
fw.flush();
}
/* Create a file with feature not supported in deprecated version. /*
* New feature for 1.7, does not exist in 1.6. * Create a file with a new feature in 1.7, not in 1.6 : "<>"
*/ */
fsource = new File("Y.java"); writeSourceFile("New17.java",
try (Writer fw = new FileWriter(fsource)) { "import java.util.List;\n" +
fw.write("import java.util.List;\n"); "import java.util.ArrayList;\n" +
fw.write("import java.util.ArrayList;\n"); "class New17 { List<String> s = new ArrayList<>(); }\n"
fw.write("class Z { List<String> s = new ArrayList<>(); }\n"); );
fw.flush();
} /*
* Create a file with a new feature in 1.8, not in 1.7 : lambda
*/
writeSourceFile("New18.java",
"public class New18 { \n" +
" void m() { \n" +
" new Thread(() -> { }); \n" +
" } \n" +
"} \n"
);
} }
protected boolean checkClassFileVersion protected boolean checkClassFileVersion

View File

@ -38,28 +38,29 @@ public class Test extends Doclet {
} }
void run() throws Exception { void run() throws Exception {
String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" " test("<body>ABC XYZ</body>");
+ "\"http://www.w3.org/TR/html4/loose.dtd\">"; test("<body>ABC XYZ</BODY>");
String headTag = "<head><title>Title </title></head>"; test("<BODY>ABC XYZ</body>");
test(docType+"<html><body>ABC XYZ</body></html>"); test("<BODY>ABC XYZ</BODY>");
test(docType+"<html><body>ABC XYZ</BODY></html>"); test("<BoDy>ABC XYZ</bOdY>");
test(docType+"<html><BODY>ABC XYZ</body></html>"); test(" ABC XYZ</bOdY>", "Body tag missing from HTML");
test(docType+"<html><BODY>ABC XYZ</BODY></html>"); test("<body>ABC XYZ ", "Close body tag missing from HTML");
test(docType+"<html><BoDy>ABC XYZ</bOdY></html>"); test(" ABC XYZ ", "Body tag missing from HTML");
test(docType+"<html>"+headTag+" ABC XYZ</bOdY></html>", "Body tag missing from HTML"); test("<body>ABC" + bigText(8192, 40) + "XYZ</body>");
test(docType+"<html><body>ABC XYZ </html>", "Close body tag missing from HTML");
test(docType+"<html>"+headTag+" ABC XYZ </html>", "Body tag missing from HTML");
test(docType+"<html><body>ABC" + bigText(8192, 40) + "XYZ</body></html>");
if (errors > 0) if (errors > 0)
throw new Exception(errors + " errors occurred"); throw new Exception(errors + " errors occurred");
} }
void test(String text) throws IOException { void test(String body) throws IOException {
test(text, null); test(body, null);
} }
void test(String text, String expectError) throws IOException { void test(String body, String expectError) throws IOException {
String docType = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" "
+ "\"http://www.w3.org/TR/html4/loose.dtd\">";
String headTag = "<head><title>Title </title></head>";
String text = docType + "<html>" + headTag + body + "</html>";
testNum++; testNum++;
System.err.println("test " + testNum); System.err.println("test " + testNum);
File file = writeFile("overview" + testNum + ".html", text); File file = writeFile("overview" + testNum + ".html", text);