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 |
} |