View | Details | Raw Unified | Return to bug 128664
Collapse All | Expand All

(-)src/org/aspectj/weaver/patterns/TypePattern.java (-235 / +328 lines)
Lines 10-16 Link Here
10
 *     PARC     initial implementation 
10
 *     PARC     initial implementation 
11
 * ******************************************************************/
11
 * ******************************************************************/
12
12
13
14
package org.aspectj.weaver.patterns;
13
package org.aspectj.weaver.patterns;
15
14
16
import java.io.DataOutputStream;
15
import java.io.DataOutputStream;
Lines 30-119 Link Here
30
import org.aspectj.weaver.VersionedDataInputStream;
29
import org.aspectj.weaver.VersionedDataInputStream;
31
import org.aspectj.weaver.WeaverMessages;
30
import org.aspectj.weaver.WeaverMessages;
32
import org.aspectj.weaver.World;
31
import org.aspectj.weaver.World;
32
33
/**
33
/**
34
 *  On creation, type pattern only contains WildTypePattern nodes, not BindingType or ExactType. 
34
 * On creation, type pattern only contains WildTypePattern nodes, not BindingType or ExactType.
35
 * 
36
 * <p>
37
 * Then we call resolveBindings() during compilation During concretization of enclosing pointcuts, we call remapAdviceFormals
35
 * 
38
 * 
36
 * <p>Then we call resolveBindings() during compilation
37
 * During concretization of enclosing pointcuts, we call remapAdviceFormals
38
  * 
39
 * @author Erik Hilsdale
39
 * @author Erik Hilsdale
40
 * @author Jim Hugunin
40
 * @author Jim Hugunin
41
 */
41
 */
42
public abstract class TypePattern extends PatternNode {
42
public abstract class TypePattern extends PatternNode {
43
	public static class MatchKind {
43
	public static class MatchKind {
44
		private String name;
44
		private String name;
45
		public MatchKind(String name) { this.name = name; }
45
46
		public String toString() { return name; }
46
		public MatchKind(String name) {
47
			this.name = name;
48
		}
49
50
		public String toString() {
51
			return name;
52
		}
47
	}
53
	}
48
	
54
49
	public static final MatchKind STATIC = new MatchKind("STATIC");
55
	public static final MatchKind STATIC = new MatchKind("STATIC");
50
	public static final MatchKind DYNAMIC = new MatchKind("DYNAMIC");
56
	public static final MatchKind DYNAMIC = new MatchKind("DYNAMIC");
51
	
57
52
	public static final TypePattern ELLIPSIS = new EllipsisTypePattern();
58
	public static final TypePattern ELLIPSIS = new EllipsisTypePattern();
53
	public static final TypePattern ANY = new AnyTypePattern();
59
	public static final TypePattern ANY = new AnyTypePattern();
54
	public static final TypePattern NO = new NoTypePattern();
60
	public static final TypePattern NO = new NoTypePattern();
55
	
61
56
	
57
	protected boolean includeSubtypes;
62
	protected boolean includeSubtypes;
58
	protected boolean isVarArgs = false;
63
	protected boolean isVarArgs = false;
59
	protected AnnotationTypePattern annotationPattern = AnnotationTypePattern.ANY;
64
	protected AnnotationTypePattern annotationPattern = AnnotationTypePattern.ANY;
60
	protected TypePatternList typeParameters = TypePatternList.EMPTY;
65
	protected TypePatternList typeParameters = TypePatternList.EMPTY;
61
	
66
62
	protected TypePattern(boolean includeSubtypes,boolean isVarArgs,TypePatternList typeParams) {
67
	protected TypePattern(boolean includeSubtypes, boolean isVarArgs, TypePatternList typeParams) {
63
		this.includeSubtypes = includeSubtypes;
68
		this.includeSubtypes = includeSubtypes;
64
		this.isVarArgs = isVarArgs;
69
		this.isVarArgs = isVarArgs;
65
		this.typeParameters = (typeParams == null ? TypePatternList.EMPTY : typeParams);
70
		this.typeParameters = (typeParams == null ? TypePatternList.EMPTY : typeParams);
66
	}
71
	}
67
	
72
68
	protected TypePattern(boolean includeSubtypes, boolean isVarArgs) {
73
	protected TypePattern(boolean includeSubtypes, boolean isVarArgs) {
69
		this(includeSubtypes,isVarArgs,null);
74
		this(includeSubtypes, isVarArgs, null);
70
	}
75
	}
71
76
72
    public AnnotationTypePattern getAnnotationPattern() {
77
	public AnnotationTypePattern getAnnotationPattern() {
73
        return annotationPattern;
78
		return annotationPattern;
74
    }
79
	}
75
80
76
    public boolean isVarArgs() {
81
	public boolean isVarArgs() {
77
        return isVarArgs;
82
		return isVarArgs;
78
    }
83
	}
79
84
80
	public boolean isStarAnnotation() {
85
	public boolean isStarAnnotation() {
81
		return annotationPattern == AnnotationTypePattern.ANY;
86
		return annotationPattern == AnnotationTypePattern.ANY;
82
	}
87
	}
83
	
88
84
	public boolean isArray() {
89
	public boolean isArray() {
85
		return false;
90
		return false;
86
	}
91
	}
87
	
92
88
	protected TypePattern(boolean includeSubtypes) {
93
	protected TypePattern(boolean includeSubtypes) {
89
		this(includeSubtypes,false);
94
		this(includeSubtypes, false);
90
	}
95
	}
91
	
96
92
	public void setAnnotationTypePattern(AnnotationTypePattern annPatt) {
97
	public void setAnnotationTypePattern(AnnotationTypePattern annPatt) {
93
		this.annotationPattern = annPatt;
98
		this.annotationPattern = annPatt;
94
	}
99
	}
95
	
100
96
	public void setTypeParameters(TypePatternList typeParams) {
101
	public void setTypeParameters(TypePatternList typeParams) {
97
		this.typeParameters = typeParams;
102
		this.typeParameters = typeParams;
98
	}
103
	}
99
	
104
100
	public TypePatternList getTypeParameters() {
105
	public TypePatternList getTypeParameters() {
101
		return this.typeParameters;
106
		return this.typeParameters;
102
	}
107
	}
103
	
108
104
	public void setIsVarArgs(boolean isVarArgs) {
109
	public void setIsVarArgs(boolean isVarArgs) {
105
		this.isVarArgs = isVarArgs;
110
		this.isVarArgs = isVarArgs;
106
	}
111
	}
107
	
112
108
	// answer conservatively...
113
	// answer conservatively...
109
	protected boolean couldEverMatchSameTypesAs(TypePattern other) {
114
	protected boolean couldEverMatchSameTypesAs(TypePattern other) {
110
		if (this.includeSubtypes || other.includeSubtypes) return true;
115
		if (this.includeSubtypes || other.includeSubtypes)
111
		if (this.annotationPattern != AnnotationTypePattern.ANY) return true;
116
			return true;
112
		if (other.annotationPattern != AnnotationTypePattern.ANY) return true;
117
		if (this.annotationPattern != AnnotationTypePattern.ANY)
118
			return true;
119
		if (other.annotationPattern != AnnotationTypePattern.ANY)
120
			return true;
113
		return false;
121
		return false;
114
	}
122
	}
115
	
123
116
	//XXX non-final for Not, && and ||
117
	public boolean matchesStatically(ResolvedType type) {
124
	public boolean matchesStatically(ResolvedType type) {
118
		if (includeSubtypes) {
125
		if (includeSubtypes) {
119
			return matchesSubtypes(type);
126
			return matchesSubtypes(type);
Lines 121-184 Link Here
121
			return matchesExactly(type);
128
			return matchesExactly(type);
122
		}
129
		}
123
	}
130
	}
124
	public abstract FuzzyBoolean matchesInstanceof(ResolvedType type);	
131
125
	
132
	public abstract FuzzyBoolean matchesInstanceof(ResolvedType type);
133
126
	public final FuzzyBoolean matches(ResolvedType type, MatchKind kind) {
134
	public final FuzzyBoolean matches(ResolvedType type, MatchKind kind) {
127
//		FuzzyBoolean typeMatch = null;
135
		// FuzzyBoolean typeMatch = null;
128
		//??? This is part of gracefully handling missing references
136
		// ??? This is part of gracefully handling missing references
129
		if (type.isMissing()) return FuzzyBoolean.NO;
137
		if (type.isMissing())
130
		
138
			return FuzzyBoolean.NO;
139
131
		if (kind == STATIC) {
140
		if (kind == STATIC) {
132
//			typeMatch = FuzzyBoolean.fromBoolean(matchesStatically(type));
141
			// typeMatch = FuzzyBoolean.fromBoolean(matchesStatically(type));
133
//			return typeMatch.and(annotationPattern.matches(type));
142
			// return typeMatch.and(annotationPattern.matches(type));
134
		    return FuzzyBoolean.fromBoolean(matchesStatically(type));
143
			return FuzzyBoolean.fromBoolean(matchesStatically(type));
135
		} else if (kind == DYNAMIC) {
144
		} else if (kind == DYNAMIC) {
136
			//System.err.println("matching: " + this + " with " + type);
145
			// System.err.println("matching: " + this + " with " + type);
137
//			typeMatch = matchesInstanceof(type);
146
			// typeMatch = matchesInstanceof(type);
138
			//System.err.println("    got: " + ret);
147
			// System.err.println("    got: " + ret);
139
//			return typeMatch.and(annotationPattern.matches(type));
148
			// return typeMatch.and(annotationPattern.matches(type));
140
		    return matchesInstanceof(type);
149
			return matchesInstanceof(type);
141
		} else {
150
		} else {
142
			throw new IllegalArgumentException("kind must be DYNAMIC or STATIC");
151
			throw new IllegalArgumentException("kind must be DYNAMIC or STATIC");
143
		}
152
		}
144
	}
153
	}
145
		
154
146
	protected abstract boolean matchesExactly(ResolvedType type);
155
	protected abstract boolean matchesExactly(ResolvedType type);
147
	
156
148
	protected abstract boolean matchesExactly(ResolvedType type, ResolvedType annotatedType);
157
	protected abstract boolean matchesExactly(ResolvedType type, ResolvedType annotatedType);
149
158
150
	protected boolean matchesSubtypes(ResolvedType type) {
159
	protected boolean matchesSubtypes(ResolvedType type) {
151
		//System.out.println("matching: " + this + " to " + type);
160
		// System.out.println("matching: " + this + " to " + type);
152
		if (matchesExactly(type)) {
161
		if (matchesExactly(type)) {
153
			//System.out.println("    true");
162
			// System.out.println("    true");
154
			return true;
163
			return true;
155
		}
164
		}
156
		// pr124808
165
		// pr124808
157
		Iterator typesIterator = null;
166
		Iterator typesIterator = null;
158
		if (type.isTypeVariableReference()) {
167
		if (type.isTypeVariableReference()) {
159
			typesIterator = ((TypeVariableReference)type).getTypeVariable().getFirstBound().resolve(type.getWorld()).getDirectSupertypes();
168
			typesIterator = ((TypeVariableReference) type).getTypeVariable().getFirstBound().resolve(type.getWorld())
169
					.getDirectSupertypes();
160
		} else {
170
		} else {
161
            // pr223605
171
			// pr223605
162
            if (type.isRawType()) {
172
			if (type.isRawType()) {
163
                type = type.getGenericType();
173
				type = type.getGenericType();
164
            }
174
			}
165
            typesIterator = type.getDirectSupertypes();
175
			typesIterator = type.getDirectSupertypes();
166
		}
176
		}
167
		
177
168
		// FuzzyBoolean ret = FuzzyBoolean.NO; // ??? -eh
178
		// FuzzyBoolean ret = FuzzyBoolean.NO; // ??? -eh
169
		for (Iterator i = typesIterator; i.hasNext(); ) {
179
		for (Iterator i = typesIterator; i.hasNext();) {
170
			ResolvedType superType = (ResolvedType)i.next();
180
			ResolvedType supertype = (ResolvedType) i.next();
171
			// TODO asc generics, temporary whilst matching isnt aware..
181
			// TODO asc generics, temporary whilst matching isnt aware..
172
			//if (superType.isParameterizedType()) superType = superType.getRawType().resolve(superType.getWorld());
182
			// if (superType.isParameterizedType()) superType = superType.getRawType().resolve(superType.getWorld());
173
			if (matchesSubtypes(superType,type)) return true;
183
			if (matchesSubtypes(supertype, type))
184
				return true;
174
		}
185
		}
175
		return false;
186
		return false;
176
	}
187
	}
177
	
188
178
	protected boolean matchesSubtypes(ResolvedType superType, ResolvedType annotatedType) {
189
	protected boolean matchesSubtypes(ResolvedType superType, ResolvedType annotatedType) {
179
		//System.out.println("matching: " + this + " to " + type);
190
		// System.out.println("matching: " + this + " to " + type);
180
		if (matchesExactly(superType,annotatedType)) {
191
		if (matchesExactly(superType, annotatedType)) {
181
			//System.out.println("    true");
192
			// System.out.println("    true");
182
			return true;
193
			return true;
183
		}
194
		}
184
		// If an ITD is applied, it will be put onto the generic type, not the parameterized or raw form
195
		// If an ITD is applied, it will be put onto the generic type, not the parameterized or raw form
Lines 186-280 Link Here
186
			superType = superType.getGenericType();
197
			superType = superType.getGenericType();
187
		}
198
		}
188
		// FuzzyBoolean ret = FuzzyBoolean.NO; // ??? -eh
199
		// FuzzyBoolean ret = FuzzyBoolean.NO; // ??? -eh
189
		for (Iterator i = superType.getDirectSupertypes(); i.hasNext(); ) {
200
		for (Iterator i = superType.getDirectSupertypes(); i.hasNext();) {
190
			ResolvedType superSuperType = (ResolvedType)i.next();
201
			ResolvedType superSuperType = (ResolvedType) i.next();
191
			if (matchesSubtypes(superSuperType,annotatedType)) return true;
202
			if (matchesSubtypes(superSuperType, annotatedType))
203
				return true;
192
		}
204
		}
193
		return false;
205
		return false;
194
	}
206
	}
