X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/MethodVerifier.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/MethodVerifier.java index 1debb98..cf46cd2 100644 --- a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/MethodVerifier.java +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/lookup/MethodVerifier.java @@ -1,19 +1,19 @@ /******************************************************************************* - * Copyright (c) 2000, 2001, 2002 International Business Machines Corp. and others. + * Copyright (c) 2000, 2003 IBM Corporation and others. * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 + * 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-v05.html + * http://www.eclipse.org/legal/cpl-v10.html * * Contributors: * IBM Corporation - initial API and implementation - ******************************************************************************/ + *******************************************************************************/ package net.sourceforge.phpdt.internal.compiler.lookup; +import net.sourceforge.phpdt.core.compiler.CharOperation; import net.sourceforge.phpdt.internal.compiler.ast.MethodDeclaration; import net.sourceforge.phpdt.internal.compiler.ast.TypeDeclaration; import net.sourceforge.phpdt.internal.compiler.problem.ProblemReporter; -import net.sourceforge.phpdt.internal.compiler.util.CharOperation; import net.sourceforge.phpdt.internal.compiler.util.HashtableOfObject; public final class MethodVerifier implements TagBits, TypeConstants { @@ -22,6 +22,7 @@ public final class MethodVerifier implements TagBits, TypeConstants { HashtableOfObject currentMethods; ReferenceBinding runtimeException; ReferenceBinding errorException; + LookupEnvironment environment; /* Binding creation is responsible for reporting all problems with types: - all modifier problems (duplicates & multiple visibility modifiers + incompatible combinations - abstract/final) @@ -38,215 +39,25 @@ Binding creation is responsible for reporting all problems with types: - shadowing an enclosing type's source name - defining a static class or interface inside a non-static nested class - defining an interface as a local type (local types can only be classes) - -verifyTypeStructure - - | hasHierarchyProblem superclass current names interfaces interfacesByIndentity duplicateExists invalidType | - - (type basicModifiers anyMask: AccModifierProblem | AccAlternateModifierProblem) ifTrue: [ - self reportModifierProblemsOnType: type]. - - type controller isJavaDefaultPackage ifFalse: [ - (nameEnvironment class doesPackageExistNamed: type javaQualifiedName) ifTrue: [ - problemSummary - reportVerificationProblem: #CollidesWithPackage - args: (Array with: type javaQualifiedName) - severity: nil - forType: type]]. - - hasHierarchyProblem := false. - - type isJavaClass - ifTrue: [ - (superclass := self superclassFor: type) ~~ nil ifTrue: [ - superclass isBuilderClass ifTrue: [ - superclass := superclass newClass]. - superclass isJavaMissing - ifTrue: [ - hasHierarchyProblem := true. - type javaSuperclassIsMissing ifTrue: [ - problemSummary - reportVerificationProblem: #MissingSuperclass - args: (Array with: superclass javaQualifiedName with: superclass unmatchedDescriptor) - severity: nil - forType: type]. - type javaSuperclassCreatesCycle ifTrue: [ - problemSummary - reportVerificationProblem: #CyclicSuperclass - args: (Array with: superclass javaQualifiedName) - severity: nil - forType: type]. - type javaSuperclassIsInterface ifTrue: [ - problemSummary - reportVerificationProblem: #ClassCannotExtendAnInterface - args: (Array with: superclass javaQualifiedName) - severity: nil - forType: type]] - ifFalse: [ - "NOTE: If type is a Java class and its superclass is - a valid descriptor then it should NEVER be an interface." - - superclass isJavaFinal ifTrue: [ - problemSummary - reportVerificationProblem: #ClassCannotExtendFinalClass - args: nil - severity: nil - forType: type]]]] - ifFalse: [ - type isJavaLocalType ifTrue: [ - problemSummary - reportVerificationProblem: #CannotDefineLocalInterface - args: nil - severity: nil - forType: type]]. - - type isJavaNestedType ifTrue: [ - (current := type) sourceName notEmpty ifTrue: [ - names := Set new. - [(current := current enclosingType) ~~ nil] whileTrue: [ - names add: current sourceName]. - - (names includes: type sourceName) ifTrue: [ - problemSummary - reportVerificationProblem: #NestedTypeCannotShadowTypeName - args: nil - severity: nil - forType: type]]. - - (type enclosingType isJavaNestedType and: [type enclosingType isJavaClass]) ifTrue: [ - type enclosingType isJavaStatic ifFalse: [ - type isJavaClass - ifTrue: [ - type isJavaStatic ifTrue: [ - problemSummary - reportVerificationProblem: #StaticClassCannotExistInNestedClass - args: nil - severity: nil - forType: type]] - ifFalse: [ - problemSummary - reportVerificationProblem: #InterfaceCannotExistInNestedClass - args: nil - severity: nil - forType: type]]]]. - - (interfaces := newClass superinterfaces) notEmpty ifTrue: [ - interfacesByIndentity := interfaces asSet. - duplicateExists := interfaces size ~~ interfacesByIndentity size. - - interfacesByIndentity do: [:interface | - duplicateExists ifTrue: [ - (interfaces occurrencesOf: interface) > 1 ifTrue: [ - problemSummary - reportVerificationProblem: #InterfaceIsSpecifiedMoreThanOnce - args: (Array with: interface javaQualifiedName) - severity: nil - forType: type]]. - - interface isJavaMissing ifTrue: [ - hasHierarchyProblem := true. - interface basicClass == JavaInterfaceIsClass basicClass - ifTrue: [ - problemSummary - reportVerificationProblem: #UsingClassWhereInterfaceIsRequired - args: (Array with: interface javaQualifiedName) - severity: nil - forType: type] - ifFalse: [ - interface basicClass == JavaMissingInterface basicClass - ifTrue: [ - problemSummary - reportVerificationProblem: #MissingInterface - args: (Array with: interface javaQualifiedName with: interface unmatchedDescriptor) - severity: nil - forType: type] - ifFalse: [ - problemSummary - reportVerificationProblem: #CyclicSuperinterface - args: (Array with: interface javaQualifiedName) - severity: nil - forType: type]]]]]. - - hasHierarchyProblem ifFalse: [ - "Search up the type's hierarchy for - 1. missing superclass, - 2. superclass cycle, or - 3. superclass is interface." - (invalidType := newClass findFirstInvalidSupertypeSkipping: EsIdentitySet new) ~~ nil ifTrue: [ - problemSummary - reportVerificationProblem: #HasHierarchyProblem - args: (Array with: invalidType javaReadableName) - severity: nil - forType: type]] - -reportModifierProblemsOnType: aType - - (type basicModifiers anyMask: AccAlternateModifierProblem) ifTrue: [ - (type basicModifiers anyMask: AccModifierProblem) - ifTrue: [ - ^problemSummary - reportVerificationProblem: #OnlyOneVisibilityModifierAllowed - args: nil - severity: nil - forType: aType] - ifFalse: [ - ^problemSummary - reportVerificationProblem: #DuplicateModifier - args: nil - severity: nil - forType: aType]]. - - type isJavaInterface ifTrue: [ - ^problemSummary - reportVerificationProblem: #IllegalModifierForInterface - args: nil - severity: nil - forType: aType]. - - (type basicModifiers allMask: AccAbstract | AccFinal) ifTrue: [ - ^problemSummary - reportVerificationProblem: #IllegalModifierCombinationAbstractFinal - args: nil - severity: nil - forType: aType]. - - ^problemSummary - reportVerificationProblem: #IllegalModifierForClass - args: nil - severity: nil - forType: aType - -void reportModifierProblems() { - if (this.type.isAbstract() && this.type.isFinal()) - this.problemReporter.illegalModifierCombinationAbstractFinal(this.type); - - // Should be able to detect all 3 problems NOT just 1 - if ((type.modifiers() & Modifiers.AccAlternateModifierProblem) == 0) { - if (this.type.isInterface()) - this.problemReporter.illegalModifierForInterface(this.type); - else - this.problemReporter.illegalModifier(this.type); - } else { - if ((type.modifiers() & Modifiers.AccModifierProblem) != 0) - this.problemReporter.onlyOneVisibilityModifierAllowed(this.type); - else - this.problemReporter.duplicateModifier(this.type); - } -} */ public MethodVerifier(LookupEnvironment environment) { - this.type = null; // Initialized with the public method verify(SourceTypeBinding) + this.type = null; // Initialized with the public method verify(SourceTypeBinding) this.inheritedMethods = null; this.currentMethods = null; this.runtimeException = null; this.errorException = null; + this.environment = environment; } private void checkAgainstInheritedMethods(MethodBinding currentMethod, MethodBinding[] methods, int length) { + currentMethod.modifiers |= CompilerModifiers.AccOverriding; for (int i = length; --i >= 0;) { MethodBinding inheritedMethod = methods[i]; + if (!currentMethod.isAbstract() && inheritedMethod.isAbstract()) + currentMethod.modifiers |= CompilerModifiers.AccImplementing; + if (currentMethod.returnType != inheritedMethod.returnType) { this.problemReporter(currentMethod).incompatibleReturnType(currentMethod, inheritedMethod); - } else if (currentMethod.isStatic() != inheritedMethod.isStatic()) { // Cannot override a static method or hide an instance method + } else if (currentMethod.isStatic() != inheritedMethod.isStatic()) { // Cannot override a static method or hide an instance method this.problemReporter(currentMethod).staticAndInstanceConflict(currentMethod, inheritedMethod); } else { if (currentMethod.thrownExceptions != NoExceptions) @@ -255,9 +66,9 @@ private void checkAgainstInheritedMethods(MethodBinding currentMethod, MethodBin this.problemReporter(currentMethod).finalMethodCannotBeOverridden(currentMethod, inheritedMethod); if (!this.isAsVisible(currentMethod, inheritedMethod)) this.problemReporter(currentMethod).visibilityConflict(currentMethod, inheritedMethod); - if (inheritedMethod.isViewedAsDeprecated()) - if (!currentMethod.isViewedAsDeprecated()) - this.problemReporter(currentMethod).overridesDeprecatedMethod(currentMethod, inheritedMethod); +// if (inheritedMethod.isViewedAsDeprecated()) +// if (!currentMethod.isViewedAsDeprecated() || environment.options.reportDeprecationInsideDeprecatedCode) +// this.problemReporter(currentMethod).overridesDeprecatedMethod(currentMethod, inheritedMethod); } } } @@ -267,7 +78,6 @@ Verify that newExceptions are all included in inheritedExceptions. Assumes all exceptions are valid and throwable. Unchecked exceptions (compatible with runtime & error) are ignored (see the spec on pg. 203). */ - private void checkExceptions(MethodBinding newMethod, MethodBinding inheritedMethod) { ReferenceBinding[] newExceptions = newMethod.thrownExceptions; ReferenceBinding[] inheritedExceptions = inheritedMethod.thrownExceptions; @@ -283,33 +93,33 @@ private void checkExceptions(MethodBinding newMethod, MethodBinding inheritedMet private void checkInheritedMethods(MethodBinding[] methods, int length) { TypeBinding returnType = methods[0].returnType; int index = length; - while ((--index > 0) && (returnType == methods[index].returnType)); - if (index > 0) { // All inherited methods do NOT have the same vmSignature + while (--index > 0 && returnType == methods[index].returnType); + if (index > 0) { // All inherited methods do NOT have the same vmSignature this.problemReporter().inheritedMethodsHaveIncompatibleReturnTypes(this.type, methods, length); return; } MethodBinding concreteMethod = null; - if (!type.isInterface()){ // ignore concrete methods for interfaces - for (int i = length; --i >= 0;) // Remember that only one of the methods can be non-abstract + if (!type.isInterface()) { // ignore concrete methods for interfaces + for (int i = length; --i >= 0;) { // Remember that only one of the methods can be non-abstract if (!methods[i].isAbstract()) { concreteMethod = methods[i]; break; } + } } if (concreteMethod == null) { if (this.type.isClass() && !this.type.isAbstract()) { for (int i = length; --i >= 0;) - if (!mustImplementAbstractMethod(methods[i])) - return; // in this case, we have already reported problem against the concrete superclass - - TypeDeclaration typeDeclaration = this.type.scope.referenceContext; - if (typeDeclaration != null) { - MethodDeclaration missingAbstractMethod = typeDeclaration.addMissingAbstractMethodFor(methods[0]); - missingAbstractMethod.scope.problemReporter().abstractMethodMustBeImplemented(this.type, methods[0]); - } else { - this.problemReporter().abstractMethodMustBeImplemented(this.type, methods[0]); - } + if (!mustImplementAbstractMethod(methods[i])) return; // have already reported problem against the concrete superclass + + TypeDeclaration typeDeclaration = this.type.scope.referenceContext; + if (typeDeclaration != null) { + MethodDeclaration missingAbstractMethod = typeDeclaration.addMissingAbstractMethodFor(methods[0]); + missingAbstractMethod.scope.problemReporter().abstractMethodMustBeImplemented(this.type, methods[0]); + } else { + this.problemReporter().abstractMethodMustBeImplemented(this.type, methods[0]); + } } return; } @@ -349,8 +159,7 @@ For each inherited method identifier (message pattern - vm signature minus the r else complain about missing implementation only if type is NOT an interface or abstract */ - -private void checkMethods() { +private void checkMethods() { boolean mustImplementAbstractMethods = this.type.isClass() && !this.type.isAbstract(); char[][] methodSelectors = this.inheritedMethods.keyTable; for (int s = methodSelectors.length; --s >= 0;) { @@ -387,22 +196,42 @@ private void checkMethods() { } if (index > 0) { this.checkInheritedMethods(matchingInherited, index + 1); // pass in the length of matching - } else { - if (mustImplementAbstractMethods && index == 0 && matchingInherited[0].isAbstract()) - if (mustImplementAbstractMethod(matchingInherited[0])) { - TypeDeclaration typeDeclaration = this.type.scope.referenceContext; - if (typeDeclaration != null) { - MethodDeclaration missingAbstractMethod = typeDeclaration.addMissingAbstractMethodFor(matchingInherited[0]); - missingAbstractMethod.scope.problemReporter().abstractMethodMustBeImplemented(this.type, matchingInherited[0]); - } else { - this.problemReporter().abstractMethodMustBeImplemented(this.type, matchingInherited[0]); - } + } else if (mustImplementAbstractMethods && index == 0 && matchingInherited[0].isAbstract()) { + if (mustImplementAbstractMethod(matchingInherited[0])) { + TypeDeclaration typeDeclaration = this.type.scope.referenceContext; + if (typeDeclaration != null) { + MethodDeclaration missingAbstractMethod = typeDeclaration.addMissingAbstractMethodFor(matchingInherited[0]); + missingAbstractMethod.scope.problemReporter().abstractMethodMustBeImplemented(this.type, matchingInherited[0]); + } else { + this.problemReporter().abstractMethodMustBeImplemented(this.type, matchingInherited[0]); } + } } } } } } +private void checkPackagePrivateAbstractMethod(MethodBinding abstractMethod) { + ReferenceBinding superType = this.type.superclass(); + char[] selector = abstractMethod.selector; + do { + if (!superType.isValidBinding()) return; + if (!superType.isAbstract()) return; // closer non abstract super type will be flagged instead + + MethodBinding[] methods = superType.getMethods(selector); + nextMethod : for (int m = methods.length; --m >= 0;) { + MethodBinding method = methods[m]; + if (method.returnType != abstractMethod.returnType || !method.areParametersEqual(abstractMethod)) + continue nextMethod; + if (method.isPrivate() || method.isConstructor() || method.isDefaultAbstract()) + continue nextMethod; + if (superType.fPackage == abstractMethod.declaringClass.fPackage) return; // found concrete implementation of abstract method in same package + } + } while ((superType = superType.superclass()) != abstractMethod.declaringClass); + + // non visible abstract methods cannot be overridden so the type must be defined abstract + this.problemReporter().abstractMethodCannotBeOverridden(this.type, abstractMethod); +} /* Binding creation is responsible for reporting: - all modifier problems (duplicates & multiple visibility modifiers + incompatible combinations) @@ -421,12 +250,9 @@ private void computeInheritedMethods() { int lastPosition = 0; interfacesToVisit[lastPosition] = type.superInterfaces(); - ReferenceBinding superType; - if (this.type.isClass()) { - superType = this.type.superclass(); - } else { // check interface methods against Object - superType = this.type.scope.getJavaLangObject(); - } + ReferenceBinding superType = this.type.isClass() + ? this.type.superclass() + : this.type.scope.getJavaLangObject(); // check interface methods against Object MethodBinding[] nonVisibleDefaultMethods = null; int nonVisibleCount = 0; @@ -444,19 +270,23 @@ private void computeInheritedMethods() { MethodBinding method = methods[m]; if (!(method.isPrivate() || method.isConstructor() || method.isDefaultAbstract())) { // look at all methods which are NOT private or constructors or default abstract MethodBinding[] existingMethods = (MethodBinding[]) this.inheritedMethods.get(method.selector); - if (existingMethods != null) - for (int i = 0, length = existingMethods.length; i < length; i++) - if (method.returnType == existingMethods[i].returnType) - if (method.areParametersEqual(existingMethods[i])) - continue nextMethod; + if (existingMethods != null) { + for (int i = 0, length = existingMethods.length; i < length; i++) { + if (method.returnType == existingMethods[i].returnType && method.areParametersEqual(existingMethods[i])) { + if (method.isDefault() && method.isAbstract() && method.declaringClass.fPackage != type.fPackage) + checkPackagePrivateAbstractMethod(method); + continue nextMethod; + } + } + } if (nonVisibleDefaultMethods != null) for (int i = 0; i < nonVisibleCount; i++) - if (method.returnType == nonVisibleDefaultMethods[i].returnType) - if (CharOperation.equals(method.selector, nonVisibleDefaultMethods[i].selector)) - if (method.areParametersEqual(nonVisibleDefaultMethods[i])) - continue nextMethod; + if (method.returnType == nonVisibleDefaultMethods[i].returnType + && CharOperation.equals(method.selector, nonVisibleDefaultMethods[i].selector) + && method.areParametersEqual(nonVisibleDefaultMethods[i])) + continue nextMethod; - if (!(method.isDefault() && (method.declaringClass.fPackage != type.fPackage))) { // ignore methods which have default visibility and are NOT defined in another package + if (!(method.isDefault() && method.declaringClass.fPackage != type.fPackage)) { // ignore methods which have default visibility and are NOT defined in another package if (existingMethods == null) existingMethods = new MethodBinding[1]; else @@ -478,11 +308,9 @@ private void computeInheritedMethods() { MethodBinding[] current = (MethodBinding[]) this.currentMethods.get(method.selector); if (current != null) { // non visible methods cannot be overridden so a warning is issued foundMatch : for (int i = 0, length = current.length; i < length; i++) { - if (method.returnType == current[i].returnType) { - if (method.areParametersEqual(current[i])) { - this.problemReporter().overridesPackageDefaultMethod(current[i], method); - break foundMatch; - } + if (method.returnType == current[i].returnType && method.areParametersEqual(current[i])) { + this.problemReporter().overridesPackageDefaultMethod(current[i], method); + break foundMatch; } } } @@ -495,6 +323,9 @@ private void computeInheritedMethods() { for (int i = 0; i <= lastPosition; i++) { ReferenceBinding[] interfaces = interfacesToVisit[i]; + if (interfaces==null) { + interfaces = new ReferenceBinding[0]; + } for (int j = 0, length = interfaces.length; j < length; j++) { superType = interfaces[j]; if ((superType.tagBits & InterfaceVisited) == 0) { @@ -527,56 +358,18 @@ private void computeInheritedMethods() { // bit reinitialization for (int i = 0; i <= lastPosition; i++) { ReferenceBinding[] interfaces = interfacesToVisit[i]; + if (interfaces==null) { + interfaces = new ReferenceBinding[0]; + } for (int j = 0, length = interfaces.length; j < length; j++) interfaces[j].tagBits &= ~InterfaceVisited; } } -/* -computeInheritedMethodMembers - - "8.4.6.4" - "Compute all of the members for the type that are inherited from its supertypes. - This includes: - All of the methods implemented in the supertype hierarchy that are not overridden. - PROBLEM: Currently we do not remove overridden methods in the interface hierarchy. - This could cause a non-existent exception error to be detected." - - | supertype allSuperinterfaces methodsSeen interfacesSeen | - inheritedMethodMembers := LookupTable new: 50. - allSuperinterfaces := OrderedCollection new. - - type isJavaClass ifTrue: [ - supertype := type. - methodsSeen := EsIdentitySet new: 20. - [(supertype := self superclassFor: supertype) == nil] whileFalse: [ - (supertype isBuilderClass or: [supertype isValidDescriptor]) ifTrue: [ - allSuperinterfaces addAll: (self superinterfacesFor: supertype). - supertype javaUserDefinedMethodsDo: [:method | - (method isJavaPrivate or: [method isJavaConstructor]) ifFalse: [ - (method isJavaDefault and: [method declaringClass package symbol ~= type package symbol]) ifFalse: [ - (methodsSeen includes: method selector) ifFalse: [ - methodsSeen add: method selector. - (inheritedMethodMembers - at: (self methodSignatureFor: method selector) - ifAbsentPut: [OrderedCollection new: 3]) - add: method]]]]]]]. - - allSuperinterfaces addAll: (self superinterfacesFor: type). - interfacesSeen := EsIdentitySet new: allSuperinterfaces size * 2. - [allSuperinterfaces notEmpty] whileTrue: [ - supertype := allSuperinterfaces removeFirst. - (interfacesSeen includes: supertype) ifFalse: [ - interfacesSeen add: supertype. - (supertype isBuilderClass or: [supertype isValidDescriptor]) ifTrue: [ - allSuperinterfaces addAll: (self superinterfacesFor: supertype). - supertype javaUserDefinedMethodsDo: [:method | "Interface methods are all abstract public." - (inheritedMethodMembers - at: (self methodSignatureFor: method selector) - ifAbsentPut: [OrderedCollection new: 3]) - add: method]]]] -*/ private void computeMethods() { MethodBinding[] methods = type.methods(); + if (methods==null) { + methods = new MethodBinding[0]; + } int size = methods.length; this.currentMethods = new HashtableOfObject(size == 0 ? 1 : size); // maps method selectors to an array of methods... must search to match paramaters & return type for (int m = size; --m >= 0;) { @@ -624,8 +417,11 @@ private boolean mustImplementAbstractMethod(MethodBinding abstractMethod) { while (superclass.isAbstract() && superclass != declaringClass) superclass = superclass.superclass(); // find the first concrete superclass or the abstract declaringClass } else { - if (this.type.implementsInterface(declaringClass, false)) - return !this.type.isAbstract(); + if (this.type.implementsInterface(declaringClass, false)) { + if (this.type.isAbstract()) return false; // leave it for the subclasses + if (!superclass.implementsInterface(declaringClass, true)) // only if a superclass does not also implement the interface + return true; + } while (superclass.isAbstract() && !superclass.implementsInterface(declaringClass, false)) superclass = superclass.superclass(); // find the first concrete superclass or the superclass which implements the interface } @@ -651,229 +447,13 @@ public void verify(SourceTypeBinding type) { this.computeInheritedMethods(); this.checkMethods(); } -private void zzFieldProblems() { -} -/* -Binding creation is responsible for reporting all problems with fields: - - all modifier problems (duplicates & multiple visibility modifiers + incompatible combinations - final/volatile) - - plus invalid modifiers given the context (the verifier did not do this before) - - include initializers in the modifier checks even though bindings are not created - - collisions... 2 fields with same name - - interfaces cannot define initializers - - nested types cannot define static fields - - with the type of the field: - - void is not a valid type (or for an array) - - an ambiguous, invisible or missing type - -verifyFields - - | toSearch | - (toSearch := newClass fields) notEmpty ifTrue: [ - newClass fromJavaClassFile - ifTrue: [ - toSearch do: [:field | - field isJavaInitializer ifFalse: [ - self verifyFieldType: field]]] - ifFalse: [ - toSearch do: [:field | - field isJavaInitializer - ifTrue: [self verifyFieldInitializer: field] - ifFalse: [self verifyField: field]]]] - -verifyFieldInitializer: field - - type isJavaInterface - ifTrue: [ - problemSummary - reportVerificationProblem: #InterfacesCannotHaveInitializers - args: #() - severity: nil - forField: field] - ifFalse: [ - field isJavaStatic - ifTrue: [ - field modifiers == AccStatic ifFalse: [ - problemSummary - reportVerificationProblem: #IllegalModifierForStaticInitializer - args: #() - severity: nil - forField: field]] - ifFalse: [ - field modifiers == 0 ifFalse: [ - problemSummary - reportVerificationProblem: #IllegalModifierForInitializer - args: #() - severity: nil - forField: field]]] - -verifyField: field - - (field basicModifiers anyMask: AccAlternateModifierProblem | AccModifierProblem) ifTrue: [ - self reportModifierProblemsOnField: field]. - - field isJavaStatic ifTrue: [ - type isJavaStatic ifFalse: [ - (type isJavaNestedType and: [type isJavaClass]) ifTrue: [ - problemSummary - reportVerificationProblem: #NestedClassCannotHaveStaticField - args: #() - severity: nil - forField: field]]]. - - self verifyFieldType: field - -verifyFieldType: field - - | descriptor fieldType | - "8.3 (Class) 9.3 (Interface)" - "Optimize the base type case" - field typeIsBaseType - ifTrue: [ - field typeName = 'V' ifTrue: [ "$NON-NLS$" - problemSummary - reportVerificationProblem: #IllegalTypeForField - args: (Array with: JavaVoid) - severity: nil - forField: field]] - ifFalse: [ - descriptor := field asDescriptorIn: nameEnvironment. - (fieldType := descriptor type) isValidDescriptor - ifTrue: [ - (fieldType isArrayType and: [fieldType leafComponentType isVoidType]) ifTrue: [ - problemSummary - reportVerificationProblem: #InvalidArrayType - args: (Array with: fieldType javaReadableName) - severity: nil - forField: field]] - ifFalse: [ - problemSummary - reportVerificationProblem: #UnboundTypeForField - args: (Array with: fieldType javaReadableName with: fieldType leafComponentType) - severity: nil - forField: field]]. - -reportModifierProblemsOnField: field - - (field basicModifiers anyMask: AccAlternateModifierProblem) ifTrue: [ - (field basicModifiers anyMask: AccModifierProblem) - ifTrue: [ - ^problemSummary - reportVerificationProblem: #OnlyOneVisibilityModifierAllowed - args: #() - severity: ErrorInfo::ConflictingModifier - forField: field] - ifFalse: [ - ^problemSummary - reportVerificationProblem: #DuplicateModifier - args: #() - severity: ErrorInfo::ConflictingModifier - forField: field]]. - - type isJavaInterface ifTrue: [ - ^problemSummary - reportVerificationProblem: #IllegalModifierForInterfaceField - args: #() - severity: nil - forField: field]. - - (field basicModifiers allMask: AccFinal | AccVolatile) ifTrue: [ - ^problemSummary - reportVerificationProblem: #IllegalModifierCombinationFinalVolatile - args: #() - severity: nil - forField: field]. - - ^problemSummary - reportVerificationProblem: #IllegalModifierForField - args: #() - severity: nil - forField: field - -void reportModifierProblems(FieldBinding field) { - if (field.isFinal() && field.isVolatile()) - this.problemReporter.illegalModifierCombinationFinalVolatile(field); - - // Should be able to detect all 3 problems NOT just 1 - if ((type.modifiers() & Modifiers.AccAlternateModifierProblem) == 0) { - if (this.type.isInterface()) - this.problemReporter.illegalModifierForInterfaceField(field); - else - this.problemReporter.illegalModifier(field); - } else { - if ((field.modifiers & Modifiers.AccModifierProblem) != 0) - this.problemReporter.onlyOneVisibilityModifierAllowed(field); - else - this.problemReporter.duplicateModifier(field); - } -} -*/ -private void zzImportProblems() { -} -/* -Binding creation is responsible for reporting all problems with imports: - - on demand imports which refer to missing packages - - with single type imports: - - resolves to an ambiguous, invisible or missing type - - conflicts with the type's source name - - has the same simple name as another import - -Note: VAJ ignored duplicate imports (only one was kept) - -verifyImports - - | importsBySimpleName nameEnvClass imports cl first | - importsBySimpleName := LookupTable new. - nameEnvClass := nameEnvironment class. - - "7.5.2" - type imports do: [:import | - import isOnDemand - ifTrue: [ - (nameEnvClass doesPackageExistNamed: import javaPackageName) ifFalse: [ - (nameEnvClass findJavaClassNamedFrom: import javaPackageName) == nil ifTrue: [ - problemSummary - reportVerificationProblem: #OnDemandImportRefersToMissingPackage - args: (Array with: import asString) - severity: ErrorInfo::ImportVerification - forType: type]]] - ifFalse: [ - (imports := importsBySimpleName at: import javaSimpleName ifAbsent: []) == nil - ifTrue: [ - importsBySimpleName at: import javaSimpleName put: (Array with: import)] - ifFalse: [ - (imports includes: import) ifFalse: [ - importsBySimpleName at: import javaSimpleName put: imports, (Array with: import)]]. - - "Ignore any imports which are simple names - we will treat these as no-ops." - - import javaPackageName notEmpty ifTrue: [ - cl := nameEnvClass findJavaClassNamedFrom: import asString. - - (cl ~~ nil and: [cl isJavaPublic or: [cl controller symbol == type controller symbol]]) ifFalse: [ - problemSummary - reportVerificationProblem: #SingleTypeImportRefersToInvisibleType - args: (Array with: import asString) - severity: ErrorInfo::ImportVerification - forType: type]]]]. - - importsBySimpleName notEmpty ifTrue: [ - importsBySimpleName keysAndValuesDo: [:simpleName :matching | - matching size == 1 - ifTrue: [ - simpleName = type sourceName ifTrue: [ - matching first javaReadableName = type javaReadableName ifFalse: [ - problemSummary - reportVerificationProblem: #SingleTypeImportConflictsWithType - args: #() - severity: nil - forType: type]]] - ifFalse: [ - problemSummary - reportVerificationProblem: #SingleTypeImportsHaveSameSimpleName - args: (Array with: simpleName) - severity: nil - forType: type]]] -*/ -private void zzTypeProblems() { +public String toString() { + StringBuffer buffer = new StringBuffer(10); + buffer.append("MethodVerifier for type: "); //$NON-NLS-1$ + buffer.append(type.readableName()); + buffer.append('\n'); + buffer.append("\t-inherited methods: "); //$NON-NLS-1$ + buffer.append(this.inheritedMethods); + return buffer.toString(); } }