SemanticUtils.checkScopedToDefaultNamespaceProblem(classScope, n, classDefinition, null);
}
// Resolve the super class, checking that it exists,
// that it is a class rather than an interface,
// that it isn't final, and that it isn't the same as this class.
ClassDefinition superclassDefinition =
SemanticUtils.resolveBaseClass(node, class_definition, project, classScope.getProblems());
// Check that the superclass isn't a forward reference, but only need to do this if both
// definitions come from the same containing source. getContainingFilePath() returns the file
// from the ASFileScope, so no need to worry about included files.
if (!classDefinition.isGeneratedEmbedClass() && classDefinition.getContainingFilePath().equals(superclassDefinition.getContainingFilePath()))
{
// If the absolute offset in the class is less than the
// offset of the super class, it must be a forward reference in the file
int classOffset = classDefinition.getAbsoluteStart();
int superClassOffset = superclassDefinition.getAbsoluteEnd();
if (classOffset < superClassOffset)
classScope.addProblem(new ForwardReferenceToBaseClassProblem(node, superclassDefinition.getQualifiedName()));
}
// Set the superclass Name.
this.superclassName = superclassDefinition.getMName(project);
iinfo.superName = superclassName;
// Resolve the interfaces.
IInterfaceDefinition[] interfaces = classDefinition.resolveImplementedInterfaces(
project, classScope.getProblems());
// Set the interface Names.
int n_interfaces = interfaces.length;
ArrayList<Name> interface_names = new ArrayList<Name>(n_interfaces);
for (int i = 0; i < n_interfaces; i++)
{
InterfaceDefinition idef = (InterfaceDefinition)interfaces[i];
if (idef != null)
{
Name interfaceName = ((InterfaceDefinition)interfaces[i]).getMName(project);
interface_names.add(interfaceName);
}
}
iinfo.interfaceNames = interface_names.toArray(new Name[interface_names.size()]);
// Set the flags corresponding to 'final' and 'dynamic'.
if (classDefinition.isFinal())
iinfo.flags |= ABCConstants.CLASS_FLAG_final;
if (!classDefinition.isDynamic())
iinfo.flags |= ABCConstants.CLASS_FLAG_sealed;
iinfo.protectedNs = ((NamespaceDefinition)classDefinition.getProtectedNamespaceReference()).getAETNamespace();
this.cv = emitter.visitClass(iinfo, cinfo);
cv.visit();
this.itraits = cv.visitInstanceTraits();
this.ctraits = cv.visitClassTraits();
this.classScope.traitsVisitor = this.itraits;
this.classStaticScope.traitsVisitor = this.ctraits;
// Build an array of the names of all the ancestor classes.
ArrayList<Name> ancestorClassNames = new ArrayList<Name>();
// Walk the superclass chain, starting with this class
// and (unless there are problems) ending with Object.
// This will accomplish three things:
// - find loops;
// - build the array of names of ancestor classes;
// - set the needsProtected flag if this class or any of its ancestor classes needs it.
boolean needsProtected = false;
// Remember the most recently examined class in case there's a cycle in the superclass
// chain, in which case we'll need it to issue a diagnostic.
ClassDefinition c = null;
IClassDefinition.IClassIterator classIterator =
classDefinition.classIterator(project, true);
while (classIterator.hasNext())
{
c = (ClassDefinition)classIterator.next();
needsProtected |= c.getOwnNeedsProtected();
if (c != classDefinition)
ancestorClassNames.add(c.getMName(project));
}
// Report a loop in the superclass chain, such as A extends B and B extends A.
// Note: A extends A was found previously by SemanticUtils.resolveBaseClass().
if (classIterator.foundLoop())
classScope.addProblem(new CircularTypeReferenceProblem(c, c.getQualifiedName()));
// In the case of class A extends A, ancestorClassNames will be empty at this point.
// Change it to be Object to prevent "Warning: Stack underflow" in the script init code below.
if (ancestorClassNames.isEmpty())
{
ClassDefinition objectDefinition = (ClassDefinition)project.getBuiltinType(
IASLanguageConstants.BuiltinType.OBJECT);
ancestorClassNames.add(objectDefinition.getMName(project));
}
// If this class or any of its ancestor classes needs the protected flag set, set it.
if (needsProtected)
iinfo.flags |= ABCConstants.CLASS_FLAG_protected;