// create an environment for evaluating the base clauses
Env<AttrContext> baseEnv = baseEnv(tree, env);
// Determine supertype.
Type supertype =
(tree.extending != null)
? attr.attribBase(tree.extending, baseEnv, true, false, true)
: ((tree.mods.flags & Flags.ENUM) != 0 && !target.compilerBootstrap(c))
? attr.attribBase(enumBase(tree.pos, c), baseEnv,
true, false, false)
: (c.fullname == names.java_lang_Object)
? Type.noType
: syms.objectType;
ct.supertype_field = modelMissingTypes(supertype, tree.extending, false);
// Determine interfaces.
ListBuffer<Type> interfaces = new ListBuffer<Type>();
ListBuffer<Type> all_interfaces = null; // lazy init
Set<Type> interfaceSet = new HashSet<Type>();
List<JCExpression> interfaceTrees = tree.implementing;
if ((tree.mods.flags & Flags.ENUM) != 0 && target.compilerBootstrap(c)) {
// add interface Comparable<T>
interfaceTrees =
interfaceTrees.prepend(make.Type(new ClassType(syms.comparableType.getEnclosingType(),
List.of(c.type),
syms.comparableType.tsym)));
// add interface Serializable
interfaceTrees =
interfaceTrees.prepend(make.Type(syms.serializableType));
}
for (JCExpression iface : interfaceTrees) {
Type i = attr.attribBase(iface, baseEnv, false, true, true);
if (i.tag == CLASS) {
interfaces.append(i);
if (all_interfaces != null) all_interfaces.append(i);
chk.checkNotRepeated(iface.pos(), types.erasure(i), interfaceSet);
} else {
if (all_interfaces == null)
all_interfaces = new ListBuffer<Type>().appendList(interfaces);
all_interfaces.append(modelMissingTypes(i, iface, true));
}
}
if ((c.flags_field & ANNOTATION) != 0) {
ct.interfaces_field = List.of(syms.annotationType);
ct.all_interfaces_field = ct.interfaces_field;
} else {
ct.interfaces_field = interfaces.toList();
ct.all_interfaces_field = (all_interfaces == null)
? ct.interfaces_field : all_interfaces.toList();
}
if (c.fullname == names.java_lang_Object) {
if (tree.extending != null) {
chk.checkNonCyclic(tree.extending.pos(),
supertype);
ct.supertype_field = Type.noType;
}
else if (tree.implementing.nonEmpty()) {
chk.checkNonCyclic(tree.implementing.head.pos(),
ct.interfaces_field.head);
ct.interfaces_field = List.nil();
}
}
// Annotations.
// In general, we cannot fully process annotations yet, but we
// can attribute the annotation types and then check to see if the
// @Deprecated annotation is present.
attr.attribAnnotationTypes(tree.mods.annotations, baseEnv);
if (hasDeprecatedAnnotation(tree.mods.annotations))
c.flags_field |= DEPRECATED;
annotateLater(tree.mods.annotations, baseEnv, c);
chk.checkNonCyclicDecl(tree);
attr.attribTypeVariables(tree.typarams, baseEnv);
// Add default constructor if needed.
if ((c.flags() & INTERFACE) == 0 &&
!TreeInfo.hasConstructors(tree.defs)) {
List<Type> argtypes = List.nil();
List<Type> typarams = List.nil();
List<Type> thrown = List.nil();
long ctorFlags = 0;
boolean based = false;
if (c.name.isEmpty()) {
JCNewClass nc = (JCNewClass)env.next.tree;
if (nc.constructor != null) {
Type superConstrType = types.memberType(c.type,
nc.constructor);
argtypes = superConstrType.getParameterTypes();
typarams = superConstrType.getTypeArguments();
ctorFlags = nc.constructor.flags() & VARARGS;
if (nc.encl != null) {
argtypes = argtypes.prepend(nc.encl.type);
based = true;
}
thrown = superConstrType.getThrownTypes();
}
}
JCTree constrDef = DefaultConstructor(make.at(tree.pos), c,
typarams, argtypes, thrown,
ctorFlags, based);