~ubuntu-branches/ubuntu/natty/aspectj/natty

« back to all changes in this revision

Viewing changes to org.aspectj/modules/weaver/src/org/aspectj/weaver/World.java

  • Committer: Bazaar Package Importer
  • Author(s): Damien Raude-Morvan
  • Date: 2009-10-04 16:37:23 UTC
  • mfrom: (1.1.3 upstream) (3.1.3 sid)
  • Revision ID: james.westby@ubuntu.com-20091004163723-ck4y7j7fhjxskkie
Tags: 1.6.6+dfsg-1
* New upstream release.
  - Update 02_use_gjdoc.diff patch
* Update my email address

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* *******************************************************************
2
 
 * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
3
 
 *               2005 Contributors
4
 
 * All rights reserved. 
5
 
 * This program and the accompanying materials are made available 
6
 
 * under the terms of the Eclipse Public License v1.0 
7
 
 * which accompanies this distribution and is available at 
8
 
 * http://www.eclipse.org/legal/epl-v10.html 
9
 
 *  
10
 
 * Contributors: 
11
 
 *     PARC     initial implementation
12
 
 *     Adrian Colyer, Andy Clement, overhaul for generics 
13
 
 * ******************************************************************/
14
 
 
15
 
package org.aspectj.weaver;
16
 
 
17
 
import java.lang.ref.ReferenceQueue;
18
 
import java.lang.ref.SoftReference;
19
 
import java.lang.ref.WeakReference;
20
 
import java.util.ArrayList;
21
 
import java.util.HashMap;
22
 
import java.util.Iterator;
23
 
import java.util.List;
24
 
import java.util.Map;
25
 
import java.util.Properties;
26
 
import java.util.WeakHashMap;
27
 
 
28
 
import org.aspectj.asm.IHierarchy;
29
 
import org.aspectj.bridge.IMessageHandler;
30
 
import org.aspectj.bridge.ISourceLocation;
31
 
import org.aspectj.bridge.Message;
32
 
import org.aspectj.bridge.MessageUtil;
33
 
import org.aspectj.bridge.IMessage.Kind;
34
 
import org.aspectj.bridge.context.PinpointingMessageHandler;
35
 
import org.aspectj.weaver.UnresolvedType.TypeKind;
36
 
import org.aspectj.weaver.bcel.BcelObjectType;
37
 
import org.aspectj.weaver.patterns.DeclarePrecedence;
38
 
import org.aspectj.weaver.patterns.PerClause;
39
 
import org.aspectj.weaver.patterns.Pointcut;
40
 
import org.aspectj.weaver.reflect.ReflectionBasedReferenceTypeDelegate;
41
 
import org.aspectj.weaver.tools.Trace;
42
 
import org.aspectj.weaver.tools.TraceFactory;
43
 
 
44
 
/**
45
 
 * A World is a collection of known types and crosscutting members.
46
 
 */
47
 
public abstract class World implements Dump.INode {
48
 
        /** handler for any messages produced during resolution etc. */
49
 
        private IMessageHandler messageHandler = IMessageHandler.SYSTEM_ERR;
50
 
        
51
 
        /** handler for cross-reference information produced during the weaving process */
52
 
        private ICrossReferenceHandler xrefHandler = null;
53
 
 
54
 
        /** Currently 'active' scope in which to lookup (resolve) typevariable references */
55
 
        private TypeVariableDeclaringElement typeVariableLookupScope;
56
 
        
57
 
        /** The heart of the world, a map from type signatures to resolved types */
58
 
    protected TypeMap typeMap = new TypeMap(this); // Signature to ResolvedType
59
 
 
60
 
    // see pr145963
61
 
    /** Should we create the hierarchy for binary classes and aspects*/
62
 
    public static boolean createInjarHierarchy = true;
63
 
 
64
 
    /** Calculator for working out aspect precedence */
65
 
    private AspectPrecedenceCalculator precedenceCalculator;
66
 
    
67
 
    /** All of the type and shadow mungers known to us */
68
 
    private CrosscuttingMembersSet crosscuttingMembersSet = 
69
 
        new CrosscuttingMembersSet(this);
70
 
    
71
 
    /** Model holds ASM relationships */
72
 
    private IHierarchy model = null;
73
 
    
74
 
    /** for processing Xlint messages */
75
 
    private Lint lint = new Lint(this);
76
 
    
77
 
    /** XnoInline option setting passed down to weaver */
78
 
    private boolean XnoInline;
79
 
    
80
 
    /** XlazyTjp option setting passed down to weaver */
81
 
    private boolean XlazyTjp;
82
 
 
83
 
    /** XhasMember option setting passed down to weaver */
84
 
    private boolean XhasMember = false;
85
 
    
86
 
    /** Xpinpoint controls whether we put out developer info showing the source of messages */
87
 
    private boolean Xpinpoint = false;
88
 
    
89
 
    /** When behaving in a Java 5 way autoboxing is considered */
90
 
    private boolean behaveInJava5Way = false;
91
 
    
92
 
    /** Determines if this world could be used for multiple compiles */
93
 
    private boolean incrementalCompileCouldFollow = false;
94
 
    
95
 
    /** The level of the aspectjrt.jar the code we generate needs to run on */
96
 
    private String targetAspectjRuntimeLevel = Constants.RUNTIME_LEVEL_DEFAULT;
97
 
    
98
 
    /** Flags for the new joinpoints that are 'optional' */
99
 
    private boolean optionalJoinpoint_ArrayConstruction = false;  // Command line flag: "-Xjoinpoints:arrayconstruction"
100
 
    private boolean optionalJoinpoint_Synchronization   = false;  // Command line flag: "-Xjoinpoints:synchronization"
101
 
    
102
 
    private boolean addSerialVerUID = false;
103
 
    
104
 
    
105
 
    private Properties extraConfiguration = null;
106
 
    private boolean checkedAdvancedConfiguration=false;
107
 
    private boolean synchronizationPointcutsInUse = false;
108
 
    // Xset'table options
109
 
    private boolean fastDelegateSupportEnabled = isASMAround;
110
 
        private boolean runMinimalMemory = false;
111
 
        private boolean shouldPipelineCompilation = true;
112
 
        protected boolean bcelRepositoryCaching = xsetBCEL_REPOSITORY_CACHING_DEFAULT.equalsIgnoreCase("true");
113
 
        private boolean completeBinaryTypes = false;
114
 
        public boolean forDEBUG_structuralChangesCode = false;
115
 
        public boolean forDEBUG_bridgingCode = false;
116
 
        
117
 
        private static Trace trace = TraceFactory.getTraceFactory().getTrace(World.class);
118
 
    
119
 
    // Records whether ASM is around ... so we might use it for delegates
120
 
    protected static boolean isASMAround = false;
121
 
    
122
 
        private long errorThreshold;
123
 
        private long warningThreshold;
124
 
    
125
 
        
126
 
//    static {
127
 
//      try {
128
 
//              Class c = Class.forName("org.aspectj.org.objectweb.asm.ClassVisitor");
129
 
//              isASMAround = true;
130
 
//      } catch (ClassNotFoundException cnfe) {
131
 
//              isASMAround = false;
132
 
//      }
133
 
//    }
134
 
    
135
 
    /** 
136
 
     * A list of RuntimeExceptions containing full stack information for every
137
 
     * type we couldn't find.
138
 
     */
139
 
    private List dumpState_cantFindTypeExceptions = null;
140
 
        
141
 
    /**
142
 
     * Play God.
143
 
     * On the first day, God created the primitive types and put them in the type
144
 
     * map.
145
 
     */
146
 