195
	
207
196
	public UnresolvedType resolveExactType(IScope scope, Bindings bindings) {
208
	public UnresolvedType resolveExactType(IScope scope, Bindings bindings) {
197
		TypePattern p = resolveBindings(scope, bindings, false, true);
209
		TypePattern p = resolveBindings(scope, bindings, false, true);
198
		if (!(p instanceof ExactTypePattern)) return ResolvedType.MISSING;
210
		if (!(p instanceof ExactTypePattern))
199
		return ((ExactTypePattern)p).getType();
211
			return ResolvedType.MISSING;
212
		return ((ExactTypePattern) p).getType();
200
	}
213
	}
201
	
214
202
	public UnresolvedType getExactType() {
215
	public UnresolvedType getExactType() {
203
		if (this instanceof ExactTypePattern) return ((ExactTypePattern)this).getType();
216
		if (this instanceof ExactTypePattern)
204
		else return ResolvedType.MISSING;
217
			return ((ExactTypePattern) this).getType();
218
		else
219
			return ResolvedType.MISSING;
205
	}
220
	}
206
	
221
207
	protected TypePattern notExactType(IScope s) {
222
	protected TypePattern notExactType(IScope s) {
208
		s.getMessageHandler().handleMessage(MessageUtil.error(
223
		s.getMessageHandler().handleMessage(
209
				WeaverMessages.format(WeaverMessages.EXACT_TYPE_PATTERN_REQD), getSourceLocation()));
224
				MessageUtil.error(WeaverMessages.format(WeaverMessages.EXACT_TYPE_PATTERN_REQD), getSourceLocation()));
210
		return NO;
225
		return NO;
211
	}
226
	}
212
	
227
213
//	public boolean assertExactType(IMessageHandler m) {
228
	// public boolean assertExactType(IMessageHandler m) {
214
//		if (this instanceof ExactTypePattern) return true;
229
	// if (this instanceof ExactTypePattern) return true;
215
//		
230
	//		
216
//		//XXX should try harder to avoid multiple errors for one problem
231
	// //XXX should try harder to avoid multiple errors for one problem
217
//		m.handleMessage(MessageUtil.error("exact type pattern required", getSourceLocation()));
232
	// m.handleMessage(MessageUtil.error("exact type pattern required", getSourceLocation()));
218
//		return false;
233
	// return false;
219
//	}
234
	// }
220
235
221
	/**
236
	/**
222
	 * This can modify in place, or return a new TypePattern if the type changes.
237
	 * This can modify in place, or return a new TypePattern if the type changes.
223
	 */
238
	 */
224
    public TypePattern resolveBindings(IScope scope, Bindings bindings, 
239
	public TypePattern resolveBindings(IScope scope, Bindings bindings, boolean allowBinding, boolean requireExactType) {
225
    								boolean allowBinding, boolean requireExactType)
240
		annotationPattern = annotationPattern.resolveBindings(scope, bindings, allowBinding);
226
    { 
241
		return this;
227
    	annotationPattern = annotationPattern.resolveBindings(scope,bindings,allowBinding);
242
	}
228
    	return this;
243
229
    }
244
	public void resolve(World world) {
230
    
245
		annotationPattern.resolve(world);
231
    public void resolve(World world) {
246
	}
232
        annotationPattern.resolve(world);
247
233
    }
248
	/**
234
    
249
	 * return a version of this type pattern in which all type variable references have been replaced by their corresponding entry
235
    /**
250
	 * in the map.
236
     * return a version of this type pattern in which all type variable references have been
251
	 */
237
     * replaced by their corresponding entry in the map.
252
	public abstract TypePattern parameterizeWith(Map typeVariableMap, World w);
238
     */
253
239
    public abstract TypePattern parameterizeWith(Map typeVariableMap,World w);
240
    
241
	public void postRead(ResolvedType enclosingType) {
254
	public void postRead(ResolvedType enclosingType) {
242
	}
255
	}
243
	
256
244
	public boolean isStar() {
257
	public boolean isStar() {
245
		return false;
258
		return false;
246
	}
259
	}
247
260
248
    
261
	/**
249
    
262
	 * This is called during concretization of pointcuts, it is used by BindingTypePattern to return a new BindingTypePattern with a
250
    /**
263
	 * formal index appropiate for the advice, rather than for the lexical declaration, i.e. this handles transforamtions through
251
     * This is called during concretization of pointcuts, it is used by BindingTypePattern
264
	 * named pointcuts.
252
     * to return a new BindingTypePattern with a formal index appropiate for the advice,
265
	 * 
253
     * rather than for the lexical declaration, i.e. this handles transforamtions through
266
	 * <pre>
254
     * named pointcuts.
267
	 * pointcut foo(String name): args(name);
255
     * <pre>
268
	 * --&gt; This makes a BindingTypePattern(0) pointing to the 0th formal
256
     * pointcut foo(String name): args(name);
269
	 * 
257
     * --&gt; This makes a BindingTypePattern(0) pointing to the 0th formal
270
	 * before(Foo f, String n): this(f) &amp;&amp; foo(n) { ... }
258
     * 
271
	 * --&gt; when resolveReferences is called on the args from the above, it
259
     * before(Foo f, String n): this(f) && foo(n) { ... }
272
	 *     will return a BindingTypePattern(1)
260
     * --&gt; when resolveReferences is called on the args from the above, it
273
	 * 
261
     *     will return a BindingTypePattern(1)
274
	 * before(Foo f): this(f) &amp;&amp; foo(*) { ... }
262
     * 
275
	 * --&gt; when resolveReferences is called on the args from the above, it
263
     * before(Foo f): this(f) && foo(*) { ... }
276
	 *     will return an ExactTypePattern(String)
264
     * --&gt; when resolveReferences is called on the args from the above, it
277
	 * </pre>
265
     *     will return an ExactTypePattern(String)
278
	 */
266
     * </pre>
267
     */
268
	public TypePattern remapAdviceFormals(IntMap bindings) {
279
	public TypePattern remapAdviceFormals(IntMap bindings) {
269
		return this;
280
		return this;
270
	}
281
	}
271
282
272
273
	public static final byte WILD = 1;
283
	public static final byte WILD = 1;
274
	public static final byte EXACT = 2;
284
	public static final byte EXACT = 2;
275
	public static final byte BINDING = 3;
285
	public static final byte BINDING = 3;
276
	public static final byte ELLIPSIS_KEY = 4; 
286
	public static final byte ELLIPSIS_KEY = 4;
277
	public static final byte ANY_KEY = 5; 
287
	public static final byte ANY_KEY = 5;
278
	public static final byte NOT = 6;
288
	public static final byte NOT = 6;
279
	public static final byte OR = 7;
289
	public static final byte OR = 7;
280
	public static final byte AND = 8;
290
	public static final byte AND = 8;
Lines 284-301 Link Here
284
294
285
	public static TypePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException {
295
	public static TypePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException {
286
		byte key = s.readByte();
296
		byte key = s.readByte();
287
		switch(key) {
297
		switch (key) {
288
			case WILD: return WildTypePattern.read(s, context);
298
		case WILD:
289
			case EXACT: return ExactTypePattern.read(s, context);
299
			return WildTypePattern.read(s, context);
290
			case BINDING: return BindingTypePattern.read(s, context);
300
		case EXACT:
291
			case ELLIPSIS_KEY: return ELLIPSIS;
301
			return ExactTypePattern.read(s, context);
292
			case ANY_KEY: return ANY;
302
		case BINDING:
293
			case NO_KEY: return NO;
303
			return BindingTypePattern.read(s, context);
294
			case NOT: return NotTypePattern.read(s, context);
304
		case ELLIPSIS_KEY:
295
			case OR: return OrTypePattern.read(s, context);
305
			return ELLIPSIS;
296
			case AND: return AndTypePattern.read(s, context);
306
		case ANY_KEY:
297
			case ANY_WITH_ANNO: return AnyWithAnnotationTypePattern.read(s,context);
307
			return ANY;
298
			case HAS_MEMBER: return HasMemberTypePattern.read(s,context);
308
		case NO_KEY:
309
			return NO;
310
		case NOT:
311
			return NotTypePattern.read(s, context);
312
		case OR:
313
			return OrTypePattern.read(s, context);
314
		case AND:
315
			return AndTypePattern.read(s, context);
316
		case ANY_WITH_ANNO:
317
			return AnyWithAnnotationTypePattern.read(s, context);
318
		case HAS_MEMBER:
319
			return HasMemberTypePattern.read(s, context);
299
		}
320
		}
300
		throw new BCException("unknown TypePattern kind: " + key);
321
		throw new BCException("unknown TypePattern kind: " + key);
301
	}
322
	}
Lines 307-334 Link Here
307
}
328
}
308
329
309
class EllipsisTypePattern extends TypePattern {
330
class EllipsisTypePattern extends TypePattern {
310
	
331
311
	/**
332
	/**
312
	 * Constructor for EllipsisTypePattern.
333
	 * Constructor for EllipsisTypePattern.
334
	 * 
313
	 * @param includeSubtypes
335
	 * @param includeSubtypes
314
	 */
336
	 */
315
	public EllipsisTypePattern() {
337
	public EllipsisTypePattern() {
316
		super(false,false,new TypePatternList());
338
		super(false, false, new TypePatternList());
317
	}
339
	}
318
340
319
	/* (non-Javadoc)
341
	/*
342
	 * (non-Javadoc)
343
	 * 
320
	 * @see org.aspectj.weaver.patterns.TypePattern#couldEverMatchSameTypesAs(org.aspectj.weaver.patterns.TypePattern)
344
	 * @see org.aspectj.weaver.patterns.TypePattern#couldEverMatchSameTypesAs(org.aspectj.weaver.patterns.TypePattern)
321
	 */
345
	 */
322
	protected boolean couldEverMatchSameTypesAs(TypePattern other) {
346
	protected boolean couldEverMatchSameTypesAs(TypePattern other) {
323
		return true;
347
		return true;
324
	}
348
	}
349
325
	/**
350
	/**
326
	 * @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType)
351
	 * @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType)
327
	 */
352
	 */
328
	protected boolean matchesExactly(ResolvedType type) {
353
	protected boolean matchesExactly(ResolvedType type) {
329
		return false;
354
		return false;
330
	}
355
	}
331
	
356
332
	protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) {
357
	protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) {
333
		return false;
358
		return false;
334
	}
359
	}
Lines 346-395 Link Here
346
	public void write(DataOutputStream s) throws IOException {
371
	public void write(DataOutputStream s) throws IOException {
347
		s.writeByte(ELLIPSIS_KEY);
372
		s.writeByte(ELLIPSIS_KEY);
348
	}
373
	}
349
	
374
350
	public String toString() { return ".."; }
375
	public String toString() {
351
	
376
		return "..";
352
	/* (non-Javadoc)
377
	}
378
379
	/*
380
	 * (non-Javadoc)
381
	 * 
353
	 * @see java.lang.Object#equals(java.lang.Object)
382
	 * @see java.lang.Object#equals(java.lang.Object)
354
	 */
383
	 */
355
	public boolean equals(Object obj) {
384
	public boolean equals(Object obj) {
356
		return (obj instanceof EllipsisTypePattern);
385
		return (obj instanceof EllipsisTypePattern);
357
	}
386
	}
358
	
387
359
	/* (non-Javadoc)
388
	/*
389
	 * (non-Javadoc)
390
	 * 
360
	 * @see java.lang.Object#hashCode()
391
	 * @see java.lang.Object#hashCode()
361
	 */
392
	 */
362
	public int hashCode() {
393
	public int hashCode() {
363
		return 17 * 37;
394
		return 17 * 37;
364
	}
395
	}
365
396
366
    public Object accept(PatternNodeVisitor visitor, Object data) {
397
	public Object accept(PatternNodeVisitor visitor, Object data) {
367
        return visitor.visit(this, data);
398
		return visitor.visit(this, data);
368
    }
399
	}
369
    
370
    public TypePattern parameterizeWith(Map typeVariableMap,World w) {
371
    	return this;
372
    }
373
400
401
	public TypePattern parameterizeWith(Map typeVariableMap, World w) {
402
		return this;
403
	}
374
404
375
}
405
}
376
406
377
class AnyTypePattern extends TypePattern {
407
class AnyTypePattern extends TypePattern {
378
	
408
379
	/**
409
	/**
380
	 * Constructor for EllipsisTypePattern.
410
	 * Constructor for EllipsisTypePattern.
411
	 * 
381
	 * @param includeSubtypes
412
	 * @param includeSubtypes
382
	 */
413
	 */
383
	public AnyTypePattern() {
414
	public AnyTypePattern() {
384
		super(false,false,new TypePatternList());
415
		super(false, false, new TypePatternList());
385
	}
416
	}
386
417
387
	/* (non-Javadoc)
418
	/*
419
	 * (non-Javadoc)
420
	 * 
388
	 * @see org.aspectj.weaver.patterns.TypePattern#couldEverMatchSameTypesAs(org.aspectj.weaver.patterns.TypePattern)
421
	 * @see org.aspectj.weaver.patterns.TypePattern#couldEverMatchSameTypesAs(org.aspectj.weaver.patterns.TypePattern)
389
	 */
422
	 */
390
	protected boolean couldEverMatchSameTypesAs(TypePattern other) {
423
	protected boolean couldEverMatchSameTypesAs(TypePattern other) {
391
		return true;
424
		return true;
392
	}
425
	}
426
393
	/**
427
	/**
394
	 * @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType)
428
	 * @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType)
395
	 */
429
	 */
Lines 400-406 Link Here
400
	protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) {
434
	protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) {
401
		return true;
435
		return true;
402
	}
436
	}
