From 3e81ed505a8c74c073197ef9c8368b7e9f6dc02f Mon Sep 17 00:00:00 2001 From: Alexander Kriegisch Date: Sun, 1 Oct 2023 12:56:22 +0700 Subject: [PATCH] AjLookupEnvironment: readability refactoring While trying to understand the code a bit better in order to fix failing builds, I applied some cosmetic refactoring and reformatting. This commit does not change any functionality. Whether the static import of CompilationAndWeavingContext.* is a good thing or not is debatable, but I like the code to be less chatty than it was before, assuming that every developer uses an IDE helping to find out where static methods and constants come from. Signed-off-by: Alexander Kriegisch --- .../compiler/lookup/AjLookupEnvironment.java | 1097 ++++++++--------- 1 file changed, 515 insertions(+), 582 deletions(-) diff --git a/org.aspectj.ajdt.core/src/main/java/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java b/org.aspectj.ajdt.core/src/main/java/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java index ff30bfc29..6fc9de7dd 100644 --- a/org.aspectj.ajdt.core/src/main/java/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java +++ b/org.aspectj.ajdt.core/src/main/java/org/aspectj/ajdt/internal/compiler/lookup/AjLookupEnvironment.java @@ -20,7 +20,6 @@ import org.aspectj.ajdt.internal.compiler.ast.AspectDeclaration; import org.aspectj.ajdt.internal.compiler.ast.PointcutDeclaration; import org.aspectj.asm.AsmManager; import org.aspectj.bridge.IMessage; -import org.aspectj.bridge.context.CompilationAndWeavingContext; import org.aspectj.bridge.context.ContextToken; import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation; import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; @@ -72,14 +71,20 @@ import org.aspectj.weaver.patterns.Declare; import org.aspectj.weaver.patterns.DeclareAnnotation; import org.aspectj.weaver.patterns.DeclareParents; +import static org.aspectj.bridge.context.CompilationAndWeavingContext.*; + /** - * Overrides the default eclipse LookupEnvironment for two purposes. - * - * 1. To provide some additional phases to completeTypeBindings that weave declare parents and inter-type declarations - * at the correct time. - * - * 2. To intercept the loading of new binary types to ensure the they will have declare parents and inter-type declarations woven - * when appropriate. + * Overrides the default Eclipse {@link LookupEnvironment} for two purposes: + *
    + *
  1. + * To provide some additional phases to {@code completeTypeBindings}, that weave declare parents and inter-type + * declarations at the correct time. + *
  2. + *
  3. + * To intercept loading of new binary types, to ensure they will have declare parents and inter-type declarations + * woven when appropriate. + *
  4. + *
* * @author Jim Hugunin */ @@ -90,27 +95,16 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC private final List pendingTypesToWeave = new ArrayList<>(); // Q: What are dangerousInterfaces? - // A: An interface is considered dangerous if an ITD has been made upon it - // and that ITD - // requires the top most implementors of the interface to be woven *and yet* - // the aspect - // responsible for the ITD is not in the 'world'. + // A: An interface is considered dangerous if an ITD has been made upon it and that ITD requires the top most + // implementors of the interface to be woven *and yet* the aspect responsible for the ITD is not in the 'world'. + // // Q: Err, how can that happen? - // A: When a type is on the inpath, it is 'processed' when completing type - // bindings. At this - // point we look at any type mungers it was affected by previously (stored - // in the weaver - // state info attribute). Effectively we are working with a type munger and - // yet may not have its - // originating aspect in the world. This is a problem if, for example, the - // aspect supplied - // a 'body' for a method targetting an interface - since the top most - // implementors should - // be woven by the munger from the aspect. When this happens we store the - // interface name here - // in the map - if we later process a type that is the topMostImplementor of - // a dangerous - // interface then we put out an error message. + // A: When a type is on the inpath, it is 'processed' when completing type bindings. At this point, we look at any + // type mungers it was affected by previously (stored in the weaver state info attribute). Effectively, we are + // working with a type munger and yet may not have its originating aspect in the world. This is a problem if e.g., + // the aspect supplied a 'body' for a method targetting an interface - since the top most implementors should be + // woven by the munger from the aspect. When this happens we store the interface name here in the map - if we later + // process a type that is the topMostImplementor of a dangerous interface, then we put out an error message. /** * interfaces targetted by ITDs that have to be implemented by accessing the topMostImplementor of the interface, yet the aspect @@ -119,7 +113,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC private final Map dangerousInterfaces = new HashMap<>(); public AjLookupEnvironment(ITypeRequestor typeRequestor, CompilerOptions options, ProblemReporter problemReporter, - INameEnvironment nameEnvironment) { + INameEnvironment nameEnvironment) { super(typeRequestor, options, problemReporter, nameEnvironment); } @@ -131,45 +125,38 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC @Override public void completeTypeBindings() { AsmManager.setCompletingTypeBindings(true); - ContextToken completeTypeBindingsToken = CompilationAndWeavingContext.enteringPhase( - CompilationAndWeavingContext.COMPLETING_TYPE_BINDINGS, ""); + ContextToken completeTypeBindingsToken = enteringPhase(COMPLETING_TYPE_BINDINGS, ""); // builtInterTypesAndPerClauses = false; // pendingTypesToWeave = new ArrayList(); stepCompleted = BUILD_TYPE_HIERARCHY; for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) { - ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.CHECK_AND_SET_IMPORTS, - units[i].compilationResult.fileName); + ContextToken tok = enteringPhase(CHECK_AND_SET_IMPORTS, units[i].compilationResult.fileName); units[i].scope.checkAndSetImports(); - CompilationAndWeavingContext.leavingPhase(tok); + leavingPhase(tok); } stepCompleted = CHECK_AND_SET_IMPORTS; for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) { - ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.CONNECTING_TYPE_HIERARCHY1, - units[i].compilationResult.fileName); + ContextToken tok = enteringPhase(CONNECTING_TYPE_HIERARCHY1, units[i].compilationResult.fileName); units[i].scope.connectTypeHierarchy1(); - CompilationAndWeavingContext.leavingPhase(tok); + leavingPhase(tok); } stepCompleted = CONNECT_TYPE_HIERARCHY1; for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) { - ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.CONNECTING_TYPE_HIERARCHY2, - units[i].compilationResult.fileName); + ContextToken tok = enteringPhase(CONNECTING_TYPE_HIERARCHY2, units[i].compilationResult.fileName); units[i].scope.connectTypeHierarchy2(); - CompilationAndWeavingContext.leavingPhase(tok); + leavingPhase(tok); } stepCompleted = CONNECT_TYPE_HIERARCHY2; for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) { - ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.BUILDING_FIELDS_AND_METHODS, - units[i].compilationResult.fileName); - // units[i].scope.checkParameterizedTypes(); do this check a little - // later, after ITDs applied to stbs + ContextToken tok = enteringPhase(BUILDING_FIELDS_AND_METHODS, units[i].compilationResult.fileName); + // units[i].scope.checkParameterizedTypes(); do this check a little later, after ITDs applied to stbs units[i].scope.buildFieldsAndMethods(); - CompilationAndWeavingContext.leavingPhase(tok); + leavingPhase(tok); } - // would like to gather up all TypeDeclarations at this point and put - // them in the factory + // would like to gather up all TypeDeclarations at this point and put them in the factory for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) { SourceTypeBinding[] b = units[i].scope.topLevelTypes; for (SourceTypeBinding sourceTypeBinding : b) { @@ -182,14 +169,11 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC } } - // We won't find out about anonymous types until later though, so - // register to be - // told about them when they turn up. + // We won't find out about anonymous types until later though, so register to be told about them when they turn up AnonymousClassPublisher.aspectOf().setAnonymousClassCreationListener(this); - // need to build inter-type declarations for all AspectDeclarations at - // this point - // this MUST be done in order from super-types to subtypes + // Need to build inter-type declarations for all AspectDeclarations at this point. This MUST be done in order from + // super-types to subtypes. List typesToProcess = new ArrayList<>(); List aspectsToProcess = new ArrayList<>(); for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) { @@ -210,7 +194,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC processInterTypeMemberTypes(aspectToProcess.scope); } - while (typesToProcess.size() > 0) { + while (!typesToProcess.isEmpty()) { // removes types from the list as they are processed... collectAllITDsAndDeclares(typesToProcess.get(0), typesToProcess); } @@ -225,30 +209,20 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC doPendingWeaves(); - // We now have some list of types to process, and we are about to apply - // the type mungers. - // There can be situations where the order of types passed to the - // compiler causes the - // output from the compiler to vary - THIS IS BAD. For example, if we - // have class A - // and class B extends A. Also, an aspect that 'declare parents: A+ - // implements Serializable' - // then depending on whether we see A first, we may or may not make B - // serializable. - - // The fix is to process them in the right order, ensuring that for a - // type we process its - // supertypes and superinterfaces first. This algorithm may have - // problems with: - // - partial hierarchies (e.g. suppose types A,B,C are in a hierarchy - // and A and C are to be woven but not B) - // - weaving that brings new types in for processing (see - // pendingTypesToWeave.add() calls) after we thought - // we had the full list. + // We now have some list of types to process, and we are about to apply the type mungers. There can be situations + // where the order of types passed to the compiler causes the output from the compiler to vary - THIS IS BAD. + // For example, if we have class A and class B extends A. Also, an aspect that 'declare parents: A+ implements + // Serializable', then depending on whether we see A first, we may or may not make B serializable. + // + // The fix is to process them in the right order, ensuring that for a type we process its supertypes and + // superinterfaces first. This algorithm may have problems with: + // - partial hierarchies (e.g. suppose types A,B,C are in a hierarchy and A and C are to be woven but not B) + // - weaving that brings new types in for processing (see pendingTypesToWeave.add() calls) after we thought + // we had the full list. // // but these aren't common cases (he bravely said...) - boolean typeProcessingOrderIsImportant = declareParents.size() > 0 || declareAnnotationOnTypes.size() > 0; // DECAT + boolean typeProcessingOrderIsImportant = !declareParents.isEmpty() || !declareAnnotationOnTypes.isEmpty(); // DECAT if (typeProcessingOrderIsImportant) { typesToProcess = new ArrayList<>(); for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) { @@ -257,16 +231,23 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC Collections.addAll(typesToProcess, stbs); } - List stb2 = new ArrayList<>(typesToProcess); + List typesToProcessCopy = new ArrayList<>(typesToProcess); - while (typesToProcess.size() > 0) { + while (!typesToProcess.isEmpty()) { // A side effect of weaveIntertypes() is that the processed type is removed from the collection - weaveIntertypes(typesToProcess, typesToProcess.get(0), typeMungers, declareParents, declareAnnotationOnTypes, 1); + weaveIntertypes( + typesToProcess, typesToProcess.get(0), typeMungers, declareParents, declareAnnotationOnTypes, + 1 // do declare parents + ); } - while (stb2.size() > 0) { + typesToProcess = typesToProcessCopy; + while (!typesToProcess.isEmpty()) { // A side effect of weaveIntertypes() is that the processed type is removed from the collection - weaveIntertypes(stb2, stb2.get(0), typeMungers, declareParents, declareAnnotationOnTypes, 2); + weaveIntertypes( + typesToProcess, typesToProcess.get(0), typeMungers, declareParents, declareAnnotationOnTypes, + 2 // do ITDs + ); } } else { @@ -283,20 +264,18 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) { SourceTypeBinding[] b = units[i].scope.topLevelTypes; for (SourceTypeBinding sourceTypeBinding : b) { - ContextToken tok = CompilationAndWeavingContext.enteringPhase( - CompilationAndWeavingContext.RESOLVING_POINTCUT_DECLARATIONS, sourceTypeBinding.sourceName); + ContextToken tok = enteringPhase(RESOLVING_POINTCUT_DECLARATIONS, sourceTypeBinding.sourceName); resolvePointcutDeclarations(sourceTypeBinding.scope); - CompilationAndWeavingContext.leavingPhase(tok); + leavingPhase(tok); } } for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) { SourceTypeBinding[] b = units[i].scope.topLevelTypes; for (SourceTypeBinding sourceTypeBinding : b) { - ContextToken tok = CompilationAndWeavingContext.enteringPhase( - CompilationAndWeavingContext.ADDING_DECLARE_WARNINGS_AND_ERRORS, sourceTypeBinding.sourceName); + ContextToken tok = enteringPhase(ADDING_DECLARE_WARNINGS_AND_ERRORS, sourceTypeBinding.sourceName); addAdviceLikeDeclares(sourceTypeBinding.scope); - CompilationAndWeavingContext.leavingPhase(tok); + leavingPhase(tok); } } @@ -308,59 +287,53 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC lastCompletedUnitIndex = lastUnitIndex; AsmManager.setCompletingTypeBindings(false); factory.getWorld().getCrosscuttingMembersSet().verify(); - CompilationAndWeavingContext.leavingPhase(completeTypeBindingsToken); + leavingPhase(completeTypeBindingsToken); if (isProcessingAnnotations) { throw new SourceTypeCollisionException(); // TODO(yushkovskiy): temporary solution; forcing to recompile units to insert mungers into types } } - // /** - // * For any given sourcetypebinding, this method checks that if it is a - // parameterized aspect that - // * the type parameters specified for any supertypes meet the bounds for - // the generic type - // * variables. - // */ - // private void verifyAnyTypeParametersMeetBounds(SourceTypeBinding - // sourceType) { - // ResolvedType onType = factory.fromEclipse(sourceType); - // if (onType.isAspect()) { - // ResolvedType superType = factory.fromEclipse(sourceType.superclass); - // // Don't need to check if it was used in its RAW form or isnt generic - // if (superType.isGenericType() || superType.isParameterizedType()) { - // TypeVariable[] typeVariables = superType.getTypeVariables(); - // UnresolvedType[] typeParams = superType.getTypeParameters(); - // if (typeVariables!=null && typeParams!=null) { - // for (int i = 0; i < typeVariables.length; i++) { - // boolean ok = - // typeVariables[i].canBeBoundTo(typeParams[i].resolve(factory.getWorld())); - // if (!ok) { // the supplied parameter violates the bounds - // // Type {0} does not meet the specification for type parameter {1} ({2}) - // in generic type {3} - // String msg = - // WeaverMessages.format( - // WeaverMessages.VIOLATES_TYPE_VARIABLE_BOUNDS, - // typeParams[i], - // new Integer(i+1), - // typeVariables[i].getDisplayName(), - // superType.getGenericType().getName()); - // factory.getWorld().getMessageHandler().handleMessage(MessageUtil.error(msg - // ,onType.getSourceLocation())); - // } - // } - // } - // } - // } - // } - + /** + * For any given sourcetypebinding, this method checks that if it is a parameterized aspect, the type parameters + * specified for any supertypes meet the bounds for the generic type variables. + */ +/* + private void verifyAnyTypeParametersMeetBounds(SourceTypeBinding sourceType) { + ResolvedType onType = factory.fromEclipse(sourceType); + if (onType.isAspect()) { + ResolvedType superType = factory.fromEclipse(sourceType.superclass); + // Don't need to check if it was used in its RAW form or isn't generic + if (superType.isGenericType() || superType.isParameterizedType()) { + TypeVariable[] typeVariables = superType.getTypeVariables(); + UnresolvedType[] typeParams = superType.getTypeParameters(); + if (typeVariables != null && typeParams != null) { + for (int i = 0; i < typeVariables.length; i++) { + boolean ok = typeVariables[i].canBeBoundTo(typeParams[i].resolve(factory.getWorld())); + if (!ok) { // the supplied parameter violates the bounds + // Type {0} does not meet the specification for type parameter {1} ({2}) in generic type {3} + String msg = WeaverMessages.format( + WeaverMessages.VIOLATES_TYPE_VARIABLE_BOUNDS, + typeParams[i], + new Integer(i + 1), + typeVariables[i].getDisplayName(), + superType.getGenericType().getName() + ); + factory.getWorld().getMessageHandler().handleMessage(MessageUtil.error(msg, onType.getSourceLocation())); + } + } + } + } + } + } +*/ public void doSupertypesFirst(ReferenceBinding rb, Collection yetToProcess) { if (rb instanceof SourceTypeBinding) { if (yetToProcess.contains(rb)) { collectAllITDsAndDeclares((SourceTypeBinding) rb, yetToProcess); } } else if (rb instanceof ParameterizedTypeBinding) { - // If its a PTB we need to pull the SourceTypeBinding out of it. + // If it is a PTB, we need to pull the SourceTypeBinding out of it. ParameterizedTypeBinding ptb = (ParameterizedTypeBinding) rb; if (ptb.type instanceof SourceTypeBinding && yetToProcess.contains(ptb.type)) { collectAllITDsAndDeclares((SourceTypeBinding) ptb.type, yetToProcess); @@ -376,8 +349,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC */ private void collectAllITDsAndDeclares(SourceTypeBinding sourceType, Collection yetToProcess) { // Look at the supertype first - ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.COLLECTING_ITDS_AND_DECLARES, - sourceType.sourceName); + ContextToken tok = enteringPhase(COLLECTING_ITDS_AND_DECLARES, sourceType.sourceName); yetToProcess.remove(sourceType); // look out our direct supertype @@ -394,7 +366,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC buildInterTypeAndPerClause(sourceType.scope); addCrosscuttingStructures(sourceType.scope); - CompilationAndWeavingContext.leavingPhase(tok); + leavingPhase(tok); } /** @@ -406,16 +378,21 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC * * @param mode 0=do everything, 1=do declare parents, 2=do ITDs */ - private void weaveIntertypes(List typesToProcess, SourceTypeBinding typeToWeave, - List typeMungers, List declareParents, - List declareAnnotationOnTypes, int mode) { + private void weaveIntertypes( + List typesToProcess, SourceTypeBinding typeToWeave, + List typeMungers, List declareParents, + List declareAnnotationOnTypes, int mode + ) { // Look at the supertype first ReferenceBinding superType = typeToWeave.superclass(); if (typesToProcess.contains(superType) && superType instanceof SourceTypeBinding) { // System.err.println("Recursing to supertype "+new // String(superType.getFileName())); - weaveIntertypes(typesToProcess, (SourceTypeBinding) superType, typeMungers, declareParents, declareAnnotationOnTypes, - mode); + weaveIntertypes( + typesToProcess, (SourceTypeBinding) superType, + typeMungers, declareParents, declareAnnotationOnTypes, + mode + ); } // Then look at the superinterface list ReferenceBinding[] interfaceTypes = typeToWeave.superInterfaces(); @@ -423,22 +400,36 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC if (typesToProcess.contains(binding) && binding instanceof SourceTypeBinding) { // System.err.println("Recursing to superinterface "+new // String(binding.getFileName())); - weaveIntertypes(typesToProcess, (SourceTypeBinding) binding, typeMungers, declareParents, declareAnnotationOnTypes, - mode); - } else if (binding instanceof ParameterizedTypeBinding && (((ParameterizedTypeBinding) binding).type instanceof SourceTypeBinding) && typesToProcess.contains(((ParameterizedTypeBinding) binding).type)) { - weaveIntertypes(typesToProcess, (SourceTypeBinding) ((ParameterizedTypeBinding) binding).type, typeMungers, declareParents, declareAnnotationOnTypes, mode); + weaveIntertypes( + typesToProcess, (SourceTypeBinding) binding, + typeMungers, declareParents, declareAnnotationOnTypes, + mode + ); + } else if ( + binding instanceof ParameterizedTypeBinding && + (((ParameterizedTypeBinding) binding).type instanceof SourceTypeBinding) && + typesToProcess.contains(((ParameterizedTypeBinding) binding).type) + ) { + weaveIntertypes( + typesToProcess, (SourceTypeBinding) ((ParameterizedTypeBinding) binding).type, + typeMungers, declareParents, declareAnnotationOnTypes, + mode + ); } } - weaveInterTypeDeclarations(typeToWeave, typeMungers, declareParents, declareAnnotationOnTypes, false, mode); + weaveInterTypeDeclarations( + typeToWeave, typeMungers, + declareParents, declareAnnotationOnTypes, false, + mode + ); typesToProcess.remove(typeToWeave); } private void doPendingWeaves() { - for (SourceTypeBinding t: pendingTypesToWeave) { - ContextToken tok = CompilationAndWeavingContext.enteringPhase( - CompilationAndWeavingContext.WEAVING_INTERTYPE_DECLARATIONS, t.sourceName); + for (SourceTypeBinding t : pendingTypesToWeave) { + ContextToken tok = enteringPhase(WEAVING_INTERTYPE_DECLARATIONS, t.sourceName); weaveInterTypeDeclarations(t); - CompilationAndWeavingContext.leavingPhase(tok); + leavingPhase(tok); } pendingTypesToWeave.clear(); } @@ -550,8 +541,8 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC if (sourceType.superclass != null) { ResolvedType parent = factory.fromEclipse(sourceType.superclass); if (parent.isAspect() && !isAspect(dec)) { - factory.showMessage(IMessage.ERROR, "class \'" + new String(sourceType.sourceName) + "\' can not extend aspect \'" - + parent.getName() + "\'", factory.fromEclipse(sourceType).getSourceLocation(), null); + factory.showMessage(IMessage.ERROR, "class '" + new String(sourceType.sourceName) + "' can not extend aspect '" + + parent.getName() + "'", factory.fromEclipse(sourceType).getSourceLocation(), null); } } @@ -595,10 +586,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC if (!CharOperation.equals("annotation".toCharArray(), qtr.tokens[3])) { return false; } - if (!CharOperation.equals("Aspect".toCharArray(), qtr.tokens[4])) { - return false; - } - return true; + return CharOperation.equals("Aspect".toCharArray(), qtr.tokens[4]); } } } @@ -606,7 +594,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC } private void weaveInterTypeDeclarations(CompilationUnitScope unit, List typeMungers, - List declareParents, List declareAnnotationOnTypes) { + List declareParents, List declareAnnotationOnTypes) { for (int i = 0, length = unit.topLevelTypes.length; i < length; i++) { weaveInterTypeDeclarations(unit.topLevelTypes[i], typeMungers, declareParents, declareAnnotationOnTypes, false, 0); } @@ -617,53 +605,57 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC if (!pendingTypesToWeave.contains(sourceType)) { pendingTypesToWeave.add(sourceType); - // inner type ITD support - may need this for some incremental cases... - // List ctms = factory.getWorld().getCrosscuttingMembersSet().getTypeMungersOfKind( - // ResolvedTypeMunger.InnerClass); - // // List innerTypeMungers = new ArrayList(); - // // for (ConcreteTypeMunger ctm : ctms) { - // // if (ctm.getMunger() != null && ctm.getMunger().getKind() == ResolvedTypeMunger.InnerClass) { - // // innerTypeMungers.add(ctm); - // // } - // // } - // // that includes the innertype one... - // // doPendingWeaves at this level is about applying inner class - // BinaryTypeBinding t = (BinaryTypeBinding) sourceType; - // for (ConcreteTypeMunger ctm : innerTypeMungers) { - // NewMemberClassTypeMunger nmctm = (NewMemberClassTypeMunger) ctm.getMunger(); - // ReferenceBinding[] rbs = t.memberTypes; - // UnresolvedType ut = factory.fromBinding(t); - // if (ut.equals(nmctm.getTargetType())) { - // // got a match here - // SourceTypeBinding aspectTypeBinding = (SourceTypeBinding) factory.makeTypeBinding(ctm.getAspectType()); - // - // char[] mungerMemberTypeName = ("$" + nmctm.getMemberTypeName()).toCharArray(); - // ReferenceBinding innerTypeBinding = null; - // for (ReferenceBinding innerType : aspectTypeBinding.memberTypes) { - // char[] compounded = CharOperation.concatWith(innerType.compoundName, '.'); - // if (org.aspectj.org.eclipse.jdt.core.compiler.CharOperation.endsWith(compounded, mungerMemberTypeName)) { - // innerTypeBinding = innerType; - // break; - // } - // } - // // may be unresolved if the aspect type binding was a BinaryTypeBinding - // if (innerTypeBinding instanceof UnresolvedReferenceBinding) { - // innerTypeBinding = BinaryTypeBinding - // .resolveType(innerTypeBinding, factory.getLookupEnvironment(), true); - // } - // t.memberTypes(); // cause initialization - // t.memberTypes = new ReferenceBinding[] { innerTypeBinding }; - // - // int stop = 1; - // // The inner type from the aspect should be put into the membertypebindings for this - // - // } - // } +/* + // Inner type ITD support - may need this for some incremental cases... + List ctms = factory.getWorld() + .getCrosscuttingMembersSet() + .getTypeMungersOfKind(ResolvedTypeMunger.InnerClass); + + List innerTypeMungers = new ArrayList(); + for (ConcreteTypeMunger ctm : ctms) { + if (ctm.getMunger() != null && ctm.getMunger().getKind() == ResolvedTypeMunger.InnerClass) { + innerTypeMungers.add(ctm); + } + } + + // ... that includes the innertype one... + // doPendingWeaves at this level is about applying inner class + BinaryTypeBinding t = (BinaryTypeBinding) sourceType; + for (ConcreteTypeMunger ctm : innerTypeMungers) { + NewMemberClassTypeMunger nmctm = (NewMemberClassTypeMunger) ctm.getMunger(); + ReferenceBinding[] rbs = t.memberTypes; + UnresolvedType ut = factory.fromBinding(t); + if (ut.equals(nmctm.getTargetType())) { + // got a match here + SourceTypeBinding aspectTypeBinding = (SourceTypeBinding) factory.makeTypeBinding(ctm.getAspectType()); + + char[] mungerMemberTypeName = ("$" + nmctm.getMemberTypeName()).toCharArray(); + ReferenceBinding innerTypeBinding = null; + for (ReferenceBinding innerType : aspectTypeBinding.memberTypes) { + char[] compounded = CharOperation.concatWith(innerType.compoundName, '.'); + if (org.aspectj.org.eclipse.jdt.core.compiler.CharOperation.endsWith(compounded, mungerMemberTypeName)) { + innerTypeBinding = innerType; + break; + } + } + // may be unresolved if the aspect type binding was a BinaryTypeBinding + if (innerTypeBinding instanceof UnresolvedReferenceBinding) { + innerTypeBinding = BinaryTypeBinding + .resolveType(innerTypeBinding, factory.getLookupEnvironment(), true); + } + t.memberTypes(); // cause initialization + t.memberTypes = new ReferenceBinding[]{innerTypeBinding}; + + int stop = 1; + // The inner type from the aspect should be put into the membertypebindings for this + } + } +*/ } } else { weaveInterTypeDeclarations(sourceType, factory.getTypeMungers(), factory.getDeclareParents(), - factory.getDeclareAnnotationOnTypes(), true, 0); + factory.getDeclareAnnotationOnTypes(), true, 0); } } @@ -671,10 +663,9 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC * @param mode 0=do everything, 1=do declare parents, 2=do ITDs */ private void weaveInterTypeDeclarations(SourceTypeBinding sourceType, List typeMungers, - List declareParents, List declareAnnotationOnTypes, boolean skipInners, int mode) { + List declareParents, List declareAnnotationOnTypes, boolean skipInners, int mode) { - ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING_INTERTYPE_DECLARATIONS, - sourceType.sourceName); + ContextToken tok = enteringPhase(WEAVING_INTERTYPE_DECLARATIONS, sourceType.sourceName); ResolvedType onType = factory.fromEclipse(sourceType); @@ -686,26 +677,18 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC WeaverStateInfo info = onType.getWeaverState(); if (mode < 2) { - // this test isnt quite right - there will be a case where we fail to - // flag a problem - // with a 'dangerous interface' because the type is reweavable when we - // should have - // because the type wasn't going to be rewoven... if that happens, we - // should perhaps - // move this test and dangerous interface processing to the end of this - // method and - // make it conditional on whether any of the typeMungers passed into - // here actually - // matched this type. + // This test isn't quite right. There will be a case where we fail to flag a problem with a 'dangerous interface', + // because the type is reweavable, when we should have, because the type wasn't going to be rewoven... If that + // happens, we should perhaps move this test and dangerous interface processing to the end of this method and make + // it conditional on whether any of the typeMungers passed into here actually matched this type. if (info != null && !info.isOldStyle() && !info.isReweavable()) { processTypeMungersFromExistingWeaverState(sourceType, onType); - CompilationAndWeavingContext.leavingPhase(tok); + leavingPhase(tok); return; } - // Check if the type we are looking at is the topMostImplementor of a - // dangerous interface - - // report a problem if it is. + // Check if the type we are looking at is the topMostImplementor of a dangerous interface. + // Report a problem, if it is. for (Map.Entry entry : dangerousInterfaces.entrySet()) { ResolvedType interfaceType = entry.getKey(); if (onType.isTopmostImplementor(interfaceType)) { @@ -718,25 +701,19 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC onType.clearInterTypeMungers(); onType.ensureConsistent(); - // FIXME asc perf Could optimize here, after processing the expected set - // of types we may bring - // binary types that are not exposed to the weaver, there is no need to - // attempt declare parents - // or declare annotation really - unless we want to report the - // not-exposed to weaver - // messages... + // FIXME asc perf + // Could optimize here, after processing the expected set of types we may bring binary types that are not + // exposed to the weaver, there is no need to attempt declare parents or declare annotation really, unless we + // want to report the not-exposed to weaver messages... List decpToRepeat = new ArrayList<>(); List decaToRepeat = new ArrayList<>(); boolean anyNewParents = false; boolean anyNewAnnotations = false; - // first pass - // try and apply all decps - if they match, then great. If they don't - // then - // check if they are starred-annotation patterns. If they are not - // starred - // annotation patterns then they might match later...remember that... + // First pass:Try and apply all decps. If they match, then great. If they don't, then check if they are + // starred-annotation patterns. If they are not starred annotation patterns, then they might match later... + // Remember that... for (DeclareParents decp : declareParents) { if (!decp.isMixin()) { boolean didSomething = doDeclareParents(decp, sourceType); @@ -765,7 +742,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC } List forRemoval = new ArrayList<>(); - // now lets loop over and over until we have done all we can + // Now let's loop over and over, until we have done all we can while ((anyNewAnnotations || anyNewParents) && (!decpToRepeat.isEmpty() || !decaToRepeat.isEmpty())) { anyNewParents = anyNewAnnotations = false; forRemoval.clear(); @@ -831,23 +808,18 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC } } - // Call if you would like to do source weaving of declare - // @method/@constructor - // at source time... no need to do this as it can't impact anything, but - // left here for - // future generations to enjoy. Method source is commented out at the - // end of this module + // Call if you would like to do source weaving of declare @method/@constructor at source time... No need to do this, + // as it can't impact anything, but left here for future generations to enjoy. Method source is commented out at the + // end of this module. // doDeclareAnnotationOnMethods(); - // Call if you would like to do source weaving of declare @field - // at source time... no need to do this as it can't impact anything, but - // left here for - // future generations to enjoy. Method source is commented out at the - // end of this module + // Call if you would like to do source weaving of declare @field at source time... No need to do this, as it can't + // impact anything, but left here for future generations to enjoy. Method source is commented out at the end of this + // module. // doDeclareAnnotationOnFields(); if (skipInners) { - CompilationAndWeavingContext.leavingPhase(tok); + leavingPhase(tok); return; } @@ -855,16 +827,16 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC for (ReferenceBinding memberType : memberTypes) { if (memberType instanceof SourceTypeBinding) { weaveInterTypeDeclarations((SourceTypeBinding) memberType, typeMungers, declareParents, - declareAnnotationOnTypes, false, mode); + declareAnnotationOnTypes, false, mode); } } - CompilationAndWeavingContext.leavingPhase(tok); + leavingPhase(tok); } /** * Called when we discover we are weaving intertype declarations on some type that has an existing 'WeaverStateInfo' object - * this is typically some previously woven type that has been passed on the inpath. - * + *