    protected World() {
147
 
        super();
148
 
        if (trace.isTraceEnabled()) trace.enter("<init>", this);
149
 
        Dump.registerNode(this.getClass(),this);
150
 
        typeMap.put("B", ResolvedType.BYTE);
151
 
        typeMap.put("S", ResolvedType.SHORT);
152
 
        typeMap.put("I", ResolvedType.INT);
153
 
        typeMap.put("J", ResolvedType.LONG);
154
 
        typeMap.put("F", ResolvedType.FLOAT);
155
 
        typeMap.put("D", ResolvedType.DOUBLE);
156
 
        typeMap.put("C", ResolvedType.CHAR);
157
 
        typeMap.put("Z", ResolvedType.BOOLEAN);
158
 
        typeMap.put("V", ResolvedType.VOID);
159
 
        precedenceCalculator = new AspectPrecedenceCalculator(this);
160
 
        if (trace.isTraceEnabled()) trace.exit("<init>");
161
 
    }
162
 
    
163
 
    /**
164
 
     * Dump processing when a fatal error occurs
165
 
     */
166
 
    public void accept (Dump.IVisitor visitor) {
167
 
//              visitor.visitObject("Extra configuration:");
168
 
//              visitor.visitList(extraConfiguration.);
169
 
                visitor.visitObject("Shadow mungers:");
170
 
                visitor.visitList(crosscuttingMembersSet.getShadowMungers());
171
 
                visitor.visitObject("Type mungers:");
172
 
                visitor.visitList(crosscuttingMembersSet.getTypeMungers());
173
 
        visitor.visitObject("Late Type mungers:");
174
 
        visitor.visitList(crosscuttingMembersSet.getLateTypeMungers());
175
 
        if (dumpState_cantFindTypeExceptions!=null) {
176
 
          visitor.visitObject("Cant find type problems:");
177
 
          visitor.visitList(dumpState_cantFindTypeExceptions);
178
 
          dumpState_cantFindTypeExceptions = null;
179
 
        }
180
 
    }
181
 
    
182
 
    
183
 
    // =============================================================================
184
 
    // T Y P E   R E S O L U T I O N
185
 
    // =============================================================================
186
 
 
187
 
    /**
188
 
     * Resolve a type that we require to be present in the world
189
 
     */
190
 
    public ResolvedType resolve(UnresolvedType ty) {
191
 
        return resolve(ty, false);
192
 
    }
193
 
 
194
 
    /**
195
 
     * Attempt to resolve a type - the source location gives you some context in which
196
 
     * resolution is taking place.  In the case of an error where we can't find the
197
 
     * type - we can then at least report why (source location) we were trying to resolve it.
198
 
     */
199
 
    public ResolvedType resolve(UnresolvedType ty,ISourceLocation isl) {
200
 
        ResolvedType ret = resolve(ty,true);
201
 
        if (ResolvedType.isMissing(ty)) {
202
 
            //IMessage msg = null;
203
 
            getLint().cantFindType.signal(WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE,ty.getName()),isl);
204
 
            //if (isl!=null) {
205
 
              //msg = MessageUtil.error(WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE,ty.getName()),isl);
206
 
            //} else {
207
 
              //msg = MessageUtil.error(WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE,ty.getName())); 
208
 
            //}
209
 
            //messageHandler.handleMessage(msg);
210
 
        }
211
 
        return ret;
212
 
    }
213
 
    
214
 
    /**
215
 
     * Convenience method for resolving an array of unresolved types
216
 
     * in one hit. Useful for e.g. resolving type parameters in signatures.
217
 
     */
218
 
    public ResolvedType[] resolve(UnresolvedType[] types) {
219
 
        if (types == null) return new ResolvedType[0];
220
 
        
221
 
        ResolvedType[] ret = new ResolvedType[types.length];
222
 
        for (int i=0; i<types.length; i++) {
223
 
            ret[i] = resolve(types[i]);
224
 
        }
225
 
        return ret;
226
 
    }
227
 
 
228
 
    /**
229
 
     * Resolve a type. This the hub of type resolution. The resolved type is added
230
 
     * to the type map by signature.
231
 
     */
232
 
    public ResolvedType resolve(UnresolvedType ty, boolean allowMissing) {
233
 
        
234
 
        // special resolution processing for already resolved types.
235
 
        if (ty instanceof ResolvedType) {
236
 
                ResolvedType rty = (ResolvedType) ty;
237
 
                rty = resolve(rty);
238
 
                return rty;
239
 
        }
240
 
 
241
 
        // dispatch back to the type variable reference to resolve its constituent parts
242
 
        // don't do this for other unresolved types otherwise you'll end up in a loop
243
 
        if (ty.isTypeVariableReference()) {
244
 
                return ty.resolve(this);
245
 
        }
246
 
        
247
 
        // if we've already got a resolved type for the signature, just return it
248
 
        // after updating the world
249
 
        String signature = ty.getSignature();
250
 
        ResolvedType ret = typeMap.get(signature);
251
 
        if (ret != null) { 
252
 
                ret.world = this;  // Set the world for the RTX
253
 
                return ret; 
254
 
        } else if ( signature.equals("?") || signature.equals("*")) {
255
 
        // might be a problem here, not sure '?' should make it to here as a signature, the 
256
 
        // proper signature for wildcard '?' is '*'
257
 
                // fault in generic wildcard, can't be done earlier because of init issues
258
 
                ResolvedType something = new BoundedReferenceType("?","Ljava/lang/Object",this);
259
 
                typeMap.put("?",something);
260
 
                return something;
261
 
        }
262
 
        
263
 
        // no existing resolved type, create one
264
 
        if (ty.isArray()) {
265
 
                ResolvedType componentType = resolve(ty.getComponentType(),allowMissing);
266
 
                //String brackets = signature.substring(0,signature.lastIndexOf("[")+1);
267
 
            ret = new ResolvedType.Array(signature, "["+componentType.getErasureSignature(),
268
 
                                             this, 
269
 
                                             componentType);
270
 
        } else {
271
 
            ret = resolveToReferenceType(ty,allowMissing);
272
 
            if (!allowMissing && ret.isMissing()) {
273
 
                ret = handleRequiredMissingTypeDuringResolution(ty);
274
 
            }
275
 
            if (completeBinaryTypes) {
276
 
                completeBinaryType(ret);
277
 
            }
278
 
        }        
279
 
  
280
 
                // Pulling in the type may have already put the right entry in the map
281
 
                if (typeMap.get(signature)==null && !ret.isMissing()) {
282
 
                typeMap.put(signature, ret);
283
 
                }
284
 
        return ret;
285
 
    }
286
 
        
287
 
        /**
288
 
     * Called when a type is resolved - enables its type hierarchy to be finished off before we
289
 
     * proceed
290
 
     */
291
 
    protected void completeBinaryType(ResolvedType ret) {}
292
 
    
293
 
    
294
 
    /**
295
 
     * Return true if the classloader relating to this world is definetly the one that will
296
 
     * define the specified class.  Return false otherwise or we don't know for certain.
297
 
     */
298
 
    public boolean isLocallyDefined(String classname) {
299
 
        return false;
300
 
    }
301
 
        
302
 
    /**
303
 
     * We tried to resolve a type and couldn't find it...
304
 
     */
305
 
        private ResolvedType handleRequiredMissingTypeDuringResolution(UnresolvedType ty) {
306
 
                // defer the message until someone asks a question of the type that we can't answer
307
 
                // just from the signature.
308
 
//              MessageUtil.error(messageHandler, 
309
 
//                              WeaverMessages.format(WeaverMessages.CANT_FIND_TYPE,ty.getName()));
310
 
                if (dumpState_cantFindTypeExceptions==null) {
311
 
                  dumpState_cantFindTypeExceptions = new ArrayList();   
312
 
                }
313
 
                dumpState_cantFindTypeExceptions.add(new RuntimeException("Can't find type "+ty.getName()));
314
 
                return new MissingResolvedTypeWithKnownSignature(ty.getSignature(),this);
315
 
        }
