You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SignaturePattern.java 36KB

15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
14 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
14 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
15 jaren geleden
14 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
14 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
15 jaren geleden
14 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
14 jaren geleden
14 jaren geleden
14 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
14 jaren geleden
15 jaren geleden
14 jaren geleden
14 jaren geleden
14 jaren geleden
14 jaren geleden
14 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
15 jaren geleden
14 jaren geleden
15 jaren geleden
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025
  1. /* *******************************************************************
  2. * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
  3. * All rights reserved.
  4. * This program and the accompanying materials are made available
  5. * under the terms of the Eclipse Public License v 2.0
  6. * which accompanies this distribution and is available at
  7. * https://www.eclipse.org/org/documents/epl-2.0/EPL-2.0.txt
  8. *
  9. * Contributors:
  10. * PARC initial implementation
  11. * ******************************************************************/
  12. package org.aspectj.weaver.patterns;
  13. import java.io.IOException;
  14. import java.util.ArrayList;
  15. import java.util.Collection;
  16. import java.util.Collections;
  17. import java.util.HashMap;
  18. import java.util.List;
  19. import java.util.Map;
  20. import java.util.Set;
  21. import org.aspectj.bridge.ISourceLocation;
  22. import org.aspectj.util.FuzzyBoolean;
  23. import org.aspectj.weaver.AjAttribute;
  24. import org.aspectj.weaver.AjcMemberMaker;
  25. import org.aspectj.weaver.AnnotationTargetKind;
  26. import org.aspectj.weaver.CompressingDataOutputStream;
  27. import org.aspectj.weaver.ConcreteTypeMunger;
  28. import org.aspectj.weaver.ISourceContext;
  29. import org.aspectj.weaver.JoinPointSignature;
  30. import org.aspectj.weaver.JoinPointSignatureIterator;
  31. import org.aspectj.weaver.Member;
  32. import org.aspectj.weaver.MemberKind;
  33. import org.aspectj.weaver.NewFieldTypeMunger;
  34. import org.aspectj.weaver.ResolvableTypeList;
  35. import org.aspectj.weaver.ResolvedMember;
  36. import org.aspectj.weaver.ResolvedType;
  37. import org.aspectj.weaver.UnresolvedType;
  38. import org.aspectj.weaver.VersionedDataInputStream;
  39. import org.aspectj.weaver.World;
  40. public class SignaturePattern extends PatternNode implements ISignaturePattern {
  41. private MemberKind kind;
  42. private ModifiersPattern modifiers;
  43. private TypePattern returnType;
  44. private TypePattern declaringType;
  45. private NamePattern name;
  46. private TypePatternList parameterTypes;
  47. private int bits = 0x0000;
  48. private static final int PARAMETER_ANNOTATION_MATCHING = 0x0001;
  49. private static final int CHECKED_FOR_PARAMETER_ANNOTATION_MATCHING = 0x0002;
  50. private ThrowsPattern throwsPattern;
  51. private AnnotationTypePattern annotationPattern;
  52. private transient int hashcode = -1;
  53. private transient boolean isExactDeclaringTypePattern = false;
  54. public SignaturePattern(MemberKind kind, ModifiersPattern modifiers, TypePattern returnType, TypePattern declaringType,
  55. NamePattern name, TypePatternList parameterTypes, ThrowsPattern throwsPattern, AnnotationTypePattern annotationPattern) {
  56. this.kind = kind;
  57. this.modifiers = modifiers;
  58. this.returnType = returnType;
  59. this.name = name;
  60. this.declaringType = declaringType;
  61. this.parameterTypes = parameterTypes;
  62. this.throwsPattern = throwsPattern;
  63. this.annotationPattern = annotationPattern;
  64. this.isExactDeclaringTypePattern = (declaringType instanceof ExactTypePattern);
  65. }
  66. @Override
  67. public SignaturePattern resolveBindings(IScope scope, Bindings bindings) {
  68. if (returnType != null) {
  69. returnType = returnType.resolveBindings(scope, bindings, false, false);
  70. checkForIncorrectTargetKind(returnType, scope, false);
  71. }
  72. if (declaringType != null) {
  73. declaringType = declaringType.resolveBindings(scope, bindings, false, false);
  74. checkForIncorrectTargetKind(declaringType, scope, false);
  75. isExactDeclaringTypePattern = (declaringType instanceof ExactTypePattern);
  76. }
  77. if (parameterTypes != null) {
  78. parameterTypes = parameterTypes.resolveBindings(scope, bindings, false, false);
  79. checkForIncorrectTargetKind(parameterTypes, scope, false, true);
  80. }
  81. if (throwsPattern != null) {
  82. throwsPattern = throwsPattern.resolveBindings(scope, bindings);
  83. if (throwsPattern.getForbidden().getTypePatterns().length > 0
  84. || throwsPattern.getRequired().getTypePatterns().length > 0) {
  85. checkForIncorrectTargetKind(throwsPattern, scope, false);
  86. }
  87. }
  88. if (annotationPattern != null) {
  89. annotationPattern = annotationPattern.resolveBindings(scope, bindings, false);
  90. checkForIncorrectTargetKind(annotationPattern, scope, true);
  91. }
  92. hashcode = -1;
  93. return this;
  94. }
  95. private void checkForIncorrectTargetKind(PatternNode patternNode, IScope scope, boolean targetsOtherThanTypeAllowed) {
  96. checkForIncorrectTargetKind(patternNode, scope, targetsOtherThanTypeAllowed, false);
  97. }
  98. // bug 115252 - adding an xlint warning if the annnotation target type is
  99. // wrong. This logic, or similar, may have to be applied elsewhere in the case
  100. // of pointcuts which don't go through SignaturePattern.resolveBindings(..)
  101. private void checkForIncorrectTargetKind(PatternNode patternNode, IScope scope, boolean targetsOtherThanTypeAllowed,
  102. boolean parameterTargettingAnnotationsAllowed) {
  103. // return if we're not in java5 mode, if the unmatchedTargetKind Xlint
  104. // warning has been turned off, or if the patternNode is *
  105. if (!scope.getWorld().isInJava5Mode() || scope.getWorld().getLint().unmatchedTargetKind == null
  106. || (patternNode instanceof AnyTypePattern)) {
  107. return;
  108. }
  109. if (patternNode instanceof ExactAnnotationTypePattern) {
  110. ResolvedType resolvedType = ((ExactAnnotationTypePattern) patternNode).getAnnotationType().resolve(scope.getWorld());
  111. if (targetsOtherThanTypeAllowed) {
  112. AnnotationTargetKind[] targetKinds = resolvedType.getAnnotationTargetKinds();
  113. if (targetKinds == null) {
  114. return;
  115. }
  116. reportUnmatchedTargetKindMessage(targetKinds, patternNode, scope, true);
  117. } else if (!targetsOtherThanTypeAllowed && !resolvedType.canAnnotationTargetType()) {
  118. // everything is incorrect since we've already checked whether we have the TYPE target annotation
  119. AnnotationTargetKind[] targetKinds = resolvedType.getAnnotationTargetKinds();
  120. if (targetKinds == null) {
  121. return;
  122. }
  123. reportUnmatchedTargetKindMessage(targetKinds, patternNode, scope, false);
  124. }
  125. } else {
  126. TypePatternVisitor visitor = new TypePatternVisitor(scope, targetsOtherThanTypeAllowed,
  127. parameterTargettingAnnotationsAllowed);
  128. patternNode.traverse(visitor, null);
  129. if (visitor.containedIncorrectTargetKind()) {
  130. Set<ExactAnnotationTypePattern> keys = visitor.getIncorrectTargetKinds().keySet();
  131. for (PatternNode node : keys) {
  132. AnnotationTargetKind[] targetKinds = visitor.getIncorrectTargetKinds().get(node);
  133. reportUnmatchedTargetKindMessage(targetKinds, node, scope, false);
  134. }
  135. }
  136. }
  137. }
  138. private void reportUnmatchedTargetKindMessage(AnnotationTargetKind[] annotationTargetKinds, PatternNode node, IScope scope,
  139. boolean checkMatchesMemberKindName) {
  140. StringBuilder targetNames = new StringBuilder("{");
  141. for (int i = 0; i < annotationTargetKinds.length; i++) {
  142. AnnotationTargetKind targetKind = annotationTargetKinds[i];
  143. if (checkMatchesMemberKindName && kind.getName().equals(targetKind.getName())) {
  144. return;
  145. }
  146. if (i < (annotationTargetKinds.length - 1)) {
  147. targetNames.append("ElementType." + targetKind.getName() + ",");
  148. } else {
  149. targetNames.append("ElementType." + targetKind.getName() + "}");
  150. }
  151. }
  152. scope.getWorld().getLint().unmatchedTargetKind.signal(new String[] { node.toString(), targetNames.toString() },
  153. getSourceLocation(), new ISourceLocation[0]);
  154. }
  155. /**
  156. * Class which visits the nodes in the TypePattern tree until an ExactTypePattern is found. Once this is found it creates a new
  157. * ExactAnnotationTypePattern and checks whether the targetKind (created via the @Target annotation) matches ElementType.TYPE if
  158. * this is the only target kind which is allowed, or matches the signature pattern kind if there is no restriction.
  159. */
  160. private class TypePatternVisitor extends AbstractPatternNodeVisitor {
  161. private IScope scope;
  162. private Map<ExactAnnotationTypePattern, AnnotationTargetKind[]> incorrectTargetKinds = new HashMap<>();
  163. private boolean targetsOtherThanTypeAllowed;
  164. private boolean parameterTargettingAnnotationsAllowed;
  165. /**
  166. * @param requiredTarget - the signature pattern Kind
  167. * @param scope
  168. * @param parameterTargettingAnnotationsAllowed
  169. */
  170. public TypePatternVisitor(IScope scope, boolean targetsOtherThanTypeAllowed, boolean parameterTargettingAnnotationsAllowed) {
  171. this.scope = scope;
  172. this.targetsOtherThanTypeAllowed = targetsOtherThanTypeAllowed;
  173. this.parameterTargettingAnnotationsAllowed = parameterTargettingAnnotationsAllowed;
  174. }
  175. @Override
  176. public Object visit(WildAnnotationTypePattern node, Object data) {
  177. node.getTypePattern().accept(this, data);
  178. return node;
  179. }
  180. /**
  181. * Do the ExactAnnotationTypePatterns have the incorrect target?
  182. */
  183. @Override
  184. public Object visit(ExactAnnotationTypePattern node, Object data) {
  185. ResolvedType resolvedType = node.getAnnotationType().resolve(scope.getWorld());
  186. if (targetsOtherThanTypeAllowed) {
  187. AnnotationTargetKind[] targetKinds = resolvedType.getAnnotationTargetKinds();
  188. if (targetKinds == null) {
  189. return data;
  190. }
  191. List<AnnotationTargetKind> incorrectTargets = new ArrayList<>();
  192. for (AnnotationTargetKind targetKind : targetKinds) {
  193. if (targetKind.getName().equals(kind.getName())
  194. || (targetKind.getName().equals("PARAMETER") && node.isForParameterAnnotationMatch())) {
  195. return data;
  196. }
  197. incorrectTargets.add(targetKind);
  198. }
  199. if (incorrectTargets.isEmpty()) {
  200. return data;
  201. }
  202. AnnotationTargetKind[] kinds = new AnnotationTargetKind[incorrectTargets.size()];
  203. incorrectTargetKinds.put(node, incorrectTargets.toArray(kinds));
  204. } else if (!targetsOtherThanTypeAllowed && !resolvedType.canAnnotationTargetType()) {
  205. AnnotationTargetKind[] targetKinds = resolvedType.getAnnotationTargetKinds();
  206. if (targetKinds == null) {
  207. return data;
  208. }
  209. // exception here is if parameter annotations are allowed
  210. if (parameterTargettingAnnotationsAllowed) {
  211. for (AnnotationTargetKind annotationTargetKind : targetKinds) {
  212. if (annotationTargetKind.getName().equals("PARAMETER") && node.isForParameterAnnotationMatch()) {
  213. return data;
  214. }
  215. }
  216. }
  217. incorrectTargetKinds.put(node, targetKinds);
  218. }
  219. return data;
  220. }
  221. @Override
  222. public Object visit(ExactTypePattern node, Object data) {
  223. ExactAnnotationTypePattern eatp = new ExactAnnotationTypePattern(node.getExactType().resolve(scope.getWorld()), null);
  224. eatp.accept(this, data);
  225. return data;
  226. }
  227. @Override
  228. public Object visit(AndTypePattern node, Object data) {
  229. node.getLeft().accept(this, data);
  230. node.getRight().accept(this, data);
  231. return node;
  232. }
  233. @Override
  234. public Object visit(OrTypePattern node, Object data) {
  235. node.getLeft().accept(this, data);
  236. node.getRight().accept(this, data);
  237. return node;
  238. }
  239. @Override
  240. public Object visit(AnyWithAnnotationTypePattern node, Object data) {
  241. node.getAnnotationPattern().accept(this, data);
  242. return node;
  243. }
  244. public boolean containedIncorrectTargetKind() {
  245. return (incorrectTargetKinds.size() != 0);
  246. }
  247. public Map<ExactAnnotationTypePattern, AnnotationTargetKind[]> getIncorrectTargetKinds() {
  248. return incorrectTargetKinds;
  249. }
  250. }
  251. public void postRead(ResolvedType enclosingType) {
  252. if (returnType != null) {
  253. returnType.postRead(enclosingType);
  254. }
  255. if (declaringType != null) {
  256. declaringType.postRead(enclosingType);
  257. }
  258. if (parameterTypes != null) {
  259. parameterTypes.postRead(enclosingType);
  260. }
  261. }
  262. /**
  263. * return a copy of this signature pattern in which every type variable reference is replaced by the corresponding entry in the
  264. * map.
  265. */
  266. @Override
  267. public SignaturePattern parameterizeWith(Map<String, UnresolvedType> typeVariableMap, World w) {
  268. SignaturePattern ret = new SignaturePattern(kind, modifiers, returnType.parameterizeWith(typeVariableMap, w), declaringType
  269. .parameterizeWith(typeVariableMap, w), name, parameterTypes.parameterizeWith(typeVariableMap, w), throwsPattern
  270. .parameterizeWith(typeVariableMap, w), annotationPattern.parameterizeWith(typeVariableMap, w));
  271. ret.copyLocationFrom(this);
  272. return ret;
  273. }
  274. @Override
  275. public boolean matches(Member joinPointSignature, World world, boolean allowBridgeMethods) {
  276. // fail (or succeed!) fast tests...
  277. if (joinPointSignature == null) {
  278. return false;
  279. }
  280. if (kind != joinPointSignature.getKind()) {
  281. return false;
  282. }
  283. if (kind == Member.ADVICE) {
  284. return true;
  285. }
  286. // do the hard work then...
  287. boolean subjectMatch = true;
  288. boolean wantsAnnotationMatch = wantToMatchAnnotationPattern();
  289. JoinPointSignatureIterator candidateMatches = joinPointSignature.getJoinPointSignatures(world);
  290. while (candidateMatches.hasNext()) {
  291. JoinPointSignature aSig = candidateMatches.next();
  292. // System.out.println(aSig);
  293. FuzzyBoolean matchResult = matchesExactly(aSig, world, allowBridgeMethods, subjectMatch);
  294. if (matchResult.alwaysTrue()) {
  295. return true;
  296. } else if (matchResult.alwaysFalse()) {
  297. return false;
  298. }
  299. // if we got a "MAYBE" it's worth looking at the other signatures
  300. // The first signature is the subject signature - and against it we must match modifiers/annotations/throws
  301. // see http://www.eclipse.org/aspectj/doc/next/adk15notebook/join-point-modifiers.html
  302. subjectMatch = false;
  303. // Early exit
  304. if (wantsAnnotationMatch) {
  305. return false;
  306. }
  307. }
  308. return false;
  309. }
  310. // Does this pattern match this exact signature (no declaring type mucking about
  311. // or chasing up the hierarchy)
  312. // return YES if it does, NO if it doesn't and no ancester member could match either,
  313. // and MAYBE if it doesn't but an ancester member could.
  314. private FuzzyBoolean matchesExactly(JoinPointSignature aMember, World inAWorld, boolean allowBridgeMethods, boolean subjectMatch) {
  315. // Java5 introduces bridge methods, we match a call to them but nothing else...
  316. if (aMember.isBridgeMethod() && !allowBridgeMethods) {
  317. return FuzzyBoolean.MAYBE;
  318. }
  319. // Only the subject is checked for modifiers
  320. // see http://www.eclipse.org/aspectj/doc/next/adk15notebook/join-point-modifiers.html
  321. if (subjectMatch && !modifiers.matches(aMember.getModifiers())) {
  322. return FuzzyBoolean.NO;
  323. }
  324. FuzzyBoolean matchesIgnoringAnnotations = FuzzyBoolean.YES;
  325. if (kind == Member.STATIC_INITIALIZATION) {
  326. matchesIgnoringAnnotations = matchesExactlyStaticInitialization(aMember, inAWorld);
  327. } else if (kind == Member.FIELD) {
  328. matchesIgnoringAnnotations = matchesExactlyField(aMember, inAWorld);
  329. } else if (kind == Member.METHOD) {
  330. matchesIgnoringAnnotations = matchesExactlyMethod(aMember, inAWorld, subjectMatch);
  331. } else if (kind == Member.CONSTRUCTOR) {
  332. matchesIgnoringAnnotations = matchesExactlyConstructor(aMember, inAWorld);
  333. }
  334. if (matchesIgnoringAnnotations.alwaysFalse()) {
  335. return FuzzyBoolean.NO;
  336. }
  337. // Only the subject is checked for annotations (239441/119749)
  338. // see http://www.eclipse.org/aspectj/doc/next/adk15notebook/join-point-modifiers.html
  339. if (subjectMatch) {
  340. // The annotations must match if specified
  341. if (!matchesAnnotations(aMember, inAWorld).alwaysTrue()) {
  342. return FuzzyBoolean.NO;
  343. } else {
  344. return matchesIgnoringAnnotations;
  345. }
  346. } else {
  347. // Unless they specified any annotation then it is a failure
  348. if (annotationPattern instanceof AnyAnnotationTypePattern) {
  349. return matchesIgnoringAnnotations;
  350. } else {
  351. return FuzzyBoolean.NO;
  352. }
  353. }
  354. // if (subjectMatch && !matchesAnnotations(aMember, inAWorld).alwaysTrue()) {
  355. // return FuzzyBoolean.NO;
  356. // } else {
  357. //
  358. // return matchesIgnoringAnnotations;
  359. // }
  360. }
  361. private boolean wantToMatchAnnotationPattern() {
  362. return !(annotationPattern instanceof AnyAnnotationTypePattern);
  363. }
  364. /**
  365. * Matches on declaring type
  366. */
  367. private FuzzyBoolean matchesExactlyStaticInitialization(JoinPointSignature aMember, World world) {
  368. return FuzzyBoolean.fromBoolean(declaringType.matchesStatically(aMember.getDeclaringType().resolve(world)));
  369. }
  370. /**
  371. * Matches on name, declaring type, field type
  372. */
  373. private FuzzyBoolean matchesExactlyField(JoinPointSignature aField, World world) {
  374. if (!name.matches(aField.getName())) {
  375. return FuzzyBoolean.NO;
  376. }
  377. ResolvedType fieldDeclaringType = aField.getDeclaringType().resolve(world);
  378. if (!declaringType.matchesStatically(fieldDeclaringType)) {
  379. return FuzzyBoolean.MAYBE;
  380. }
  381. if (!returnType.matchesStatically(aField.getReturnType().resolve(world))) {
  382. // looking bad, but there might be parameterization to consider...
  383. if (!returnType.matchesStatically(aField.getGenericReturnType().resolve(world))) {
  384. // ok, it's bad.
  385. return FuzzyBoolean.MAYBE;
  386. }
  387. }
  388. // passed all the guards...
  389. return FuzzyBoolean.YES;
  390. }
  391. /**
  392. * Quickly detect if the joinpoint absolutely cannot match becaused the method parameters at the joinpoint cannot match against
  393. * this signature pattern.
  394. *
  395. * @param methodJoinpoint the joinpoint to quickly match against
  396. * @return true if it is impossible for the joinpoint to match this signature
  397. */
  398. private boolean parametersCannotMatch(JoinPointSignature methodJoinpoint) {
  399. if (methodJoinpoint.isVarargsMethod()) {
  400. // just give up early (for now)
  401. return false;
  402. }
  403. int patternParameterCount = parameterTypes.size();
  404. if (patternParameterCount == 0 || parameterTypes.ellipsisCount == 0) {
  405. boolean equalCount = patternParameterCount == methodJoinpoint.getParameterTypes().length;
  406. // Quick rule: pattern specifies zero parameters, and joinpoint has parameters *OR*
  407. if (patternParameterCount == 0 && !equalCount) {
  408. return true;
  409. }
  410. // Quick rule: pattern doesn't specify ellipsis and there are a different number of parameters on the
  411. // method join point as compared with the pattern
  412. if (parameterTypes.ellipsisCount == 0 && !equalCount) {
  413. if (patternParameterCount > 0 && parameterTypes.get(patternParameterCount - 1).isVarArgs()) {
  414. return false;
  415. }
  416. return true;
  417. }
  418. }
  419. return false;
  420. }
  421. /**
  422. * Matches on name, declaring type, return type, parameter types, throws types
  423. */
  424. private FuzzyBoolean matchesExactlyMethod(JoinPointSignature aMethod, World world, boolean subjectMatch) {
  425. if (!returnType.matchesArray(aMethod.getReturnType())) {
  426. return FuzzyBoolean.NO;
  427. }
  428. if (parametersCannotMatch(aMethod)) {
  429. // System.err.println("Parameter types pattern " + parameterTypes + " pcount: " + aMethod.getParameterTypes().length);
  430. return FuzzyBoolean.NO;
  431. }
  432. // OPTIMIZE only for exact match do the pattern match now? Otherwise defer it until other fast checks complete?
  433. if (!name.matches(aMethod.getName())) {
  434. return FuzzyBoolean.NO;
  435. }
  436. // Check the throws pattern
  437. if (subjectMatch && !throwsPattern.matches(aMethod.getExceptions(), world)) {
  438. return FuzzyBoolean.NO;
  439. }
  440. // '*' trivially matches everything, no need to check further
  441. if (!declaringType.isStar()) {
  442. if (!declaringType.matchesStatically(aMethod.getDeclaringType().resolve(world))) {
  443. return FuzzyBoolean.MAYBE;
  444. }
  445. }
  446. // '*' would match any return value
  447. if (!returnType.isStar()) {
  448. boolean b = returnType.isBangVoid();
  449. if (b) {
  450. String s = aMethod.getReturnType().getSignature();
  451. if (s.length() == 1 && s.charAt(0) == 'V') {
  452. // it is void, so not a match
  453. return FuzzyBoolean.NO;
  454. }
  455. } else {
  456. if (returnType.isVoid()) {
  457. String s = aMethod.getReturnType().getSignature();
  458. if (s.length() != 1 || s.charAt(0) != 'V') {
  459. // it is not void, so not a match
  460. return FuzzyBoolean.NO;
  461. }
  462. } else {
  463. if (!returnType.matchesStatically(aMethod.getReturnType().resolve(world))) {
  464. // looking bad, but there might be parameterization to consider...
  465. if (!returnType.matchesStatically(aMethod.getGenericReturnType().resolve(world))) {
  466. // ok, it's bad.
  467. return FuzzyBoolean.MAYBE;
  468. }
  469. }
  470. }
  471. }
  472. }
  473. // The most simple case: pattern is (..) will match anything
  474. if (parameterTypes.size() == 1 && parameterTypes.get(0).isEllipsis()) {
  475. return FuzzyBoolean.YES;
  476. }
  477. if (!parameterTypes.canMatchSignatureWithNParameters(aMethod.getParameterTypes().length)) {
  478. return FuzzyBoolean.NO;
  479. }
  480. // OPTIMIZE both resolution of these types and their annotations should be deferred - just pass down a world and do it lower
  481. // down
  482. // ResolvedType[] resolvedParameters = world.resolve(aMethod.getParameterTypes());
  483. ResolvableTypeList rtl = new ResolvableTypeList(world, aMethod.getParameterTypes());
  484. // Only fetch the parameter annotations if the pointcut is going to be matching on them
  485. ResolvedType[][] parameterAnnotationTypes = null;
  486. if (isMatchingParameterAnnotations()) {
  487. parameterAnnotationTypes = aMethod.getParameterAnnotationTypes();
  488. if (parameterAnnotationTypes != null && parameterAnnotationTypes.length == 0) {
  489. parameterAnnotationTypes = null;
  490. }
  491. }
  492. if (!parameterTypes.matches(rtl, TypePattern.STATIC, parameterAnnotationTypes).alwaysTrue()) {
  493. // It could still be a match based on the generic sig parameter types of a parameterized type
  494. if (!parameterTypes.matches(new ResolvableTypeList(world, aMethod.getGenericParameterTypes()), TypePattern.STATIC,
  495. parameterAnnotationTypes).alwaysTrue()) {
  496. return FuzzyBoolean.MAYBE;
  497. // It could STILL be a match based on the erasure of the parameter types??
  498. // to be determined via test cases...
  499. }
  500. }
  501. // check that varargs specifications match
  502. if (!matchesVarArgs(aMethod, world)) {
  503. return FuzzyBoolean.MAYBE;
  504. }
  505. // passed all the guards..
  506. return FuzzyBoolean.YES;
  507. }
  508. /**
  509. * Determine if any pattern in the parameter type pattern list is attempting to match on parameter annotations.
  510. *
  511. * @return true if a parameter type pattern wants to match on a parameter annotation
  512. */
  513. private boolean isMatchingParameterAnnotations() {
  514. if ((bits & CHECKED_FOR_PARAMETER_ANNOTATION_MATCHING) == 0) {
  515. bits |= CHECKED_FOR_PARAMETER_ANNOTATION_MATCHING;
  516. for (int tp = 0, max = parameterTypes.size(); tp < max; tp++) {
  517. TypePattern typePattern = parameterTypes.get(tp);
  518. if (isParameterAnnotationMatching(typePattern)) {
  519. bits |= PARAMETER_ANNOTATION_MATCHING;
  520. }
  521. }
  522. }
  523. return (bits & PARAMETER_ANNOTATION_MATCHING) != 0;
  524. }
  525. /**
  526. * Walk the simple structure of a type pattern and determine if any leaf node is involved in parameter annotation matching.
  527. */
  528. private boolean isParameterAnnotationMatching(TypePattern tp) {
  529. if (tp instanceof OrTypePattern) {
  530. OrTypePattern orAtp = (OrTypePattern) tp;
  531. return (isParameterAnnotationMatching(orAtp.getLeft()) || isParameterAnnotationMatching(orAtp.getRight()));
  532. } else if (tp instanceof AndTypePattern) {
  533. AndTypePattern andAtp = (AndTypePattern) tp;
  534. return (isParameterAnnotationMatching(andAtp.getLeft()) || isParameterAnnotationMatching(andAtp.getRight()));
  535. } else if (tp instanceof NotTypePattern) {
  536. NotTypePattern notAtp = (NotTypePattern) tp;
  537. return (isParameterAnnotationMatching(notAtp.getNegatedPattern()));
  538. } else {
  539. AnnotationTypePattern atp = tp.getAnnotationPattern();
  540. return isParameterAnnotationMatching(atp);
  541. }
  542. }
  543. private boolean isParameterAnnotationMatching(AnnotationTypePattern tp) {
  544. if (tp instanceof OrAnnotationTypePattern) {
  545. OrAnnotationTypePattern orAtp = (OrAnnotationTypePattern) tp;
  546. return (isParameterAnnotationMatching(orAtp.getLeft()) || isParameterAnnotationMatching(orAtp.getRight()));
  547. } else if (tp instanceof AndAnnotationTypePattern) {
  548. AndAnnotationTypePattern andAtp = (AndAnnotationTypePattern) tp;
  549. return (isParameterAnnotationMatching(andAtp.getLeft()) || isParameterAnnotationMatching(andAtp.getRight()));
  550. } else if (tp instanceof NotAnnotationTypePattern) {
  551. NotAnnotationTypePattern notAtp = (NotAnnotationTypePattern) tp;
  552. return (isParameterAnnotationMatching(notAtp.negatedPattern));
  553. } else {
  554. return tp.isForParameterAnnotationMatch();
  555. }
  556. }
  557. /**
  558. * match on declaring type, parameter types, throws types
  559. */
  560. private FuzzyBoolean matchesExactlyConstructor(JoinPointSignature aConstructor, World world) {
  561. if (!declaringType.matchesStatically(aConstructor.getDeclaringType().resolve(world))) {
  562. return FuzzyBoolean.NO;
  563. }
  564. if (!parameterTypes.canMatchSignatureWithNParameters(aConstructor.getParameterTypes().length)) {
  565. return FuzzyBoolean.NO;
  566. }
  567. ResolvedType[] resolvedParameters = world.resolve(aConstructor.getParameterTypes());
  568. ResolvedType[][] parameterAnnotationTypes = aConstructor.getParameterAnnotationTypes();
  569. if (parameterAnnotationTypes == null || parameterAnnotationTypes.length == 0) {
  570. parameterAnnotationTypes = null;
  571. }
  572. if (!parameterTypes.matches(resolvedParameters, TypePattern.STATIC, parameterAnnotationTypes).alwaysTrue()) {
  573. // It could still be a match based on the generic sig parameter types of a parameterized type
  574. if (!parameterTypes.matches(world.resolve(aConstructor.getGenericParameterTypes()), TypePattern.STATIC, parameterAnnotationTypes).alwaysTrue()) {
  575. return FuzzyBoolean.MAYBE;
  576. // It could STILL be a match based on the erasure of the parameter types??
  577. // to be determined via test cases...
  578. }
  579. }
  580. // check that varargs specifications match
  581. if (!matchesVarArgs(aConstructor, world)) {
  582. return FuzzyBoolean.NO;
  583. }
  584. // Check the throws pattern
  585. if (!throwsPattern.matches(aConstructor.getExceptions(), world)) {
  586. return FuzzyBoolean.NO;
  587. }
  588. // passed all the guards..
  589. return FuzzyBoolean.YES;
  590. }
  591. /**
  592. * We've matched against this method or constructor so far, but without considering varargs (which has been matched as a simple
  593. * array thus far). Now we do the additional checks to see if the parties agree on whether the last parameter is varargs or a
  594. * straight array.
  595. */
  596. private boolean matchesVarArgs(JoinPointSignature aMethodOrConstructor, World inAWorld) {
  597. if (parameterTypes.size() == 0) {
  598. return true;
  599. }
  600. TypePattern lastPattern = parameterTypes.get(parameterTypes.size() - 1);
  601. boolean canMatchVarArgsSignature = lastPattern.isStar() || lastPattern.isVarArgs() || (lastPattern == TypePattern.ELLIPSIS);
  602. if (aMethodOrConstructor.isVarargsMethod()) {
  603. // we have at least one parameter in the pattern list, and the method has a varargs signature
  604. if (!canMatchVarArgsSignature) {
  605. // XXX - Ideally the shadow would be included in the msg but we don't know it...
  606. inAWorld.getLint().cantMatchArrayTypeOnVarargs.signal(aMethodOrConstructor.toString(), getSourceLocation());
  607. return false;
  608. }
  609. } else {
  610. // the method ends with an array type, check that we don't *require* a varargs
  611. if (lastPattern.isVarArgs()) {
  612. return false;
  613. }
  614. }
  615. return true;
  616. }
  617. private FuzzyBoolean matchesAnnotations(ResolvedMember member, World world) {
  618. if (member == null) {
  619. // world.getLint().unresolvableMember.signal(member.toString(), getSourceLocation());
  620. return FuzzyBoolean.NO;
  621. }
  622. annotationPattern.resolve(world);
  623. // optimization before we go digging around for annotations on ITDs
  624. if (annotationPattern instanceof AnyAnnotationTypePattern) {
  625. return FuzzyBoolean.YES;
  626. }
  627. // fake members represent ITD'd fields - for their annotations we should go and look up the
  628. // relevant member in the original aspect
  629. if (member.isAnnotatedElsewhere() && member.getKind() == Member.FIELD) {
  630. // FIXME asc duplicate of code in AnnotationPointcut.matchInternal()? same fixmes apply here.
  631. // ResolvedMember [] mems = member.getDeclaringType().resolve(world).getDeclaredFields(); // FIXME asc should include
  632. // supers with getInterTypeMungersIncludingSupers?
  633. List<ConcreteTypeMunger> mungers = member.getDeclaringType().resolve(world).getInterTypeMungers();
  634. for (ConcreteTypeMunger typeMunger : mungers) {
  635. if (typeMunger.getMunger() instanceof NewFieldTypeMunger) {
  636. ResolvedMember fakerm = typeMunger.getSignature();
  637. ResolvedMember ajcMethod = AjcMemberMaker.interFieldInitializer(fakerm, typeMunger.getAspectType());
  638. ResolvedMember rmm = findMethod(typeMunger.getAspectType(), ajcMethod);
  639. if (fakerm.equals(member)) {
  640. member = rmm;
  641. }
  642. }
  643. }
  644. }
  645. if (annotationPattern.matches(member).alwaysTrue()) {
  646. return FuzzyBoolean.YES;
  647. } else {
  648. // do NOT look at ancestor members... only the subject can have an annotation match
  649. // see http://www.eclipse.org/aspectj/doc/next/adk15notebook/join-point-modifiers.html
  650. return FuzzyBoolean.NO;
  651. }
  652. }
  653. private ResolvedMember findMethod(ResolvedType aspectType, ResolvedMember ajcMethod) {
  654. ResolvedMember decMethods[] = aspectType.getDeclaredMethods();
  655. for (ResolvedMember member : decMethods) {
  656. if (member.equals(ajcMethod)) {
  657. return member;
  658. }
  659. }
  660. return null;
  661. }
  662. public boolean declaringTypeMatchAllowingForCovariance(Member member, UnresolvedType shadowDeclaringType, World world,
  663. TypePattern returnTypePattern, ResolvedType sigReturn) {
  664. ResolvedType onType = shadowDeclaringType.resolve(world);
  665. // fastmatch
  666. if (declaringType.matchesStatically(onType) && returnTypePattern.matchesStatically(sigReturn)) {
  667. return true;
  668. }
  669. Collection<ResolvedType> declaringTypes = member.getDeclaringTypes(world);
  670. boolean checkReturnType = true;
  671. // XXX Possible enhancement? Doesn't seem to speed things up
  672. // if (returnTypePattern.isStar()) {
  673. // if (returnTypePattern instanceof WildTypePattern) {
  674. // if (((WildTypePattern)returnTypePattern).getDimensions()==0) checkReturnType = false;
  675. // }
  676. // }
  677. // Sometimes that list includes types that don't explicitly declare the member we are after -
  678. // they are on the list because their supertype is on the list, that's why we use
  679. // lookupMethod rather than lookupMemberNoSupers()
  680. for (ResolvedType type : declaringTypes) {
  681. if (declaringType.matchesStatically(type)) {
  682. if (!checkReturnType) {
  683. return true;
  684. }
  685. ResolvedMember rm = type.lookupMethod(member);
  686. if (rm == null) {
  687. rm = type.lookupMethodInITDs(member); // It must be in here, or we have *real* problems
  688. }
  689. if (rm == null) {
  690. continue; // might be currently looking at the generic type and we need to continue searching in case we hit a
  691. }
  692. // parameterized version of this same type...
  693. UnresolvedType returnTypeX = rm.getReturnType();
  694. ResolvedType returnType = returnTypeX.resolve(world);
  695. if (returnTypePattern.matchesStatically(returnType)) {
  696. return true;
  697. }
  698. }
  699. }
  700. return false;
  701. }
  702. // private Collection getDeclaringTypes(Signature sig) {
  703. // List l = new ArrayList();
  704. // Class onType = sig.getDeclaringType();
  705. // String memberName = sig.getName();
  706. // if (sig instanceof FieldSignature) {
  707. // Class fieldType = ((FieldSignature)sig).getFieldType();
  708. // Class superType = onType;
  709. // while(superType != null) {
  710. // try {
  711. // Field f = (superType.getDeclaredField(memberName));
  712. // if (f.getType() == fieldType) {
  713. // l.add(superType);
  714. // }
  715. // } catch (NoSuchFieldException nsf) {}
  716. // superType = superType.getSuperclass();
  717. // }
  718. // } else if (sig instanceof MethodSignature) {
  719. // Class[] paramTypes = ((MethodSignature)sig).getParameterTypes();
  720. // Class superType = onType;
  721. // while(superType != null) {
  722. // try {
  723. // superType.getDeclaredMethod(memberName,paramTypes);
  724. // l.add(superType);
  725. // } catch (NoSuchMethodException nsm) {}
  726. // superType = superType.getSuperclass();
  727. // }
  728. // }
  729. // return l;
  730. // }
  731. public NamePattern getName() {
  732. return name;
  733. }
  734. public TypePattern getDeclaringType() {
  735. return declaringType;
  736. }
  737. public MemberKind getKind() {
  738. return kind;
  739. }
  740. @Override
  741. public String toString() {
  742. StringBuilder buf = new StringBuilder();
  743. if (annotationPattern != AnnotationTypePattern.ANY) {
  744. buf.append(annotationPattern.toString());
  745. buf.append(' ');
  746. }
  747. if (modifiers != ModifiersPattern.ANY) {
  748. buf.append(modifiers.toString());
  749. buf.append(' ');
  750. }
  751. if (kind == Member.STATIC_INITIALIZATION) {
  752. buf.append(declaringType.toString());
  753. buf.append(".<clinit>()");// FIXME AV - bad, cannot be parsed again
  754. } else if (kind == Member.HANDLER) {
  755. buf.append("handler(");
  756. buf.append(parameterTypes.get(0));
  757. buf.append(")");
  758. } else {
  759. if (!(kind == Member.CONSTRUCTOR)) {
  760. buf.append(returnType.toString());
  761. buf.append(' ');
  762. }
  763. if (declaringType != TypePattern.ANY) {
  764. buf.append(declaringType.toString());
  765. buf.append('.');
  766. }
  767. if (kind == Member.CONSTRUCTOR) {
  768. buf.append("new");
  769. } else {
  770. buf.append(name.toString());
  771. }
  772. if (kind == Member.METHOD || kind == Member.CONSTRUCTOR) {
  773. buf.append(parameterTypes.toString());
  774. }
  775. // FIXME AV - throws is not printed here, weird
  776. }
  777. return buf.toString();
  778. }
  779. @Override
  780. public boolean equals(Object other) {
  781. if (!(other instanceof SignaturePattern)) {
  782. return false;
  783. }
  784. SignaturePattern o = (SignaturePattern) other;
  785. return o.kind.equals(this.kind) && o.modifiers.equals(this.modifiers) && o.returnType.equals(this.returnType)
  786. && o.declaringType.equals(this.declaringType) && o.name.equals(this.name)
  787. && o.parameterTypes.equals(this.parameterTypes) && o.throwsPattern.equals(this.throwsPattern)
  788. && o.annotationPattern.equals(this.annotationPattern);
  789. }
  790. @Override
  791. public int hashCode() {
  792. if (hashcode == -1) {
  793. hashcode = 17;
  794. hashcode = 37 * hashcode + kind.hashCode();
  795. hashcode = 37 * hashcode + modifiers.hashCode();
  796. hashcode = 37 * hashcode + returnType.hashCode();
  797. hashcode = 37 * hashcode + declaringType.hashCode();
  798. hashcode = 37 * hashcode + name.hashCode();
  799. hashcode = 37 * hashcode + parameterTypes.hashCode();
  800. hashcode = 37 * hashcode + throwsPattern.hashCode();
  801. hashcode = 37 * hashcode + annotationPattern.hashCode();
  802. }
  803. return hashcode;
  804. }
  805. @Override
  806. public void write(CompressingDataOutputStream s) throws IOException {
  807. kind.write(s);
  808. modifiers.write(s);
  809. returnType.write(s);
  810. declaringType.write(s);
  811. name.write(s);
  812. parameterTypes.write(s);
  813. throwsPattern.write(s);
  814. annotationPattern.write(s);
  815. writeLocation(s);
  816. }
  817. public static SignaturePattern read(VersionedDataInputStream s, ISourceContext context) throws IOException {
  818. // ISignaturePattern kind should already have been read by the time this read is entered
  819. MemberKind kind = MemberKind.read(s);
  820. ModifiersPattern modifiers = ModifiersPattern.read(s);
  821. TypePattern returnType = TypePattern.read(s, context);
  822. TypePattern declaringType = TypePattern.read(s, context);
  823. NamePattern name = NamePattern.read(s);
  824. TypePatternList parameterTypes = TypePatternList.read(s, context);
  825. ThrowsPattern throwsPattern = ThrowsPattern.read(s, context);
  826. AnnotationTypePattern annotationPattern = AnnotationTypePattern.ANY;
  827. if (s.getMajorVersion() >= AjAttribute.WeaverVersionInfo.WEAVER_VERSION_MAJOR_AJ150) {
  828. annotationPattern = AnnotationTypePattern.read(s, context);
  829. }
  830. SignaturePattern ret = new SignaturePattern(kind, modifiers, returnType, declaringType, name, parameterTypes,
  831. throwsPattern, annotationPattern);
  832. ret.readLocation(context, s);
  833. return ret;
  834. }
  835. /**
  836. * @return
  837. */
  838. public ModifiersPattern getModifiers() {
  839. return modifiers;
  840. }
  841. /**
  842. * @return
  843. */
  844. public TypePatternList getParameterTypes() {
  845. return parameterTypes;
  846. }
  847. /**
  848. * @return
  849. */
  850. public TypePattern getReturnType() {
  851. return returnType;
  852. }
  853. /**
  854. * @return
  855. */
  856. public ThrowsPattern getThrowsPattern() {
  857. return throwsPattern;
  858. }
  859. /**
  860. * return true if last argument in params is an Object[] but the modifiers say this method was declared with varargs
  861. * (Object...). We shouldn't be matching if this is the case.
  862. */
  863. // private boolean matchedArrayAgainstVarArgs(TypePatternList params,int modifiers) {
  864. // if (params.size()>0 && (modifiers & Constants.ACC_VARARGS)!=0) {
  865. // // we have at least one parameter in the pattern list, and the method has a varargs signature
  866. // TypePattern lastPattern = params.get(params.size()-1);
  867. // if (lastPattern.isArray() && !lastPattern.isVarArgs) return true;
  868. // }
  869. // return false;
  870. // }
  871. public AnnotationTypePattern getAnnotationPattern() {
  872. return annotationPattern;
  873. }
  874. @Override
  875. public boolean isStarAnnotation() {
  876. return annotationPattern == AnnotationTypePattern.ANY;
  877. }
  878. @Override
  879. public Object accept(PatternNodeVisitor visitor, Object data) {
  880. return visitor.visit(this, data);
  881. }
  882. public Object traverse(PatternNodeVisitor visitor, Object data) {
  883. Object ret = accept(visitor, data);
  884. if (this.annotationPattern != null)
  885. this.annotationPattern.traverse(visitor, ret);
  886. if (this.returnType != null)
  887. this.returnType.traverse(visitor, ret);
  888. if (this.declaringType != null)
  889. this.declaringType.traverse(visitor, ret);
  890. if (this.name != null)
  891. this.name.traverse(visitor, ret);
  892. if (this.parameterTypes != null)
  893. this.parameterTypes.traverse(visitor, ret);
  894. if (this.throwsPattern != null)
  895. this.throwsPattern.traverse(visitor, ret);
  896. return ret;
  897. }
  898. public boolean isExactDeclaringTypePattern() {
  899. return isExactDeclaringTypePattern;
  900. }
  901. @Override
  902. public boolean isMatchOnAnyName() {
  903. return getName().isAny();
  904. }
  905. @Override
  906. public List<ExactTypePattern> getExactDeclaringTypes() {
  907. if (declaringType instanceof ExactTypePattern) {
  908. List<ExactTypePattern> l = new ArrayList<>();
  909. l.add((ExactTypePattern) declaringType);
  910. return l;
  911. } else {
  912. return Collections.emptyList();
  913. }
  914. }
  915. @Override
  916. public boolean couldEverMatch(ResolvedType type) {
  917. return declaringType.matches(type, TypePattern.STATIC).maybeTrue();
  918. }
  919. }