403
	
437
404
	/**
438
	/**
405
	 * @see org.aspectj.weaver.patterns.TypePattern#matchesInstanceof(IType)
439
	 * @see org.aspectj.weaver.patterns.TypePattern#matchesInstanceof(IType)
406
	 */
440
	 */
Lines 418-473 Link Here
418
	/**
452
	/**
419
	 * @see org.aspectj.weaver.patterns.TypePattern#matches(IType, MatchKind)
453
	 * @see org.aspectj.weaver.patterns.TypePattern#matches(IType, MatchKind)
420
	 */
454
	 */
421
//	public FuzzyBoolean matches(IType type, MatchKind kind) {
455
	// public FuzzyBoolean matches(IType type, MatchKind kind) {
422
//		return FuzzyBoolean.YES;
456
	// return FuzzyBoolean.YES;
423
//	}
457
	// }
424
425
	/**
458
	/**
426
	 * @see org.aspectj.weaver.patterns.TypePattern#matchesSubtypes(IType)
459
	 * @see org.aspectj.weaver.patterns.TypePattern#matchesSubtypes(IType)
427
	 */
460
	 */
428
	protected boolean matchesSubtypes(ResolvedType type) {
461
	protected boolean matchesSubtypes(ResolvedType type) {
429
		return true;
462
		return true;
430
	}
463
	}
431
	
464
432
	
433
	public boolean isStar() {
465
	public boolean isStar() {
434
		return true;
466
		return true;
435
	}
467
	}
436
	
468
437
	public String toString() { return "*"; }
469
	public String toString() {
438
	
470
		return "*";
471
	}
472
439
	public boolean equals(Object obj) {
473
	public boolean equals(Object obj) {
440
		return (obj instanceof AnyTypePattern);
474
		return (obj instanceof AnyTypePattern);
441
	}
475
	}
442
	
476
443
	public int hashCode() {
477
	public int hashCode() {
444
		return 37;
478
		return 37;
445
	}
479
	}
446
480
447
    public Object accept(PatternNodeVisitor visitor, Object data) {
481
	public Object accept(PatternNodeVisitor visitor, Object data) {
448
        return visitor.visit(this, data);
482
		return visitor.visit(this, data);
449
    }
483
	}
450
    
484
451
    public TypePattern parameterizeWith(Map arg0,World w) {
485
	public TypePattern parameterizeWith(Map arg0, World w) {
452
    	return this;
486
		return this;
453
    }
487
	}
454
}
488
}
455
489
456
/**
490
/**
457
 * This type represents a type pattern of '*' but with an annotation specified,
491
 * This type represents a type pattern of '*' but with an annotation specified, e.g. '@Color *'
458
 * e.g. '@Color *'
459
 */
492
 */
460
class AnyWithAnnotationTypePattern extends TypePattern {
493
class AnyWithAnnotationTypePattern extends TypePattern {
461
	
494
462
	public AnyWithAnnotationTypePattern(AnnotationTypePattern atp) {
495
	public AnyWithAnnotationTypePattern(AnnotationTypePattern atp) {
463
		super(false,false);
496
		super(false, false);
464
		annotationPattern = atp;
497
		annotationPattern = atp;
465
	}
498
	}
466
499
467
	public Object accept(PatternNodeVisitor visitor, Object data) {
500
	public Object accept(PatternNodeVisitor visitor, Object data) {
468
		return visitor.visit(this,data);
501
		return visitor.visit(this, data);
469
	}
502
	}
470
	
503
471
	protected boolean couldEverMatchSameTypesAs(TypePattern other) {
504
	protected boolean couldEverMatchSameTypesAs(TypePattern other) {
472
		return true;
505
		return true;
473
	}
506
	}
Lines 475-492 Link Here
475
	protected boolean matchesExactly(ResolvedType type) {
508
	protected boolean matchesExactly(ResolvedType type) {
476
		annotationPattern.resolve(type.getWorld());
509
		annotationPattern.resolve(type.getWorld());
477
		boolean b = false;
510
		boolean b = false;
478
		if (type.temporaryAnnotationTypes!=null) {
511
		if (type.temporaryAnnotationTypes != null) {
479
			b = annotationPattern.matches(type,type.temporaryAnnotationTypes).alwaysTrue();
512
			b = annotationPattern.matches(type, type.temporaryAnnotationTypes).alwaysTrue();
480
		} else {
513
		} else {
481
			b = annotationPattern.matches(type).alwaysTrue();
514
			b = annotationPattern.matches(type).alwaysTrue();
482
		}
515
		}
483
		return b;
516
		return b;
484
	}
517
	}
485
	
518
486
	
519
	/**
520
	 * Coming in here means we are looking at a pattern like "(@SomeAnnotation *)+" - so a type or any subtype that has the
521
	 * annotation SomeAnnotation (pr128664).
522
	 * 
523
	 * If we are matching on some type X, we first see if X is an exact match for our pattern. Then we look at the direct supertypes
524
	 * of X. The variant matchSubtypes() that involves two parameters is for when the type to match is different to the type against
525
	 * which the annotations are stored. This happens for parameter annotations where, temporarily during matching, the
526
	 * annotatedType is marked with any parameter annotations it has. That doesn't apply in the case we are dealing with here
527
	 * (AnyWithAnnotationTypePattern)
528
	 * 
529
	 */
530
	protected boolean matchesSubtypes(ResolvedType type) {
531
		if (matchesExactly(type)) {
532
			return true;
533
		}
534
		// pr124808
535
		Iterator typesIterator = null;
536
		if (type.isTypeVariableReference()) {
537
			typesIterator = ((TypeVariableReference) type).getTypeVariable().getFirstBound().resolve(type.getWorld())
538
					.getDirectSupertypes();
539
		} else {
540
			// pr223605
541
			if (type.isRawType()) {
542
				type = type.getGenericType();
543
			}
544
			typesIterator = type.getDirectSupertypes();
545
		}
546
547
		for (Iterator i = typesIterator; i.hasNext();) {
548
			ResolvedType supertype = (ResolvedType) i.next();
549
			if (matchesSubtypes(supertype, supertype)) {
550
				return true;
551
			}
552
		}
553
		return false;
554
	}
555
556
	protected boolean matchesSubtypes(ResolvedType superType, ResolvedType annotatedType) {
557
		if (matchesExactly(superType, annotatedType)) {
558
			return true;
559
		}
560
		// If an ITD is applied, it will be put onto the generic type, not the parameterized or raw form
561
		if (superType.isParameterizedType() || superType.isRawType()) {
562
			superType = superType.getGenericType();
563
		}
564
		// FuzzyBoolean ret = FuzzyBoolean.NO; // ??? -eh
565
		for (Iterator i = superType.getDirectSupertypes(); i.hasNext();) {
566
			ResolvedType superSuperType = (ResolvedType) i.next();
567
			if (matchesSubtypes(superSuperType, superSuperType))
568
				return true;
569
		}
570
		return false;
571
	}
572
487
	protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) {
573
	protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) {
488
		annotationPattern.resolve(type.getWorld());
574
		annotationPattern.resolve(type.getWorld());
489
		return annotationPattern.matches(annotatedType).alwaysTrue();		
575
		return annotationPattern.matches(annotatedType).alwaysTrue();
490
	}
576
	}
491
577
492
	public FuzzyBoolean matchesInstanceof(ResolvedType type) {
578
	public FuzzyBoolean matchesInstanceof(ResolvedType type) {
Lines 496-565 Link Here
496
		return FuzzyBoolean.MAYBE;
582
		return FuzzyBoolean.MAYBE;
497
	}
583
	}
498
584
499
	public TypePattern parameterizeWith(Map typeVariableMap,World w) {
585
	public TypePattern parameterizeWith(Map typeVariableMap, World w) {
500
		AnyWithAnnotationTypePattern ret = new AnyWithAnnotationTypePattern(this.annotationPattern.parameterizeWith(typeVariableMap,w));
586
		AnyWithAnnotationTypePattern ret = new AnyWithAnnotationTypePattern(this.annotationPattern.parameterizeWith(
587
				typeVariableMap, w));
501
		ret.copyLocationFrom(this);
588
		ret.copyLocationFrom(this);
502
		return ret;
589
		return ret;
503
	}
590
	}
504
	
591
505
	public void write(DataOutputStream s) throws IOException {
592
	public void write(DataOutputStream s) throws IOException {
506
		s.writeByte(TypePattern.ANY_WITH_ANNO);
593
		s.writeByte(TypePattern.ANY_WITH_ANNO);
507
		annotationPattern.write(s);
594
		annotationPattern.write(s);
508
		writeLocation(s);
595
		writeLocation(s);
596
		s.writeBoolean(includeSubtypes);
509
	}
597
	}
510
	
598
511
	public static TypePattern read(VersionedDataInputStream s,ISourceContext c) throws IOException {
599
	public static TypePattern read(VersionedDataInputStream s, ISourceContext c) throws IOException {
512
		 AnnotationTypePattern annPatt = AnnotationTypePattern.read(s,c);
600
		AnnotationTypePattern annPatt = AnnotationTypePattern.read(s, c);
513
		 AnyWithAnnotationTypePattern ret = new AnyWithAnnotationTypePattern(annPatt);
601
		AnyWithAnnotationTypePattern ret = new AnyWithAnnotationTypePattern(annPatt);
514
		 ret.readLocation(c, s);
602
		ret.readLocation(c, s);
515
		 return ret;
603
		ret.includeSubtypes = s.readBoolean();
604
		return ret;
516
	}
605
	}
517
606
518
//	public FuzzyBoolean matches(IType type, MatchKind kind) {
607
	// public FuzzyBoolean matches(IType type, MatchKind kind) {
519
//		return FuzzyBoolean.YES;
608
	// return FuzzyBoolean.YES;
520
//	}
609
	// }
521
610
522
	protected boolean matchesSubtypes(ResolvedType type) {
523
		return true;
524
	}
525
	
526
	public boolean isStar() {
611
	public boolean isStar() {
527
		return false;
612
		return false;
528
	}
613
	}
529
	
614
530
	public String toString() { return annotationPattern+" *"; }
615
	public String toString() {
531
	
616
		return annotationPattern + " *";
617
	}
618
532
	public boolean equals(Object obj) {
619
	public boolean equals(Object obj) {
533
		if  (!(obj instanceof AnyWithAnnotationTypePattern)) return false;
620
		if (!(obj instanceof AnyWithAnnotationTypePattern))
621
			return false;
534
		AnyWithAnnotationTypePattern awatp = (AnyWithAnnotationTypePattern) obj;
622
		AnyWithAnnotationTypePattern awatp = (AnyWithAnnotationTypePattern) obj;
535
		return (annotationPattern.equals(awatp.annotationPattern));
623
		return (annotationPattern.equals(awatp.annotationPattern));
536
	}
624
	}
537
	
625
538
	public int hashCode() {
626
	public int hashCode() {
539
		return annotationPattern.hashCode();
627
		return annotationPattern.hashCode();
540
	}
628
	}