316
 
    
317
 
    /**
318
 
     * Some TypeFactory operations create resolved types directly, but these won't be
319
 
     * in the typeMap - this resolution process puts them there. Resolved types are
320
 
     * also told their world which is needed for the special autoboxing resolved types.
321
 
     */
322
 
    public ResolvedType resolve(ResolvedType ty) {
323
 
        if (ty.isTypeVariableReference()) return ty; // until type variables have proper sigs...
324
 
        ResolvedType resolved = typeMap.get(ty.getSignature());
325
 
        if (resolved == null) {
326
 
                typeMap.put(ty.getSignature(), ty);
327
 
                resolved = ty;
328
 
        }
329
 
        resolved.world = this;
330
 
        return resolved;
331
 
    }
332
 
    
333
 
    /**
334
 
     * Convenience method for finding a type by name and resolving it in one step.
335
 
     */
336
 
    public ResolvedType resolve(String name) {
337
 
//      trace.enter("resolve", this, new Object[] {name});
338
 
        ResolvedType ret = resolve(UnresolvedType.forName(name));
339
 
//      trace.exit("resolve", ret);
340
 
        return ret;
341
 
    }
342
 
    
343
 
    public ResolvedType resolve(String name,boolean allowMissing) {
344
 
        return resolve(UnresolvedType.forName(name),allowMissing);
345
 
    }
346
 
    
347
 
        private ResolvedType currentlyResolvingBaseType;
348
 
 
349
 
        /**
350
 
         * Resolve to a ReferenceType - simple, raw, parameterized, or generic.
351
 
     * Raw, parameterized, and generic versions of a type share a delegate.
352
 
     */
353
 
    private final ResolvedType resolveToReferenceType(UnresolvedType ty,boolean allowMissing) {
354
 
                if (ty.isParameterizedType()) {
355
 
                        // ======= parameterized types ================
356
 
                        ResolvedType rt = resolveGenericTypeFor(ty,allowMissing);
357
 
                        if (rt.isMissing()) return rt;
358
 
                        ReferenceType genericType = (ReferenceType)rt;
359
 
                        currentlyResolvingBaseType = genericType;
360
 
                                                ReferenceType parameterizedType = 
361
 
                                TypeFactory.createParameterizedType(genericType, ty.typeParameters, this);
362
 
                        currentlyResolvingBaseType = null;
363
 
                        return parameterizedType;
364
 
                        
365
 
                } else if (ty.isGenericType()) {
366
 
                        // ======= generic types ======================
367
 
                        ReferenceType genericType = (ReferenceType)resolveGenericTypeFor(ty,false);
368
 
                        return genericType;
369
 
                        
370
 
                } else if (ty.isGenericWildcard()) {
371
 
                        // ======= generic wildcard types =============
372
 
                        return resolveGenericWildcardFor(ty);
373
 
        } else {
374
 
                        // ======= simple and raw types ===============
375
 
                        String erasedSignature = ty.getErasureSignature();
376
 
                ReferenceType simpleOrRawType = new ReferenceType(erasedSignature, this);
377
 
                if (ty.needsModifiableDelegate()) simpleOrRawType.setNeedsModifiableDelegate(true);
378
 
                ReferenceTypeDelegate delegate = resolveDelegate(simpleOrRawType);
379
 
                // 117854
380
 
//              if (delegate == null) return ResolvedType.MISSING;
381
 
                if (delegate == null) return new MissingResolvedTypeWithKnownSignature(ty.getSignature(),erasedSignature,this);//ResolvedType.MISSING;
382
 
                
383
 
                if (delegate.isGeneric() && behaveInJava5Way) {
384
 
                        // ======== raw type ===========
385
 
                        simpleOrRawType.typeKind = TypeKind.RAW;
386
 
                        ReferenceType genericType = makeGenericTypeFrom(delegate,simpleOrRawType); 
387
 
                        // name =  ReferenceType.fromTypeX(UnresolvedType.forRawTypeNames(ty.getName()),this);
388
 
                        simpleOrRawType.setDelegate(delegate);
389
 
                        genericType.setDelegate(delegate);
390
 
                        simpleOrRawType.setGenericType(genericType);
391
 
                        return simpleOrRawType;
392
 
                        
393
 
                } else {
394
 
                        // ======== simple type =========
395
 
                        simpleOrRawType.setDelegate(delegate);
396
 
                        return simpleOrRawType;
397
 
                }
398
 
                }
399
 
    }
400
 
 
401
 
    /**
402
 
     * Attempt to resolve a type that should be a generic type.  
403
 
     */
404
 
    public ResolvedType resolveGenericTypeFor(UnresolvedType anUnresolvedType, boolean allowMissing) {
405
 
        // Look up the raw type by signature
406
 
        String rawSignature = anUnresolvedType.getRawType().getSignature();
407
 
        ResolvedType rawType = (ResolvedType) typeMap.get(rawSignature);
408
 
        if (rawType==null) {
409
 
                rawType = resolve(UnresolvedType.forSignature(rawSignature),allowMissing);
410
 
                typeMap.put(rawSignature,rawType);
411
 
        }
412
 
        if (rawType.isMissing()) return rawType;
413
 
        
414
 
        // Does the raw type know its generic form? (It will if we created the
415
 
        // raw type from a source type, it won't if its been created just through
416
 
        // being referenced, e.g. java.util.List
417
 
        ResolvedType genericType = rawType.getGenericType();
418
 
        
419
 
        // There is a special case to consider here (testGenericsBang_pr95993 highlights it)
420
 
        // You may have an unresolvedType for a parameterized type but it
421
 
        // is backed by a simple type rather than a generic type.  This occurs for
422
 
        // inner types of generic types that inherit their enclosing types
423
 
        // type variables.
424
 
        if (rawType.isSimpleType() && (anUnresolvedType.typeParameters==null || anUnresolvedType.typeParameters.length==0)) {
425
 
                rawType.world = this;
426
 
                return rawType; 
427
 
        }
428
 
        
429
 
        if (genericType != null) { 
430
 
                genericType.world = this;
431
 
                return genericType; 
432
 
        } else {
433
 
                // Fault in the generic that underpins the raw type ;)
434
 
                ReferenceTypeDelegate delegate = resolveDelegate((ReferenceType)rawType);
435
 
                ReferenceType genericRefType = makeGenericTypeFrom(delegate,((ReferenceType)rawType));
436
 
                ((ReferenceType)rawType).setGenericType(genericRefType);
437
 
                genericRefType.setDelegate(delegate);
438
 
                ((ReferenceType)rawType).setDelegate(delegate);
439
 
                return genericRefType;
440
 
        }
441
 
    }
442
 
    
443
 
    private ReferenceType makeGenericTypeFrom(ReferenceTypeDelegate delegate, ReferenceType rawType) {
444
 
        String genericSig = delegate.getDeclaredGenericSignature();
445
 
        if (genericSig != null) {
446
 
                return new ReferenceType(
447
 
                                UnresolvedType.forGenericTypeSignature(rawType.getSignature(),delegate.getDeclaredGenericSignature()),this);
448
 
        } else {
449
 
                return new ReferenceType(
450
 
                                UnresolvedType.forGenericTypeVariables(rawType.getSignature(), delegate.getTypeVariables()),this);
451
 
        }
452
 
    }
453
 
 
454
 
    /**
455
 
     * Go from an unresolved generic wildcard (represented by UnresolvedType) to a resolved version (BoundedReferenceType).
456
 
     */
