X-Git-Url: http://git.megacz.com/?a=blobdiff_plain;f=src%2Forg%2Feclipse%2Fjdt%2Finternal%2Fcompiler%2Flookup%2FClassScope.java;fp=src%2Forg%2Feclipse%2Fjdt%2Finternal%2Fcompiler%2Flookup%2FClassScope.java;h=0000000000000000000000000000000000000000;hb=6f0cd02d46e011bd5599e1b7fefc6159cb811135;hp=6d839435404fd3ca672cc02791359db143e79c44;hpb=622d0e5a4b1b35b6918a516a79a0cc22272a919e;p=org.ibex.tool.git diff --git a/src/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java b/src/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java deleted file mode 100644 index 6d83943..0000000 --- a/src/org/eclipse/jdt/internal/compiler/lookup/ClassScope.java +++ /dev/null @@ -1,921 +0,0 @@ -/******************************************************************************* - * Copyright (c) 2000, 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM Corporation - initial API and implementation - *******************************************************************************/ -package org.eclipse.jdt.internal.compiler.lookup; - -import org.eclipse.jdt.core.compiler.CharOperation; -import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; -import org.eclipse.jdt.internal.compiler.ast.Clinit; -import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; -import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; -import org.eclipse.jdt.internal.compiler.ast.TypeReference; -import org.eclipse.jdt.internal.compiler.problem.AbortCompilation; -import org.eclipse.jdt.internal.compiler.problem.ProblemReporter; -import org.eclipse.jdt.internal.compiler.util.HashtableOfObject; - -public class ClassScope extends Scope { - public TypeDeclaration referenceContext; - - private final static char[] IncompleteHierarchy = new char[] {'h', 'a', 's', ' ', 'i', 'n', 'c', 'o', 'n', 's', 'i', 's', 't', 'e', 'n', 't', ' ', 'h', 'i', 'e', 'r', 'a', 'r', 'c', 'h', 'y'}; - - public ClassScope(Scope parent, TypeDeclaration context) { - super(CLASS_SCOPE, parent); - this.referenceContext = context; - } - - void buildAnonymousTypeBinding(SourceTypeBinding enclosingType, ReferenceBinding supertype) { - - LocalTypeBinding anonymousType = buildLocalType(enclosingType, enclosingType.fPackage); - - SourceTypeBinding sourceType = referenceContext.binding; - if (supertype.isInterface()) { - sourceType.superclass = getJavaLangObject(); - sourceType.superInterfaces = new ReferenceBinding[] { supertype }; - } else { - sourceType.superclass = supertype; - sourceType.superInterfaces = TypeConstants.NoSuperInterfaces; - } - connectMemberTypes(); - buildFieldsAndMethods(); - anonymousType.faultInTypesForFieldsAndMethods(); - sourceType.verifyMethods(environment().methodVerifier()); - } - - private void buildFields() { - boolean hierarchyIsInconsistent = referenceContext.binding.isHierarchyInconsistent(); - if (referenceContext.fields == null) { - if (hierarchyIsInconsistent) { // 72468 - referenceContext.binding.fields = new FieldBinding[1]; - referenceContext.binding.fields[0] = - new FieldBinding(IncompleteHierarchy, VoidBinding, AccPrivate, referenceContext.binding, null); - } else { - referenceContext.binding.fields = NoFields; - } - return; - } - // count the number of fields vs. initializers - FieldDeclaration[] fields = referenceContext.fields; - int size = fields.length; - int count = 0; - for (int i = 0; i < size; i++) - if (fields[i].isField()) - count++; - - if (hierarchyIsInconsistent) - count++; - // iterate the field declarations to create the bindings, lose all duplicates - FieldBinding[] fieldBindings = new FieldBinding[count]; - HashtableOfObject knownFieldNames = new HashtableOfObject(count); - boolean duplicate = false; - count = 0; - for (int i = 0; i < size; i++) { - FieldDeclaration field = fields[i]; - if (!field.isField()) { - if (referenceContext.binding.isInterface()) - problemReporter().interfaceCannotHaveInitializers(referenceContext.binding, field); - } else { - FieldBinding fieldBinding = new FieldBinding(field, null, field.modifiers | AccUnresolved, referenceContext.binding); - // field's type will be resolved when needed for top level types - checkAndSetModifiersForField(fieldBinding, field); - - if (knownFieldNames.containsKey(field.name)) { - duplicate = true; - FieldBinding previousBinding = (FieldBinding) knownFieldNames.get(field.name); - if (previousBinding != null) { - for (int f = 0; f < i; f++) { - FieldDeclaration previousField = fields[f]; - if (previousField.binding == previousBinding) { - problemReporter().duplicateFieldInType(referenceContext.binding, previousField); - previousField.binding = null; - break; - } - } - } - knownFieldNames.put(field.name, null); // ensure that the duplicate field is found & removed - problemReporter().duplicateFieldInType(referenceContext.binding, field); - field.binding = null; - } else { - knownFieldNames.put(field.name, fieldBinding); - // remember that we have seen a field with this name - if (fieldBinding != null) - fieldBindings[count++] = fieldBinding; - } - } - } - // remove duplicate fields - if (duplicate) { - FieldBinding[] newFieldBindings = new FieldBinding[knownFieldNames.size() - 1]; - // we know we'll be removing at least 1 duplicate name - size = count; - count = 0; - for (int i = 0; i < size; i++) { - FieldBinding fieldBinding = fieldBindings[i]; - if (knownFieldNames.get(fieldBinding.name) != null) - newFieldBindings[count++] = fieldBinding; - } - fieldBindings = newFieldBindings; - } - if (hierarchyIsInconsistent) - fieldBindings[count++] = new FieldBinding(IncompleteHierarchy, VoidBinding, AccPrivate, referenceContext.binding, null); - - if (count != fieldBindings.length) - System.arraycopy(fieldBindings, 0, fieldBindings = new FieldBinding[count], 0, count); - for (int i = 0; i < count; i++) - fieldBindings[i].id = i; - referenceContext.binding.fields = fieldBindings; - } - - void buildFieldsAndMethods() { - buildFields(); - buildMethods(); - - SourceTypeBinding sourceType = referenceContext.binding; - if (sourceType.isMemberType() && !sourceType.isLocalType()) - ((MemberTypeBinding) sourceType).checkSyntheticArgsAndFields(); - - ReferenceBinding[] memberTypes = sourceType.memberTypes; - for (int i = 0, length = memberTypes.length; i < length; i++) - ((SourceTypeBinding) memberTypes[i]).scope.buildFieldsAndMethods(); - } - - private LocalTypeBinding buildLocalType( - SourceTypeBinding enclosingType, - PackageBinding packageBinding) { - - referenceContext.scope = this; - referenceContext.staticInitializerScope = new MethodScope(this, referenceContext, true); - referenceContext.initializerScope = new MethodScope(this, referenceContext, false); - - // build the binding or the local type - LocalTypeBinding localType = new LocalTypeBinding(this, enclosingType, this.switchCase()); - referenceContext.binding = localType; - checkAndSetModifiers(); - - // Look at member types - ReferenceBinding[] memberTypeBindings = NoMemberTypes; - if (referenceContext.memberTypes != null) { - int size = referenceContext.memberTypes.length; - memberTypeBindings = new ReferenceBinding[size]; - int count = 0; - nextMember : for (int i = 0; i < size; i++) { - TypeDeclaration memberContext = referenceContext.memberTypes[i]; - if (memberContext.isInterface()) { - problemReporter().nestedClassCannotDeclareInterface(memberContext); - continue nextMember; - } - ReferenceBinding type = localType; - // check that the member does not conflict with an enclosing type - do { - if (CharOperation.equals(type.sourceName, memberContext.name)) { - problemReporter().hidingEnclosingType(memberContext); - continue nextMember; - } - type = type.enclosingType(); - } while (type != null); - // check the member type does not conflict with another sibling member type - for (int j = 0; j < i; j++) { - if (CharOperation.equals(referenceContext.memberTypes[j].name, memberContext.name)) { - problemReporter().duplicateNestedType(memberContext); - continue nextMember; - } - } - - ClassScope memberScope = new ClassScope(this, referenceContext.memberTypes[i]); - LocalTypeBinding memberBinding = memberScope.buildLocalType(localType, packageBinding); - memberBinding.setAsMemberType(); - memberTypeBindings[count++] = memberBinding; - } - if (count != size) - System.arraycopy(memberTypeBindings, 0, memberTypeBindings = new ReferenceBinding[count], 0, count); - } - localType.memberTypes = memberTypeBindings; - return localType; - } - - void buildLocalTypeBinding(SourceTypeBinding enclosingType) { - - LocalTypeBinding localType = buildLocalType(enclosingType, enclosingType.fPackage); - connectTypeHierarchy(); - buildFieldsAndMethods(); - localType.faultInTypesForFieldsAndMethods(); - - referenceContext.binding.verifyMethods(environment().methodVerifier()); - } - - private void buildMethods() { - if (referenceContext.methods == null) { - referenceContext.binding.methods = NoMethods; - return; - } - - // iterate the method declarations to create the bindings - AbstractMethodDeclaration[] methods = referenceContext.methods; - int size = methods.length; - int clinitIndex = -1; - for (int i = 0; i < size; i++) { - if (methods[i] instanceof Clinit) { - clinitIndex = i; - break; - } - } - MethodBinding[] methodBindings = new MethodBinding[clinitIndex == -1 ? size : size - 1]; - - int count = 0; - for (int i = 0; i < size; i++) { - if (i != clinitIndex) { - MethodScope scope = new MethodScope(this, methods[i], false); - MethodBinding methodBinding = scope.createMethod(methods[i]); - if (methodBinding != null) // is null if binding could not be created - methodBindings[count++] = methodBinding; - } - } - if (count != methodBindings.length) - System.arraycopy(methodBindings, 0, methodBindings = new MethodBinding[count], 0, count); - - referenceContext.binding.methods = methodBindings; - referenceContext.binding.modifiers |= AccUnresolved; // until methods() is sent - } - SourceTypeBinding buildType(SourceTypeBinding enclosingType, PackageBinding packageBinding) { - // provide the typeDeclaration with needed scopes - referenceContext.scope = this; - referenceContext.staticInitializerScope = new MethodScope(this, referenceContext, true); - referenceContext.initializerScope = new MethodScope(this, referenceContext, false); - - if (enclosingType == null) { - char[][] className = CharOperation.arrayConcat(packageBinding.compoundName, referenceContext.name); - referenceContext.binding = new SourceTypeBinding(className, packageBinding, this); - } else { - char[][] className = CharOperation.deepCopy(enclosingType.compoundName); - className[className.length - 1] = - CharOperation.concat(className[className.length - 1], referenceContext.name, '$'); - referenceContext.binding = new MemberTypeBinding(className, this, enclosingType); - } - - SourceTypeBinding sourceType = referenceContext.binding; - sourceType.fPackage.addType(sourceType); - checkAndSetModifiers(); - - // Look at member types - ReferenceBinding[] memberTypeBindings = NoMemberTypes; - if (referenceContext.memberTypes != null) { - int size = referenceContext.memberTypes.length; - memberTypeBindings = new ReferenceBinding[size]; - int count = 0; - nextMember : for (int i = 0; i < size; i++) { - TypeDeclaration memberContext = referenceContext.memberTypes[i]; - if (memberContext.isInterface() - && sourceType.isNestedType() - && sourceType.isClass() - && !sourceType.isStatic()) { - problemReporter().nestedClassCannotDeclareInterface(memberContext); - continue nextMember; - } - ReferenceBinding type = sourceType; - // check that the member does not conflict with an enclosing type - do { - if (CharOperation.equals(type.sourceName, memberContext.name)) { - problemReporter().hidingEnclosingType(memberContext); - continue nextMember; - } - type = type.enclosingType(); - } while (type != null); - // check that the member type does not conflict with another sibling member type - for (int j = 0; j < i; j++) { - if (CharOperation.equals(referenceContext.memberTypes[j].name, memberContext.name)) { - problemReporter().duplicateNestedType(memberContext); - continue nextMember; - } - } - - ClassScope memberScope = new ClassScope(this, memberContext); - memberTypeBindings[count++] = memberScope.buildType(sourceType, packageBinding); - } - if (count != size) - System.arraycopy(memberTypeBindings, 0, memberTypeBindings = new ReferenceBinding[count], 0, count); - } - sourceType.memberTypes = memberTypeBindings; - return sourceType; - } - - private void checkAndSetModifiers() { - SourceTypeBinding sourceType = referenceContext.binding; - int modifiers = sourceType.modifiers; - if ((modifiers & AccAlternateModifierProblem) != 0) - problemReporter().duplicateModifierForType(sourceType); - - ReferenceBinding enclosingType = sourceType.enclosingType(); - boolean isMemberType = sourceType.isMemberType(); - - if (isMemberType) { - // checks for member types before local types to catch local members - if (enclosingType.isStrictfp()) - modifiers |= AccStrictfp; - if (enclosingType.isViewedAsDeprecated() && !sourceType.isDeprecated()) - modifiers |= AccDeprecatedImplicitly; - if (enclosingType.isInterface()) - modifiers |= AccPublic; - } else if (sourceType.isLocalType()) { - if (sourceType.isAnonymousType()) - modifiers |= AccFinal; - Scope scope = this; - do { - switch (scope.kind) { - case METHOD_SCOPE : - MethodScope methodScope = (MethodScope) scope; - if (methodScope.isInsideInitializer()) { - SourceTypeBinding type = ((TypeDeclaration) methodScope.referenceContext).binding; - - // inside field declaration ? check field modifier to see if deprecated - if (methodScope.initializedField != null) { - // currently inside this field initialization - if (methodScope.initializedField.isViewedAsDeprecated() && !sourceType.isDeprecated()){ - modifiers |= AccDeprecatedImplicitly; - } - } else { - if (type.isStrictfp()) - modifiers |= AccStrictfp; - if (type.isViewedAsDeprecated() && !sourceType.isDeprecated()) - modifiers |= AccDeprecatedImplicitly; - } - } else { - MethodBinding method = ((AbstractMethodDeclaration) methodScope.referenceContext).binding; - if (method != null){ - if (method.isStrictfp()) - modifiers |= AccStrictfp; - if (method.isViewedAsDeprecated() && !sourceType.isDeprecated()) - modifiers |= AccDeprecatedImplicitly; - } - } - break; - case CLASS_SCOPE : - // local member - if (enclosingType.isStrictfp()) - modifiers |= AccStrictfp; - if (enclosingType.isViewedAsDeprecated() && !sourceType.isDeprecated()) - modifiers |= AccDeprecatedImplicitly; - break; - } - scope = scope.parent; - } while (scope != null); - } - // after this point, tests on the 16 bits reserved. - int realModifiers = modifiers & AccJustFlag; - - if ((realModifiers & AccInterface) != 0) { - // detect abnormal cases for interfaces - if (isMemberType) { - int unexpectedModifiers = - ~(AccPublic | AccPrivate | AccProtected | AccStatic | AccAbstract | AccInterface | AccStrictfp); - if ((realModifiers & unexpectedModifiers) != 0) - problemReporter().illegalModifierForMemberInterface(sourceType); - /* - } else if (sourceType.isLocalType()) { //interfaces cannot be defined inside a method - int unexpectedModifiers = ~(AccAbstract | AccInterface | AccStrictfp); - if ((realModifiers & unexpectedModifiers) != 0) - problemReporter().illegalModifierForLocalInterface(sourceType); - */ - } else { - int unexpectedModifiers = ~(AccPublic | AccAbstract | AccInterface | AccStrictfp); - if ((realModifiers & unexpectedModifiers) != 0) - problemReporter().illegalModifierForInterface(sourceType); - } - modifiers |= AccAbstract; - } else { - // detect abnormal cases for types - if (isMemberType) { // includes member types defined inside local types - int unexpectedModifiers = - ~(AccPublic | AccPrivate | AccProtected | AccStatic | AccAbstract | AccFinal | AccStrictfp); - if ((realModifiers & unexpectedModifiers) != 0) - problemReporter().illegalModifierForMemberClass(sourceType); - } else if (sourceType.isLocalType()) { - int unexpectedModifiers = ~(AccAbstract | AccFinal | AccStrictfp); - if ((realModifiers & unexpectedModifiers) != 0) - problemReporter().illegalModifierForLocalClass(sourceType); - } else { - int unexpectedModifiers = ~(AccPublic | AccAbstract | AccFinal | AccStrictfp); - if ((realModifiers & unexpectedModifiers) != 0) - problemReporter().illegalModifierForClass(sourceType); - } - - // check that Final and Abstract are not set together - if ((realModifiers & (AccFinal | AccAbstract)) == (AccFinal | AccAbstract)) - problemReporter().illegalModifierCombinationFinalAbstractForClass(sourceType); - } - - if (isMemberType) { - // test visibility modifiers inconsistency, isolate the accessors bits - if (enclosingType.isInterface()) { - if ((realModifiers & (AccProtected | AccPrivate)) != 0) { - problemReporter().illegalVisibilityModifierForInterfaceMemberType(sourceType); - - // need to keep the less restrictive - if ((realModifiers & AccProtected) != 0) - modifiers ^= AccProtected; - if ((realModifiers & AccPrivate) != 0) - modifiers ^= AccPrivate; - } - } else { - int accessorBits = realModifiers & (AccPublic | AccProtected | AccPrivate); - if ((accessorBits & (accessorBits - 1)) > 1) { - problemReporter().illegalVisibilityModifierCombinationForMemberType(sourceType); - - // need to keep the less restrictive - if ((accessorBits & AccPublic) != 0) { - if ((accessorBits & AccProtected) != 0) - modifiers ^= AccProtected; - if ((accessorBits & AccPrivate) != 0) - modifiers ^= AccPrivate; - } - if ((accessorBits & AccProtected) != 0) - if ((accessorBits & AccPrivate) != 0) - modifiers ^= AccPrivate; - } - } - - // static modifier test - if ((realModifiers & AccStatic) == 0) { - if (enclosingType.isInterface()) - modifiers |= AccStatic; - } else { - if (!enclosingType.isStatic()) - // error the enclosing type of a static field must be static or a top-level type - problemReporter().illegalStaticModifierForMemberType(sourceType); - } - } - - sourceType.modifiers = modifiers; - } - - /* This method checks the modifiers of a field. - * - * 9.3 & 8.3 - * Need to integrate the check for the final modifiers for nested types - * - * Note : A scope is accessible by : fieldBinding.declaringClass.scope - */ - private void checkAndSetModifiersForField(FieldBinding fieldBinding, FieldDeclaration fieldDecl) { - int modifiers = fieldBinding.modifiers; - if ((modifiers & AccAlternateModifierProblem) != 0) - problemReporter().duplicateModifierForField(fieldBinding.declaringClass, fieldDecl); - - if (fieldBinding.declaringClass.isInterface()) { - int expectedValue = AccPublic | AccStatic | AccFinal; - // set the modifiers - modifiers |= expectedValue; - - // and then check that they are the only ones - if ((modifiers & AccJustFlag) != expectedValue) - problemReporter().illegalModifierForInterfaceField(fieldBinding.declaringClass, fieldDecl); - fieldBinding.modifiers = modifiers; - return; - } - - // after this point, tests on the 16 bits reserved. - int realModifiers = modifiers & AccJustFlag; - int unexpectedModifiers = - ~(AccPublic | AccPrivate | AccProtected | AccFinal | AccStatic | AccTransient | AccVolatile); - if ((realModifiers & unexpectedModifiers) != 0) - problemReporter().illegalModifierForField(fieldBinding.declaringClass, fieldDecl); - - int accessorBits = realModifiers & (AccPublic | AccProtected | AccPrivate); - if ((accessorBits & (accessorBits - 1)) > 1) { - problemReporter().illegalVisibilityModifierCombinationForField( - fieldBinding.declaringClass, - fieldDecl); - - // need to keep the less restrictive - if ((accessorBits & AccPublic) != 0) { - if ((accessorBits & AccProtected) != 0) - modifiers ^= AccProtected; - if ((accessorBits & AccPrivate) != 0) - modifiers ^= AccPrivate; - } - if ((accessorBits & AccProtected) != 0) - if ((accessorBits & AccPrivate) != 0) - modifiers ^= AccPrivate; - } - - if ((realModifiers & (AccFinal | AccVolatile)) == (AccFinal | AccVolatile)) - problemReporter().illegalModifierCombinationFinalVolatileForField( - fieldBinding.declaringClass, - fieldDecl); - - if (fieldDecl.initialization == null && (modifiers & AccFinal) != 0) { - modifiers |= AccBlankFinal; - } - fieldBinding.modifiers = modifiers; - } - - private void checkForInheritedMemberTypes(SourceTypeBinding sourceType) { - // search up the hierarchy of the sourceType to see if any superType defines a member type - // when no member types are defined, tag the sourceType & each superType with the HasNoMemberTypes bit - ReferenceBinding currentType = sourceType; - ReferenceBinding[][] interfacesToVisit = null; - int lastPosition = -1; - do { - if ((currentType.tagBits & HasNoMemberTypes) != 0) - break; // already know it has no inherited member types, can stop looking up - if (currentType.hasMemberTypes()) // avoid resolving member types eagerly - return; // has member types - ReferenceBinding[] itsInterfaces = currentType.superInterfaces(); - if (itsInterfaces != NoSuperInterfaces) { - if (interfacesToVisit == null) - interfacesToVisit = new ReferenceBinding[5][]; - if (++lastPosition == interfacesToVisit.length) - System.arraycopy( - interfacesToVisit, - 0, - interfacesToVisit = new ReferenceBinding[lastPosition * 2][], - 0, - lastPosition); - interfacesToVisit[lastPosition] = itsInterfaces; - } - } while ((currentType = currentType.superclass()) != null); - - boolean hasMembers = false; - if (interfacesToVisit != null) { - done : for (int i = 0; i <= lastPosition; i++) { - ReferenceBinding[] interfaces = interfacesToVisit[i]; - for (int j = 0, length = interfaces.length; j < length; j++) { - ReferenceBinding anInterface = interfaces[j]; - if ((anInterface.tagBits & InterfaceVisited) == 0) { // if interface as not already been visited - anInterface.tagBits |= InterfaceVisited; - if ((anInterface.tagBits & HasNoMemberTypes) != 0) - continue; // already know it has no inherited member types - if (anInterface.memberTypes() != NoMemberTypes) { - hasMembers = true; - break done; - } - - ReferenceBinding[] itsInterfaces = anInterface.superInterfaces(); - if (itsInterfaces != NoSuperInterfaces) { - if (++lastPosition == interfacesToVisit.length) - System.arraycopy( - interfacesToVisit, - 0, - interfacesToVisit = new ReferenceBinding[lastPosition * 2][], - 0, - lastPosition); - interfacesToVisit[lastPosition] = itsInterfaces; - } - } - } - } - - for (int i = 0; i <= lastPosition; i++) { - ReferenceBinding[] interfaces = interfacesToVisit[i]; - for (int j = 0, length = interfaces.length; j < length; j++) { - interfaces[j].tagBits &= ~InterfaceVisited; - if (!hasMembers) - interfaces[j].tagBits |= HasNoMemberTypes; - } - } - } - - if (!hasMembers) { - currentType = sourceType; - do { - currentType.tagBits |= HasNoMemberTypes; - } while ((currentType = currentType.superclass()) != null); - } - } - - private void connectMemberTypes() { - SourceTypeBinding sourceType = referenceContext.binding; - if (sourceType.memberTypes != NoMemberTypes) - for (int i = 0, size = sourceType.memberTypes.length; i < size; i++) - ((SourceTypeBinding) sourceType.memberTypes[i]).scope.connectTypeHierarchy(); - } - /* - Our current belief based on available JCK tests is: - inherited member types are visible as a potential superclass. - inherited interfaces are not visible when defining a superinterface. - - Error recovery story: - ensure the superclass is set to java.lang.Object if a problem is detected - resolving the superclass. - - Answer false if an error was reported against the sourceType. - */ - private boolean connectSuperclass() { - SourceTypeBinding sourceType = referenceContext.binding; - if (sourceType.id == T_Object) { // handle the case of redefining java.lang.Object up front - sourceType.superclass = null; - sourceType.superInterfaces = NoSuperInterfaces; - if (referenceContext.superclass != null || referenceContext.superInterfaces != null) - problemReporter().objectCannotHaveSuperTypes(sourceType); - return true; // do not propagate Object's hierarchy problems down to every subtype - } - if (referenceContext.superclass == null) { - sourceType.superclass = getJavaLangObject(); - return !detectCycle(sourceType, sourceType.superclass, null); - } - ReferenceBinding superclass = findSupertype(referenceContext.superclass); - if (superclass != null) { // is null if a cycle was detected cycle - referenceContext.superclass.resolvedType = superclass; // hold onto the problem type - if (!superclass.isValidBinding()) { - problemReporter().invalidSuperclass(sourceType, referenceContext.superclass, superclass); - } else if (superclass.isInterface()) { - problemReporter().superclassMustBeAClass(sourceType, referenceContext.superclass, superclass); - } else if (superclass.isFinal()) { - problemReporter().classExtendFinalClass(sourceType, referenceContext.superclass, superclass); - } else { - // only want to reach here when no errors are reported - sourceType.superclass = superclass; - return true; - } - } - sourceType.tagBits |= HierarchyHasProblems; - sourceType.superclass = getJavaLangObject(); - if ((sourceType.superclass.tagBits & BeginHierarchyCheck) == 0) - detectCycle(sourceType, sourceType.superclass, null); - return false; // reported some error against the source type - } - - /* - Our current belief based on available JCK 1.3 tests is: - inherited member types are visible as a potential superclass. - inherited interfaces are visible when defining a superinterface. - - Error recovery story: - ensure the superinterfaces contain only valid visible interfaces. - - Answer false if an error was reported against the sourceType. - */ - private boolean connectSuperInterfaces() { - SourceTypeBinding sourceType = referenceContext.binding; - sourceType.superInterfaces = NoSuperInterfaces; - if (referenceContext.superInterfaces == null) - return true; - if (sourceType.id == T_Object) // already handled the case of redefining java.lang.Object - return true; - - boolean noProblems = true; - int length = referenceContext.superInterfaces.length; - ReferenceBinding[] interfaceBindings = new ReferenceBinding[length]; - int count = 0; - nextInterface : for (int i = 0; i < length; i++) { - ReferenceBinding superInterface = findSupertype(referenceContext.superInterfaces[i]); - if (superInterface == null) { // detected cycle - noProblems = false; - continue nextInterface; - } - referenceContext.superInterfaces[i].resolvedType = superInterface; // hold onto the problem type - if (!superInterface.isValidBinding()) { - problemReporter().invalidSuperinterface( - sourceType, - referenceContext.superInterfaces[i], - superInterface); - sourceType.tagBits |= HierarchyHasProblems; - noProblems = false; - continue nextInterface; - } - // Check for a duplicate interface once the name is resolved, otherwise we may be confused (ie : a.b.I and c.d.I) - for (int k = 0; k < count; k++) { - if (interfaceBindings[k] == superInterface) { - // should this be treated as a warning? - problemReporter().duplicateSuperinterface(sourceType, referenceContext, superInterface); - continue nextInterface; - } - } - if (superInterface.isClass()) { - problemReporter().superinterfaceMustBeAnInterface(sourceType, referenceContext, superInterface); - sourceType.tagBits |= HierarchyHasProblems; - noProblems = false; - continue nextInterface; - } - - // only want to reach here when no errors are reported - interfaceBindings[count++] = superInterface; - } - // hold onto all correctly resolved superinterfaces - if (count > 0) { - if (count != length) - System.arraycopy(interfaceBindings, 0, interfaceBindings = new ReferenceBinding[count], 0, count); - sourceType.superInterfaces = interfaceBindings; - } - return noProblems; - } - - void connectTypeHierarchy() { - SourceTypeBinding sourceType = referenceContext.binding; - if ((sourceType.tagBits & BeginHierarchyCheck) == 0) { - boolean noProblems = true; - sourceType.tagBits |= BeginHierarchyCheck; - if (sourceType.isClass()) - noProblems &= connectSuperclass(); - noProblems &= connectSuperInterfaces(); - sourceType.tagBits |= EndHierarchyCheck; - if (noProblems && sourceType.isHierarchyInconsistent()) - problemReporter().hierarchyHasProblems(sourceType); - } - connectMemberTypes(); - try { - checkForInheritedMemberTypes(sourceType); - } catch (AbortCompilation e) { - e.updateContext(referenceContext, referenceCompilationUnit().compilationResult); - throw e; - } - } - - private void connectTypeHierarchyWithoutMembers() { - // must ensure the imports are resolved - if (parent instanceof CompilationUnitScope) { - if (((CompilationUnitScope) parent).imports == null) - ((CompilationUnitScope) parent).checkAndSetImports(); - } else if (parent instanceof ClassScope) { - // ensure that the enclosing type has already been checked - ((ClassScope) parent).connectTypeHierarchyWithoutMembers(); - } - - // double check that the hierarchy search has not already begun... - SourceTypeBinding sourceType = referenceContext.binding; - if ((sourceType.tagBits & BeginHierarchyCheck) != 0) - return; - - boolean noProblems = true; - sourceType.tagBits |= BeginHierarchyCheck; - if (sourceType.isClass()) - noProblems &= connectSuperclass(); - noProblems &= connectSuperInterfaces(); - sourceType.tagBits |= EndHierarchyCheck; - if (noProblems && sourceType.isHierarchyInconsistent()) - problemReporter().hierarchyHasProblems(sourceType); - } - - // Answer whether a cycle was found between the sourceType & the superType - private boolean detectCycle( - SourceTypeBinding sourceType, - ReferenceBinding superType, - TypeReference reference) { - if (sourceType == superType) { - problemReporter().hierarchyCircularity(sourceType, superType, reference); - sourceType.tagBits |= HierarchyHasProblems; - return true; - } - - if (superType.isBinaryBinding()) { - // force its superclass & superinterfaces to be found... 2 possibilities exist - the source type is included in the hierarchy of: - // - a binary type... this case MUST be caught & reported here - // - another source type... this case is reported against the other source type - boolean hasCycle = false; - if (superType.superclass() != null) { - if (sourceType == superType.superclass()) { - problemReporter().hierarchyCircularity(sourceType, superType, reference); - sourceType.tagBits |= HierarchyHasProblems; - superType.tagBits |= HierarchyHasProblems; - return true; - } - hasCycle |= detectCycle(sourceType, superType.superclass(), reference); - if ((superType.superclass().tagBits & HierarchyHasProblems) != 0) { - sourceType.tagBits |= HierarchyHasProblems; - superType.tagBits |= HierarchyHasProblems; // propagate down the hierarchy - } - } - - ReferenceBinding[] itsInterfaces = superType.superInterfaces(); - if (itsInterfaces != NoSuperInterfaces) { - for (int i = 0, length = itsInterfaces.length; i < length; i++) { - ReferenceBinding anInterface = itsInterfaces[i]; - if (sourceType == anInterface) { - problemReporter().hierarchyCircularity(sourceType, superType, reference); - sourceType.tagBits |= HierarchyHasProblems; - superType.tagBits |= HierarchyHasProblems; - return true; - } - hasCycle |= detectCycle(sourceType, anInterface, reference); - if ((anInterface.tagBits & HierarchyHasProblems) != 0) { - sourceType.tagBits |= HierarchyHasProblems; - superType.tagBits |= HierarchyHasProblems; - } - } - } - return hasCycle; - } - - if ((superType.tagBits & EndHierarchyCheck) == 0 - && (superType.tagBits & BeginHierarchyCheck) != 0) { - problemReporter().hierarchyCircularity(sourceType, superType, reference); - sourceType.tagBits |= HierarchyHasProblems; - superType.tagBits |= HierarchyHasProblems; - return true; - } - if ((superType.tagBits & BeginHierarchyCheck) == 0) - // ensure if this is a source superclass that it has already been checked - ((SourceTypeBinding) superType).scope.connectTypeHierarchyWithoutMembers(); - if ((superType.tagBits & HierarchyHasProblems) != 0) - sourceType.tagBits |= HierarchyHasProblems; - return false; - } - - private ReferenceBinding findSupertype(TypeReference typeReference) { - try { - typeReference.aboutToResolve(this); // allows us to trap completion & selection nodes - char[][] compoundName = typeReference.getTypeName(); - compilationUnitScope().recordQualifiedReference(compoundName); - SourceTypeBinding sourceType = referenceContext.binding; - int size = compoundName.length; - int n = 1; - ReferenceBinding superType; - - // resolve the first name of the compoundName - if (CharOperation.equals(compoundName[0], sourceType.sourceName)) { - superType = sourceType; - // match against the sourceType even though nested members cannot be supertypes - } else { - Binding typeOrPackage = parent.getTypeOrPackage(compoundName[0], TYPE | PACKAGE); - if (typeOrPackage == null || !typeOrPackage.isValidBinding()) - return new ProblemReferenceBinding( - compoundName[0], - typeOrPackage == null ? NotFound : typeOrPackage.problemId()); - - boolean checkVisibility = false; - for (; n < size; n++) { - if (!(typeOrPackage instanceof PackageBinding)) - break; - PackageBinding packageBinding = (PackageBinding) typeOrPackage; - typeOrPackage = packageBinding.getTypeOrPackage(compoundName[n]); - if (typeOrPackage == null || !typeOrPackage.isValidBinding()) - return new ProblemReferenceBinding( - CharOperation.subarray(compoundName, 0, n + 1), - typeOrPackage == null ? NotFound : typeOrPackage.problemId()); - checkVisibility = true; - } - - // convert to a ReferenceBinding - if (typeOrPackage instanceof PackageBinding) // error, the compoundName is a packageName - return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, n), NotFound); - superType = (ReferenceBinding) typeOrPackage; - compilationUnitScope().recordTypeReference(superType); // to record supertypes - - if (checkVisibility - && n == size) { // if we're finished and know the final supertype then check visibility - if (!superType.canBeSeenBy(sourceType.fPackage)) - // its a toplevel type so just check package access - return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, n), superType, NotVisible); - } - } - // at this point we know we have a type but we have to look for cycles - while (true) { - // must detect cycles & force connection up the hierarchy... also handle cycles with binary types. - // must be guaranteed that the superType knows its entire hierarchy - if (detectCycle(sourceType, superType, typeReference)) - return null; // cycle error was already reported - - if (n >= size) - break; - - // retrieve the next member type - char[] typeName = compoundName[n++]; - superType = findMemberType(typeName, superType); - if (superType == null) - return new ProblemReferenceBinding(CharOperation.subarray(compoundName, 0, n), NotFound); - if (!superType.isValidBinding()) { - superType.compoundName = CharOperation.subarray(compoundName, 0, n); - return superType; - } - } - return superType; - } catch (AbortCompilation e) { - e.updateContext(typeReference, referenceCompilationUnit().compilationResult); - throw e; - } - } - - /* Answer the problem reporter to use for raising new problems. - * - * Note that as a side-effect, this updates the current reference context - * (unit, type or method) in case the problem handler decides it is necessary - * to abort. - */ - public ProblemReporter problemReporter() { - MethodScope outerMethodScope; - if ((outerMethodScope = outerMostMethodScope()) == null) { - ProblemReporter problemReporter = referenceCompilationUnit().problemReporter; - problemReporter.referenceContext = referenceContext; - return problemReporter; - } - return outerMethodScope.problemReporter(); - } - - /* Answer the reference type of this scope. - * It is the nearest enclosing type of this scope. - */ - public TypeDeclaration referenceType() { - return referenceContext; - } - - public String toString() { - if (referenceContext != null) - return "--- Class Scope ---\n\n" //$NON-NLS-1$ - + referenceContext.binding.toString(); - return "--- Class Scope ---\n\n Binding not initialized" ; //$NON-NLS-1$ - } -}