541
}
629
}
542
630
543
class NoTypePattern extends TypePattern {
631
class NoTypePattern extends TypePattern {
544
	
632
545
	public NoTypePattern() {
633
	public NoTypePattern() {
546
		super(false,false,new TypePatternList());
634
		super(false, false, new TypePatternList());
547
	}
635
	}
548
636
549
	
637
	/*
550
	/* (non-Javadoc)
638
	 * (non-Javadoc)
639
	 * 
551
	 * @see org.aspectj.weaver.patterns.TypePattern#couldEverMatchSameTypesAs(org.aspectj.weaver.patterns.TypePattern)
640
	 * @see org.aspectj.weaver.patterns.TypePattern#couldEverMatchSameTypesAs(org.aspectj.weaver.patterns.TypePattern)
552
	 */
641
	 */
553
	protected boolean couldEverMatchSameTypesAs(TypePattern other) {
642
	protected boolean couldEverMatchSameTypesAs(TypePattern other) {
554
		return false;
643
		return false;
555
	}
644
	}
645
556
	/**
646
	/**
557
	 * @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType)
647
	 * @see org.aspectj.weaver.patterns.TypePattern#matchesExactly(IType)
558
	 */
648
	 */
559
	protected boolean matchesExactly(ResolvedType type) {
649
	protected boolean matchesExactly(ResolvedType type) {
560
		return false;
650
		return false;
561
	}
651
	}
562
	
652
563
	protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) {
653
	protected boolean matchesExactly(ResolvedType type, ResolvedType annotatedType) {
564
		return false;
654
		return false;
565
	}
655
	}
Lines 581-624 Link Here
581
	/**
671
	/**
582
	 * @see org.aspectj.weaver.patterns.TypePattern#matches(IType, MatchKind)
672
	 * @see org.aspectj.weaver.patterns.TypePattern#matches(IType, MatchKind)
583
	 */
673
	 */
584
//	public FuzzyBoolean matches(IType type, MatchKind kind) {
674
	// public FuzzyBoolean matches(IType type, MatchKind kind) {
585
//		return FuzzyBoolean.YES;
675
	// return FuzzyBoolean.YES;
586
//	}
676
	// }
587
588
	/**
677
	/**
589
	 * @see org.aspectj.weaver.patterns.TypePattern#matchesSubtypes(IType)
678
	 * @see org.aspectj.weaver.patterns.TypePattern#matchesSubtypes(IType)
590
	 */
679
	 */
591
	protected boolean matchesSubtypes(ResolvedType type) {
680
	protected boolean matchesSubtypes(ResolvedType type) {
592
		return false;
681
		return false;
593
	}
682
	}
594
	
683
595
	
596
	public boolean isStar() {
684
	public boolean isStar() {
597
		return false;
685
		return false;
598
	}
686
	}
599
	
687
600
	public String toString() { return "<nothing>"; }//FIXME AV - bad! toString() cannot be parsed back (not idempotent)
688
	public String toString() {
601
	
689
		return "<nothing>";
602
	/* (non-Javadoc)
690
	}// FIXME AV - bad! toString() cannot be parsed back (not idempotent)
691
692
	/*
693
	 * (non-Javadoc)
694
	 * 
603
	 * @see java.lang.Object#equals(java.lang.Object)
695
	 * @see java.lang.Object#equals(java.lang.Object)
604
	 */
696
	 */
605
	public boolean equals(Object obj) {
697
	public boolean equals(Object obj) {
606
		return (obj instanceof NoTypePattern);
698
		return (obj instanceof NoTypePattern);
607
	}
699
	}
608
	
700
609
	/* (non-Javadoc)
701
	/*
702
	 * (non-Javadoc)
703
	 * 
610
	 * @see java.lang.Object#hashCode()
704
	 * @see java.lang.Object#hashCode()
611
	 */
705
	 */
612
	public int hashCode() {
706
	public int hashCode() {
613
		return 17 * 37 * 37;
707
		return 17 * 37 * 37;
614
	}
708
	}
615
709
616
    public Object accept(PatternNodeVisitor visitor, Object data) {
710
	public Object accept(PatternNodeVisitor visitor, Object data) {
617
        return visitor.visit(this, data);
711
		return visitor.visit(this, data);
618
    }
712
	}
619
    
620
    public TypePattern parameterizeWith(Map arg0,World w) {
621
    	return this;
622
    }
623
}
624
713
714
	public TypePattern parameterizeWith(Map arg0, World w) {
715
		return this;
716
	}
717
}
(-)src/org/aspectj/weaver/patterns/SignaturePattern.java (-415 / +427 lines)
Lines 10-16 Link Here
10
 *     PARC     initial implementation 
10
 *     PARC     initial implementation 
11
 * ******************************************************************/
11
 * ******************************************************************/