457
 
    private ReferenceType resolveGenericWildcardFor(UnresolvedType aType) {
458
 
        BoundedReferenceType ret = null;
459
 
        // FIXME asc doesnt take account of additional interface bounds (e.g. ? super R & Serializable - can you do that?)
460
 
        if (aType.isExtends()) {
461
 
                ReferenceType upperBound = (ReferenceType)resolve(aType.getUpperBound());
462
 
                ret = new BoundedReferenceType(upperBound,true,this);
463
 
        } else if (aType.isSuper()) {
464
 
                ReferenceType lowerBound = (ReferenceType) resolve(aType.getLowerBound());
465
 
                ret = new BoundedReferenceType(lowerBound,false,this);
466
 
        } else {
467
 
                // must be ? on its own!
468
 
        }
469
 
        return ret;
470
 
    }
471
 
    
472
 
    /**
473
 
     * Find the ReferenceTypeDelegate behind this reference type so that it can 
474
 
     * fulfill its contract.
475
 
     */
476
 
    protected abstract ReferenceTypeDelegate resolveDelegate(ReferenceType ty);
477
 
    
478
 
    /**
479
 
     * Special resolution for "core" types like OBJECT. These are resolved just like
480
 
     * any other type, but if they are not found it is more serious and we issue an
481
 
     * error message immediately.
482
 
     */
483
 
    public ResolvedType getCoreType(UnresolvedType tx) {
484
 
        ResolvedType coreTy = resolve(tx,true);
485
 
        if (coreTy.isMissing()) {
486
 
                 MessageUtil.error(messageHandler, 
487
 
                WeaverMessages.format(WeaverMessages.CANT_FIND_CORE_TYPE,tx.getName()));
488
 
        }
489
 
        return coreTy;
490
 
    }
491
 
 
492
 
    /**
493
 
     * Lookup a type by signature, if not found then build one and put it in the
494
 
     * map.
495
 
     */
496
 
        public ReferenceType lookupOrCreateName(UnresolvedType ty) {
497
 
                String signature = ty.getSignature();
498
 
        ReferenceType ret = lookupBySignature(signature);
499
 
        if (ret == null) {
500
 
                ret = ReferenceType.fromTypeX(ty, this);
501
 
                typeMap.put(signature, ret);
502
 
        }
503
 
                return ret;
504
 
        }
505
 
 
506
 
        /**
507
 
         * Lookup a reference type in the world by its signature. Returns
508
 
         * null if not found.
509
 
         */
510
 
        public ReferenceType lookupBySignature(String signature) {
511
 
                return (ReferenceType) typeMap.get(signature);
512
 
        }
513
 
        
514
 
 
515
 
    // =============================================================================
516
 
    // T Y P E   R E S O L U T I O N  -- E N D
517
 
    // =============================================================================
518
 
 
519
 
    /**
520
 
     * Member resolution is achieved by resolving the declaring type and then
521
 
     * looking up the member in the resolved declaring type.
522
 
     */
523
 
    public ResolvedMember resolve(Member member) {
524
 
        ResolvedType declaring = member.getDeclaringType().resolve(this);
525
 
        if (declaring.isRawType()) declaring = declaring.getGenericType();
526
 
        ResolvedMember ret;
527
 
        if (member.getKind() == Member.FIELD) {
528
 
            ret = declaring.lookupField(member);
529
 
        } else {
530
 
            ret = declaring.lookupMethod(member);
531
 
        }
532
 
        
533
 
        if (ret != null) return ret;
534
 
        
535
 
        return declaring.lookupSyntheticMember(member);   
536
 
    }
537
 
    
538
 
    // Methods for creating various cross-cutting members...
539
 
    // ===========================================================
540
 
    
541
 
    /**
542
 
     * Create an advice shadow munger from the given advice attribute 
543
 
     */
544
 
    public abstract Advice createAdviceMunger(
545
 
        AjAttribute.AdviceAttribute attribute,
546
 
        Pointcut pointcut,
547
 
        Member signature);
548
 
        
549
 
    /**
550
 
     * Create an advice shadow munger for the given advice kind
551
 
     */
552
 
    public final Advice createAdviceMunger(
553
 
        AdviceKind kind,
554
 
        Pointcut p,
555
 
        Member signature,
556
 
        int extraParameterFlags,
557
 
        IHasSourceLocation loc)
558
 
    {
559
 
        AjAttribute.AdviceAttribute attribute = 
560
 
                new AjAttribute.AdviceAttribute(kind, p, extraParameterFlags, loc.getStart(), loc.getEnd(), loc.getSourceContext());
561
 
                return createAdviceMunger(attribute, p, signature);
562
 
    }
563
 
        
564
 
        public abstract ConcreteTypeMunger makeCflowStackFieldAdder(ResolvedMember cflowField);
565
 
        
566
 
        public abstract ConcreteTypeMunger makeCflowCounterFieldAdder(ResolvedMember cflowField);
567
 
 
568
 
    /**
569
 
     * Register a munger for perclause @AJ aspect so that we add aspectOf(..) to them as needed
570
 
     * @see org.aspectj.weaver.bcel.BcelWorld#makePerClauseAspect(ResolvedType, org.aspectj.weaver.patterns.PerClause.Kind)
571
 
     */
572
 
    public abstract ConcreteTypeMunger makePerClauseAspect(ResolvedType aspect, PerClause.Kind kind);
573
 
 
574
 
    public abstract ConcreteTypeMunger concreteTypeMunger(ResolvedTypeMunger munger, ResolvedType aspectType);
575
 
 
576
 
        /**
577
 
         * Same signature as org.aspectj.util.PartialOrder.PartialComparable.compareTo
578
 
         */
579
 
        public int compareByPrecedence(ResolvedType aspect1, ResolvedType aspect2) {
580
 
                return precedenceCalculator.compareByPrecedence(aspect1, aspect2);
581
 
        }
582
 
        public Integer getPrecedenceIfAny(ResolvedType aspect1, ResolvedType aspect2) {
583
 
                return precedenceCalculator.getPrecedenceIfAny(aspect1, aspect2);
584
 
        }
585
 
                
586
 
        /**
587
 
         * compares by precedence with the additional rule that a super-aspect is 
588
 
         * sorted before its sub-aspects
589
 
         */
590
 
        public int compareByPrecedenceAndHierarchy(ResolvedType aspect1, ResolvedType aspect2) {
591
 
                return precedenceCalculator.compareByPrecedenceAndHierarchy(aspect1, aspect2);
592
 
        }
593
 
 
594
 
    // simple property getter and setters
595
 
    // ===========================================================
596
 
    
597
 
        /**
598
 
         * Nobody should hold onto a copy of this message handler, or setMessageHandler won't
599
 
         * work right.
600
 
         */
601
 
        public IMessageHandler getMessageHandler() {
602
 
                return messageHandler;
603
 
        }
604
 
 
605
 
        public void setMessageHandler(IMessageHandler messageHandler) {
606
 
                if (this.isInPinpointMode()) {
607
 
                        this.messageHandler = new PinpointingMessageHandler(messageHandler);
608
 
                } else {
609
 
                        this.messageHandler = messageHandler;                   
610
 
                }
611
 
        }
612
 
 
613
 
        /**
614
 
         * convenenience method for creating and issuing messages via the message handler - 
615
 
         * if you supply two locations you will get two messages.
616
 
         */
617
 
        public void showMessage(
618
 
                        Kind kind,
619
 
                        String message,
620
 
                        ISourceLocation loc1,
621
 
                        ISourceLocation loc2)
622
 
                {
623
 
                        if (loc1 != null) {
624
 
                                messageHandler.handleMessage(new Message(message, kind, null, loc1));
625
 
                                if (loc2 != null) {
626
 
                                        messageHandler.handleMessage(new Message(message, kind, null, loc2));
627
 
                                }
628
 
                        } else {
629
 
                                messageHandler.handleMessage(new Message(message, kind, null, loc2));
630
 
                        }
631
 
                }
632
 
 
633
 
        public boolean debug (String message) {
634
 
                return MessageUtil.debug(messageHandler,message);
635
 
        }
636
 
 
637
 
        public void setCrossReferenceHandler(ICrossReferenceHandler xrefHandler) {
638
 
                this.xrefHandler = xrefHandler;
639
 
        }
