123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671 |
- /* *******************************************************************
- * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
- * All rights reserved.
- * This program and the accompanying materials are made available
- * under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- * PARC initial implementation
- * ******************************************************************/
-
- package org.aspectj.ajdt.internal.compiler.lookup;
-
- import java.lang.reflect.Modifier;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.HashMap;
- import java.util.HashSet;
- import java.util.Iterator;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
-
- import org.aspectj.ajdt.internal.compiler.CommonPrinter;
- 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;
- import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
- import org.aspectj.org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
- import org.aspectj.org.eclipse.jdt.internal.compiler.ast.NormalAnnotation;
- import org.aspectj.org.eclipse.jdt.internal.compiler.ast.QualifiedTypeReference;
- import org.aspectj.org.eclipse.jdt.internal.compiler.ast.SingleTypeReference;
- import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
- import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeReference;
- import org.aspectj.org.eclipse.jdt.internal.compiler.env.AccessRestriction;
- import org.aspectj.org.eclipse.jdt.internal.compiler.env.IBinaryType;
- import org.aspectj.org.eclipse.jdt.internal.compiler.env.INameEnvironment;
- import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
- import org.aspectj.org.eclipse.jdt.internal.compiler.impl.ITypeRequestor;
- import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.BinaryTypeBinding;
- import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ClassScope;
- import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.CompilationUnitScope;
- import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.LocalTypeBinding;
- import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.LookupEnvironment;
- import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
- import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MissingTypeBinding;
- import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ModuleBinding;
- import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.PackageBinding;
- import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ParameterizedTypeBinding;
- import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.RawTypeBinding;
- import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
- import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
- import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeCollisionException;
- import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TagBits;
- import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
- import org.aspectj.org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
- import org.aspectj.weaver.AnnotationAJ;
- import org.aspectj.weaver.ConcreteTypeMunger;
- import org.aspectj.weaver.ReferenceType;
- import org.aspectj.weaver.ReferenceTypeDelegate;
- import org.aspectj.weaver.ResolvedMember;
- import org.aspectj.weaver.ResolvedType;
- import org.aspectj.weaver.ResolvedTypeMunger;
- import org.aspectj.weaver.UnresolvedType;
- import org.aspectj.weaver.WeaverMessages;
- import org.aspectj.weaver.WeaverStateInfo;
- import org.aspectj.weaver.World;
- import org.aspectj.weaver.bcel.BcelAnnotation;
- import org.aspectj.weaver.bcel.BcelObjectType;
- import org.aspectj.weaver.bcel.FakeAnnotation;
- import org.aspectj.weaver.bcel.LazyClassGen;
- import org.aspectj.weaver.patterns.DeclareAnnotation;
- import org.aspectj.weaver.patterns.DeclareParents;
-
- /**
- * Overrides the default eclipse LookupEnvironment for two purposes.
- *
- * 1. To provide some additional phases to <code>completeTypeBindings</code> 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.
- *
- * @author Jim Hugunin
- */
- public class AjLookupEnvironment extends LookupEnvironment implements AnonymousClassCreationListener {
- public EclipseFactory factory = null;
-
- // private boolean builtInterTypesAndPerClauses = false;
- private final List<SourceTypeBinding> 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'.
- // 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.
-
- /**
- * interfaces targetted by ITDs that have to be implemented by accessing the topMostImplementor of the interface, yet the aspect
- * where the ITD originated is not in the world
- */
- private final Map dangerousInterfaces = new HashMap();
-
- public AjLookupEnvironment(ITypeRequestor typeRequestor, CompilerOptions options, ProblemReporter problemReporter,
- INameEnvironment nameEnvironment) {
- super(typeRequestor, options, problemReporter, nameEnvironment);
- }
-
- public AjLookupEnvironment(LookupEnvironment env, ModuleBinding moduleBinding) {
- super(env, moduleBinding);
- }
-
- // ??? duplicates some of super's code
- @Override
- public void completeTypeBindings() {
- AsmManager.setCompletingTypeBindings(true);
- ContextToken completeTypeBindingsToken = CompilationAndWeavingContext.enteringPhase(
- CompilationAndWeavingContext.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);
- units[i].scope.checkAndSetImports();
- CompilationAndWeavingContext.leavingPhase(tok);
- }
- stepCompleted = CHECK_AND_SET_IMPORTS;
-
- for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
- ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.CONNECTING_TYPE_HIERARCHY,
- units[i].compilationResult.fileName);
- units[i].scope.connectTypeHierarchy();
- CompilationAndWeavingContext.leavingPhase(tok);
- }
- stepCompleted = CONNECT_TYPE_HIERARCHY;
-
- 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
- units[i].scope.buildFieldsAndMethods();
- CompilationAndWeavingContext.leavingPhase(tok);
- }
-
- // 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) {
- factory.addSourceTypeBinding(sourceTypeBinding, units[i]);
- if (sourceTypeBinding.superclass instanceof MissingTypeBinding) {
- // e37: Undoing the work in ClassScope.connectSuperClass() as it will lead to cascade errors
- // TODO allow MissingTypeBinding through here and cope with it in all situations later?
- sourceTypeBinding.superclass = units[i].scope.getJavaLangObject();
- }
- }
- }
-
- // 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
- List<SourceTypeBinding> typesToProcess = new ArrayList<>();
- List<SourceTypeBinding> aspectsToProcess = new ArrayList<>();
- for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
- CompilationUnitScope cus = units[i].scope;
- SourceTypeBinding[] stbs = cus.topLevelTypes;
- for (SourceTypeBinding stb : stbs) {
- typesToProcess.add(stb);
- TypeDeclaration typeDeclaration = stb.scope.referenceContext;
- if (typeDeclaration instanceof AspectDeclaration) {
- aspectsToProcess.add(stb);
- }
- }
- }
- factory.getWorld().getCrosscuttingMembersSet().reset();
-
- // Need to do these before the other ITDs
- for (SourceTypeBinding aspectToProcess : aspectsToProcess) {
- processInterTypeMemberTypes(aspectToProcess.scope);
- }
-
- while (typesToProcess.size() > 0) {
- // removes types from the list as they are processed...
- collectAllITDsAndDeclares(typesToProcess.get(0), typesToProcess);
- }
-
- factory.finishTypeMungers();
-
- // now do weaving
- final List<ConcreteTypeMunger> typeMungers = factory.getTypeMungers();
-
- final List<DeclareParents> declareParents = factory.getDeclareParents();
- final List<DeclareAnnotation> declareAnnotationOnTypes = factory.getDeclareAnnotationOnTypes();
-
- 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.
- //
- // but these aren't common cases (he bravely said...)
- boolean typeProcessingOrderIsImportant = declareParents.size() > 0 || declareAnnotationOnTypes.size() > 0; // DECAT
-
- if (typeProcessingOrderIsImportant) {
- typesToProcess = new ArrayList<>();
- for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
- CompilationUnitScope cus = units[i].scope;
- SourceTypeBinding[] stbs = cus.topLevelTypes;
- for (SourceTypeBinding stb : stbs) {
- typesToProcess.add(stb);
- }
- }
-
- List<SourceTypeBinding> stb2 = new ArrayList<>();
- stb2.addAll(typesToProcess);
-
- while (typesToProcess.size() > 0) {
- // A side effect of weaveIntertypes() is that the processed type is removed from the collection
- weaveIntertypes(typesToProcess, typesToProcess.get(0), typeMungers, declareParents, declareAnnotationOnTypes, 1);
- }
-
- while (stb2.size() > 0) {
- // A side effect of weaveIntertypes() is that the processed type is removed from the collection
- weaveIntertypes(stb2, stb2.get(0), typeMungers, declareParents, declareAnnotationOnTypes, 2);
- }
-
- } else {
- // Order isn't important
- for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
- weaveInterTypeDeclarations(units[i].scope, typeMungers, declareParents, declareAnnotationOnTypes);
- }
- }
-
- for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
- units[i].scope.checkParameterizedTypes();
- }
-
- 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);
- resolvePointcutDeclarations(sourceTypeBinding.scope);
- CompilationAndWeavingContext.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);
- addAdviceLikeDeclares(sourceTypeBinding.scope);
- CompilationAndWeavingContext.leavingPhase(tok);
- }
- }
-
- for (int i = lastCompletedUnitIndex + 1; i <= lastUnitIndex; i++) {
- units[i] = null; // release unnecessary reference to the parsed unit
- }
-
- stepCompleted = BUILD_FIELDS_AND_METHODS;
- lastCompletedUnitIndex = lastUnitIndex;
- AsmManager.setCompletingTypeBindings(false);
- factory.getWorld().getCrosscuttingMembersSet().verify();
- CompilationAndWeavingContext.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()));
- // }
- // }
- // }
- // }
- // }
- // }
-
- public void doSupertypesFirst(ReferenceBinding rb, Collection<? extends ReferenceBinding> 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.
- ParameterizedTypeBinding ptb = (ParameterizedTypeBinding) rb;
- if (ptb.type instanceof SourceTypeBinding && yetToProcess.contains(ptb.type)) {
- collectAllITDsAndDeclares((SourceTypeBinding) ptb.type, yetToProcess);
- }
- }
- }
-
- /**
- * Find all the ITDs and Declares, but it is important we do this from the supertypes down to the subtypes.
- *
- * @param sourceType
- * @param yetToProcess
- */
- private void collectAllITDsAndDeclares(SourceTypeBinding sourceType, Collection<? extends ReferenceBinding> yetToProcess) {
- // Look at the supertype first
- ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.COLLECTING_ITDS_AND_DECLARES,
- sourceType.sourceName);
-
- yetToProcess.remove(sourceType);
- // look out our direct supertype
- doSupertypesFirst(sourceType.superclass(), yetToProcess);
-
- // now check our membertypes (pr119570)
- ReferenceBinding[] memberTypes = sourceType.memberTypes;
- for (ReferenceBinding memberType : memberTypes) {
- SourceTypeBinding rb = (SourceTypeBinding) memberType;
- if (!rb.superclass().equals(sourceType)) {
- doSupertypesFirst(rb.superclass(), yetToProcess);
- }
- }
-
- buildInterTypeAndPerClause(sourceType.scope);
- addCrosscuttingStructures(sourceType.scope);
- CompilationAndWeavingContext.leavingPhase(tok);
- }
-
- /**
- * Weave the parents and intertype decls into a given type. This method looks at the supertype and superinterfaces for the
- * specified type and recurses to weave those first if they are in the full list of types we are going to process during this
- * compile... it stops recursing the first time it hits a type we aren't going to process during this compile. This could cause
- * problems if you supply 'pieces' of a hierarchy, i.e. the bottom and the top, but not the middle - but what the hell are you
- * doing if you do that?
- *
- * @param mode 0=do everything, 1=do declare parents, 2=do ITDs
- */
- private void weaveIntertypes(List<SourceTypeBinding> typesToProcess, SourceTypeBinding typeToWeave,
- List<ConcreteTypeMunger> typeMungers, List<DeclareParents> declareParents,
- List<DeclareAnnotation> 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);
- }
- // Then look at the superinterface list
- ReferenceBinding[] interfaceTypes = typeToWeave.superInterfaces();
- for (ReferenceBinding binding : interfaceTypes) {
- 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);
- }
- }
- 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);
- weaveInterTypeDeclarations(t);
- CompilationAndWeavingContext.leavingPhase(tok);
- }
- pendingTypesToWeave.clear();
- }
-
- private void addAdviceLikeDeclares(ClassScope s) {
- TypeDeclaration dec = s.referenceContext;
-
- if (dec instanceof AspectDeclaration) {
- ResolvedType typeX = factory.fromEclipse(dec.binding);
- factory.getWorld().getCrosscuttingMembersSet().addAdviceLikeDeclares(typeX);
- }
-
- SourceTypeBinding sourceType = s.referenceContext.binding;
- ReferenceBinding[] memberTypes = sourceType.memberTypes;
- for (ReferenceBinding memberType : memberTypes) {
- addAdviceLikeDeclares(((SourceTypeBinding) memberType).scope);
- }
- }
-
- private void addCrosscuttingStructures(ClassScope s) {
- TypeDeclaration dec = s.referenceContext;
-
- if (dec instanceof AspectDeclaration) {
- ResolvedType typeX = factory.fromEclipse(dec.binding);
- factory.getWorld().getCrosscuttingMembersSet().addOrReplaceAspect(typeX, false);
-
- if (typeX.getSuperclass().isAspect() && !typeX.getSuperclass().isExposedToWeaver()) {
- factory.getWorld().getCrosscuttingMembersSet().addOrReplaceAspect(typeX.getSuperclass(), false);
- }
- }
-
- SourceTypeBinding sourceType = s.referenceContext.binding;
- ReferenceBinding[] memberTypes = sourceType.memberTypes;
- for (ReferenceBinding memberType : memberTypes) {
- addCrosscuttingStructures(((SourceTypeBinding) memberType).scope);
- }
- }
-
- private void resolvePointcutDeclarations(ClassScope s) {
- TypeDeclaration dec = s.referenceContext;
- SourceTypeBinding sourceType = s.referenceContext.binding;
- boolean hasPointcuts = false;
- AbstractMethodDeclaration[] methods = dec.methods;
- boolean initializedMethods = false;
- if (methods != null) {
- for (AbstractMethodDeclaration method : methods) {
- if (method instanceof PointcutDeclaration) {
- hasPointcuts = true;
- if (!initializedMethods) {
- sourceType.methods(); // force initialization
- initializedMethods = true;
- }
- ((PointcutDeclaration) method).resolvePointcut(s);
- }
- }
- }
-
- if (hasPointcuts || dec instanceof AspectDeclaration || couldBeAnnotationStyleAspectDeclaration(dec)) {
- ReferenceType name = (ReferenceType) factory.fromEclipse(sourceType);
- EclipseSourceType eclipseSourceType = (EclipseSourceType) name.getDelegate();
- eclipseSourceType.checkPointcutDeclarations();
- }
-
- ReferenceBinding[] memberTypes = sourceType.memberTypes;
- for (ReferenceBinding memberType : memberTypes) {
- resolvePointcutDeclarations(((SourceTypeBinding) memberType).scope);
- }
- }
-
- /**
- * Return true if the declaration has @Aspect annotation. Called 'couldBe' rather than 'is' because someone else may have
- * defined an annotation called Aspect - we can't verify the full name (including package name) because it may not have been
- * resolved just yet and rather going through expensive resolution when we dont have to, this gives us a cheap check that tells
- * us whether to bother.
- */
- private boolean couldBeAnnotationStyleAspectDeclaration(TypeDeclaration dec) {
- Annotation[] annotations = dec.annotations;
- boolean couldBeAtAspect = false;
- if (annotations != null) {
- for (int i = 0; i < annotations.length && !couldBeAtAspect; i++) {
- if (annotations[i].toString().equals("@Aspect")) {
- couldBeAtAspect = true;
- }
- }
- }
- return couldBeAtAspect;
- }
-
- /**
- * Applies any intertype member type declarations up front.
- */
- private void processInterTypeMemberTypes(ClassScope classScope) {
- TypeDeclaration dec = classScope.referenceContext;
- if (dec instanceof AspectDeclaration) {
- ((AspectDeclaration) dec).processIntertypeMemberTypes(classScope);
- }
- // if we are going to support nested aspects making itd member types, copy the logic from the end of
- // buildInterTypeAndPerClause() which walks members
- }
-
- private void buildInterTypeAndPerClause(ClassScope s) {
- TypeDeclaration dec = s.referenceContext;
- if (dec instanceof AspectDeclaration) {
- ((AspectDeclaration) dec).buildInterTypeAndPerClause(s);
- }
-
- SourceTypeBinding sourceType = s.referenceContext.binding;
- // test classes don't extend aspects
- 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);
- }
- }
-
- ReferenceBinding[] memberTypes = sourceType.memberTypes;
- if (memberTypes == null) {
- System.err.println("Unexpectedly found null for memberTypes of " + sourceType.debugName());
- }
- if (memberTypes != null) {
- for (ReferenceBinding memberType : memberTypes) {
- buildInterTypeAndPerClause(((SourceTypeBinding) memberType).scope);
- }
- }
- }
-
- private boolean isAspect(TypeDeclaration decl) {
- if ((decl instanceof AspectDeclaration)) {
- return true;
- } else if (decl.annotations == null) {
- return false;
- } else {
- for (int i = 0; i < decl.annotations.length; i++) {
- Annotation ann = decl.annotations[i];
- if (ann.type instanceof SingleTypeReference) {
- if (CharOperation.equals("Aspect".toCharArray(), ((SingleTypeReference) ann.type).token)) {
- return true;
- }
- } else if (ann.type instanceof QualifiedTypeReference) {
- QualifiedTypeReference qtr = (QualifiedTypeReference) ann.type;
- if (qtr.tokens.length != 5) {
- return false;
- }
- if (!CharOperation.equals("org".toCharArray(), qtr.tokens[0])) {
- return false;
- }
- if (!CharOperation.equals("aspectj".toCharArray(), qtr.tokens[1])) {
- return false;
- }
- if (!CharOperation.equals("lang".toCharArray(), qtr.tokens[2])) {
- return false;
- }
- if (!CharOperation.equals("annotation".toCharArray(), qtr.tokens[3])) {
- return false;
- }
- if (!CharOperation.equals("Aspect".toCharArray(), qtr.tokens[4])) {
- return false;
- }
- return true;
- }
- }
- }
- return false;
- }
-
- private void weaveInterTypeDeclarations(CompilationUnitScope unit, List<ConcreteTypeMunger> typeMungers,
- List<DeclareParents> declareParents, List<DeclareAnnotation> declareAnnotationOnTypes) {
- for (int i = 0, length = unit.topLevelTypes.length; i < length; i++) {
- weaveInterTypeDeclarations(unit.topLevelTypes[i], typeMungers, declareParents, declareAnnotationOnTypes, false, 0);
- }
- }
-
- private void weaveInterTypeDeclarations(SourceTypeBinding sourceType) {
- if (!factory.areTypeMungersFinished()) {
- if (!pendingTypesToWeave.contains(sourceType)) {
- pendingTypesToWeave.add(sourceType);
-
- // inner type ITD support - may need this for some incremental cases...
- // List<ConcreteTypeMunger> ctms = factory.getWorld().getCrosscuttingMembersSet().getTypeMungersOfKind(
- // ResolvedTypeMunger.InnerClass);
- // // List<ConcreteTypeMunger> innerTypeMungers = new ArrayList<ConcreteTypeMunger>();
- // // 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);
- }
- }
-
- /**
- * @param mode 0=do everything, 1=do declare parents, 2=do ITDs
- */
- private void weaveInterTypeDeclarations(SourceTypeBinding sourceType, List<ConcreteTypeMunger> typeMungers,
- List<DeclareParents> declareParents, List<DeclareAnnotation> declareAnnotationOnTypes, boolean skipInners, int mode) {
-
- ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.WEAVING_INTERTYPE_DECLARATIONS,
- sourceType.sourceName);
-
- ResolvedType onType = factory.fromEclipse(sourceType);
-
- // AMC we shouldn't need this when generic sigs are fixed??
- if (onType.isRawType()) {
- onType = onType.getGenericType();
- }
-
- 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.
- if (info != null && !info.isOldStyle() && !info.isReweavable()) {
- processTypeMungersFromExistingWeaverState(sourceType, onType);
- CompilationAndWeavingContext.leavingPhase(tok);
- return;
- }
-
- // Check if the type we are looking at is the topMostImplementor of a
- // dangerous interface -
- // report a problem if it is.
- for (Object o : dangerousInterfaces.entrySet()) {
- Map.Entry entry = (Map.Entry) o;
- ResolvedType interfaceType = (ResolvedType) entry.getKey();
- if (onType.isTopmostImplementor(interfaceType)) {
- factory.showMessage(IMessage.ERROR, onType + ": " + entry.getValue(), onType.getSourceLocation(), null);
- }
- }
-
- boolean needOldStyleWarning = (info != null && info.isOldStyle());
-
- 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...
-
- List<DeclareParents> decpToRepeat = new ArrayList<>();
- List<DeclareAnnotation> 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...
- for (DeclareParents decp : declareParents) {
- if (!decp.isMixin()) {
- boolean didSomething = doDeclareParents(decp, sourceType);
- if (didSomething) {
- if (factory.pushinCollector != null) {
- factory.pushinCollector.tagAsMunged(sourceType, decp.getParents().get(0));
- }
- anyNewParents = true;
- } else {
- if (!decp.getChild().isStarAnnotation()) {
- decpToRepeat.add(decp);
- }
- }
- }
- }
-
- for (DeclareAnnotation deca : declareAnnotationOnTypes) {
- boolean didSomething = doDeclareAnnotations(deca, sourceType, true);
- if (didSomething) {
- anyNewAnnotations = true;
- } else {
- if (!deca.getTypePattern().isStar()) {
- decaToRepeat.add(deca);
- }
- }
- }
-
- List<Object> forRemoval = new ArrayList<>();
- // now lets loop over and over until we have done all we can
- while ((anyNewAnnotations || anyNewParents) && (!decpToRepeat.isEmpty() || !decaToRepeat.isEmpty())) {
- anyNewParents = anyNewAnnotations = false;
- forRemoval.clear();
- for (DeclareParents decp : decpToRepeat) {
- boolean didSomething = doDeclareParents(decp, sourceType);
- if (didSomething) {
- if (factory.pushinCollector != null) {
- factory.pushinCollector.tagAsMunged(sourceType, decp.getParents().get(0));
- }
- anyNewParents = true;
- forRemoval.add(decp);
- }
- }
- decpToRepeat.removeAll(forRemoval);
-
- forRemoval.clear();
- for (DeclareAnnotation deca : decaToRepeat) {
- boolean didSomething = doDeclareAnnotations(deca, sourceType, false);
- if (didSomething) {
- if (factory.pushinCollector != null) {
- factory.pushinCollector.tagAsMunged(sourceType, deca.getAnnotationString());
- }
- anyNewAnnotations = true;
- forRemoval.add(deca);
- }
- }
- decaToRepeat.removeAll(forRemoval);
- }
- }
- if (mode == 0 || mode == 2) {
- for (ConcreteTypeMunger typeMunger : typeMungers) {
- EclipseTypeMunger munger = (EclipseTypeMunger) typeMunger;
- if (munger.matches(onType)) {
- // if (needOldStyleWarning) {
- // factory.showMessage(IMessage.WARNING, "The class for " + onType
- // + " should be recompiled with ajc-1.1.1 for best results", onType.getSourceLocation(), null);
- // needOldStyleWarning = false;
- // }
- onType.addInterTypeMunger(munger, true);
- if (munger.getMunger() != null && munger.getMunger().getKind() == ResolvedTypeMunger.InnerClass) {
- // Must do these right now, because if we do an ITD member afterwards it may attempt to reference the
- // type being applied (the call above 'addInterTypeMunger' will fail for these ITDs if it needed
- // it to be in place)
- if (munger.munge(sourceType, onType)) {
- if (factory.pushinCollector != null) {
- factory.pushinCollector.tagAsMunged(sourceType, munger.getSourceMethod());
- }
- }
- }
- }
- }
-
- onType.checkInterTypeMungers();
- for (ConcreteTypeMunger concreteTypeMunger : onType.getInterTypeMungers()) {
- EclipseTypeMunger munger = (EclipseTypeMunger) concreteTypeMunger;
- if (munger.getMunger() == null || munger.getMunger().getKind() != ResolvedTypeMunger.InnerClass) {
- if (munger.munge(sourceType, onType)) {
- if (factory.pushinCollector != null) {
- factory.pushinCollector.tagAsMunged(sourceType, munger.getSourceMethod());
- }
- }
- }
- }
- }
-
- // 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
- // doDeclareAnnotationOnFields();
-
- if (skipInners) {
- CompilationAndWeavingContext.leavingPhase(tok);
- return;
- }
-
- ReferenceBinding[] memberTypes = sourceType.memberTypes;
- for (ReferenceBinding memberType : memberTypes) {
- if (memberType instanceof SourceTypeBinding) {
- weaveInterTypeDeclarations((SourceTypeBinding) memberType, typeMungers, declareParents,
- declareAnnotationOnTypes, false, mode);
- }
- }
- CompilationAndWeavingContext.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) {
- List<ConcreteTypeMunger> previouslyAppliedMungers = onType.getWeaverState().getTypeMungers(onType);
-
- for (ConcreteTypeMunger m : previouslyAppliedMungers) {
- EclipseTypeMunger munger = factory.makeEclipseTypeMunger(m);
- if (munger.munge(sourceType, onType)) {
- 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());
- }
- }
- }
-
- }
- }
-
- private boolean doDeclareParents(DeclareParents declareParents, SourceTypeBinding sourceType) {
- ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_DECLARE_PARENTS,
- sourceType.sourceName);
- ResolvedType resolvedSourceType = factory.fromEclipse(sourceType);
- List<ResolvedType> newParents = declareParents.findMatchingNewParents(resolvedSourceType, false);
- if (!newParents.isEmpty()) {
- for (ResolvedType parent : newParents) {
- if (dangerousInterfaces.containsKey(parent)) {
- ResolvedType onType = factory.fromEclipse(sourceType);
- factory.showMessage(IMessage.ERROR, onType + ": " + dangerousInterfaces.get(parent),
- onType.getSourceLocation(), null);
- }
- if (Modifier.isFinal(parent.getModifiers())) {
- factory.showMessage(IMessage.ERROR, "cannot extend final class " + parent.getClassName(),
- 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);
- addParent(sourceType, parent);
- }
- }
- CompilationAndWeavingContext.leavingPhase(tok);
- return true;
- }
- CompilationAndWeavingContext.leavingPhase(tok);
- return false;
- }
-
- private String stringifyTargets(long bits) {
- if ((bits & TagBits.AnnotationTargetMASK) == 0) {
- return "";
- }
- Set<String> s = new HashSet<>();
- if ((bits & TagBits.AnnotationForAnnotationType) != 0) {
- s.add("ANNOTATION_TYPE");
- }
- if ((bits & TagBits.AnnotationForConstructor) != 0) {
- s.add("CONSTRUCTOR");
- }
- if ((bits & TagBits.AnnotationForField) != 0) {
- s.add("FIELD");
- }
- if ((bits & TagBits.AnnotationForLocalVariable) != 0) {
- s.add("LOCAL_VARIABLE");
- }
- if ((bits & TagBits.AnnotationForMethod) != 0) {
- s.add("METHOD");
- }
- if ((bits & TagBits.AnnotationForPackage) != 0) {
- s.add("PACKAGE");
- }
- if ((bits & TagBits.AnnotationForParameter) != 0) {
- s.add("PARAMETER");
- }
- if ((bits & TagBits.AnnotationForType) != 0) {
- s.add("TYPE");
- }
- StringBuffer sb = new StringBuffer();
- sb.append("{");
- for (Iterator<String> iter = s.iterator(); iter.hasNext();) {
- String element = iter.next();
- sb.append(element);
- if (iter.hasNext()) {
- sb.append(",");
- }
- }
- sb.append("}");
- return sb.toString();
- }
-
- private boolean doDeclareAnnotations(DeclareAnnotation decA, SourceTypeBinding sourceType, boolean reportProblems) {
- ResolvedType rtx = factory.fromEclipse(sourceType);
- if (!decA.matches(rtx)) {
- return false;
- }
- if (!rtx.isExposedToWeaver()) {
- return false;
- }
-
- ContextToken tok = CompilationAndWeavingContext.enteringPhase(CompilationAndWeavingContext.PROCESSING_DECLARE_ANNOTATIONS,
- sourceType.sourceName);
-
- // Get the annotation specified in the declare
- UnresolvedType aspectType = decA.getAspect();
- if (aspectType instanceof ReferenceType) {
- ReferenceType rt = (ReferenceType) aspectType;
- if (rt.isParameterizedType() || rt.isRawType()) {
- aspectType = rt.getGenericType();
- }
- }
- 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)
- // 3. ?
-
- SourceTypeBinding stb = (SourceTypeBinding) tb;
- Annotation[] toAdd = null;
- long abits = 0;
-
- AbstractMethodDeclaration methodDecl = null;
- // 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
- // if (decA.getAnnotationMethod() != null) {
- char[] declareSelector = decA.getAnnotationMethod().toCharArray();
-
- ReferenceBinding rb = stb;
- String declaringAspectName = decA.getDeclaringType().getRawName();
- while (rb != null && !new String(CharOperation.concatWith(rb.compoundName, '.')).equals(declaringAspectName)) {
- rb = rb.superclass();
- }
- MethodBinding[] mbs = rb.getMethods(declareSelector);
-
- ReferenceBinding declaringBinding = mbs[0].declaringClass;
- if (declaringBinding instanceof ParameterizedTypeBinding) {
- // Unwrap - this means we don't allow the type of the annotation to be parameterized, may need to revisit that
- declaringBinding = ((ParameterizedTypeBinding) declaringBinding).type;
- }
- if (declaringBinding instanceof BinaryTypeBinding) {
- toAdd = retrieveAnnotationFromBinaryTypeBinding(decA, declaringBinding);
- if (toAdd != null && toAdd.length > 0 && toAdd[0].resolvedType != null) {
- abits = toAdd[0].resolvedType.getAnnotationTagBits();
- }
- } else {
- abits = mbs[0].getAnnotationTagBits(); // ensure resolved
- TypeDeclaration typeDecl = ((SourceTypeBinding) declaringBinding).scope.referenceContext;
- methodDecl = typeDecl.declarationOf(mbs[0]);
- toAdd = methodDecl.annotations; // this is what to add
- toAdd[0] = createAnnotationCopy(toAdd[0]);
- if (toAdd[0].resolvedType != null) {
- abits = toAdd[0].resolvedType.getAnnotationTagBits();
- // }
- }
- }
- }
-
- // 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);
- 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
- 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)
- // In this case an error will be put out about the annotation but not if we crash here
- if (theAnnotationType == null) {
- return false;
- }
- String sig = new String(theAnnotationType.signature());
- UnresolvedType bcelAnnotationType = UnresolvedType.forSignature(sig);
- String name = bcelAnnotationType.getName();
- if (theTargetType.hasAnnotation(bcelAnnotationType)) {
- CompilationAndWeavingContext.leavingPhase(tok);
- return false;
- }
-
- // FIXME asc tidy up this code that duplicates whats below!
- // Simple checks on the bits
- boolean giveupnow = false;
- if (((abits & TagBits.AnnotationTargetMASK) != 0)) {
- if (isAnnotationTargettingSomethingOtherThanAnnotationOrNormal(abits)) {
- // error will have been already reported
- giveupnow = true;
- } else if ((sourceType.isAnnotationType() && (abits & TagBits.AnnotationForAnnotationType) == 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);
- }
- // 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);
- // }
- // }
- }
- giveupnow = true;
- }
- }
- if (giveupnow) {
- CompilationAndWeavingContext.leavingPhase(tok);
- return false;
- }
-
- theTargetType.addAnnotation(new BcelAnnotation(new FakeAnnotation(name, sig,
- (abits & TagBits.AnnotationRuntimeRetention) != 0), factory.getWorld()));
- CompilationAndWeavingContext.leavingPhase(tok);
- return true;
- }
-
- 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
- if (a.equals(b)) {
- CompilationAndWeavingContext.leavingPhase(tok);
- return false;
- }
- }
- }
-
- 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);
- return false;
- }
- if ((sourceType.isAnnotationType() && (abits & TagBits.AnnotationForAnnotationType) == 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);
- }
- // 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);
- // }
- // }
- }
- CompilationAndWeavingContext.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)
- sourceType.scope.referenceContext.rememberAnnotations();
-
- // AsmRelationshipProvider.getDefault().addDeclareAnnotationRelationship(
- // decA.getSourceLocation(), rtx.getSourceLocation());
- final Annotation[] abefore = sourceType.scope.referenceContext.annotations;
- final Annotation[] newset = new Annotation[toAdd.length + (abefore == null ? 0 : abefore.length)];
- System.arraycopy(toAdd, 0, newset, 0, toAdd.length);
- if (abefore != null) {
- System.arraycopy(abefore, 0, newset, toAdd.length, abefore.length);
- }
- sourceType.scope.referenceContext.annotations = newset;
- if ((sourceType.tagBits & TagBits.AnnotationResolved)!=0) {
- sourceType.tagBits = sourceType.tagBits - TagBits.AnnotationResolved;
- }
- CompilationAndWeavingContext.leavingPhase(tok);
- if (factory.pushinCollector != null) {
- factory.pushinCollector.tagAsMunged(sourceType, new CommonPrinter((methodDecl == null ? null : methodDecl.scope))
- .printAnnotation(toAdd[0]).toString());
- }
- return true;
- }
-
- private Annotation[] retrieveAnnotationFromBinaryTypeBinding(DeclareAnnotation decA, ReferenceBinding declaringBinding) {
- ReferenceType rt = (ReferenceType) factory.fromEclipse(declaringBinding);
- ResolvedMember[] methods = rt.getDeclaredMethods();
- ResolvedMember decaMethod = null;
- String nameToLookFor = decA.getAnnotationMethod();
- for (ResolvedMember method : methods) {
- if (method.getName().equals(nameToLookFor)) {
- decaMethod = method;
- break;
- }
- }
- if (decaMethod != null) { // could assert this ...
- AnnotationAJ[] axs = decaMethod.getAnnotations();
- 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.
- // if (toAdd[0].resolvedType != null) {
- // abits = toAdd[0].resolvedType.getAnnotationTagBits();
- // }
- return toAdd;
- }
- }
- return null;
- }
-
- /**
- * Transform an annotation from its AJ form to an eclipse form. We *DONT* care about the values of the annotation. that is
- * because it is only being stuck on a type during type completion to allow for other constructs (decps, decas) that might be
- * looking for it - when the class actually gets to disk it wont have this new annotation on it and during weave time we will do
- * the right thing copying across values too.
- */
- private static Annotation createAnnotationFromBcelAnnotation(AnnotationAJ annX, int pos, EclipseFactory factory) {
- String name = annX.getTypeName();
- TypeBinding tb = factory.makeTypeBinding(annX.getType());
- // String theName = annX.getSignature().getBaseName();
- char[][] typeName = CharOperation.splitOn('.', name.replace('$', '.').toCharArray()); // pr149293 - not bulletproof...
- long[] positions = new long[typeName.length];
- for (int i = 0; i < positions.length; i++) {
- positions[i] = pos;
- }
- TypeReference annType = new QualifiedTypeReference(typeName, positions);
- NormalAnnotation ann = new NormalAnnotation(annType, pos);
- ann.resolvedType = tb; // yuck - is this OK in all cases?
- // We don't need membervalues...
- // Expression pcExpr = new
- // StringLiteral(pointcutExpression.toCharArray(),pos,pos);
- // MemberValuePair[] mvps = new MemberValuePair[2];
- // mvps[0] = new MemberValuePair("value".toCharArray(),pos,pos,pcExpr);
- // Expression argNamesExpr = new
- // StringLiteral(argNames.toCharArray(),pos,pos);
- // mvps[1] = new
- // MemberValuePair("argNames".toCharArray(),pos,pos,argNamesExpr);
- // ann.memberValuePairs = mvps;
- return ann;
- }
-
- /**
- * Create a copy of an annotation, not deep but deep enough so we don't copy across fields that will get us into trouble like
- * 'recipient'
- */
- private static Annotation createAnnotationCopy(Annotation ann) {
- NormalAnnotation ann2 = new NormalAnnotation(ann.type, ann.sourceStart);
- ann2.memberValuePairs = ann.memberValuePairs();
- ann2.resolvedType = ann.resolvedType;
- ann2.bits = ann.bits;
- return ann2;
- // String name = annX.getTypeName();
- // TypeBinding tb = factory.makeTypeBinding(annX.getSignature());
- // String theName = annX.getSignature().getBaseName();
- // char[][] typeName =
- // CharOperation.splitOn('.',name.replace('$','.').toCharArray());
- // //pr149293 - not bulletproof...
- // long[] positions = new long[typeName.length];
- // for (int i = 0; i < positions.length; i++) positions[i]=pos;
- // TypeReference annType = new
- // QualifiedTypeReference(typeName,positions);
- // NormalAnnotation ann = new NormalAnnotation(annType,pos);
- // ann.resolvedType=tb; // yuck - is this OK in all cases?
- // // We don't need membervalues...
- // // Expression pcExpr = new
- // StringLiteral(pointcutExpression.toCharArray(),pos,pos);
- // // MemberValuePair[] mvps = new MemberValuePair[2];
- // // mvps[0] = new
- // MemberValuePair("value".toCharArray(),pos,pos,pcExpr);
- // // Expression argNamesExpr = new
- // StringLiteral(argNames.toCharArray(),pos,pos);
- // // mvps[1] = new
- // MemberValuePair("argNames".toCharArray(),pos,pos,argNamesExpr);
- // // ann.memberValuePairs = mvps;
- // return ann;
- }
-
- private boolean isAnnotationTargettingSomethingOtherThanAnnotationOrNormal(long abits) {
- 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 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)
- if (!factory.getWorld().isInJava5Mode()) {
- parentBinding = (ReferenceBinding)convertToRawType(parentBinding, false /*do not force conversion of enclosing types*/);
- } else if (sourceType.isGenericType()) {
- 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()) {
- rawTargetType.superclass = parentBinding;
- } else {
- ReferenceBinding[] oldI = rawTargetType.superInterfaces;
- ReferenceBinding[] newI;
- if (oldI == null) {
- newI = new ReferenceBinding[1];
- newI[0] = parentBinding;
- } else {
- int n = oldI.length;
- newI = new ReferenceBinding[n + 1];
- System.arraycopy(oldI, 0, newI, 0, n);
- newI[n] = parentBinding;
- }
- rawTargetType.superInterfaces = newI;
- }
- }
- // TODO what about parameterized types?
- }
- sourceType.rememberTypeHierarchy();
- 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!
- // 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);
-
- } else {
- ReferenceBinding[] oldI = sourceType.superInterfaces;
- ReferenceBinding[] newI;
- if (oldI == null) {
- newI = new ReferenceBinding[1];
- newI[0] = parentBinding;
- } else {
- int n = oldI.length;
- newI = new ReferenceBinding[n + 1];
- System.arraycopy(oldI, 0, newI, 0, n);
- newI[n] = parentBinding;
- }
- sourceType.superInterfaces = newI;
- // 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!
- // TAG: WeavingMessage DECLARE PARENTS: IMPLEMENTS
- // 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
- if (sourceType instanceof BinaryTypeBinding) {
- ResolvedType onType = factory.fromEclipse(sourceType);
- ReferenceType rt = (ReferenceType) onType;
- ReferenceTypeDelegate rtd = rt.getDelegate();
- if (rtd instanceof BcelObjectType) {
- if (rt.isRawType()) {
- rt = rt.getGenericType();
- }
- rt.addParent(parent);
- // ((BcelObjectType) rtd).addParent(parent);
- }
- }
-
- }
-
- public void warnOnAddedInterface(ResolvedType type, ResolvedType parent) {
- 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);
- }
- }
-
- private final List pendingTypesToFinish = new ArrayList();
- boolean inBinaryTypeCreationAndWeaving = false;
- boolean processingTheQueue = false;
-
- @Override
- public BinaryTypeBinding createBinaryTypeFrom(IBinaryType binaryType, PackageBinding packageBinding,
- boolean needFieldsAndMethods, AccessRestriction accessRestriction) {
-
- if (inBinaryTypeCreationAndWeaving) {
- BinaryTypeBinding ret = super.createBinaryTypeFrom(binaryType, packageBinding, needFieldsAndMethods, accessRestriction);
- pendingTypesToFinish.add(ret);
- return ret;
- }
-
- inBinaryTypeCreationAndWeaving = true;
- try {
- BinaryTypeBinding ret = super.createBinaryTypeFrom(binaryType, packageBinding, needFieldsAndMethods, accessRestriction);
- factory.getWorld().validateType(factory.fromBinding(ret));
- // if you need the bytes to pass to validate, here they
- // are:((ClassFileReader)binaryType).getReferenceBytes()
- weaveInterTypeDeclarations(ret);
- return ret;
- } finally {
- inBinaryTypeCreationAndWeaving = false;
-
- // Start processing the list...
- if (pendingTypesToFinish.size() > 0) {
- processingTheQueue = true;
- while (!pendingTypesToFinish.isEmpty()) {
- BinaryTypeBinding nextVictim = (BinaryTypeBinding) pendingTypesToFinish.remove(0);
- // During this call we may recurse into this method and add
- // more entries to the pendingTypesToFinish list.
- weaveInterTypeDeclarations(nextVictim);
- }
- processingTheQueue = false;
- }
- }
- }
-
- /**
- * Callback driven when the compiler detects an anonymous type during block resolution. We need to add it to the weaver so that
- * we don't trip up later.
- *
- * @param aBinding
- */
- @Override
- public void anonymousTypeBindingCreated(LocalTypeBinding aBinding) {
- 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) {
- 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");
- // }
- //
- // }
- // }
|