12
12
13
14
package org.aspectj.weaver.patterns;
13
package org.aspectj.weaver.patterns;
15
14
16
import java.io.DataOutputStream;
15
import java.io.DataOutputStream;
Lines 25-31 Link Here
25
24
26
import org.aspectj.bridge.ISourceLocation;
25
import org.aspectj.bridge.ISourceLocation;
27
import org.aspectj.util.FuzzyBoolean;
26
import org.aspectj.util.FuzzyBoolean;
28
import org.aspectj.weaver.AjAttribute; 
27
import org.aspectj.weaver.AjAttribute;
29
import org.aspectj.weaver.AjcMemberMaker;
28
import org.aspectj.weaver.AjcMemberMaker;
30
import org.aspectj.weaver.AnnotationTargetKind;
29
import org.aspectj.weaver.AnnotationTargetKind;
31
import org.aspectj.weaver.ConcreteTypeMunger;
30
import org.aspectj.weaver.ConcreteTypeMunger;
Lines 40-62 Link Here
40
import org.aspectj.weaver.VersionedDataInputStream;
39
import org.aspectj.weaver.VersionedDataInputStream;
41
import org.aspectj.weaver.World;
40
import org.aspectj.weaver.World;
42
41
43
44
public class SignaturePattern extends PatternNode {
42
public class SignaturePattern extends PatternNode {
45
	private MemberKind kind;
43
	private MemberKind kind;
46
	private ModifiersPattern modifiers;
44
	private ModifiersPattern modifiers;
47
	private TypePattern returnType;
45
	private TypePattern returnType;
48
    private TypePattern declaringType;
46
	private TypePattern declaringType;
49
	private NamePattern name;
47
	private NamePattern name;
50
    private TypePatternList parameterTypes;
48
	private TypePatternList parameterTypes;
51
    private ThrowsPattern throwsPattern;
49
	private ThrowsPattern throwsPattern;
52
    private AnnotationTypePattern annotationPattern;
50
	private AnnotationTypePattern annotationPattern;
53
    private transient int hashcode = -1;
51
	private transient int hashcode = -1;
54
    	
52
55
	public SignaturePattern(MemberKind kind, ModifiersPattern modifiers,
53
	public SignaturePattern(MemberKind kind, ModifiersPattern modifiers, TypePattern returnType, TypePattern declaringType,
56
	                         TypePattern returnType, TypePattern declaringType,
54
			NamePattern name, TypePatternList parameterTypes, ThrowsPattern throwsPattern, AnnotationTypePattern annotationPattern) {
57
	                         NamePattern name, TypePatternList parameterTypes,
58
	                         ThrowsPattern throwsPattern,
59
							 AnnotationTypePattern annotationPattern) {
60
		this.kind = kind;
55
		this.kind = kind;
61
		this.modifiers = modifiers;
56
		this.modifiers = modifiers;
62
		this.returnType = returnType;
57
		this.returnType = returnType;
Lines 66-149 Link Here
66
		this.throwsPattern = throwsPattern;
61
		this.throwsPattern = throwsPattern;
67
		this.annotationPattern = annotationPattern;
62
		this.annotationPattern = annotationPattern;
68
	}
63
	}
69
	
64
70
	
65
	public SignaturePattern resolveBindings(IScope scope, Bindings bindings) {
71
    public SignaturePattern resolveBindings(IScope scope, Bindings bindings) { 
72
		if (returnType != null) {
66
		if (returnType != null) {
73
			returnType = returnType.resolveBindings(scope, bindings, false, false);
67
			returnType = returnType.resolveBindings(scope, bindings, false, false);
74
			checkForIncorrectTargetKind(returnType,scope,false);
68
			checkForIncorrectTargetKind(returnType, scope, false);
75
		} 
69
		}
76
		if (declaringType != null) {
70
		if (declaringType != null) {
77
			declaringType = declaringType.resolveBindings(scope, bindings, false, false);
71
			declaringType = declaringType.resolveBindings(scope, bindings, false, false);
78
			checkForIncorrectTargetKind(declaringType,scope,false);
72
			checkForIncorrectTargetKind(declaringType, scope, false);
79
		}
73
		}
80
		if (parameterTypes != null) {
74
		if (parameterTypes != null) {
81
			parameterTypes = parameterTypes.resolveBindings(scope, bindings, false, false);
75
			parameterTypes = parameterTypes.resolveBindings(scope, bindings, false, false);
82
			checkForIncorrectTargetKind(parameterTypes,scope,false,true);
76
			checkForIncorrectTargetKind(parameterTypes, scope, false, true);
83
		}
77
		}
84
		if (throwsPattern != null) {
78
		if (throwsPattern != null) {
85
			throwsPattern = throwsPattern.resolveBindings(scope, bindings);
79
			throwsPattern = throwsPattern.resolveBindings(scope, bindings);
86
			if (throwsPattern.getForbidden().getTypePatterns().length > 0 
80
			if (throwsPattern.getForbidden().getTypePatterns().length > 0
87
					|| throwsPattern.getRequired().getTypePatterns().length > 0) {
81
					|| throwsPattern.getRequired().getTypePatterns().length > 0) {
88
				checkForIncorrectTargetKind(throwsPattern,scope,false);				
82
				checkForIncorrectTargetKind(throwsPattern, scope, false);
89
			}
83
			}
90
		}
84
		}
91
		if (annotationPattern != null) {
85
		if (annotationPattern != null) {
92
			annotationPattern = annotationPattern.resolveBindings(scope,bindings,false);
86
			annotationPattern = annotationPattern.resolveBindings(scope, bindings, false);
93
			checkForIncorrectTargetKind(annotationPattern,scope,true);
87
			checkForIncorrectTargetKind(annotationPattern, scope, true);
94
		}
88
		}
95
		hashcode =-1;
89
		hashcode = -1;
96
    	return this;
90
		return this;
97
    }
91
	}
98
    private void checkForIncorrectTargetKind(PatternNode patternNode, IScope scope, boolean targetsOtherThanTypeAllowed) {
92
99
    	checkForIncorrectTargetKind(patternNode, scope, targetsOtherThanTypeAllowed, false);
93
	private void checkForIncorrectTargetKind(PatternNode patternNode, IScope scope, boolean targetsOtherThanTypeAllowed) {
100
    	
94
		checkForIncorrectTargetKind(patternNode, scope, targetsOtherThanTypeAllowed, false);
101
    }
95
102
    
96
	}
103
    // bug 115252 - adding an xlint warning if the annnotation target type is 
97
104
    // wrong. This logic, or similar, may have to be applied elsewhere in the case
98
	// bug 115252 - adding an xlint warning if the annnotation target type is
105
    // of pointcuts which don't go through SignaturePattern.resolveBindings(..)
99
	// wrong. This logic, or similar, may have to be applied elsewhere in the case
106
    private void checkForIncorrectTargetKind(PatternNode patternNode, IScope scope, boolean targetsOtherThanTypeAllowed, boolean parameterTargettingAnnotationsAllowed) {
100
	// of pointcuts which don't go through SignaturePattern.resolveBindings(..)
107
    	// return if we're not in java5 mode, if the unmatchedTargetKind Xlint
101
	private void checkForIncorrectTargetKind(PatternNode patternNode, IScope scope, boolean targetsOtherThanTypeAllowed,
108
    	// warning has been turned off, or if the patternNode is *
102
			boolean parameterTargettingAnnotationsAllowed) {
109
    	if (!scope.getWorld().isInJava5Mode()
103
		// return if we're not in java5 mode, if the unmatchedTargetKind Xlint
110
    			|| scope.getWorld().getLint().unmatchedTargetKind == null
104
		// warning has been turned off, or if the patternNode is *
111
    			|| (patternNode instanceof AnyTypePattern)) {
105
		if (!scope.getWorld().isInJava5Mode() || scope.getWorld().getLint().unmatchedTargetKind == null
106
				|| (patternNode instanceof AnyTypePattern)) {
112
			return;
107
			return;
113
		}
108
		}
114
		if (patternNode instanceof ExactAnnotationTypePattern) {
109
		if (patternNode instanceof ExactAnnotationTypePattern) {
115
			ResolvedType resolvedType = ((ExactAnnotationTypePattern)patternNode).getAnnotationType().resolve(scope.getWorld());
110
			ResolvedType resolvedType = ((ExactAnnotationTypePattern) patternNode).getAnnotationType().resolve(scope.getWorld());
116
			if (targetsOtherThanTypeAllowed) {
111
			if (targetsOtherThanTypeAllowed) {
117
				AnnotationTargetKind[] targetKinds = resolvedType.getAnnotationTargetKinds();
112
				AnnotationTargetKind[] targetKinds = resolvedType.getAnnotationTargetKinds();
118
				if (targetKinds == null) return;
113
				if (targetKinds == null)
119
				reportUnmatchedTargetKindMessage(targetKinds,patternNode,scope,true);
114
					return;
115
				reportUnmatchedTargetKindMessage(targetKinds, patternNode, scope, true);
120
			} else if (!targetsOtherThanTypeAllowed && !resolvedType.canAnnotationTargetType()) {
116
			} else if (!targetsOtherThanTypeAllowed && !resolvedType.canAnnotationTargetType()) {
121
				// everything is incorrect since we've already checked whether we have the TYPE target annotation
117
				// everything is incorrect since we've already checked whether we have the TYPE target annotation
122
				AnnotationTargetKind[] targetKinds = resolvedType.getAnnotationTargetKinds();
118
				AnnotationTargetKind[] targetKinds = resolvedType.getAnnotationTargetKinds();
123
				if (targetKinds == null) return;
119
				if (targetKinds == null)
124
				reportUnmatchedTargetKindMessage(targetKinds,patternNode,scope,false);
120
					return;
121
				reportUnmatchedTargetKindMessage(targetKinds, patternNode, scope, false);
125
			}
122
			}
126
		} else {
123
		} else {
127
			TypePatternVisitor visitor = new TypePatternVisitor(scope,targetsOtherThanTypeAllowed,parameterTargettingAnnotationsAllowed);
124
			TypePatternVisitor visitor = new TypePatternVisitor(scope, targetsOtherThanTypeAllowed,
128
			patternNode.traverse(visitor,null);
125
					parameterTargettingAnnotationsAllowed);
126
			patternNode.traverse(visitor, null);
129
			if (visitor.containedIncorrectTargetKind()) {
127
			if (visitor.containedIncorrectTargetKind()) {
130
				Set keys = visitor.getIncorrectTargetKinds().keySet();				
128
				Set keys = visitor.getIncorrectTargetKinds().keySet();
131
				for (Iterator iter = keys.iterator(); iter.hasNext();) {
129
				for (Iterator iter = keys.iterator(); iter.hasNext();) {
132
					PatternNode node = (PatternNode)iter.next();
130
					PatternNode node = (PatternNode) iter.next();
133
					AnnotationTargetKind[] targetKinds =  (AnnotationTargetKind[]) visitor.getIncorrectTargetKinds().get(node);
131
					AnnotationTargetKind[] targetKinds = (AnnotationTargetKind[]) visitor.getIncorrectTargetKinds().get(node);
134
					reportUnmatchedTargetKindMessage(targetKinds,node,scope,false);
132
					reportUnmatchedTargetKindMessage(targetKinds, node, scope, false);
135
				}
133
				}
136
			}
134
			}
137
		}
135
		}
138
    }
136
	}
139
    
137
140
    private void reportUnmatchedTargetKindMessage(
138
	private void reportUnmatchedTargetKindMessage(AnnotationTargetKind[] annotationTargetKinds, PatternNode node, IScope scope,
141
    		AnnotationTargetKind[] annotationTargetKinds,  
139
			boolean checkMatchesMemberKindName) {
142
    		PatternNode node,
140
		StringBuffer targetNames = new StringBuffer("{");
143
    		IScope scope,
141
		for (int i = 0; i < annotationTargetKinds.length; i++) {
144
    		boolean checkMatchesMemberKindName) {
145
    	StringBuffer targetNames = new StringBuffer("{");
146
    	for (int i = 0; i < annotationTargetKinds.length; i++) {
147
			AnnotationTargetKind targetKind = annotationTargetKinds[i];
142
			AnnotationTargetKind targetKind = annotationTargetKinds[i];
148
			if (checkMatchesMemberKindName && kind.getName().equals(targetKind.getName())) {
143
			if (checkMatchesMemberKindName && kind.getName().equals(targetKind.getName())) {
149
				return;
144
				return;
Lines 154-265 Link Here
154
				targetNames.append("ElementType." + targetKind.getName() + "}");
149
				targetNames.append("ElementType." + targetKind.getName() + "}");
155
			}
150
			}
156
		}
151
		}
157
		scope.getWorld().getLint().unmatchedTargetKind.signal(new String[] {node.toString(),targetNames.toString()}, getSourceLocation(), new ISourceLocation[0]);
152
		scope.getWorld().getLint().unmatchedTargetKind.signal(new String[] { node.toString(), targetNames.toString() },
158
    }
153
				getSourceLocation(), new ISourceLocation[0]);
159
    
154
	}
160
    /**
155
161
     * Class which visits the nodes in the TypePattern tree until an
156
	/**
162
     * ExactTypePattern is found. Once this is found it creates a new
157
	 * Class which visits the nodes in the TypePattern tree until an ExactTypePattern is found. Once this is found it creates a new
163
     * ExactAnnotationTypePattern and checks whether the targetKind
158
	 * ExactAnnotationTypePattern and checks whether the targetKind (created via the @Target annotation) matches ElementType.TYPE if
164
     * (created via the @Target annotation) matches ElementType.TYPE if
159
	 * this is the only target kind which is allowed, or matches the signature pattern kind if there is no restriction.
165
     * this is the only target kind which is allowed, or matches the
160
	 */
166
     * signature pattern kind if there is no restriction.
161
	private class TypePatternVisitor extends AbstractPatternNodeVisitor {
167
     */
162
168
    private class TypePatternVisitor extends AbstractPatternNodeVisitor {
163
		private IScope scope;
169
164
		private Map incorrectTargetKinds /* PatternNode -> AnnotationTargetKind[] */= new HashMap();
170
    	private IScope scope;
165
		private boolean targetsOtherThanTypeAllowed;
171
    	private Map incorrectTargetKinds /* PatternNode -> AnnotationTargetKind[] */ = new HashMap();
172
    	private boolean targetsOtherThanTypeAllowed;
173
		private boolean parameterTargettingAnnotationsAllowed;
166
		private boolean parameterTargettingAnnotationsAllowed;
174
167
175
    	/**
168
		/**
176
    	 * @param requiredTarget - the signature pattern Kind
169
		 * @param requiredTarget - the signature pattern Kind
177
    	 * @param scope
170
		 * @param scope
178
    	 * @param parameterTargettingAnnotationsAllowed 
171
		 * @param parameterTargettingAnnotationsAllowed
179
    	 */
172
		 */
180
    	public TypePatternVisitor(IScope scope, boolean targetsOtherThanTypeAllowed, boolean parameterTargettingAnnotationsAllowed) {
173
		public TypePatternVisitor(IScope scope, boolean targetsOtherThanTypeAllowed, boolean parameterTargettingAnnotationsAllowed) {
181
    		this.scope = scope;
174
			this.scope = scope;
182
    		this.targetsOtherThanTypeAllowed = targetsOtherThanTypeAllowed;
175
			this.targetsOtherThanTypeAllowed = targetsOtherThanTypeAllowed;
183
    		this.parameterTargettingAnnotationsAllowed = parameterTargettingAnnotationsAllowed;
176
			this.parameterTargettingAnnotationsAllowed = parameterTargettingAnnotationsAllowed;
184
    	}
177
		}
185
    	
178
186
    	public Object visit(WildAnnotationTypePattern node, Object data) {
179
		public Object visit(WildAnnotationTypePattern node, Object data) {
187
    		node.getTypePattern().accept(this,data);
180
			node.getTypePattern().accept(this, data);
188
    		return node;
181
			return node;
189
    	}
182
		}
190
    	
183
191
    	/**
184
		/**
192
    	 * Do the ExactAnnotationTypePatterns have the incorrect target?
185
		 * Do the ExactAnnotationTypePatterns have the incorrect target?
193
    	 */
186
		 */
194
    	public Object visit(ExactAnnotationTypePattern node, Object data) {
187
		public Object visit(ExactAnnotationTypePattern node, Object data) {
195
    		ResolvedType resolvedType = node.getAnnotationType().resolve(scope.getWorld());
188
			ResolvedType resolvedType = node.getAnnotationType().resolve(scope.getWorld());
196
			if (targetsOtherThanTypeAllowed) {
189
			if (targetsOtherThanTypeAllowed) {
197
				AnnotationTargetKind[] targetKinds = resolvedType.getAnnotationTargetKinds();
190
				AnnotationTargetKind[] targetKinds = resolvedType.getAnnotationTargetKinds();
198
				if (targetKinds == null) return data;
191
				if (targetKinds == null)
192
					return data;
199
				List incorrectTargets = new ArrayList();
193
				List incorrectTargets = new ArrayList();
200
				for (int i = 0; i < targetKinds.length; i++) {
194
				for (int i = 0; i < targetKinds.length; i++) {
201
					if (targetKinds[i].getName().equals(kind.getName()) ||
195
					if (targetKinds[i].getName().equals(kind.getName())
202
							(targetKinds[i].getName().equals("PARAMETER") && node.isForParameterAnnotationMatch())
196
							|| (targetKinds[i].getName().equals("PARAMETER") && node.isForParameterAnnotationMatch())) {
203
							) {
204
						return data;
197
						return data;
205
					}
198
					}
206
					incorrectTargets.add(targetKinds[i]);
199
					incorrectTargets.add(targetKinds[i]);
207
				}
200
				}
208
				if (incorrectTargets.isEmpty()) return data;
201
				if (incorrectTargets.isEmpty())
202
					return data;
209
				AnnotationTargetKind[] kinds = new AnnotationTargetKind[incorrectTargets.size()];
203
				AnnotationTargetKind[] kinds = new AnnotationTargetKind[incorrectTargets.size()];
210
				incorrectTargetKinds.put(node,(AnnotationTargetKind[]) incorrectTargets.toArray(kinds));	
204
				incorrectTargetKinds.put(node, (AnnotationTargetKind[]) incorrectTargets.toArray(kinds));
211
			} else if (!targetsOtherThanTypeAllowed && !resolvedType.canAnnotationTargetType()) {
205
			} else if (!targetsOtherThanTypeAllowed && !resolvedType.canAnnotationTargetType()) {
212
				AnnotationTargetKind[] targetKinds = resolvedType.getAnnotationTargetKinds();
206
				AnnotationTargetKind[] targetKinds = resolvedType.getAnnotationTargetKinds();
213
				if (targetKinds == null) return data;
207
				if (targetKinds == null)
208
					return data;
214
				// exception here is if parameter annotations are allowed
209
				// exception here is if parameter annotations are allowed
215
				if (parameterTargettingAnnotationsAllowed) {
210
				if (parameterTargettingAnnotationsAllowed) {
216
					for (int i = 0; i < targetKinds.length; i++) {
211
					for (int i = 0; i < targetKinds.length; i++) {
217
						AnnotationTargetKind annotationTargetKind = targetKinds[i];
212
						AnnotationTargetKind annotationTargetKind = targetKinds[i];
218
						if (annotationTargetKind.getName().equals("PARAMETER")  && node.isForParameterAnnotationMatch()) return data;
213
						if (annotationTargetKind.getName().equals("PARAMETER") && node.isForParameterAnnotationMatch())
214
							return data;
219
					}
215
					}
220
				}
216
				}
221
				incorrectTargetKinds.put(node,targetKinds);
217
				incorrectTargetKinds.put(node, targetKinds);
222
			}
218
			}
223
    		return data;
219
			return data;
224
    	}
220
		}
225
    	
221
226
    	public Object visit(ExactTypePattern node, Object data) {
222
		public Object visit(ExactTypePattern node, Object data) {
227
    		ExactAnnotationTypePattern eatp =  new ExactAnnotationTypePattern(node.getExactType().resolve(scope.getWorld()),null);
223
			ExactAnnotationTypePattern eatp = new ExactAnnotationTypePattern(node.getExactType().resolve(scope.getWorld()), null);
228
    		eatp.accept(this,data);		
224
			eatp.accept(this, data);
229
    		return data;
225
			return data;
230
    	}
226
		}
231
    	
227
232
    	public Object visit(AndTypePattern node, Object data) {
228
		public Object visit(AndTypePattern node, Object data) {
233
    		node.getLeft().accept(this,data);
229
			node.getLeft().accept(this, data);
234
    		node.getRight().accept(this,data);
230
			node.getRight().accept(this, data);
235
    		return node;
231
			return node;
236
    	}
232
		}
237
233
238
    	public Object visit(OrTypePattern node, Object data) {
234
		public Object visit(OrTypePattern node, Object data) {
239
    		node.getLeft().accept(this,data);
235
			node.getLeft().accept(this, data);
240
    		node.getRight().accept(this,data);
236
			node.getRight().accept(this, data);
241
    		return node;
237
			return node;
242
    	}
238
		}
243
239
244
    	public Object visit(AnyWithAnnotationTypePattern node, Object data) {
240
		public Object visit(AnyWithAnnotationTypePattern node, Object data) {
245
    		node.getAnnotationPattern().accept(this,data);
241
			node.getAnnotationPattern().accept(this, data);
246
    		return node;
242
			return node;
247
    	}
243
		}
248
    	
244
249
    	public boolean containedIncorrectTargetKind() {
245
		public boolean containedIncorrectTargetKind() {
250
    		return (incorrectTargetKinds.size() != 0);
246
			return (incorrectTargetKinds.size() != 0);
251
    	}
247
		}
252
    	
248
253
    	public Map getIncorrectTargetKinds() {
249
		public Map getIncorrectTargetKinds() {
254
    		return incorrectTargetKinds;
250
			return incorrectTargetKinds;
255
    	}
251
		}
256
    }
252
	}
257
    
253
258
    
259
	public void postRead(ResolvedType enclosingType) {
254
	public void postRead(ResolvedType enclosingType) {
260
		if (returnType != null) {
255
		if (returnType != null) {
261
			returnType.postRead(enclosingType);
256
			returnType.postRead(enclosingType);
262
		} 
257
		}
263
		if (declaringType != null) {
258
		if (declaringType != null) {
264
			declaringType.postRead(enclosingType);
259
			declaringType.postRead(enclosingType);
265
		}
260
		}
Lines 267-303 Link Here
267
			parameterTypes.postRead(enclosingType);
262
			parameterTypes.postRead(enclosingType);
268
		}
263
		}
269
	}
264
	}
270
	
265
271
	/**
266
	/**
272
	 * return a copy of this signature pattern in which every type variable reference
267
	 * return a copy of this signature pattern in which every type variable reference is replaced by the corresponding entry in the
273
	 * is replaced by the corresponding entry in the map.
268
	 * map.
274
	 */
269
	 */
275
	public SignaturePattern parameterizeWith(Map typeVariableMap,World w) {
270
	public SignaturePattern parameterizeWith(Map typeVariableMap, World w) {
276
		SignaturePattern ret = new SignaturePattern(
271
		SignaturePattern ret = new SignaturePattern(kind, modifiers, returnType.parameterizeWith(typeVariableMap, w), declaringType
277
						kind,
272
				.parameterizeWith(typeVariableMap, w), name, parameterTypes.parameterizeWith(typeVariableMap, w), throwsPattern
278
						modifiers,
273
				.parameterizeWith(typeVariableMap, w), annotationPattern.parameterizeWith(typeVariableMap, w));
279
						returnType.parameterizeWith(typeVariableMap,w),
280
						declaringType.parameterizeWith(typeVariableMap,w),
281
						name,
282
						parameterTypes.parameterizeWith(typeVariableMap,w),
283
						throwsPattern.parameterizeWith(typeVariableMap,w),
284
						annotationPattern.parameterizeWith(typeVariableMap,w));
285
		ret.copyLocationFrom(this);
274
		ret.copyLocationFrom(this);
286
		return ret;
275
		return ret;
287
	}
276
	}
288
	