640
 
 
641
 
    /**
642
 
     * Get the cross-reference handler for the world, may be null.
643
 
     */
644
 
    public ICrossReferenceHandler getCrossReferenceHandler() {
645
 
        return this.xrefHandler;
646
 
    }
647
 
    
648
 
    public void setTypeVariableLookupScope(TypeVariableDeclaringElement scope) {
649
 
        this.typeVariableLookupScope = scope;
650
 
    }
651
 
 
652
 
    public TypeVariableDeclaringElement getTypeVariableLookupScope() {
653
 
        return typeVariableLookupScope;
654
 
    }
655
 
 
656
 
 
657
 
        public List getDeclareParents() {
658
 
                return crosscuttingMembersSet.getDeclareParents();
659
 
        }
660
 
        
661
 
        public List getDeclareAnnotationOnTypes() {
662
 
                return crosscuttingMembersSet.getDeclareAnnotationOnTypes();
663
 
        }
664
 
        
665
 
        public List getDeclareAnnotationOnFields() {
666
 
                return crosscuttingMembersSet.getDeclareAnnotationOnFields();
667
 
        }
668
 
        
669
 
        public List getDeclareAnnotationOnMethods() {
670
 
                return crosscuttingMembersSet.getDeclareAnnotationOnMethods();
671
 
        }
672
 
 
673
 
        public List getDeclareSoft() {
674
 
                return crosscuttingMembersSet.getDeclareSofts();
675
 
        }
676
 
 
677
 
        public CrosscuttingMembersSet getCrosscuttingMembersSet() {
678
 
                return crosscuttingMembersSet;
679
 
        }
680
 
 
681
 
        public IHierarchy getModel() {
682
 
                return model;
683
 
        }
684
 
 
685
 
        public void setModel(IHierarchy model) {
686
 
                this.model = model;
687
 
        }
688
 
 
689
 
        public Lint getLint() {
690
 
                return lint;
691
 
        }
692
 
 
693
 
        public void setLint(Lint lint) {
694
 
                this.lint = lint;
695
 
        }
696
 
 
697
 
        public boolean isXnoInline() {
698
 
                return XnoInline;
699
 
        }
700
 
 
701
 
        public void setXnoInline(boolean xnoInline) {
702
 
                XnoInline = xnoInline;
703
 
        }
704
 
        
705
 
        public boolean isXlazyTjp() {
706
 
                return XlazyTjp;
707
 
        }
708
 
 
709
 
        public void setXlazyTjp(boolean b) {
710
 
                XlazyTjp = b;
711
 
        }
712
 
        
713
 
        public boolean isHasMemberSupportEnabled() {
714
 
                return XhasMember;
715
 
        }
716
 
        
717
 
        public void setXHasMemberSupportEnabled(boolean b) {
718
 
                XhasMember = b;
719
 
        }
720
 
 
721
 
        public boolean isInPinpointMode() {
722
 
                return Xpinpoint;
723
 
        }
724
 
        
725
 
        public void setPinpointMode(boolean b) {
726
 
                this.Xpinpoint = b;
727
 
        }
728
 
        
729
 
        public void setBehaveInJava5Way(boolean b) {
730
 
        behaveInJava5Way = b;
731
 
    }
732
 
        
733
 
        /**
734
 
         * Set the error and warning threashold which can be taken from 
735
 
         * CompilerOptions (see bug 129282)
736
 
         * 
737
 
         * @param errorThreshold
738
 
         * @param warningThreshold
739
 
         */
740
 
        public void setErrorAndWarningThreshold(long errorThreshold, long warningThreshold) {
741
 
                this.errorThreshold = errorThreshold;
742
 
                this.warningThreshold = warningThreshold;
743
 
        }
744
 
        
745
 
        /**
746
 
         * @return true if ignoring the UnusedDeclaredThrownException and false if
747
 
         *         this compiler option is set to error or warning
748
 
         */
749
 
        public boolean isIgnoringUnusedDeclaredThrownException() {
750
 
                // the 0x800000 is CompilerOptions.UnusedDeclaredThrownException
751
 
                // which is ASTNode.bit24
752
 
                if((this.errorThreshold & 0x800000) != 0 
753
 
                                || (this.warningThreshold & 0x800000) != 0)
754
 
                        return false;
755
 
                return true;
756
 
        }
757
 
        
758
 
        public void performExtraConfiguration(String config) {
759
 
                if (config==null) return;
760
 
                // Bunch of name value pairs to split
761
 
                extraConfiguration = new Properties();
762
 
                int pos =-1;
763
 
                while ((pos=config.indexOf(","))!=-1) {
764
 
                        String nvpair = config.substring(0,pos);
765
 
                        int pos2 = nvpair.indexOf("=");
766
 
                        if (pos2!=-1) {
767
 
                                String n = nvpair.substring(0,pos2);
768
 
                                String v = nvpair.substring(pos2+1);
769
 
                                extraConfiguration.setProperty(n,v);
770
 
                        }
771
 
                        config = config.substring(pos+1);
772
 
                }
773
 
                if (config.length()>0) {
774
 
                        int pos2 = config.indexOf("=");
775
 
                        if (pos2!=-1) {
776
 
                                String n = config.substring(0,pos2);
777
 
                                String v = config.substring(pos2+1);
778
 
                                extraConfiguration.setProperty(n,v);
779
 
                        }
780
 
                }
781
 
                ensureAdvancedConfigurationProcessed();
782
 
        }
783
 
        
784
 
        /**
785
 
         * may return null
786
 
         */
787
 
        public Properties getExtraConfiguration() {
788
 
                return extraConfiguration;
789
 
        }
790
 
        public final static String xsetCAPTURE_ALL_CONTEXT = "captureAllContext"; // default false
791
 
        public final static String xsetACTIVATE_LIGHTWEIGHT_DELEGATES = "activateLightweightDelegates"; // default true
792
 
        public final static String xsetRUN_MINIMAL_MEMORY ="runMinimalMemory"; // default true
793
 
        public final static String xsetDEBUG_STRUCTURAL_CHANGES_CODE = "debugStructuralChangesCode"; // default false
794
 
        public final static String xsetDEBUG_BRIDGING = "debugBridging"; // default false
795
 
        public final static String xsetBCEL_REPOSITORY_CACHING = "bcelRepositoryCaching";
796
 
        public final static String xsetPIPELINE_COMPILATION = "pipelineCompilation";
797
 
        public final static String xsetPIPELINE_COMPILATION_DEFAULT = "true"; 
798
 
        public final static String xsetCOMPLETE_BINARY_TYPES = "completeBinaryTypes";
799
 
        public final static String xsetCOMPLETE_BINARY_TYPES_DEFAULT = "false"; 
800
 
        public final static String xsetBCEL_REPOSITORY_CACHING_DEFAULT = "true"; 
801
 
        
802
 
        public boolean isInJava5Mode() {
803
 
                return behaveInJava5Way;
804
 
        }
805
 
        
806
 
        public void setTargetAspectjRuntimeLevel(String s) {
807
 
                targetAspectjRuntimeLevel = s;
808
 
        }
809
 
        
810
 
        public void setOptionalJoinpoints(String jps) {
811
 
                if (jps==null) return;
812
 
                if (jps.indexOf("arrayconstruction")!=-1) optionalJoinpoint_ArrayConstruction = true;
813
 
                if (jps.indexOf("synchronization")!=-1)   optionalJoinpoint_Synchronization = true;
814
 
        }
815
 
        
816
 
        public boolean isJoinpointArrayConstructionEnabled() {
817
 
                return optionalJoinpoint_ArrayConstruction;
818
 
        }
819
 
        public boolean isJoinpointSynchronizationEnabled() {
820
 
                return optionalJoinpoint_Synchronization;
821
 
        }