* sourceType and onType are the 'same type' - the former is the 'Eclipse' version and the latter is the 'Weaver' version. */ private void processTypeMungersFromExistingWeaverState(SourceTypeBinding sourceType, ResolvedType onType) { @@ -876,7 +848,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC if (onType.isInterface() && munger.getMunger().needsAccessToTopmostImplementor()) { if (!onType.getWorld().getCrosscuttingMembersSet().containsAspect(munger.getAspectType())) { dangerousInterfaces - .put(onType, "implementors of " + onType + " must be woven by " + munger.getAspectType()); + .put(onType, "implementors of " + onType + " must be woven by " + munger.getAspectType()); } } } @@ -885,8 +857,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC } private boolean doDeclareParents(DeclareParents declareParents, SourceTypeBinding sourceType) { - ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_DECLARE_PARENTS, - sourceType.sourceName); + ContextToken tok = enteringPhase(PROCESSING_DECLARE_PARENTS, sourceType.sourceName); ResolvedType resolvedSourceType = factory.fromEclipse(sourceType); List newParents = declareParents.findMatchingNewParents(resolvedSourceType, false); if (!newParents.isEmpty()) { @@ -894,28 +865,28 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC if (dangerousInterfaces.containsKey(parent)) { ResolvedType onType = factory.fromEclipse(sourceType); factory.showMessage(IMessage.ERROR, onType + ": " + dangerousInterfaces.get(parent), - onType.getSourceLocation(), null); + onType.getSourceLocation(), null); } if (Modifier.isFinal(parent.getModifiers())) { factory.showMessage(IMessage.ERROR, "cannot extend final class " + parent.getClassName(), - declareParents.getSourceLocation(), null); + declareParents.getSourceLocation(), null); } else { // do not actually do it if the type isn't exposed - this // will correctly reported as a problem elsewhere if (!resolvedSourceType.isExposedToWeaver()) { return false; } - // AsmRelationshipProvider.getDefault(). - // addDeclareParentsRelationship - // (declareParents.getSourceLocation(), - // factory.fromEclipse(sourceType), newParents); + // AsmRelationshipProvider.getDefault() + // .addDeclareParentsRelationship( + // declareParents.getSourceLocation(), factory.fromEclipse(sourceType), newParents + // ); addParent(sourceType, parent); } } - CompilationAndWeavingContext.leavingPhase(tok); + leavingPhase(tok); return true; } - CompilationAndWeavingContext.leavingPhase(tok); + leavingPhase(tok); return false; } @@ -950,7 +921,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC } StringBuilder sb = new StringBuilder(); sb.append("{"); - for (Iterator iter = s.iterator(); iter.hasNext();) { + for (Iterator iter = s.iterator(); iter.hasNext(); ) { String element = iter.next(); sb.append(element); if (iter.hasNext()) { @@ -970,8 +941,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC return false; } - ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_DECLARE_ANNOTATIONS, - sourceType.sourceName); + ContextToken tok = enteringPhase(PROCESSING_DECLARE_ANNOTATIONS, sourceType.sourceName); // Get the annotation specified in the declare UnresolvedType aspectType = decA.getAspect(); @@ -984,21 +954,14 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC TypeBinding tb = factory.makeTypeBinding(aspectType); // Hideousness follows: - - // There are multiple situations to consider here and they relate to the - // combinations of - // where the annotation is coming from and where the annotation is going - // to be put: // - // 1. Straight full build, all from source - the annotation is from a - // dec@type and - // is being put on some type. Both types are real SourceTypeBindings. - // WORKS - // 2. Incremental build, changing the affected type - the annotation is - // from a - // dec@type in a BinaryTypeBinding (so has to be accessed via bcel) and - // the - // affected type is a real SourceTypeBinding. Mostly works (pr128665) + // There are multiple situations to consider here, and they relate to the combinations of where the annotation is + // coming from and where the annotation is going to be put: + // + // 1. Straight full build, all from source - the annotation is from a dec@type and is being put on some type. Both + // types are real SourceTypeBindings. WORKS + // 2. Incremental build, changing the affected type - the annotation is from a dec@type in a BinaryTypeBinding (so + // has to be accessed via bcel) and the affected type is a real SourceTypeBinding. Mostly works (pr128665) // 3. ? SourceTypeBinding stb = (SourceTypeBinding) tb; @@ -1006,16 +969,14 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC long abits = 0; AbstractMethodDeclaration methodDecl = null; - // Might have to retrieve the annotation through BCEL and construct an - // eclipse one for it. + // Might have to retrieve the annotation through BCEL and construct an Eclipse one for it if (stb instanceof BinaryTypeBinding) { toAdd = retrieveAnnotationFromBinaryTypeBinding(decA, stb); if (toAdd != null && toAdd.length > 0 && toAdd[0].resolvedType != null) { abits = toAdd[0].resolvedType.getAnnotationTagBits(); } } else if (stb != null) { - // much nicer, its a real SourceTypeBinding so we can stay in - // eclipse land + // Much nicer, it's a real SourceTypeBinding so we can stay in Eclipse land // if (decA.getAnnotationMethod() != null) { char[] declareSelector = decA.getAnnotationMethod().toCharArray(); @@ -1051,13 +1012,12 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC // This happens if there is another error in the code - that should be reported separately if (toAdd == null || toAdd[0] == null || toAdd[0].type == null) { - CompilationAndWeavingContext.leavingPhase(tok); + leavingPhase(tok); return false; } if (sourceType instanceof BinaryTypeBinding) { - // In this case we can't access the source type binding to add a new - // annotation, so let's put something - // on the weaver type temporarily + // In this case we can't access the source type binding to add a new annotation, so let's put something on the + // weaver type temporarily ResolvedType theTargetType = factory.fromEclipse(sourceType); TypeBinding theAnnotationType = toAdd[0].resolvedType; // The annotation type may be null if it could not be resolved (eg. the relevant import has not been added yet) @@ -1069,7 +1029,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC UnresolvedType bcelAnnotationType = UnresolvedType.forSignature(sig); String name = bcelAnnotationType.getName(); if (theTargetType.hasAnnotation(bcelAnnotationType)) { - CompilationAndWeavingContext.leavingPhase(tok); + leavingPhase(tok); return false; } @@ -1081,53 +1041,53 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC // error will have been already reported giveupnow = true; } else if ((sourceType.isAnnotationType() && (abits & TagBits.AnnotationForAnnotationType) == 0) - || (!sourceType.isAnnotationType() && (abits & TagBits.AnnotationForType) == 0)) { + || (!sourceType.isAnnotationType() && (abits & TagBits.AnnotationForType) == 0)) { if (reportProblems) { if (decA.isExactPattern()) { factory.showMessage(IMessage.ERROR, WeaverMessages.format( - WeaverMessages.INCORRECT_TARGET_FOR_DECLARE_ANNOTATION, rtx.getName(), toAdd[0].type, - stringifyTargets(abits)), decA.getSourceLocation(), null); + WeaverMessages.INCORRECT_TARGET_FOR_DECLARE_ANNOTATION, rtx.getName(), toAdd[0].type, + stringifyTargets(abits)), decA.getSourceLocation(), null); } - // dont put out the lint - the weaving process will do - // that - // else { - // if (factory.getWorld().getLint(). - // invalidTargetForAnnotation.isEnabled()) { - // factory.getWorld().getLint().invalidTargetForAnnotation - // .signal(new - // String[]{rtx.getName(),toAdd[0].type.toString(), - // stringifyTargets - // (abits)},decA.getSourceLocation(),null); - // } - // } + // Don't put out the lint - the weaving process will do that + /* + else { + if (factory.getWorld().getLint(). + invalidTargetForAnnotation.isEnabled()) { + factory.getWorld().getLint().invalidTargetForAnnotation + .signal( + new String[] {rtx.getName(), toAdd[0].type.toString(), stringifyTargets(abits)}, + decA.getSourceLocation(), + null + ); + } + } + */ } giveupnow = true; } } if (giveupnow) { - CompilationAndWeavingContext.leavingPhase(tok); + leavingPhase(tok); return false; } theTargetType.addAnnotation(new BcelAnnotation(new FakeAnnotation(name, sig, - (abits & TagBits.AnnotationRuntimeRetention) != 0), factory.getWorld())); - CompilationAndWeavingContext.leavingPhase(tok); + (abits & TagBits.AnnotationRuntimeRetention) != 0), factory.getWorld())); + leavingPhase(tok); return true; } - Annotation currentAnnotations[] = sourceType.scope.referenceContext.annotations; + Annotation[] currentAnnotations = sourceType.scope.referenceContext.annotations; if (currentAnnotations != null) { for (Annotation annotation : currentAnnotations) { String a = CharOperation.toString(annotation.type.getTypeName()); String b = CharOperation.toString(toAdd[0].type.getTypeName()); - // FIXME asc we have a lint for attempting to add an annotation - // twice to a method, - // we could put it out here *if* we can resolve the problem of - // errors coming out - // multiple times if we have cause to loop through here + // FIXME asc + // We have a lint for attempting to add an annotation twice to a method, we could put it out here *if* we can + // resolve the problem of errors coming out multiple times if we have cause to loop through here. if (a.equals(b)) { - CompilationAndWeavingContext.leavingPhase(tok); + leavingPhase(tok); return false; } } @@ -1135,42 +1095,43 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC if (((abits & TagBits.AnnotationTargetMASK) != 0)) { if ((abits & (TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType)) == 0) { - // this means it specifies something other than annotation or - // normal type - error will have been already reported, - // just resolution process above - CompilationAndWeavingContext.leavingPhase(tok); + // This means, it specifies something other than annotation or normal type - error will have been already + // reported, just resolution process above. + leavingPhase(tok); return false; } if ((sourceType.isAnnotationType() && (abits & TagBits.AnnotationForAnnotationType) == 0) - || (!sourceType.isAnnotationType() && (abits & TagBits.AnnotationForType) == 0)) { + || (!sourceType.isAnnotationType() && (abits & TagBits.AnnotationForType) == 0)) { if (reportProblems) { if (decA.isExactPattern()) { factory.showMessage(IMessage.ERROR, WeaverMessages.format( - WeaverMessages.INCORRECT_TARGET_FOR_DECLARE_ANNOTATION, rtx.getName(), toAdd[0].type, - stringifyTargets(abits)), decA.getSourceLocation(), null); + WeaverMessages.INCORRECT_TARGET_FOR_DECLARE_ANNOTATION, rtx.getName(), toAdd[0].type, + stringifyTargets(abits)), decA.getSourceLocation(), null); } - // dont put out the lint - the weaving process will do that - // else { - // if - // (factory.getWorld().getLint().invalidTargetForAnnotation - // .isEnabled()) { - // factory.getWorld().getLint().invalidTargetForAnnotation. - // signal(new - // String[]{rtx.getName(),toAdd[0].type.toString(), - // stringifyTargets(abits)},decA.getSourceLocation(),null); - // } - // } + // Don't put out the lint - the weaving process will do that + /* + else { + if + (factory.getWorld().getLint().invalidTargetForAnnotation.isEnabled()) { + factory.getWorld().getLint().invalidTargetForAnnotation + .signal( + new String[] {rtx.getName(), toAdd[0].type.toString(), stringifyTargets(abits)}, + decA.getSourceLocation(), + null + ); + } + } + */ } - CompilationAndWeavingContext.leavingPhase(tok); + leavingPhase(tok); return false; } } // Build a new array of annotations - // remember the current set (rememberAnnotations only does something the - // first time it is called for a type) + // Remember the current set (rememberAnnotations only does something the first time it is called for a type) sourceType.scope.referenceContext.rememberAnnotations(); // AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship( @@ -1182,13 +1143,13 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC System.arraycopy(abefore, 0, newset, toAdd.length, abefore.length); } sourceType.scope.referenceContext.annotations = newset; - if ((sourceType.tagBits & TagBits.AnnotationResolved)!=0) { + if ((sourceType.tagBits & TagBits.AnnotationResolved) != 0) { sourceType.tagBits = sourceType.tagBits - TagBits.AnnotationResolved; } - CompilationAndWeavingContext.leavingPhase(tok); + leavingPhase(tok); if (factory.pushinCollector != null) { factory.pushinCollector.tagAsMunged(sourceType, new CommonPrinter((methodDecl == null ? null : methodDecl.scope)) - .printAnnotation(toAdd[0]).toString()); + .printAnnotation(toAdd[0]).toString()); } return true; } @@ -1209,13 +1170,11 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC if (axs != null) { // another error has occurred, dont crash here because of it Annotation[] toAdd = new Annotation[1]; toAdd[0] = createAnnotationFromBcelAnnotation(axs[0], decaMethod.getSourceLocation().getOffset(), factory); - // BUG BUG BUG - We dont test these abits are correct, in fact - // we'll be very lucky if they are. - // What does that mean? It means on an incremental compile you - // might get away with an - // annotation that isn't allowed on a type being put on a type. + // BUG BUG BUG - We don't test these abits are correct, in fact we'll be very lucky if they are. + // What does that mean? It means on an incremental compile you might get away with an annotation that isn't + // allowed on a type being put on a type. // if (toAdd[0].resolvedType != null) { - // abits = toAdd[0].resolvedType.getAnnotationTagBits(); + // abits = toAdd[0].resolvedType.getAnnotationTagBits(); // } return toAdd; } @@ -1294,46 +1253,50 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC return (abits & (TagBits.AnnotationForAnnotationType | TagBits.AnnotationForType)) == 0; } -// private void reportDeclareParentsMessage(WeaveMessage.WeaveMessageKind wmk, SourceTypeBinding sourceType, ResolvedType parent) { -// if (!factory.getWorld().getMessageHandler().isIgnoring(IMessage.WEAVEINFO)) { -// String filename = new String(sourceType.getFileName()); -// -// int takefrom = filename.lastIndexOf('/'); -// if (takefrom == -1) { -// takefrom = filename.lastIndexOf('\\'); -// } -// filename = filename.substring(takefrom + 1); -// -// factory.getWorld() -// .getMessageHandler() -// .handleMessage( -// WeaveMessage.constructWeavingMessage(wmk, -// new String[] { CharOperation.toString(sourceType.compoundName), filename, -// parent.getClassName(), -// getShortname(parent.getSourceLocation().getSourceFile().getPath()) })); -// } -// } - -// private String getShortname(String path) { -// int takefrom = path.lastIndexOf('/'); -// if (takefrom == -1) { -// takefrom = path.lastIndexOf('\\'); -// } -// return path.substring(takefrom + 1); -// } +/* + private void reportDeclareParentsMessage(WeaveMessage.WeaveMessageKind wmk, SourceTypeBinding sourceType, ResolvedType parent) { + if (!factory.getWorld().getMessageHandler().isIgnoring(IMessage.WEAVEINFO)) { + String filename = new String(sourceType.getFileName()); + + int takefrom = filename.lastIndexOf('/'); + if (takefrom == -1) { + takefrom = filename.lastIndexOf('\\'); + } + filename = filename.substring(takefrom + 1); + + factory.getWorld() + .getMessageHandler() + .handleMessage( + WeaveMessage.constructWeavingMessage(wmk, + new String[] { CharOperation.toString(sourceType.compoundName), filename, + parent.getClassName(), + getShortname(parent.getSourceLocation().getSourceFile().getPath()) })); + } + } +*/ + +/* + private String getShortname(String path) { + int takefrom = path.lastIndexOf('/'); + if (takefrom == -1) { + takefrom = path.lastIndexOf('\\'); + } + return path.substring(takefrom + 1); + } +*/ private void addParent(SourceTypeBinding sourceType, ResolvedType parent) { ReferenceBinding parentBinding = (ReferenceBinding) factory.makeTypeBinding(parent); if (parentBinding == null) { return; // The parent is missing, it will be reported elsewhere. } - // Due to e37 switching to MethodVerifier15 for everything, it is important added types are correctly - // raw or not. For example, if Comparable is used in generic form compareTo(T) will be used to check - // methods against in the verifier rather than compareTo(Object) + // Due to e37 switching to MethodVerifier15 for everything, it is important added types are correctly raw or not. + // For example, if Comparable is used in generic form compareTo(T) will be used to check methods against in the + // verifier rather than compareTo(Object) if (!factory.getWorld().isInJava5Mode()) { - parentBinding = (ReferenceBinding)convertToRawType(parentBinding, false /*do not force conversion of enclosing types*/); + parentBinding = (ReferenceBinding) convertToRawType(parentBinding, false /*do not force conversion of enclosing types*/); } else if (sourceType.isGenericType()) { - RawTypeBinding rawTargetType = (RawTypeBinding)convertToRawType(sourceType, false); + RawTypeBinding rawTargetType = (RawTypeBinding) convertToRawType(sourceType, false); if (rawTargetType != null) { // assert: don't need to 'rememberTypeHierarchy' because the class file is constructed based on the generic type if (parentBinding.isClass()) { @@ -1359,13 +1322,10 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC if (parentBinding.isClass()) { sourceType.superclass = parentBinding; - // this used to be true, but I think I've fixed it now, decp is done - // at weave time! + // This used to be true, but I think I've fixed it now, decp is done at weave time! // TAG: WeavingMessage DECLARE PARENTS: EXTENDS - // Compiler restriction: Can't do EXTENDS at weave time - // So, only see this message if doing a source compilation - // reportDeclareParentsMessage(WeaveMessage. - // WEAVEMESSAGE_DECLAREPARENTSEXTENDS,sourceType,parent); + // Compiler restriction: Can't do EXTENDS at weave time So, only see this message if doing a source compilation + // reportDeclareParentsMessage(WeaveMessage.WEAVEMESSAGE_DECLAREPARENTSEXTENDS,sourceType,parent); } else { ReferenceBinding[] oldI = sourceType.superInterfaces; @@ -1380,20 +1340,16 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC newI[n] = parentBinding; } sourceType.superInterfaces = newI; - // warnOnAddedInterface(factory.fromEclipse(sourceType),parent); // - // now reported at weave time... + // warnOnAddedInterface(factory.fromEclipse(sourceType),parent); // now reported at weave time... - // this used to be true, but I think I've fixed it now, decp is done - // at weave time! + // This used to be true, but I think I've fixed it now, decp is done at weave time! // TAG: WeavingMessage DECLARE PARENTS: IMPLEMENTS - // This message will come out of BcelTypeMunger.munge if doing a - // binary weave - // reportDeclareParentsMessage(WeaveMessage. - // WEAVEMESSAGE_DECLAREPARENTSIMPLEMENTS,sourceType,parent); + // This message will come out of BcelTypeMunger.munge if doing a binary weave + // reportDeclareParentsMessage(WeaveMessage.WEAVEMESSAGE_DECLAREPARENTSIMPLEMENTS,sourceType,parent); } - // also add it to the bcel delegate if there is one + // Also add it to the bcel delegate if there is one if (sourceType instanceof BinaryTypeBinding) { ResolvedType onType = factory.fromEclipse(sourceType); ReferenceType rt = (ReferenceType) onType; @@ -1413,9 +1369,9 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC World world = factory.getWorld(); ResolvedType serializable = world.getCoreType(UnresolvedType.SERIALIZABLE); if (serializable.isAssignableFrom(type) && !serializable.isAssignableFrom(parent) - && !LazyClassGen.hasSerialVersionUIDField(type)) { - world.getLint().needsSerialVersionUIDField.signal(new String[] { type.getName().toString(), - "added interface " + parent.getName().toString() }, null, null); + && !LazyClassGen.hasSerialVersionUIDField(type)) { + world.getLint().needsSerialVersionUIDField.signal(new String[]{type.getName(), + "added interface " + parent.getName()}, null, null); } } @@ -1425,7 +1381,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC @Override public BinaryTypeBinding createBinaryTypeFrom(IBinaryType binaryType, PackageBinding packageBinding, - boolean needFieldsAndMethods, AccessRestriction accessRestriction) { + boolean needFieldsAndMethods, AccessRestriction accessRestriction) { if (inBinaryTypeCreationAndWeaving) { BinaryTypeBinding ret = super.createBinaryTypeFrom(binaryType, packageBinding, needFieldsAndMethods, accessRestriction); @@ -1445,7 +1401,7 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC inBinaryTypeCreationAndWeaving = false; // Start processing the list... - if (pendingTypesToFinish.size() > 0) { + if (!pendingTypesToFinish.isEmpty()) { processingTheQueue = true; while (!pendingTypesToFinish.isEmpty()) { BinaryTypeBinding nextVictim = pendingTypesToFinish.remove(0); @@ -1469,201 +1425,178 @@ public class AjLookupEnvironment extends LookupEnvironment implements AnonymousC factory.addSourceTypeBinding(aBinding, null); } - @Override - public void buildTypeBindings(CompilationUnitDeclaration unit, AccessRestriction accessRestriction) { - if (this.isProcessingAnnotations && hasAspectDeclarations(unit)) { - throw new SourceTypeCollisionException(); - } - super.buildTypeBindings(unit, accessRestriction); - } - - private static boolean hasAspectDeclarations(CompilationUnitDeclaration unit) { - if (unit.types == null) - return false; - for (int j = 0; j < unit.types.length; j++) { - if (unit.types[j] instanceof AspectDeclaration) { - return true; - } - } - return false; - } - - @Override - public void reset() { - this.factory.cleanup(); - super.reset(); - } - - @Override -public LookupEnvironment wrapInModuleEnvironment(ModuleBinding moduleBinding) { - AjLookupEnvironment newAjLookupEnvironment = new AjLookupEnvironment(this, moduleBinding); - newAjLookupEnvironment.factory = this.factory; - return newAjLookupEnvironment; - } -} + @Override + public void buildTypeBindings(CompilationUnitDeclaration unit, AccessRestriction accessRestriction) { + if (this.isProcessingAnnotations && hasAspectDeclarations(unit)) { + throw new SourceTypeCollisionException(); + } + super.buildTypeBindings(unit, accessRestriction); + } -// commented out, supplied as info on how to manipulate annotations in an -// eclipse world -// -// public void doDeclareAnnotationOnMethods() { -// Do the declare annotation on fields/methods/ctors -// Collection daoms = factory.getDeclareAnnotationOnMethods(); -// if (daoms!=null && daoms.size()>0 && !(sourceType instanceof -// BinaryTypeBinding)) { -// System.err.println("Going through the methods on "+sourceType.debugName()+ -// " looking for DECA matches"); -// // We better take a look through them... -// for (Iterator iter = daoms.iterator(); iter.hasNext();) { -// DeclareAnnotation element = (DeclareAnnotation) iter.next(); -// System.err.println("Looking for anything that might match "+element+" on "+ -// sourceType.debugName()+" "+getType(sourceType. -// compoundName).debugName()+" "+(sourceType instanceof BinaryTypeBinding)); -// -// ReferenceBinding rbb = getType(sourceType.compoundName); -// // fix me if we ever uncomment this code... should iterate the other way -// round, over the methods then over the decas -// sourceType.methods(); -// MethodBinding sourceMbs[] = sourceType.methods; -// for (int i = 0; i < sourceMbs.length; i++) { -// MethodBinding sourceMb = sourceMbs[i]; -// MethodBinding mbbbb = -// ((SourceTypeBinding)rbb).getExactMethod(sourceMb.selector -// ,sourceMb.parameters); -// boolean isCtor = sourceMb.selector[0]=='<'; -// -// if ((element.isDeclareAtConstuctor() ^ !isCtor)) { -// System.err.println("Checking "+sourceMb+" ... declaringclass="+sourceMb. -// declaringClass.debugName()+" rbb="+rbb.debugName()+" "+ -// sourceMb.declaringClass.equals(rbb)); -// -// ResolvedMember rm = null; -// rm = EclipseFactory.makeResolvedMember(mbbbb); -// if (element.matches(rm,factory.getWorld())) { -// System.err.println("MATCH"); -// -// // Determine the set of annotations that are currently on the method -// ReferenceBinding rb = getType(sourceType.compoundName); -// // TypeBinding tb = factory.makeTypeBinding(decA.getAspect()); -// MethodBinding mb = -// ((SourceTypeBinding)rb).getExactMethod(sourceMb.selector,sourceMb -// .parameters); -// //long abits = mbs[0].getAnnotationTagBits(); // ensure resolved -// TypeDeclaration typeDecl = -// ((SourceTypeBinding)sourceMb.declaringClass).scope.referenceContext; -// AbstractMethodDeclaration methodDecl = typeDecl.declarationOf(sourceMb); -// Annotation[] currentlyHas = methodDecl.annotations; // this is what to add -// //abits = toAdd[0].resolvedType.getAnnotationTagBits(); -// -// // Determine the annotations to add to that method -// TypeBinding tb = factory.makeTypeBinding(element.getAspect()); -// MethodBinding[] aspectMbs = -// ((SourceTypeBinding)tb).getMethods(element.getAnnotationMethod -// ().toCharArray()); -// long abits = aspectMbs[0].getAnnotationTagBits(); // ensure resolved -// TypeDeclaration typeDecl2 = -// ((SourceTypeBinding)aspectMbs[0].declaringClass).scope.referenceContext; -// AbstractMethodDeclaration methodDecl2 = -// typeDecl2.declarationOf(aspectMbs[0]); -// Annotation[] toAdd = methodDecl2.annotations; // this is what to add -// // abits = toAdd[0].resolvedType.getAnnotationTagBits(); -// System.err.println("Has: "+currentlyHas+" toAdd: "+toAdd); -// -// // fix me? should check if it already has the annotation -// //Annotation abefore[] = sourceType.scope.referenceContext.annotations; -// Annotation[] newset = new -// Annotation[(currentlyHas==null?0:currentlyHas.length)+1]; -// System.arraycopy(toAdd,0,newset,0,toAdd.length); -// if (currentlyHas!=null) { -// System.arraycopy(currentlyHas,0,newset,1,currentlyHas.length); -// } -// methodDecl.annotations = newset; -// System.err.println("New set on "+CharOperation.charToString(sourceMb.selector) -// +" is "+newset); -// } else -// System.err.println("NO MATCH"); -// } -// } -// } -// } -// } - -// commented out, supplied as info on how to manipulate annotations in an -// eclipse world -// -// public void doDeclareAnnotationOnFields() { -// Collection daofs = factory.getDeclareAnnotationOnFields(); -// if (daofs!=null && daofs.size()>0 && !(sourceType instanceof -// BinaryTypeBinding)) { -// System.err.println("Going through the fields on "+sourceType.debugName()+ -// " looking for DECA matches"); -// // We better take a look through them... -// for (Iterator iter = daofs.iterator(); iter.hasNext();) { -// DeclareAnnotation element = (DeclareAnnotation) iter.next(); -// System.err.println("Processing deca "+element+" on "+sourceType.debugName()+ -// " "+getType(sourceType.compoundName).debugName()+" " -// +(sourceType instanceof BinaryTypeBinding)); -// -// ReferenceBinding rbb = getType(sourceType.compoundName); -// // fix me? should iterate the other way round, over the methods then over the -// decas -// sourceType.fields(); // resolve the bloody things -// FieldBinding sourceFbs[] = sourceType.fields; -// for (int i = 0; i < sourceFbs.length; i++) { -// FieldBinding sourceFb = sourceFbs[i]; -// //FieldBinding fbbbb = -// ((SourceTypeBinding)rbb).getgetExactMethod(sourceMb.selector -// ,sourceMb.parameters); -// -// System.err.println("Checking "+sourceFb+" ... declaringclass="+sourceFb. -// declaringClass.debugName()+" rbb="+rbb.debugName()); -// -// ResolvedMember rm = null; -// rm = EclipseFactory.makeResolvedMember(sourceFb); -// if (element.matches(rm,factory.getWorld())) { -// System.err.println("MATCH"); -// -// // Determine the set of annotations that are currently on the field -// ReferenceBinding rb = getType(sourceType.compoundName); -// // TypeBinding tb = factory.makeTypeBinding(decA.getAspect()); -// FieldBinding fb = ((SourceTypeBinding)rb).getField(sourceFb.name,true); -// //long abits = mbs[0].getAnnotationTagBits(); // ensure resolved -// TypeDeclaration typeDecl = -// ((SourceTypeBinding)sourceFb.declaringClass).scope.referenceContext; -// FieldDeclaration fd = typeDecl.declarationOf(sourceFb); -// //AbstractMethodDeclaration methodDecl = typeDecl.declarationOf(sourceMb); -// Annotation[] currentlyHas = fd.annotations; // this is what to add -// //abits = toAdd[0].resolvedType.getAnnotationTagBits(); -// -// // Determine the annotations to add to that method -// TypeBinding tb = factory.makeTypeBinding(element.getAspect()); -// MethodBinding[] aspectMbs = -// ((SourceTypeBinding)tb).getMethods(element.getAnnotationMethod -// ().toCharArray()); -// long abits = aspectMbs[0].getAnnotationTagBits(); // ensure resolved -// TypeDeclaration typeDecl2 = -// ((SourceTypeBinding)aspectMbs[0].declaringClass).scope.referenceContext; -// AbstractMethodDeclaration methodDecl2 = -// typeDecl2.declarationOf(aspectMbs[0]); -// Annotation[] toAdd = methodDecl2.annotations; // this is what to add -// // abits = toAdd[0].resolvedType.getAnnotationTagBits(); -// System.err.println("Has: "+currentlyHas+" toAdd: "+toAdd); -// -// // fix me? check if it already has the annotation -// -// -// //Annotation abefore[] = sourceType.scope.referenceContext.annotations; -// Annotation[] newset = new -// Annotation[(currentlyHas==null?0:currentlyHas.length)+1]; -// System.arraycopy(toAdd,0,newset,0,toAdd.length); -// if (currentlyHas!=null) { -// System.arraycopy(currentlyHas,0,newset,1,currentlyHas.length); -// } -// fd.annotations = newset; -// System.err.println("New set on "+CharOperation.charToString(sourceFb.name)+ -// " is "+newset); -// } else -// System.err.println("NO MATCH"); -// } -// -// } -// } + private static boolean hasAspectDeclarations(CompilationUnitDeclaration unit) { + if (unit.types == null) + return false; + for (int j = 0; j < unit.types.length; j++) { + if (unit.types[j] instanceof AspectDeclaration) { + return true; + } + } + return false; + } + + @Override + public void reset() { + this.factory.cleanup(); + super.reset(); + } + + @Override + public LookupEnvironment wrapInModuleEnvironment(ModuleBinding moduleBinding) { + AjLookupEnvironment newAjLookupEnvironment = new AjLookupEnvironment(this, moduleBinding); + newAjLookupEnvironment.factory = this.factory; + return newAjLookupEnvironment; + } + + // Commented out, supplied as info on how to manipulate annotations in an Eclipse world +/* + public void doDeclareAnnotationOnMethods() { + // Do the declare annotation on fields/methods/ctors + Collection daoms = factory.getDeclareAnnotationOnMethods(); + if (daoms != null && daoms.size() > 0 && !(sourceType instanceof BinaryTypeBinding)) { + System.err.println("Going through the methods on " + sourceType.debugName() + + " looking for DECA matches"); + // We better take a look through them... + for (Iterator iter = daoms.iterator(); iter.hasNext(); ) { + DeclareAnnotation element = (DeclareAnnotation) iter.next(); + System.err.println("Looking for anything that might match " + element + " on " + + sourceType.debugName() + " " + getType(sourceType. + compoundName).debugName() + " " + (sourceType instanceof BinaryTypeBinding)); + + ReferenceBinding rbb = getType(sourceType.compoundName); + // Fix me, if we ever uncomment this code... should iterate the other way round, + // over the methods then over the decas + sourceType.methods(); + MethodBinding sourceMbs[] = sourceType.methods; + for (int i = 0; i < sourceMbs.length; i++) { + MethodBinding sourceMb = sourceMbs[i]; + MethodBinding mbbbb = ((SourceTypeBinding) rbb).getExactMethod(sourceMb.selector, sourceMb.parameters); + boolean isCtor = sourceMb.selector[0] == '<'; + + if ((element.isDeclareAtConstuctor() ^ !isCtor)) { + System.err.println("Checking " + sourceMb + " ... declaringclass=" + sourceMb.declaringClass.debugName() + + " rbb=" + rbb.debugName() + " " + sourceMb.declaringClass.equals(rbb)); + + ResolvedMember rm = null; + rm = EclipseFactory.makeResolvedMember(mbbbb); + if (element.matches(rm, factory.getWorld())) { + System.err.println("MATCH"); + + // Determine the set of annotations that are currently on the method + ReferenceBinding rb = getType(sourceType.compoundName); + // TypeBinding tb = factory.makeTypeBinding(decA.getAspect()); + MethodBinding mb = ((SourceTypeBinding) rb).getExactMethod(sourceMb.selector, sourceMb.parameters); + //long abits = mbs[0].getAnnotationTagBits(); // ensure resolved + TypeDeclaration typeDecl = ((SourceTypeBinding) sourceMb.declaringClass).scope.referenceContext; + AbstractMethodDeclaration methodDecl = typeDecl.declarationOf(sourceMb); + Annotation[] currentlyHas = methodDecl.annotations; // this is what to add + //abits = toAdd[0].resolvedType.getAnnotationTagBits(); + + // Determine the annotations to add to that method + TypeBinding tb = factory.makeTypeBinding(element.getAspect()); + MethodBinding[] aspectMbs = ((SourceTypeBinding) tb).getMethods(element.getAnnotationMethod().toCharArray()); + long abits = aspectMbs[0].getAnnotationTagBits(); // ensure resolved + TypeDeclaration typeDecl2 = ((SourceTypeBinding) aspectMbs[0].declaringClass).scope.referenceContext; + AbstractMethodDeclaration methodDecl2 = typeDecl2.declarationOf(aspectMbs[0]); + Annotation[] toAdd = methodDecl2.annotations; // this is what to add + // abits = toAdd[0].resolvedType.getAnnotationTagBits(); + System.err.println("Has: " + currentlyHas + " toAdd: " + toAdd); + + // Fix me? should check if it already has the annotation + //Annotation abefore[] = sourceType.scope.referenceContext.annotations; + Annotation[] newset = new Annotation[(currentlyHas == null ? 0 : currentlyHas.length) + 1]; + System.arraycopy(toAdd, 0, newset, 0, toAdd.length); + if (currentlyHas != null) { + System.arraycopy(currentlyHas, 0, newset, 1, currentlyHas.length); + } + methodDecl.annotations = newset; + System.err.println("New set on " + CharOperation.charToString(sourceMb.selector) + " is " + newset); + } else + System.err.println("NO MATCH"); + } + } + } + } + } +*/ + + // Commented out, supplied as info on how to manipulate annotations in an Eclipse world +/* + public void doDeclareAnnotationOnFields() { + Collection daofs = factory.getDeclareAnnotationOnFields(); + if (daofs != null && daofs.size() > 0 && !(sourceType instanceof BinaryTypeBinding)) { + System.err.println("Going through the fields on " + sourceType.debugName() + " looking for DECA matches"); + // We better take a look through them... + for (Iterator iter = daofs.iterator(); iter.hasNext(); ) { + DeclareAnnotation element = (DeclareAnnotation) iter.next(); + System.err.println("Processing deca " + element + " on " + sourceType.debugName() + + " " + getType(sourceType.compoundName).debugName() + " " + + (sourceType instanceof BinaryTypeBinding)); + + ReferenceBinding rbb = getType(sourceType.compoundName); + // Fix me? should iterate the other way round, over the methods then over the decas. + sourceType.fields(); // resolve the bloody things + FieldBinding sourceFbs[] = sourceType.fields; + for (int i = 0; i < sourceFbs.length; i++) { + FieldBinding sourceFb = sourceFbs[i]; + //FieldBinding fbbbb = ((SourceTypeBinding) rbb).getgetExactMethod(sourceMb.selector, sourceMb.parameters); + + System.err.println("Checking " + sourceFb + " ... declaringclass=" + + sourceFb.declaringClass.debugName() + " rbb=" + rbb.debugName()); + + ResolvedMember rm = null; + rm = EclipseFactory.makeResolvedMember(sourceFb); + if (element.matches(rm, factory.getWorld())) { + System.err.println("MATCH"); + + // Determine the set of annotations that are currently on the field + ReferenceBinding rb = getType(sourceType.compoundName); + // TypeBinding tb = factory.makeTypeBinding(decA.getAspect()); + FieldBinding fb = ((SourceTypeBinding) rb).getField(sourceFb.name, true); + //long abits = mbs[0].getAnnotationTagBits(); // ensure resolved + TypeDeclaration typeDecl = + ((SourceTypeBinding) sourceFb.declaringClass).scope.referenceContext; + FieldDeclaration fd = typeDecl.declarationOf(sourceFb); + //AbstractMethodDeclaration methodDecl = typeDecl.declarationOf(sourceMb); + Annotation[] currentlyHas = fd.annotations; // this is what to add + //abits = toAdd[0].resolvedType.getAnnotationTagBits(); + + // Determine the annotations to add to that method + TypeBinding tb = factory.makeTypeBinding(element.getAspect()); + MethodBinding[] aspectMbs = ((SourceTypeBinding) tb).getMethods(element.getAnnotationMethod().toCharArray()); + long abits = aspectMbs[0].getAnnotationTagBits(); // ensure resolved + TypeDeclaration typeDecl2 = ((SourceTypeBinding) aspectMbs[0].declaringClass).scope.referenceContext; + AbstractMethodDeclaration methodDecl2 = typeDecl2.declarationOf(aspectMbs[0]); + Annotation[] toAdd = methodDecl2.annotations; // this is what to add + // abits = toAdd[0].resolvedType.getAnnotationTagBits(); + System.err.println("Has: " + currentlyHas + " toAdd: " + toAdd); + + // Fix me? Check if it already has the annotation. + + //Annotation abefore[] = sourceType.scope.referenceContext.annotations; + Annotation[] newset = new + Annotation[(currentlyHas == null ? 0 : currentlyHas.length) + 1]; + System.arraycopy(toAdd, 0, newset, 0, toAdd.length); + if (currentlyHas != null) { + System.arraycopy(currentlyHas, 0, newset, 1, currentlyHas.length); + } + fd.annotations = newset; + System.err.println("New set on " + CharOperation.charToString(sourceFb.name) + " is " + newset); + } else + System.err.println("NO MATCH"); + } + } + } + } +*/ + +} -- 2.39.5