277
289
	public boolean matches(Member joinPointSignature, World world, boolean allowBridgeMethods) {
278
	public boolean matches(Member joinPointSignature, World world, boolean allowBridgeMethods) {
290
		// fail (or succeed!) fast tests...
279
		// fail (or succeed!) fast tests...
291
		if (joinPointSignature == null) return false;
280
		if (joinPointSignature == null)
292
		if (kind != joinPointSignature.getKind()) return false;
281
			return false;
293
		if (kind == Member.ADVICE) return true;
282
		if (kind != joinPointSignature.getKind())
294
		
283
			return false;
284
		if (kind == Member.ADVICE)
285
			return true;
286
295
		// do the hard work then...
287
		// do the hard work then...
296
		boolean subjectMatch = true;
288
		boolean subjectMatch = true;
297
		Iterator candidateMatches = joinPointSignature.getJoinPointSignatures(world);
289
		Iterator candidateMatches = joinPointSignature.getJoinPointSignatures(world);
298
		while(candidateMatches.hasNext()) {
290
		while (candidateMatches.hasNext()) {
299
			JoinPointSignature aSig = (JoinPointSignature) candidateMatches.next();
291
			JoinPointSignature aSig = (JoinPointSignature) candidateMatches.next();
300
			FuzzyBoolean matchResult = matchesExactly(aSig,world,allowBridgeMethods,subjectMatch); 
292
			FuzzyBoolean matchResult = matchesExactly(aSig, world, allowBridgeMethods, subjectMatch);
301
			if (matchResult.alwaysTrue()) {
293
			if (matchResult.alwaysTrue()) {
302
				return true;
294
				return true;
303
			} else if (matchResult.alwaysFalse()) {
295
			} else if (matchResult.alwaysFalse()) {
Lines 308-369 Link Here
308
		}
300
		}
309
		return false;
301
		return false;
310
	}
302
	}
311
	
303
312
	// Does this pattern match this exact signature (no declaring type mucking about
304
	// Does this pattern match this exact signature (no declaring type mucking about
313
	// or chasing up the hierarchy)
305
	// or chasing up the hierarchy)
314
	// return YES if it does, NO if it doesn't and no ancester member could match either,
306
	// return YES if it does, NO if it doesn't and no ancester member could match either,
315
	// and MAYBE if it doesn't but an ancester member could.
307
	// and MAYBE if it doesn't but an ancester member could.
316
	private FuzzyBoolean matchesExactly(JoinPointSignature aMember, World inAWorld, boolean allowBridgeMethods,boolean subjectMatch) {
308
	private FuzzyBoolean matchesExactly(JoinPointSignature aMember, World inAWorld, boolean allowBridgeMethods, boolean subjectMatch) {
317
		// Java5 introduces bridge methods, we match a call to them but nothing else...
309
		// Java5 introduces bridge methods, we match a call to them but nothing else...
318
		if (aMember.isBridgeMethod() && !allowBridgeMethods) {
310
		if (aMember.isBridgeMethod() && !allowBridgeMethods) {
319
			return FuzzyBoolean.MAYBE;
311
			return FuzzyBoolean.MAYBE;
320
		}
312
		}
321
			
313
322
		// modifiers match on the *subject*
314
		// modifiers match on the *subject*
323
		if (subjectMatch && !modifiers.matches(aMember.getModifiers())) {
315
		if (subjectMatch && !modifiers.matches(aMember.getModifiers())) {
324
			return FuzzyBoolean.NO;
316
			return FuzzyBoolean.NO;
325
//			if (aMember.isPrivate()) return FuzzyBoolean.NO;
317
			// if (aMember.isPrivate()) return FuzzyBoolean.NO;
326
//			else return FuzzyBoolean.MAYBE;
318
			// else return FuzzyBoolean.MAYBE;
327
		}
319
		}
328
		
320
329
		
330
		FuzzyBoolean matchesIgnoringAnnotations = FuzzyBoolean.YES;
321
		FuzzyBoolean matchesIgnoringAnnotations = FuzzyBoolean.YES;
331
		if (kind == Member.STATIC_INITIALIZATION) {
322
		if (kind == Member.STATIC_INITIALIZATION) {
332
			matchesIgnoringAnnotations = matchesExactlyStaticInitialization(aMember, inAWorld);
323
			matchesIgnoringAnnotations = matchesExactlyStaticInitialization(aMember, inAWorld);
333
		} else if (kind == Member.FIELD) {
324
		} else if (kind == Member.FIELD) {
334
			matchesIgnoringAnnotations = matchesExactlyField(aMember,inAWorld);
325
			matchesIgnoringAnnotations = matchesExactlyField(aMember, inAWorld);
335
		} else if (kind == Member.METHOD) {
326
		} else if (kind == Member.METHOD) {
336
			matchesIgnoringAnnotations = matchesExactlyMethod(aMember,inAWorld, subjectMatch);
327
			matchesIgnoringAnnotations = matchesExactlyMethod(aMember, inAWorld, subjectMatch);
337
		} else if (kind == Member.CONSTRUCTOR) {
328
		} else if (kind == Member.CONSTRUCTOR) {
338
			matchesIgnoringAnnotations = matchesExactlyConstructor(aMember, inAWorld);
329
			matchesIgnoringAnnotations = matchesExactlyConstructor(aMember, inAWorld);
339
		}
330
		}
340
		if (matchesIgnoringAnnotations.alwaysFalse()) return FuzzyBoolean.NO;
331
		if (matchesIgnoringAnnotations.alwaysFalse())
341
		
332
			return FuzzyBoolean.NO;
333
342
		// why did Adrian put this comment in:
334
		// why did Adrian put this comment in:
343
		// annotations match on the *subject* 
335
		// annotations match on the *subject*
344
		// surely you never want execution(@Something * *(..)) to match something just because
336
		// surely you never want execution(@Something * *(..)) to match something just because
345
		// it is a secondary join point signature for a join point and doesn't have the annotation?
337
		// it is a secondary join point signature for a join point and doesn't have the annotation?
346
		// pr239441
338
		// pr239441
347
		if (matchesIgnoringAnnotations.alwaysTrue()) {
339
		if (matchesIgnoringAnnotations.alwaysTrue()) {
348
			return matchesAnnotations(aMember,inAWorld);
340
			return matchesAnnotations(aMember, inAWorld);
349
		} else {
341
		} else {
350
			return matchesIgnoringAnnotations;
342
			return matchesIgnoringAnnotations;
351
		}
343
		}
352
		
344
353
	}
345
	}
354
	
346
355
	/**
347
	/**
356
	 * Matches on declaring type
348
	 * Matches on declaring type
357
	 */
349
	 */
358
	private FuzzyBoolean matchesExactlyStaticInitialization(JoinPointSignature aMember,World world) {
350
	private FuzzyBoolean matchesExactlyStaticInitialization(JoinPointSignature aMember, World world) {
359
		return FuzzyBoolean.fromBoolean(declaringType.matchesStatically(aMember.getDeclaringType().resolve(world)));
351
		return FuzzyBoolean.fromBoolean(declaringType.matchesStatically(aMember.getDeclaringType().resolve(world)));
360
	}
352
	}
361
	
353
362
	/**
354
	/**
363
	 * Matches on name, declaring type, field type
355
	 * Matches on name, declaring type, field type
364
	 */
356
	 */
365
	private FuzzyBoolean matchesExactlyField(JoinPointSignature aField, World world) {
357
	private FuzzyBoolean matchesExactlyField(JoinPointSignature aField, World world) {
366
		if (!name.matches(aField.getName())) return FuzzyBoolean.NO;
358
		if (!name.matches(aField.getName()))
359
			return FuzzyBoolean.NO;
367
		ResolvedType fieldDeclaringType = aField.getDeclaringType().resolve(world);
360
		ResolvedType fieldDeclaringType = aField.getDeclaringType().resolve(world);
368
		if (!declaringType.matchesStatically(fieldDeclaringType)) {
361
		if (!declaringType.matchesStatically(fieldDeclaringType)) {
369
			return FuzzyBoolean.MAYBE;
362
			return FuzzyBoolean.MAYBE;
Lines 378-393 Link Here
378
		// passed all the guards...
371
		// passed all the guards...
379
		return FuzzyBoolean.YES;
372
		return FuzzyBoolean.YES;
380
	}
373
	}
381
	
374
382
	/**
375
	/**
383
	 * Matches on name, declaring type, return type, parameter types, throws types
376
	 * Matches on name, declaring type, return type, parameter types, throws types
384
	 */
377
	 */
385
	private FuzzyBoolean matchesExactlyMethod(JoinPointSignature aMethod, World world, boolean subjectMatch) {
378
	private FuzzyBoolean matchesExactlyMethod(JoinPointSignature aMethod, World world, boolean subjectMatch) {
386
		if (!name.matches(aMethod.getName())) return FuzzyBoolean.NO;
379
		if (!name.matches(aMethod.getName()))
380
			return FuzzyBoolean.NO;
387
		// Check the throws pattern
381
		// Check the throws pattern
388
		if (subjectMatch && !throwsPattern.matches(aMethod.getExceptions(), world)) return FuzzyBoolean.NO;
382
		if (subjectMatch && !throwsPattern.matches(aMethod.getExceptions(), world))
389
		
383
			return FuzzyBoolean.NO;
390
		if (!declaringType.matchesStatically(aMethod.getDeclaringType().resolve(world))) return FuzzyBoolean.MAYBE;
384
385
		if (!declaringType.matchesStatically(aMethod.getDeclaringType().resolve(world)))
386
			return FuzzyBoolean.MAYBE;
391
		if (!returnType.matchesStatically(aMethod.getReturnType().resolve(world))) {
387
		if (!returnType.matchesStatically(aMethod.getReturnType().resolve(world))) {
392
			// looking bad, but there might be parameterization to consider...
388
			// looking bad, but there might be parameterization to consider...
393
			if (!returnType.matchesStatically(aMethod.getGenericReturnType().resolve(world))) {
389
			if (!returnType.matchesStatically(aMethod.getGenericReturnType().resolve(world))) {
Lines 395-670 Link Here
395
				return FuzzyBoolean.MAYBE;
391
				return FuzzyBoolean.MAYBE;
396
			}
392
			}
397
		}
393
		}
398
		if (!parameterTypes.canMatchSignatureWithNParameters(aMethod.getParameterTypes().length)) return FuzzyBoolean.NO;
394
		if (!parameterTypes.canMatchSignatureWithNParameters(aMethod.getParameterTypes().length))
395
			return FuzzyBoolean.NO;
399
		ResolvedType[] resolvedParameters = world.resolve(aMethod.getParameterTypes());
396
		ResolvedType[] resolvedParameters = world.resolve(aMethod.getParameterTypes());
400
		ResolvedType[][] parameterAnnotationTypes = aMethod.getParameterAnnotationTypes();
397
		ResolvedType[][] parameterAnnotationTypes = aMethod.getParameterAnnotationTypes();
401
		if (parameterAnnotationTypes==null || parameterAnnotationTypes.length==0) parameterAnnotationTypes=null;
398
		if (parameterAnnotationTypes == null || parameterAnnotationTypes.length == 0)
402
		if (!parameterTypes.matches(resolvedParameters, TypePattern.STATIC,parameterAnnotationTypes).alwaysTrue()) {
399
			parameterAnnotationTypes = null;
400
		if (!parameterTypes.matches(resolvedParameters, TypePattern.STATIC, parameterAnnotationTypes).alwaysTrue()) {
403
			// It could still be a match based on the generic sig parameter types of a parameterized type
401
			// It could still be a match based on the generic sig parameter types of a parameterized type
404
			if (!parameterTypes.matches(world.resolve(aMethod.getGenericParameterTypes()),TypePattern.STATIC,parameterAnnotationTypes).alwaysTrue()) {
402
			if (!parameterTypes.matches(world.resolve(aMethod.getGenericParameterTypes()), TypePattern.STATIC,
403
					parameterAnnotationTypes).alwaysTrue()) {
405
				return FuzzyBoolean.MAYBE;
404
				return FuzzyBoolean.MAYBE;
406
				// It could STILL be a match based on the erasure of the parameter types??
405
				// It could STILL be a match based on the erasure of the parameter types??
407
				// to be determined via test cases...
406
				// to be determined via test cases...
408
			}
407
			}
409
		}
408
		}
410
		
409
411
		// check that varargs specifications match
410
		// check that varargs specifications match
412
		if (!matchesVarArgs(aMethod,world)) return FuzzyBoolean.MAYBE;
411
		if (!matchesVarArgs(aMethod, world))
413
		
412
			return FuzzyBoolean.MAYBE;
413
414
		// passed all the guards..
414
		// passed all the guards..
415
		return FuzzyBoolean.YES;
415
		return FuzzyBoolean.YES;
416
	}
416
	}
417
	
418
419
417
420
	/**
418
	/**
421
	 * match on declaring type, parameter types, throws types
419
	 * match on declaring type, parameter types, throws types
422
	 */
420
	 */
423
	private FuzzyBoolean matchesExactlyConstructor(JoinPointSignature aConstructor, World world) {
421
	private FuzzyBoolean matchesExactlyConstructor(JoinPointSignature aConstructor, World world) {
424
		if (!declaringType.matchesStatically(aConstructor.getDeclaringType().resolve(world))) return FuzzyBoolean.NO;
422
		if (!declaringType.matchesStatically(aConstructor.getDeclaringType().resolve(world)))
423
			return FuzzyBoolean.NO;
425
424
426
		if (!parameterTypes.canMatchSignatureWithNParameters(aConstructor.getParameterTypes().length)) return FuzzyBoolean.NO;
425
		if (!parameterTypes.canMatchSignatureWithNParameters(aConstructor.getParameterTypes().length))
426
			return FuzzyBoolean.NO;
427
		ResolvedType[] resolvedParameters = world.resolve(aConstructor.getParameterTypes());
427
		ResolvedType[] resolvedParameters = world.resolve(aConstructor.getParameterTypes());
428
		
428
429
		ResolvedType[][] parameterAnnotationTypes = aConstructor.getParameterAnnotationTypes();
429
		ResolvedType[][] parameterAnnotationTypes = aConstructor.getParameterAnnotationTypes();
430
430
431
		if (parameterAnnotationTypes==null || parameterAnnotationTypes.length==0) parameterAnnotationTypes=null;
431
		if (parameterAnnotationTypes == null || parameterAnnotationTypes.length == 0)
432
			parameterAnnotationTypes = null;
432
433
433
		if (!parameterTypes.matches(resolvedParameters, TypePattern.STATIC,parameterAnnotationTypes).alwaysTrue()) {
434
		if (!parameterTypes.matches(resolvedParameters, TypePattern.STATIC, parameterAnnotationTypes).alwaysTrue()) {
434
			// It could still be a match based on the generic sig parameter types of a parameterized type
435
			// It could still be a match based on the generic sig parameter types of a parameterized type
435
			if (!parameterTypes.matches(world.resolve(aConstructor.getGenericParameterTypes()),TypePattern.STATIC).alwaysTrue()) {
436
			if (!parameterTypes.matches(world.resolve(aConstructor.getGenericParameterTypes()), TypePattern.STATIC).alwaysTrue()) {
436
				return FuzzyBoolean.MAYBE;
437
				return FuzzyBoolean.MAYBE;
437
				// It could STILL be a match based on the erasure of the parameter types??
438
				// It could STILL be a match based on the erasure of the parameter types??
438
				// to be determined via test cases...
439
				// to be determined via test cases...
439
			}
440
			}
440
		}
441
		}
441
		
442
442
		// check that varargs specifications match
443
		// check that varargs specifications match
443
		if (!matchesVarArgs(aConstructor,world)) return FuzzyBoolean.NO;
444
		if (!matchesVarArgs(aConstructor, world))
444
		
445
			return FuzzyBoolean.NO;
446
445
		// Check the throws pattern
447
		// Check the throws pattern
446
		if (!throwsPattern.matches(aConstructor.getExceptions(), world)) return FuzzyBoolean.NO;
448
		if (!throwsPattern.matches(aConstructor.getExceptions(), world))
447
		
449
			return FuzzyBoolean.NO;
450
448
		// passed all the guards..
451
		// passed all the guards..
449
		return FuzzyBoolean.YES;		
452
		return FuzzyBoolean.YES;
450
	}
453
	}
451
	
454
452
	/**
455
	/**
453
	 * We've matched against this method or constructor so far, but without considering
456
	 * We've matched against this method or constructor so far, but without considering varargs (which has been matched as a simple
454
	 * varargs (which has been matched as a simple array thus far). Now we do the additional
457
	 * array thus far). Now we do the additional checks to see if the parties agree on whether the last parameter is varargs or a
455
	 * checks to see if the parties agree on whether the last parameter is varargs or a 
458
	 * straight array.
456
	 * straight array. 
457
	 */
459
	 */
458
	private boolean matchesVarArgs(JoinPointSignature aMethodOrConstructor, World inAWorld) {
460
	private boolean matchesVarArgs(JoinPointSignature aMethodOrConstructor, World inAWorld) {
459
		if (parameterTypes.size() == 0) return true;
461
		if (parameterTypes.size() == 0)
460
		
462
			return true;
461
		TypePattern lastPattern = parameterTypes.get(parameterTypes.size()-1);
463
462
		boolean canMatchVarArgsSignature = lastPattern.isStar() || 
464
		TypePattern lastPattern = parameterTypes.get(parameterTypes.size() - 1);
463
		                                    lastPattern.isVarArgs() ||
465
		boolean canMatchVarArgsSignature = lastPattern.isStar() || lastPattern.isVarArgs() || (lastPattern == TypePattern.ELLIPSIS);
464
		                                    (lastPattern == TypePattern.ELLIPSIS);
466
465
		
466
		if (aMethodOrConstructor.isVarargsMethod()) {
467
		if (aMethodOrConstructor.isVarargsMethod()) {
467
			// we have at least one parameter in the pattern list, and the method has a varargs signature
468
			// we have at least one parameter in the pattern list, and the method has a varargs signature
468
			if (!canMatchVarArgsSignature) {
469
			if (!canMatchVarArgsSignature) {
469
				// XXX - Ideally the shadow would be included in the msg but we don't know it...
470
				// XXX - Ideally the shadow would be included in the msg but we don't know it...
470
				inAWorld.getLint().cantMatchArrayTypeOnVarargs.signal(aMethodOrConstructor.toString(),getSourceLocation());
471
				inAWorld.getLint().cantMatchArrayTypeOnVarargs.signal(aMethodOrConstructor.toString(), getSourceLocation());
471
				return false;
472
				return false;
472
			}
473
			}
473
		} else {
474
		} else {
474
			// the method ends with an array type, check that we don't *require* a varargs
475
			// the method ends with an array type, check that we don't *require* a varargs
475
			if (lastPattern.isVarArgs()) return false;
476
			if (lastPattern.isVarArgs())
477
				return false;
476
		}
478
		}
477
479
478
		return true;
480
		return true;
479
	}
481
	}
480
		
482
481
	private FuzzyBoolean matchesAnnotations(ResolvedMember member,World world) {
483
	private FuzzyBoolean matchesAnnotations(ResolvedMember member, World world) {
482
	  if (member == null) {
484
		if (member == null) {
483
            //			world.getLint().unresolvableMember.signal(member.toString(), getSourceLocation());
485
			// world.getLint().unresolvableMember.signal(member.toString(), getSourceLocation());
484
			return FuzzyBoolean.NO;
486
			return FuzzyBoolean.NO;
485
	  }
487
		}
486
	  annotationPattern.resolve(world);
488
		annotationPattern.resolve(world);
487
	 
489
488
	  // optimization before we go digging around for annotations on ITDs
490
		// optimization before we go digging around for annotations on ITDs
489
	  if (annotationPattern instanceof AnyAnnotationTypePattern) return FuzzyBoolean.YES;
491
		if (annotationPattern instanceof AnyAnnotationTypePattern)
490
	  
492
			return FuzzyBoolean.YES;
491
	  // fake members represent ITD'd fields - for their annotations we should go and look up the
493
492
	  // relevant member in the original aspect
494
		// fake members represent ITD'd fields - for their annotations we should go and look up the
493
	  if (member.isAnnotatedElsewhere() && member.getKind()==Member.FIELD) {
495
		// relevant member in the original aspect
494
	    // FIXME asc duplicate of code in AnnotationPointcut.matchInternal()?  same fixmes apply here.
496
		if (member.isAnnotatedElsewhere() && member.getKind() == Member.FIELD) {
495
//	    ResolvedMember [] mems = member.getDeclaringType().resolve(world).getDeclaredFields(); // FIXME asc should include supers with getInterTypeMungersIncludingSupers?
497
			// FIXME asc duplicate of code in AnnotationPointcut.matchInternal()? same fixmes apply here.
496
	    List mungers = member.getDeclaringType().resolve(world).getInterTypeMungers(); 
498
			// ResolvedMember [] mems = member.getDeclaringType().resolve(world).getDeclaredFields(); // FIXME asc should include
497
		for (Iterator iter = mungers.iterator(); iter.hasNext();) {
499
			// supers with getInterTypeMungersIncludingSupers?
498
	        ConcreteTypeMunger typeMunger = (ConcreteTypeMunger) iter.next();
500
			List mungers = member.getDeclaringType().resolve(world).getInterTypeMungers();
499
			if (typeMunger.getMunger() instanceof NewFieldTypeMunger) {
501
			for (Iterator iter = mungers.iterator(); iter.hasNext();) {
500
			  ResolvedMember fakerm = typeMunger.getSignature();
502
				ConcreteTypeMunger typeMunger = (ConcreteTypeMunger) iter.next();
501
			  ResolvedMember ajcMethod = AjcMemberMaker.interFieldInitializer(fakerm,typeMunger.getAspectType());
503
				if (typeMunger.getMunger() instanceof NewFieldTypeMunger) {
502
		  	  ResolvedMember rmm       = findMethod(typeMunger.getAspectType(),ajcMethod);
504
					ResolvedMember fakerm = typeMunger.getSignature();
503
			  if (fakerm.equals(member)) {
505
					ResolvedMember ajcMethod = AjcMemberMaker.interFieldInitializer(fakerm, typeMunger.getAspectType());
504
				member = rmm;
506
					ResolvedMember rmm = findMethod(typeMunger.getAspectType(), ajcMethod);
505
			  }
507
					if (fakerm.equals(member)) {
506
			}
508
						member = rmm;
507
		}
509
					}
508
	  }
510
				}
509
	  
511
			}
510
	  if (annotationPattern.matches(member).alwaysTrue()) {
512
		}
511
		  return FuzzyBoolean.YES;
513
512
	  } else {
514
		if (annotationPattern.matches(member).alwaysTrue()) {
513
		  return FuzzyBoolean.NO;  // do NOT look at ancestor members...
515
			return FuzzyBoolean.YES;
514
	  }
516
		} else {
517
			return FuzzyBoolean.NO; // do NOT look at ancestor members...
518
		}
515
	}
519
	}
516
	
520
517
	private ResolvedMember findMethod(ResolvedType aspectType, ResolvedMember ajcMethod) {
521
	private ResolvedMember findMethod(ResolvedType aspectType, ResolvedMember ajcMethod) {
518
	       ResolvedMember decMethods[] = aspectType.getDeclaredMethods();
522
		ResolvedMember decMethods[] = aspectType.getDeclaredMethods();
519
	       for (int i = 0; i < decMethods.length; i++) {
523
		for (int i = 0; i < decMethods.length; i++) {
520
			ResolvedMember member = decMethods[i];
524
			ResolvedMember member = decMethods[i];
521
			if (member.equals(ajcMethod)) return member;
525
			if (member.equals(ajcMethod))
522
	   }
526
				return member;
523
			return null;
527
		}
524
	}
528
		return null;
525
	
529
	}
526
	public boolean declaringTypeMatchAllowingForCovariance(Member member, UnresolvedType shadowDeclaringType, World world,TypePattern returnTypePattern,ResolvedType sigReturn) {
530
527
		
531
	public boolean declaringTypeMatchAllowingForCovariance(Member member, UnresolvedType shadowDeclaringType, World world,
532
			TypePattern returnTypePattern, ResolvedType sigReturn) {
533
528
		ResolvedType onType = shadowDeclaringType.resolve(world);
534
		ResolvedType onType = shadowDeclaringType.resolve(world);
529
			
535
530
		// fastmatch
536
		// fastmatch
531
		if (declaringType.matchesStatically(onType) && returnTypePattern.matchesStatically(sigReturn)) 
537
		if (declaringType.matchesStatically(onType) && returnTypePattern.matchesStatically(sigReturn))
532
			return true;
538
			return true;
533
			
539
534
		Collection declaringTypes = member.getDeclaringTypes(world);
540
		Collection declaringTypes = member.getDeclaringTypes(world);
535
		
541
536
		boolean checkReturnType = true;
542
		boolean checkReturnType = true;
537
		// XXX Possible enhancement?  Doesn't seem to speed things up
543
		// XXX Possible enhancement? Doesn't seem to speed things up
538
		//	if (returnTypePattern.isStar()) {
544
		// if (returnTypePattern.isStar()) {
539
		//		if (returnTypePattern instanceof WildTypePattern) {
545
		// if (returnTypePattern instanceof WildTypePattern) {
540
		//			if (((WildTypePattern)returnTypePattern).getDimensions()==0) checkReturnType = false;
546
		// if (((WildTypePattern)returnTypePattern).getDimensions()==0) checkReturnType = false;
541
		//		}
547
		// }
542
		//	}
548
		// }
543
			
549
544
		// Sometimes that list includes types that don't explicitly declare the member we are after -
550
		// Sometimes that list includes types that don't explicitly declare the member we are after -
545
		// they are on the list because their supertype is on the list, that's why we use
551
		// they are on the list because their supertype is on the list, that's why we use
546
		// lookupMethod rather than lookupMemberNoSupers()
552
		// lookupMethod rather than lookupMemberNoSupers()
547
		for (Iterator i = declaringTypes.iterator(); i.hasNext(); ) {
553
		for (Iterator i = declaringTypes.iterator(); i.hasNext();) {
548
			ResolvedType type = (ResolvedType)i.next();
554
			ResolvedType type = (ResolvedType) i.next();
549
			if (declaringType.matchesStatically(type)) {
555
			if (declaringType.matchesStatically(type)) {
550
			  if (!checkReturnType) return true;
556
				if (!checkReturnType)
551
			  ResolvedMember rm = type.lookupMethod(member);
557
					return true;
552
			  if (rm==null)  rm = type.lookupMethodInITDs(member); // It must be in here, or we have *real* problems
558
				ResolvedMember rm = type.lookupMethod(member);
553
			  if (rm==null) continue; // might be currently looking at the generic type and we need to continue searching in case we hit a parameterized version of this same type...
559
				if (rm == null)
554
			  UnresolvedType returnTypeX = rm.getReturnType();
560
					rm = type.lookupMethodInITDs(member); // It must be in here, or we have *real* problems
555
			  ResolvedType returnType = returnTypeX.resolve(world);
561
				if (rm == null)
556
			  if (returnTypePattern.matchesStatically(returnType)) return true;
562
					continue; // might be currently looking at the generic type and we need to continue searching in case we hit a
563
				// parameterized version of this same type...
564
				UnresolvedType returnTypeX = rm.getReturnType();
565
				ResolvedType returnType = returnTypeX.resolve(world);
566
				if (returnTypePattern.matchesStatically(returnType))
567
					return true;
557
			}
568
			}
558
		}
569
		}
559
		return false;
570
		return false;
560
	}
571
	}
561
	
572
562
//	private Collection getDeclaringTypes(Signature sig) {
573
	// private Collection getDeclaringTypes(Signature sig) {
563
//		List l = new ArrayList();
574
	// List l = new ArrayList();
564
//		Class onType = sig.getDeclaringType();
575
	// Class onType = sig.getDeclaringType();
565
//		String memberName = sig.getName();
576
	// String memberName = sig.getName();
566
//		if (sig instanceof FieldSignature) {
577
	// if (sig instanceof FieldSignature) {
567
//			Class fieldType = ((FieldSignature)sig).getFieldType();
578
	// Class fieldType = ((FieldSignature)sig).getFieldType();
568
//			Class superType = onType;
579
	// Class superType = onType;
569
//			while(superType != null) {
580
	// while(superType != null) {
570
//				try {
581
	// try {
571
//					Field f =  (superType.getDeclaredField(memberName));
582
	// Field f = (superType.getDeclaredField(memberName));
572
//					if (f.getType() == fieldType) {
583
	// if (f.getType() == fieldType) {
573
//						l.add(superType);
584
	// l.add(superType);
574
//					}
585
	// }
575
//				} catch (NoSuchFieldException nsf) {}
586
	// } catch (NoSuchFieldException nsf) {}
576
//				superType = superType.getSuperclass();
587
	// superType = superType.getSuperclass();
577
//			}
588
	// }
578
//		} else if (sig instanceof MethodSignature) {
589
	// } else if (sig instanceof MethodSignature) {
579
//			Class[] paramTypes = ((MethodSignature)sig).getParameterTypes();
590
	// Class[] paramTypes = ((MethodSignature)sig).getParameterTypes();
580
//			Class superType = onType;
591
	// Class superType = onType;
581
//			while(superType != null) {
592
	// while(superType != null) {
582
//				try {
593
	// try {
583
//					superType.getDeclaredMethod(memberName,paramTypes);
594
	// superType.getDeclaredMethod(memberName,paramTypes);
584
//					l.add(superType);
595
	// l.add(superType);
585
//				} catch (NoSuchMethodException nsm) {}
596
	// } catch (NoSuchMethodException nsm) {}
586
//				superType = superType.getSuperclass();
597
	// superType = superType.getSuperclass();
587
//			}
598
	// }
588
//		}
599
	// }
589
//		return l;
600
	// return l;
590
//	}
601
	// }
591
	
602
592
    public NamePattern getName() { return name; }
603
	public NamePattern getName() {
593
    public TypePattern getDeclaringType() { return declaringType; }
604
		return name;
594
    
605
	}
595
    public MemberKind getKind() {
606
596
    	return kind;
607
	public TypePattern getDeclaringType() {
597
    }
608
		return declaringType;
598
    
609
	}
599
    public String toString() {
610
600
    	StringBuffer buf = new StringBuffer();
611
	public MemberKind getKind() {
601
    	
612
		return kind;
602
    	if (annotationPattern != AnnotationTypePattern.ANY) {
613
	}
614
615
	public String toString() {
616
		StringBuffer buf = new StringBuffer();
617
618
		if (annotationPattern != AnnotationTypePattern.ANY) {
603
			buf.append(annotationPattern.toString());
619
			buf.append(annotationPattern.toString());
604
			buf.append(' ');
620
			buf.append(' ');
605
    	}
621
		}
606
    	
622
607
    	if (modifiers != ModifiersPattern.ANY) {
623
		if (modifiers != ModifiersPattern.ANY) {
608
    		buf.append(modifiers.toString());
624
			buf.append(modifiers.toString());
609
    		buf.append(' ');
625
			buf.append(' ');
610
    	}
626
		}
611
    	
627
612
    	if (kind == Member.STATIC_INITIALIZATION) {
628
		if (kind == Member.STATIC_INITIALIZATION) {
613
    		buf.append(declaringType.toString());
629
			buf.append(declaringType.toString());
614
    		buf.append(".<clinit>()");//FIXME AV - bad, cannot be parsed again
630
			buf.append(".<clinit>()");// FIXME AV - bad, cannot be parsed again
615
    	} else if (kind == Member.HANDLER) {
631
		} else if (kind == Member.HANDLER) {
616
    		buf.append("handler(");
632
			buf.append("handler(");
617
    		buf.append(parameterTypes.get(0));
633
			buf.append(parameterTypes.get(0));
618
    		buf.append(")");
634
			buf.append(")");
619
    	} else {
635
		} else {
620
    		if (!(kind == Member.CONSTRUCTOR)) {
636
			if (!(kind == Member.CONSTRUCTOR)) {
621
    			buf.append(returnType.toString());
637
				buf.append(returnType.toString());
622
    		    buf.append(' ');
638
				buf.append(' ');
623
    		}
639
			}
624
    		if (declaringType != TypePattern.ANY) {
640
			if (declaringType != TypePattern.ANY) {
625
    			buf.append(declaringType.toString());
641
				buf.append(declaringType.toString());
626
    			buf.append('.');
642
				buf.append('.');
627
    		}
643
			}
628
    		if (kind == Member.CONSTRUCTOR) {
644
			if (kind == Member.CONSTRUCTOR) {
629
    			buf.append("new");
645
				buf.append("new");
630
    		} else {
646
			} else {
631
    		    buf.append(name.toString());
647
				buf.append(name.toString());
632
    		}
648
			}
633
    		if (kind == Member.METHOD || kind == Member.CONSTRUCTOR) {
649
			if (kind == Member.METHOD || kind == Member.CONSTRUCTOR) {
634
    			buf.append(parameterTypes.toString());
650
				buf.append(parameterTypes.toString());
635
    		}
651
			}
636
            //FIXME AV - throws is not printed here, weird
652
			// FIXME AV - throws is not printed here, weird
637
    	}
653
		}
638
    	return buf.toString();
654
		return buf.toString();
639
    }
655
	}
640
    
656
641
    public boolean equals(Object other) {
657
	public boolean equals(Object other) {
642
    	if (!(other instanceof SignaturePattern)) return false;
658
		if (!(other instanceof SignaturePattern))
643
    	SignaturePattern o = (SignaturePattern)other;
659
			return false;
644
    	return o.kind.equals(this.kind)
660
		SignaturePattern o = (SignaturePattern) other;
645
    		&& o.modifiers.equals(this.modifiers)
661
		return o.kind.equals(this.kind) && o.modifiers.equals(this.modifiers) && o.returnType.equals(this.returnType)
646
    		&& o.returnType.equals(this.returnType)
662
				&& o.declaringType.equals(this.declaringType) && o.name.equals(this.name)
647
    		&& o.declaringType.equals(this.declaringType)
663
				&& o.parameterTypes.equals(this.parameterTypes) && o.throwsPattern.equals(this.throwsPattern)
648
    		&& o.name.equals(this.name)
664
				&& o.annotationPattern.equals(this.annotationPattern);
649
    		&& o.parameterTypes.equals(this.parameterTypes)
665
	}
650
			&& o.throwsPattern.equals(this.throwsPattern)
666
651
			&& o.annotationPattern.equals(this.annotationPattern);
667
	public int hashCode() {
652
    }
668
		if (hashcode == -1) {
653
    public int hashCode() {
669
			hashcode = 17;
654
    	if (hashcode==-1) {
670
			hashcode = 37 * hashcode + kind.hashCode();
655
          hashcode = 17;
671
			hashcode = 37 * hashcode + modifiers.hashCode();
656
          hashcode = 37*hashcode + kind.hashCode();
672
			hashcode = 37 * hashcode + returnType.hashCode();
657
          hashcode = 37*hashcode + modifiers.hashCode();
673
			hashcode = 37 * hashcode + declaringType.hashCode();
658
          hashcode = 37*hashcode + returnType.hashCode();
674
			hashcode = 37 * hashcode + name.hashCode();
659
          hashcode = 37*hashcode + declaringType.hashCode();
675
			hashcode = 37 * hashcode + parameterTypes.hashCode();
660
          hashcode = 37*hashcode + name.hashCode();
676
			hashcode = 37 * hashcode + throwsPattern.hashCode();
661
          hashcode = 37*hashcode + parameterTypes.hashCode();
677
			hashcode = 37 * hashcode + annotationPattern.hashCode();
662
          hashcode = 37*hashcode + throwsPattern.hashCode();
678
		}
663
          hashcode = 37*hashcode + annotationPattern.hashCode();
679
		return hashcode;
664
    	}
680
	}
665
        return hashcode;
681
666
    }
667
    
668
	public void write(DataOutputStream s) throws IOException {
682
	public void write(DataOutputStream s) throws IOException {
669
		kind.write(s);
683
		kind.write(s);
670
		modifiers.write(s);
684
		modifiers.write(s);
Lines 685-699 Link Here
685
		NamePattern name = NamePattern.read(s);
699
		NamePattern name = NamePattern.read(s);
686
		TypePatternList parameterTypes = TypePatternList.read(s, context);
700
		TypePatternList parameterTypes = TypePatternList.read(s, context);
687
		ThrowsPattern throwsPattern = ThrowsPattern.read(s, context);
701
		ThrowsPattern throwsPattern = ThrowsPattern.read(s, context);
688
		
702
689
		AnnotationTypePattern annotationPattern = AnnotationTypePattern.ANY;
703
		AnnotationTypePattern annotationPattern = AnnotationTypePattern.ANY;
690
		
704
691
		if (s.getMajorVersion()>=AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150) {
705
		if (s.getMajorVersion() >= AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150) {
692
		  annotationPattern = AnnotationTypePattern.read(s,context);
706
			annotationPattern = AnnotationTypePattern.read(s, context);
693
		}
707
		}
694
708
695
		SignaturePattern ret = new SignaturePattern(kind, modifiers, returnType, declaringType,
709
		SignaturePattern ret = new SignaturePattern(kind, modifiers, returnType, declaringType, name, parameterTypes,
696
					name, parameterTypes, throwsPattern,annotationPattern);
710
				throwsPattern, annotationPattern);
697
		ret.readLocation(context, s);
711
		ret.readLocation(context, s);
698
		return ret;
712
		return ret;
699
	}
713
	}
Lines 725-754 Link Here
725
	public ThrowsPattern getThrowsPattern() {
739
	public ThrowsPattern getThrowsPattern() {
726
		return throwsPattern;
740
		return throwsPattern;
727
	}
741
	}
728
	
742
729
	/**
743
	/**
730
	 * return true if last argument in params is an Object[] but the modifiers say this method
744
	 * return true if last argument in params is an Object[] but the modifiers say this method was declared with varargs
731
	 * was declared with varargs (Object...).  We shouldn't be matching if this is the case.
745
	 * (Object...). We shouldn't be matching if this is the case.
732
	 */
746
	 */
733
//	private boolean matchedArrayAgainstVarArgs(TypePatternList params,int modifiers) {
747
	// private boolean matchedArrayAgainstVarArgs(TypePatternList params,int modifiers) {
734
//		if (params.size()>0 && (modifiers & Constants.ACC_VARARGS)!=0) {
748
	// if (params.size()>0 && (modifiers & Constants.ACC_VARARGS)!=0) {
735
//			// we have at least one parameter in the pattern list, and the method has a varargs signature
749
	// // we have at least one parameter in the pattern list, and the method has a varargs signature
736
//			TypePattern lastPattern = params.get(params.size()-1);
750
	// TypePattern lastPattern = params.get(params.size()-1);
737
//			if (lastPattern.isArray() && !lastPattern.isVarArgs) return true;
751
	// if (lastPattern.isArray() && !lastPattern.isVarArgs) return true;
738
//		}
752
	// }
739
//	    return false;
753
	// return false;
740
//	}
754
	// }
741
	
742
	public AnnotationTypePattern getAnnotationPattern() {
755
	public AnnotationTypePattern getAnnotationPattern() {
743
		return annotationPattern;
756
		return annotationPattern;
744
	}
757
	}
745
758
746
747
	public boolean isStarAnnotation() {
759
	public boolean isStarAnnotation() {
748
		return annotationPattern == AnnotationTypePattern.ANY;
760
		return annotationPattern == AnnotationTypePattern.ANY;
749
	}
761
	}
750
762
751
    public Object accept(PatternNodeVisitor visitor, Object data) {
763
	public Object accept(PatternNodeVisitor visitor, Object data) {
752
        return visitor.visit(this, data);
764
		return visitor.visit(this, data);
753
    }
765
	}
754
}
766
}
(-)src/org/aspectj/weaver/patterns/WildTypePattern.java (+1 lines)
Lines 655-660 Link Here
655
		} else if (!isVarArgs) {
655
		} else if (!isVarArgs) {
656
			annotationPattern = annotationPattern.resolveBindings(scope, bindings, allowBinding);
656
			annotationPattern = annotationPattern.resolveBindings(scope, bindings, allowBinding);
657
			AnyWithAnnotationTypePattern ret = new AnyWithAnnotationTypePattern(annotationPattern);
657
			AnyWithAnnotationTypePattern ret = new AnyWithAnnotationTypePattern(annotationPattern);
658
			ret.includeSubtypes = includeSubtypes;
658
			ret.setLocation(sourceContext, start, end);
659
			ret.setLocation(sourceContext, start, end);
659
			return ret;
660
			return ret;
660
		}
661
		}

Return to bug 128664