822
 
        
823
 
        public String getTargetAspectjRuntimeLevel() {
824
 
                return targetAspectjRuntimeLevel;
825
 
        }
826
 
        
827
 
        public boolean isTargettingAspectJRuntime12() {
828
 
                boolean b = false; // pr116679
829
 
                if (!isInJava5Mode()) b=true;
830
 
                else b = getTargetAspectjRuntimeLevel().equals(org.aspectj.weaver.Constants.RUNTIME_LEVEL_12);
831
 
                //System.err.println("Asked if targetting runtime 1.2 , returning: "+b);
832
 
                return b;
833
 
        }
834
 
        
835
 
        /*
836
 
         *  Map of types in the world, can have 'references' to expendable ones which 
837
 
         *  can be garbage collected to recover memory.
838
 
         *  An expendable type is a reference type that is not exposed to the weaver (ie
839
 
         *  just pulled in for type resolution purposes).
840
 
         */
841
 
        protected static class TypeMap {
842
 
                
843
 
                private static boolean debug = false;
844
 
 
845
 
                // Strategy for entries in the expendable map
846
 
                public static int DONT_USE_REFS = 0; // Hang around forever
847
 
                public static int USE_WEAK_REFS = 1; // Collected asap
848
 
                public static int USE_SOFT_REFS = 2; // Collected when short on memory
849
 
                
850
 
                // SECRETAPI - Can switch to a policy of choice ;)
851
 
                public static int policy  = USE_SOFT_REFS; 
852
 
 
853
 
                // Map of types that never get thrown away
854
 
                private Map /* String -> ResolvedType */ tMap = new HashMap();
855
 
                
856
 
                // Map of types that may be ejected from the cache if we need space
857
 
                private Map expendableMap = new WeakHashMap();
858
 
                
859
 
                private World w;
860
 
 
861
 
                // profiling tools...
862
 
                private boolean memoryProfiling = false;
863
 
                private int maxExpendableMapSize = -1;
864
 
                private int collectedTypes = 0;
865
 
                private ReferenceQueue rq = new ReferenceQueue();
866
 
                
867
 
                private static Trace trace = TraceFactory.getTraceFactory().getTrace(World.TypeMap.class);
868
 
                
869
 
                TypeMap(World w) {
870
 
                        if (trace.isTraceEnabled()) trace.enter("<init>",this,w);
871
 
                        this.w = w;
872
 
                        memoryProfiling = false;// !w.getMessageHandler().isIgnoring(Message.INFO);
873
 
                        if (trace.isTraceEnabled()) trace.exit("<init>");
874
 
                }
875
 
                
876
 
                /** 
877
 
                 * Add a new type into the map, the key is the type signature.
878
 
                 * Some types do *not* go in the map, these are ones involving
879
 
                 * *member* type variables.  The reason is that when all you have is the
880
 
                 * signature which gives you a type variable name, you cannot 
881
 
                 * guarantee you are using the type variable in the same way 
882
 
                 * as someone previously working with a similarly
883
 
                 * named type variable.  So, these do not go into the map:
884
 
                 * - TypeVariableReferenceType.
885
 
                 * - ParameterizedType where a member type variable is involved.
886
 
                 * - BoundedReferenceType when one of the bounds is a type variable.
887
 
                 * 
888
 
                 * definition: "member type variables" - a tvar declared on a generic 
889
 
                 * method/ctor as opposed to those you see declared on a generic type.
890
 
                 */
891
 
                public ResolvedType put(String key, ResolvedType type) { 
892
 
                        if (type.isParameterizedType() && type.isParameterizedWithAMemberTypeVariable()) {
893
 
                                if (debug) 
894
 
                                        System.err.println("Not putting a parameterized type that utilises member declared type variables into the typemap: key="+key+" type="+type);
895
 
                                return type;
896
 
                        }
897
 
                        if (type.isTypeVariableReference()) {
898
 
                                if (debug) 
899
 
                                        System.err.println("Not putting a type variable reference type into the typemap: key="+key+" type="+type);
900
 
                                return type;
901
 
                        }
902
 
                        // this test should be improved - only avoid putting them in if one of the
903
 
                        // bounds is a member type variable
904
 
                        if (type instanceof BoundedReferenceType) {
905
 
                                if (debug) 
906
 
                                        System.err.println("Not putting a bounded reference type into the typemap: key="+key+" type="+type);
907
 
                                return type;
908
 
                        }
909
 
                        if (type instanceof MissingResolvedTypeWithKnownSignature) {
910
 
                                if (debug) 
911
 
                                        System.err.println("Not putting a missing type into the typemap: key="+key+" type="+type);
912
 
                                return type;
913
 
                        }
914
 
                        
915
 
                        if ((type instanceof ReferenceType) && (((ReferenceType)type).getDelegate()==null) && w.isExpendable(type)) {
916
 
                                if (debug) 
917
 
                                    System.err.println("Not putting expendable ref type with null delegate into typemap: key="+key+" type="+type);
918
 
                                return type;
919
 
                        }
920
 
                                                
921
 
                        if (w.isExpendable(type))  {
922
 
                                // Dont use reference queue for tracking if not profiling...
923
 
                                if (policy==USE_WEAK_REFS) {
924
 
                                    if (memoryProfiling) expendableMap.put(key,new WeakReference(type,rq));
925
 
                                    else                 expendableMap.put(key,new WeakReference(type));
926
 
                                } else if (policy==USE_SOFT_REFS) {
927
 
                                        if (memoryProfiling) expendableMap.put(key,new SoftReference(type,rq));
928
 
                                        else                 expendableMap.put(key,new SoftReference(type));
929
 
                                } else {
930
 
                                  expendableMap.put(key,type);
931
 
                                }
932
 
                                if (memoryProfiling && expendableMap.size()>maxExpendableMapSize) {
933
 
                                        maxExpendableMapSize = expendableMap.size();
934
 
                                }
935
 
                            return type;
936
 
                        } else {
937
 
                                return (ResolvedType) tMap.put(key,type);
938
 
                        }
939
 
                }
940
 
                
941
 
                public void report() {
942
 
                        if (!memoryProfiling) return;
943
 
                        checkq();
944
 
                        w.getMessageHandler().handleMessage(MessageUtil.info("MEMORY: world expendable type map reached maximum size of #"+maxExpendableMapSize+" entries"));
945
 
                        w.getMessageHandler().handleMessage(MessageUtil.info("MEMORY: types collected through garbage collection #"+collectedTypes+" entries"));
946
 
                }
947
 
                
948
 
                public void checkq() {
949
 
                        if (!memoryProfiling) return;
950
 
                        while (rq.poll()!=null) collectedTypes++;
951
 
                }
952
 
                
953
 
                /** 
954
 
                 * Lookup a type by its signature, always look 
955
 
                 * in the real map before the expendable map 
956
 
                 */
957
 
                public ResolvedType get(String key) {
958
 
                        checkq();
959
 
                        ResolvedType ret = (ResolvedType) tMap.get(key);
960
 
                        if (ret == null) {
961
 
                                if (policy==USE_WEAK_REFS) {
962
 
                                        WeakReference ref = (WeakReference)expendableMap.get(key);
963
 
                                        if (ref != null) {
964
 
                                                ret = (ResolvedType) ref.get();
965
 
                                        }
966
 
                                } else if (policy==USE_SOFT_REFS) {
967
 
                                        SoftReference ref = (SoftReference)expendableMap.get(key);
968
 
                                        if (ref != null) {
969
 
                                                ret = (ResolvedType) ref.get();
970
 
                                        }
971
 
                                } else {
972
 
                                    return (ResolvedType)expendableMap.get(key);
973
 
                                }
974
 
                        }
975
 
                        return ret;
976
 
                }
977
 
                
978
 
                /** Remove a type from the map */
979
 
                public ResolvedType remove(String key) {
980
 
                        ResolvedType ret = (ResolvedType) tMap.remove(key);
981
 
                        if (ret == null) {
982
 
                                if (policy==USE_WEAK_REFS) { 
983
 
                                        WeakReference wref = (WeakReference)expendableMap.remove(key);
984
 
                                        if (wref!=null) ret = (ResolvedType)wref.get();
985
 
                                } else if (policy==USE_SOFT_REFS) {
986
 
                                        SoftReference wref = (SoftReference)expendableMap.remove(key);
987
 
                                        if (wref!=null) ret = (ResolvedType)wref.get();
988
 
                                } else {
989
 
                                        ret = (ResolvedType)expendableMap.remove(key);
990
 
                                }
991
 
                        }
992
 
                        return ret;
993
 
                }
994
 
                
995
 
            public String toString() {
996
 
                StringBuffer sb = new StringBuffer();
997
 
                sb.append("types:\n");
998
 
                sb.append(dumpthem(tMap));
999
 
                sb.append("expendables:\n");
1000
 
                sb.append(dumpthem(expendableMap));
1001
 
                return sb.toString();
1002
 
            }
1003
 
            
1004
 
            private String dumpthem(Map m) {
1005
 
                StringBuffer sb = new StringBuffer();
1006
 
                
1007
 
                int otherTypes = 0;
1008
 
                int bcelDel = 0;
1009
 
                int refDel = 0;
1010
 
                
1011
 
                for (Iterator iter = m.entrySet().iterator(); iter.hasNext();) {
1012
 
                                Map.Entry entry = (Map.Entry) iter.next();
1013
 
                                Object val = entry.getValue();
1014
 
                                if (val instanceof WeakReference) {
1015
 
                                        val = ((WeakReference)val).get();
1016
 
                                } else 
1017
 
                                if (val instanceof SoftReference) {
1018
 
                                        val = ((SoftReference)val).get();
1019
 
                                } 
1020
 
                                sb.append(entry.getKey()+"="+val).append("\n");
1021
 
                                if (val instanceof ReferenceType) {
1022
 
                                        ReferenceType refType = (ReferenceType)val;
1023
 
                                        if (refType.getDelegate() instanceof BcelObjectType) {
1024
 
                                                bcelDel++;
1025
 
                                        } else if (refType.getDelegate() instanceof ReflectionBasedReferenceTypeDelegate) {
1026
 
                                                refDel++;
1027
 
                                        } else {
1028
 
                                                otherTypes++;
1029
 
                                        }
1030
 
                                } else {
1031
 
                                        otherTypes++;
1032
 
                                }
1033
 
                        }
1034
 
                sb.append("# BCEL = "+bcelDel+", # REF = "+refDel+", # Other = "+otherTypes);
1035
 
                
1036
 
                return sb.toString();
1037
 
            }
1038
 
            
1039
 
            public int totalSize() {
1040
 
                return tMap.size()+expendableMap.size();
1041
 
            }
1042
 
            public int hardSize() {
1043
 
                return tMap.size();
1044
 
            }
1045
 
            
1046
 
                public ResolvedType[] getAllTypes() {
1047
 
                        List/*ResolvedType*/ results = new ArrayList();
1048
 
 
1049
 
                        collectTypes(expendableMap, results);
1050
 
                        collectTypes(tMap, results);
1051
 
                        return (ResolvedType[]) results.toArray(new ResolvedType[results.size()]);
1052
 
                }
1053
 
 
1054
 
                private void collectTypes(Map map, List/*ResolvedType*/ results) {
1055
 
                        for (Iterator iterator = map.keySet().iterator(); iterator.hasNext();) {
1056
 
                                String key = (String) iterator.next();
1057
 
                                ResolvedType type = get((String)key);
1058
 
                                if (type!=null) results.add(type);
1059
 
                                else System.err.println("null!:"+key);
1060
 
                        }
1061
 
                }
1062
 
 
1063
 
 
1064
 
        }       
1065
 
        
1066
 
        /** Reference types we don't intend to weave may be ejected from
1067
 
         * the cache if we need the space.
1068
 
         */
1069
 
        protected boolean isExpendable(ResolvedType type) {
1070
 
                return (
1071
 
                                !type.equals(UnresolvedType.OBJECT) && 
1072
 
                                  (type != null) &&
1073
 
                                  (!type.isExposedToWeaver()) &&
1074
 
                                  (!type.isPrimitiveType())
1075
 
                                );
1076
 
        }
1077
 
 
1078
 
        /**
1079
 
         * This class is used to compute and store precedence relationships between
1080
 
         * aspects.
1081
 
         */
1082
 
        private static class AspectPrecedenceCalculator {
1083
 
                
1084
 
                private World world;
1085
 
                private Map cachedResults;
1086
 
                
1087
 
                public AspectPrecedenceCalculator(World forSomeWorld) {
1088
 
                        this.world = forSomeWorld;
1089
 
                        this.cachedResults = new HashMap();
1090
 
                }
1091
 
                
1092
 
                /**
1093
 
                 * Ask every declare precedence in the world to order the two aspects.
1094
 
                 * If more than one declare precedence gives an ordering, and the orderings
1095
 
                 * conflict, then that's an error. 
1096
 
                 */
1097
 
                public int compareByPrecedence(ResolvedType firstAspect, ResolvedType secondAspect) {
1098
 
                        PrecedenceCacheKey key = new PrecedenceCacheKey(firstAspect,secondAspect);
1099
 
                        if (cachedResults.containsKey(key)) {
1100
 
                                return ((Integer) cachedResults.get(key)).intValue();
1101
 
                        } else {
1102
 
                                int order = 0;
1103
 
                                DeclarePrecedence orderer = null; // Records the declare precedence statement that gives the first ordering
1104
 
                                for (Iterator i = world.getCrosscuttingMembersSet().getDeclareDominates().iterator(); i.hasNext(); ) {
1105
 
                                        DeclarePrecedence d = (DeclarePrecedence)i.next();
1106
 
                                        int thisOrder = d.compare(firstAspect, secondAspect);
1107
 
                                        if (thisOrder != 0) {
1108
 
                                                if (orderer==null) orderer = d;
1109
 
                                                if (order != 0 && order != thisOrder) {
1110
 
                                                        ISourceLocation[] isls = new ISourceLocation[2];
1111
 
                                                        isls[0]=orderer.getSourceLocation();
1112
 
                                                        isls[1]=d.getSourceLocation();
1113
 
                                                        Message m = 
1114
 
                                                          new Message("conflicting declare precedence orderings for aspects: "+
1115
 
                                                                      firstAspect.getName()+" and "+secondAspect.getName(),null,true,isls);
1116
 
                                                        world.getMessageHandler().handleMessage(m);
1117
 
                                                } else {
1118
 
                                                        order = thisOrder;
1119
 
                                                }
1120
 
                                        }
1121
 
                                }               
1122
 
                                cachedResults.put(key, new Integer(order));
1123
 
                                return order;
1124
 
                        }
1125
 
                }
1126
 
                
1127
 
                public Integer getPrecedenceIfAny(ResolvedType aspect1,ResolvedType aspect2) {
1128
 
                        return (Integer)cachedResults.get(new PrecedenceCacheKey(aspect1,aspect2));
1129
 
                }
1130
 
                
1131
 
                public int compareByPrecedenceAndHierarchy(ResolvedType firstAspect, ResolvedType secondAspect) {
1132
 
                        if (firstAspect.equals(secondAspect)) return 0;
1133
 
                        
1134
 
                        int ret = compareByPrecedence(firstAspect, secondAspect);
1135
 
                        if (ret != 0) return ret;
1136
 
                        
1137
 
                        if (firstAspect.isAssignableFrom(secondAspect)) return -1;
1138
 
                        else if (secondAspect.isAssignableFrom(firstAspect)) return +1;
1139
 
 
1140
 
                        return 0;
1141
 
                }
1142
 
                
1143
 
                
1144
 
                private static class PrecedenceCacheKey {
1145
 
                        public ResolvedType aspect1;
1146
 
                        public ResolvedType aspect2;
1147
 
                        
1148
 
                        public PrecedenceCacheKey(ResolvedType a1, ResolvedType a2) {
1149
 
                                this.aspect1 = a1;
1150
 
                                this.aspect2 = a2;
1151
 
                        }
1152
 
                        
1153
 
                        public boolean equals(Object obj) {
1154
 
                                if (!(obj instanceof PrecedenceCacheKey)) return false;
1155
 
                                PrecedenceCacheKey other = (PrecedenceCacheKey) obj;
1156
 
                                return (aspect1 == other.aspect1 && aspect2 == other.aspect2);
1157
 
                        }
1158
 
                        
1159
 
                        public int hashCode() {
1160
 
                                return aspect1.hashCode() + aspect2.hashCode();
1161
 
                        }
1162
 
                }
1163
 
        }
1164
 
 
1165
 
        public void validateType(UnresolvedType type) { }
1166
 
 
1167
 
    // --- with java5 we can get into a recursive mess if we aren't careful when resolving types (*cough* java.lang.Enum) ---
1168
 
        
1169
 
    // --- this first map is for java15 delegates which may try and recursively access the same type variables.
1170
 
        // --- I would rather stash this against a reference type - but we don't guarantee referencetypes are unique for
1171
 
        //     so we can't :(
1172
 
        private Map workInProgress1 = new HashMap();
1173
 
        public TypeVariable[] getTypeVariablesCurrentlyBeingProcessed(Class baseClass) {
1174
 
                return (TypeVariable[])workInProgress1.get(baseClass);
1175
 
        }
1176
 
        public void recordTypeVariablesCurrentlyBeingProcessed(Class baseClass, TypeVariable[] typeVariables) {
1177
 
                workInProgress1.put(baseClass,typeVariables);
1178
 
        }
1179
 
        public void forgetTypeVariablesCurrentlyBeingProcessed(Class baseClass) {
1180
 
                workInProgress1.remove(baseClass);
1181
 
        }
1182
 
 
1183
 
    public void setAddSerialVerUID(boolean b) { addSerialVerUID=b;}
1184
 
    public boolean isAddSerialVerUID() { return addSerialVerUID;}
1185
 
    
1186
 
    /** be careful calling this - pr152257 */
1187
 
        public void flush() {
1188
 
                typeMap.expendableMap.clear();
1189
 
        }
1190
 
        
1191
 
         public void ensureAdvancedConfigurationProcessed() {
1192
 
                // Check *once* whether the user has switched asm support off
1193
 
                if (!checkedAdvancedConfiguration) {
1194
 
                        Properties p = getExtraConfiguration();
1195
 
                        if (p!=null) {
1196
 
                                
1197
 
                                if (isASMAround) { // dont bother if its not...
1198
 
                                String s = p.getProperty(xsetACTIVATE_LIGHTWEIGHT_DELEGATES,"true");
1199
 
                                fastDelegateSupportEnabled = s.equalsIgnoreCase("true");
1200
 
                                if (!fastDelegateSupportEnabled) 
1201
 
                                        getMessageHandler().handleMessage(MessageUtil.info("[activateLightweightDelegates=false] Disabling optimization to use lightweight delegates for non-woven types"));
1202
 
                                }
1203
 
                                
1204
 
                                String s = p.getProperty(xsetBCEL_REPOSITORY_CACHING,xsetBCEL_REPOSITORY_CACHING_DEFAULT);
1205
 
                                bcelRepositoryCaching = s.equalsIgnoreCase("true");
1206
 
                                if (!bcelRepositoryCaching) {
1207
 
                                        getMessageHandler().handleMessage(MessageUtil.info("[bcelRepositoryCaching=false] AspectJ will not use a bcel cache for class information"));
1208
 
                                }
1209
 
                                
1210
 
                                s = p.getProperty(xsetPIPELINE_COMPILATION,xsetPIPELINE_COMPILATION_DEFAULT);
1211
 
                                shouldPipelineCompilation = s.equalsIgnoreCase("true");
1212
 
 
1213
 
                                s = p.getProperty(xsetCOMPLETE_BINARY_TYPES,xsetCOMPLETE_BINARY_TYPES_DEFAULT);
1214
 
                                completeBinaryTypes = s.equalsIgnoreCase("true");
1215
 
                                if (completeBinaryTypes) {
1216
 
                                        getMessageHandler().handleMessage(MessageUtil.info("[completeBinaryTypes=true] Completion of binary types activated"));
1217
 
                                }
1218
 
                                
1219
 
                                s = p.getProperty(xsetRUN_MINIMAL_MEMORY,"false");
1220
 
                        runMinimalMemory = s.equalsIgnoreCase("true");
1221
 
//                      if (runMinimalMemory) 
1222
 
//                              getMessageHandler().handleMessage(MessageUtil.info("[runMinimalMemory=true] Optimizing bcel processing (and cost of performance) to use less memory"));
1223
 
                        
1224
 
                        
1225
 
                        s = p.getProperty(xsetDEBUG_STRUCTURAL_CHANGES_CODE,"false");
1226
 
                        forDEBUG_structuralChangesCode = s.equalsIgnoreCase("true");
1227
 
                        
1228
 
                        s = p.getProperty(xsetDEBUG_BRIDGING,"false");
1229
 
                        forDEBUG_bridgingCode = s.equalsIgnoreCase("true");
1230
 
                                
1231
 
                }
1232
 
                checkedAdvancedConfiguration=true;
1233
 
        }
1234
 
     }
1235
 
            
1236
 
            public boolean isRunMinimalMemory() {
1237
 
              ensureAdvancedConfigurationProcessed();
1238
 
                  return runMinimalMemory;
1239
 
            }
1240
 
            
1241
 
            public boolean shouldPipelineCompilation() {
1242
 
                ensureAdvancedConfigurationProcessed();
1243
 
                return shouldPipelineCompilation;
1244
 
            }
1245
 
            
1246
 
            public void setFastDelegateSupport(boolean b) { 
1247
 
                  if (b && !isASMAround) {
1248
 
                        throw new BCException("Unable to activate fast delegate support, ASM classes cannot be found");
1249
 
                  }
1250
 
                  fastDelegateSupportEnabled = b; 
1251
 
            }
1252
 
            
1253
 
            public boolean isFastDelegateSupportEnabled() {
1254
 
                  return false; // ASM not currently being used
1255
 
//                ensureAdvancedConfigurationProcessed();
1256
 
//                return fastDelegateSupportEnabled;
1257
 
            }
1258
 
                
1259
 
            public void setIncrementalCompileCouldFollow(boolean b) {incrementalCompileCouldFollow = b;}
1260
 
            public boolean couldIncrementalCompileFollow()           {return incrementalCompileCouldFollow;}
1261
 
        
1262
 
            public void setSynchronizationPointcutsInUse() {
1263
 
                if (trace.isTraceEnabled()) trace.enter("setSynchronizationPointcutsInUse", this);
1264
 
                synchronizationPointcutsInUse =true;
1265
 
                if (trace.isTraceEnabled()) trace.exit("setSynchronizationPointcutsInUse");
1266
 
            }
1267
 
            public boolean areSynchronizationPointcutsInUse() {return synchronizationPointcutsInUse;}
1268
 
            
1269
 
            public boolean isASMAround() { 
1270
 
                return isASMAround;
1271
 
            }
1272
 
            
1273
 
                public ResolvedType[] getAllTypes() {
1274
 
                        return typeMap.getAllTypes();
1275
 
                }
1276
 
 
1277
 
}
 
 
b'\\ No newline at end of file'