1 /* *******************************************************************
2 * Copyright (c) 2002 Palo Alto Research Center, Incorporated (PARC).
4 * This program and the accompanying materials are made available
5 * under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
10 * PARC initial implementation
11 * ******************************************************************/
13 package org.aspectj.ajdt.internal.compiler.problem;
15 import java.io.PrintWriter;
16 import java.io.StringWriter;
17 import java.lang.reflect.Modifier;
18 import java.util.Collection;
19 import java.util.HashSet;
20 import java.util.Iterator;
21 import java.util.List;
24 import org.aspectj.ajdt.internal.compiler.ast.AdviceDeclaration;
25 import org.aspectj.ajdt.internal.compiler.ast.AspectDeclaration;
26 import org.aspectj.ajdt.internal.compiler.ast.DeclareAnnotationDeclaration;
27 import org.aspectj.ajdt.internal.compiler.ast.IfMethodDeclaration;
28 import org.aspectj.ajdt.internal.compiler.ast.PointcutDeclaration;
29 import org.aspectj.ajdt.internal.compiler.ast.Proceed;
30 import org.aspectj.ajdt.internal.compiler.lookup.EclipseFactory;
31 import org.aspectj.ajdt.internal.compiler.lookup.InterTypeMethodBinding;
32 import org.aspectj.ajdt.internal.compiler.lookup.PrivilegedFieldBinding;
33 import org.aspectj.bridge.context.CompilationAndWeavingContext;
34 import org.aspectj.org.eclipse.jdt.core.compiler.CharOperation;
35 import org.aspectj.org.eclipse.jdt.core.compiler.IProblem;
36 import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult;
37 import org.aspectj.org.eclipse.jdt.internal.compiler.IErrorHandlingPolicy;
38 import org.aspectj.org.eclipse.jdt.internal.compiler.IProblemFactory;
39 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ASTNode;
40 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration;
41 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Annotation;
42 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Argument;
43 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.ExplicitConstructorCall;
44 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.Expression;
45 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.FieldDeclaration;
46 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.LocalDeclaration;
47 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.QualifiedNameReference;
48 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.TypeDeclaration;
49 import org.aspectj.org.eclipse.jdt.internal.compiler.impl.CompilerOptions;
50 import org.aspectj.org.eclipse.jdt.internal.compiler.impl.ReferenceContext;
51 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ArrayBinding;
52 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.IPrivilegedHandler;
53 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.LocalVariableBinding;
54 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.MethodBinding;
55 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ParameterizedMethodBinding;
56 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding;
57 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.Scope;
58 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.SourceTypeBinding;
59 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TagBits;
60 import org.aspectj.org.eclipse.jdt.internal.compiler.lookup.TypeBinding;
61 import org.aspectj.org.eclipse.jdt.internal.compiler.problem.ProblemReporter;
62 import org.aspectj.org.eclipse.jdt.internal.compiler.problem.ProblemSeverities;
63 import org.aspectj.util.FuzzyBoolean;
64 import org.aspectj.weaver.AjcMemberMaker;
65 import org.aspectj.weaver.ConcreteTypeMunger;
66 import org.aspectj.weaver.ReferenceType;
67 import org.aspectj.weaver.ResolvedMember;
68 import org.aspectj.weaver.ResolvedType;
69 import org.aspectj.weaver.ResolvedTypeMunger;
70 import org.aspectj.weaver.Shadow;
71 import org.aspectj.weaver.UnresolvedType;
72 import org.aspectj.weaver.patterns.Declare;
73 import org.aspectj.weaver.patterns.DeclareAnnotation;
74 import org.aspectj.weaver.patterns.DeclareParents;
75 import org.aspectj.weaver.patterns.DeclareSoft;
76 import org.aspectj.weaver.patterns.TypePattern;
79 * Extends problem reporter to support compiler-side implementation of declare soft. Also overrides error reporting for the need to
80 * implement abstract methods to account for inter-type declarations and pointcut declarations. This second job might be better done
81 * directly in the SourceTypeBinding/ClassScope classes.
85 public class AjProblemReporter extends ProblemReporter {
87 private static final boolean DUMP_STACK = false;
89 public EclipseFactory factory;
91 public AjProblemReporter(IErrorHandlingPolicy policy, CompilerOptions options, IProblemFactory problemFactory) {
92 super(policy, options, problemFactory);
95 public void unhandledException(TypeBinding exceptionType, ASTNode location) {
96 if (!factory.getWorld().getDeclareSoft().isEmpty()) {
97 Shadow callSite = factory.makeShadow(location, referenceContext);
98 Shadow enclosingExec = factory.makeShadow(referenceContext);
99 // PR 72157 - calls to super / this within a constructor are not part of the cons join point.
100 if ((callSite == null) && (enclosingExec.getKind() == Shadow.ConstructorExecution)
101 && (location instanceof ExplicitConstructorCall)) {
102 super.unhandledException(exceptionType, location);
105 // System.err.println("about to show error for unhandled exception: " + new String(exceptionType.sourceName()) +
106 // " at " + location + " in " + referenceContext);
108 for (DeclareSoft d: factory.getWorld().getDeclareSoft()) {
109 // for (Iterator<DeclareSoft> i = factory.getWorld().getDeclareSoft().iterator(); i.hasNext();) {
110 // DeclareSoft d = (DeclareSoft) i.next();
111 // We need the exceptionType to match the type in the declare soft statement
112 // This means it must either be the same type or a subtype
113 ResolvedType throwException = factory.fromEclipse((ReferenceBinding) exceptionType);
114 FuzzyBoolean isExceptionTypeOrSubtype = d.getException().matchesInstanceof(throwException);
115 if (!isExceptionTypeOrSubtype.alwaysTrue())
118 if (callSite != null) {
119 FuzzyBoolean match = d.getPointcut().match(callSite);
120 if (match.alwaysTrue()) {
121 // System.err.println("matched callSite: " + callSite + " with " + d);
123 } else if (!match.alwaysFalse()) {
124 // !!! need this check to happen much sooner
125 // throw new RuntimeException("unimplemented, shouldn't have fuzzy match here");
128 if (enclosingExec != null) {
129 FuzzyBoolean match = d.getPointcut().match(enclosingExec);
130 if (match.alwaysTrue()) {
131 // System.err.println("matched enclosingExec: " + enclosingExec + " with " + d);
133 } else if (!match.alwaysFalse()) {
134 // !!! need this check to happen much sooner
135 // throw new RuntimeException("unimplemented, shouldn't have fuzzy match here");
141 // ??? is this always correct
142 if (location instanceof Proceed) {
146 super.unhandledException(exceptionType, location);
149 public void unhandledExceptionFromAutoClose(TypeBinding exceptionType, ASTNode location) {
150 if (!factory.getWorld().getDeclareSoft().isEmpty()) {
151 Shadow callSite = factory.makeShadow(location, referenceContext);
152 Shadow enclosingExec = factory.makeShadow(referenceContext);
153 // PR 72157 - calls to super / this within a constructor are not part of the cons join point.
154 if ((callSite == null) && (enclosingExec.getKind() == Shadow.ConstructorExecution)
155 && (location instanceof ExplicitConstructorCall)) {
156 super.unhandledException(exceptionType, location);
159 // System.err.println("about to show error for unhandled exception: " + new String(exceptionType.sourceName()) +
160 // " at " + location + " in " + referenceContext);
162 for (DeclareSoft d: factory.getWorld().getDeclareSoft()) {
163 // for (Iterator<DeclareSoft> i = factory.getWorld().getDeclareSoft().iterator(); i.hasNext();) {
164 // DeclareSoft d = (DeclareSoft) i.next();
165 // We need the exceptionType to match the type in the declare soft statement
166 // This means it must either be the same type or a subtype
167 ResolvedType throwException = factory.fromEclipse((ReferenceBinding) exceptionType);
168 FuzzyBoolean isExceptionTypeOrSubtype = d.getException().matchesInstanceof(throwException);
169 if (!isExceptionTypeOrSubtype.alwaysTrue())
172 if (callSite != null) {
173 FuzzyBoolean match = d.getPointcut().match(callSite);
174 if (match.alwaysTrue()) {
175 // System.err.println("matched callSite: " + callSite + " with " + d);
177 } else if (!match.alwaysFalse()) {
178 // !!! need this check to happen much sooner
179 // throw new RuntimeException("unimplemented, shouldn't have fuzzy match here");
182 if (enclosingExec != null) {
183 FuzzyBoolean match = d.getPointcut().match(enclosingExec);
184 if (match.alwaysTrue()) {
185 // System.err.println("matched enclosingExec: " + enclosingExec + " with " + d);
187 } else if (!match.alwaysFalse()) {
188 // !!! need this check to happen much sooner
189 // throw new RuntimeException("unimplemented, shouldn't have fuzzy match here");
195 // ??? is this always correct
196 if (location instanceof Proceed) {
200 super.unhandledExceptionFromAutoClose(exceptionType, location);
203 private boolean isPointcutDeclaration(MethodBinding binding) {
204 return CharOperation.prefixEquals(PointcutDeclaration.mangledPrefix, binding.selector);
207 private boolean isIntertypeDeclaration(MethodBinding binding) {
208 return (binding instanceof InterTypeMethodBinding);
211 public void abstractMethodCannotBeOverridden(SourceTypeBinding type, MethodBinding concreteMethod) {
212 if (isPointcutDeclaration(concreteMethod)) {
215 super.abstractMethodCannotBeOverridden(type, concreteMethod);
218 public void inheritedMethodReducesVisibility(SourceTypeBinding type, MethodBinding concreteMethod,
219 MethodBinding[] abstractMethods) {
220 // if we implemented this method by a public inter-type declaration, then there is no error
222 ResolvedType onTypeX = null;
223 // If the type is anonymous, look at its supertype
224 if (!type.isAnonymousType()) {
225 onTypeX = factory.fromEclipse(type);
227 // Hmmm. If the ITD is on an interface that is being 'instantiated' using an anonymous type,
228 // we sort it out elsewhere and don't come into this method -
229 // so we don't have to worry about interfaces, just the superclass.
230 onTypeX = factory.fromEclipse(type.superclass()); // abstractMethod.declaringClass);
232 for (ConcreteTypeMunger m : onTypeX.getInterTypeMungersIncludingSupers()) {
233 ResolvedMember sig = m.getSignature();
234 if (!Modifier.isAbstract(sig.getModifiers())) {
235 if (ResolvedType.matches(
236 AjcMemberMaker.interMethod(sig, m.getAspectType(), sig.getDeclaringType().resolve(factory.getWorld())
237 .isInterface()), factory.makeResolvedMember(concreteMethod))) {
243 super.inheritedMethodReducesVisibility(type, concreteMethod, abstractMethods);
246 // if either of the MethodBinding is an ITD, we have already reported it.
247 public void staticAndInstanceConflict(MethodBinding currentMethod, MethodBinding inheritedMethod) {
248 if (currentMethod instanceof InterTypeMethodBinding)
250 if (inheritedMethod instanceof InterTypeMethodBinding)
252 super.staticAndInstanceConflict(currentMethod, inheritedMethod);
255 public void abstractMethodMustBeImplemented(SourceTypeBinding type, MethodBinding abstractMethod) {
256 // if this is a PointcutDeclaration then there is no error
257 if (isPointcutDeclaration(abstractMethod))
260 if (isIntertypeDeclaration(abstractMethod))
261 return; // when there is a problem with an ITD not being implemented, it will be reported elsewhere
263 if (CharOperation.prefixEquals("ajc$interField".toCharArray(), abstractMethod.selector)) {
264 // ??? think through how this could go wrong
268 // if we implemented this method by an inter-type declaration, then there is no error
269 // ??? be sure this is always right
270 ResolvedType onTypeX = null;
272 // If the type is anonymous, look at its supertype
273 if (!type.isAnonymousType()) {
274 onTypeX = factory.fromEclipse(type);
276 // Hmmm. If the ITD is on an interface that is being 'instantiated' using an anonymous type,
277 // we sort it out elsewhere and don't come into this method -
278 // so we don't have to worry about interfaces, just the superclass.
279 onTypeX = factory.fromEclipse(type.superclass()); // abstractMethod.declaringClass);
282 if (onTypeX.isRawType())
283 onTypeX = onTypeX.getGenericType();
285 List<ConcreteTypeMunger> mungers = onTypeX.getInterTypeMungersIncludingSupers();
286 for (ConcreteTypeMunger m : mungers) {
287 ResolvedMember sig = m.getSignature();
288 if (sig != null && !Modifier.isAbstract(sig.getModifiers())) {
289 ResolvedMember abstractMember = factory.makeResolvedMember(abstractMethod);
290 if (abstractMember.getName().startsWith("ajc$interMethodDispatch")) {
291 ResolvedType dType = factory.getWorld().resolve(sig.getDeclaringType(), false);
292 if (ResolvedType.matches(AjcMemberMaker.interMethod(sig, m.getAspectType(), dType.isInterface()),
297 // In this case we have something like:
299 // abstract class C implements I { abstract void foo();}
300 // class D extends C {}
301 // ITD: public void I.foo() {...}
302 // The ITD is providing the implementation of foo in the class D but when checking for whether the abstract
303 // method is overridden, we won't be looking at whether the ITD overrides ajc$interMethodDispath$...foo but
304 // whether it overrides the foo method from class C
305 if (ResolvedType.matches(sig, factory.makeResolvedMember(abstractMethod)))
311 super.abstractMethodMustBeImplemented(type, abstractMethod);
318 * org.aspectj.org.eclipse.jdt.internal.compiler.problem.ProblemReporter#disallowedTargetForAnnotation(org.aspectj.org.eclipse
319 * .jdt.internal.compiler.ast.Annotation)
321 public void disallowedTargetForAnnotation(Annotation annotation) {
322 // if the annotation's recipient is an ITD, it might be allowed after all...
323 if (annotation.recipient instanceof MethodBinding) {
324 MethodBinding binding = (MethodBinding) annotation.recipient;
325 String name = new String(binding.selector);
326 if (name.startsWith("ajc$")) {
327 long metaTagBits = annotation.resolvedType.getAnnotationTagBits(); // could be forward reference
328 if (name.indexOf("interField") != -1) {
329 if ((metaTagBits & TagBits.AnnotationForField) != 0)
331 } else if (name.indexOf("interConstructor") != -1) {
332 if ((metaTagBits & TagBits.AnnotationForConstructor) != 0)
334 } else if (name.indexOf("interMethod") != -1) {
335 if ((metaTagBits & TagBits.AnnotationForMethod) != 0)
337 } else if (name.indexOf("declare_" + DeclareAnnotation.AT_TYPE + "_") != -1) {
338 if ((metaTagBits & TagBits.AnnotationForAnnotationType) != 0 || (metaTagBits & TagBits.AnnotationForType) != 0)
340 } else if (name.indexOf("declare_" + DeclareAnnotation.AT_FIELD + "_") != -1) {
341 if ((metaTagBits & TagBits.AnnotationForField) != 0)
343 } else if (name.indexOf("declare_" + DeclareAnnotation.AT_CONSTRUCTOR + "_") != -1) {
344 if ((metaTagBits & TagBits.AnnotationForConstructor) != 0)
346 } else if (name.indexOf("declare_eow") != -1) {
347 if ((metaTagBits & TagBits.AnnotationForField) != 0)
353 // not our special case, report the problem...
354 super.disallowedTargetForAnnotation(annotation);
357 public void overridesPackageDefaultMethod(MethodBinding localMethod, MethodBinding inheritedMethod) {
358 if (new String(localMethod.selector).startsWith("ajc$"))
360 super.overridesPackageDefaultMethod(localMethod, inheritedMethod);
363 public void handle(int problemId, String[] problemArguments, String[] messageArguments, int severity, int problemStartPosition,
364 int problemEndPosition, ReferenceContext referenceContext, CompilationResult unitResult) {
365 if (severity != ProblemSeverities.Ignore && DUMP_STACK) {
368 super.handle(problemId, problemArguments,
369 0, // no message elaboration
370 messageArguments, severity, problemStartPosition, problemEndPosition,
371 referenceContext, unitResult);
375 public void javadocMissingParamTag(char[] name, int sourceStart, int sourceEnd, int modifiers) {
376 boolean reportIt = true;
377 String sName = new String(name);
378 if (sName.startsWith("ajc$"))
380 if (sName.equals("thisJoinPoint"))
382 if (sName.equals("thisJoinPointStaticPart"))
384 if (sName.equals("thisEnclosingJoinPointStaticPart"))
386 if (sName.equals("ajc_aroundClosure"))
389 super.javadocMissingParamTag(name, sourceStart, sourceEnd, modifiers);
392 public void abstractMethodInAbstractClass(SourceTypeBinding type, AbstractMethodDeclaration methodDecl) {
394 String abstractMethodName = new String(methodDecl.selector);
395 if (abstractMethodName.startsWith("ajc$pointcut")) {
396 // This will already have been reported, see: PointcutDeclaration.postParse()
399 String[] arguments = new String[] { new String(type.sourceName()), abstractMethodName };
400 super.handle(IProblem.AbstractMethodInAbstractClass, arguments, arguments, methodDecl.sourceStart, methodDecl.sourceEnd,
401 this.referenceContext, this.referenceContext == null ? null : this.referenceContext.compilationResult());
405 * Called when there is an ITD marked @override that doesn't override a supertypes method. The method and the binding are passed
406 * - some information is useful from each. The 'method' knows about source offsets for the message, the 'binding' has the
407 * signature of what the ITD is trying to be in the target class.
409 public void itdMethodMustOverride(AbstractMethodDeclaration method, MethodBinding binding) {
410 this.handle(IProblem.MethodMustOverride,
411 new String[] { new String(binding.selector), typesAsString(binding.isVarargs(), binding.parameters, false),
412 new String(binding.declaringClass.readableName()), },
413 new String[] { new String(binding.selector), typesAsString(binding.isVarargs(), binding.parameters, true),
414 new String(binding.declaringClass.shortReadableName()), }, method.sourceStart, method.sourceEnd,
415 this.referenceContext, this.referenceContext == null ? null : this.referenceContext.compilationResult());
419 * Overrides the implementation in ProblemReporter and is ITD aware. To report a *real* problem with an ITD marked @override,
420 * the other methodMustOverride() method is used.
422 public void methodMustOverride(AbstractMethodDeclaration method, long complianceLevel) {
424 // ignore ajc$ methods
425 if (new String(method.selector).startsWith("ajc$"))
427 ResolvedMember possiblyErroneousRm = factory.makeResolvedMember(method.binding);
429 ResolvedType onTypeX = factory.fromEclipse(method.binding.declaringClass);
430 // Can't use 'getInterTypeMungersIncludingSupers()' since that will exclude abstract ITDs
431 // on any super classes - so we have to trawl up ourselves.. I wonder if this problem
432 // affects other code in the problem reporter that looks through ITDs...
433 ResolvedType supertypeToLookAt = onTypeX.getSuperclass();
434 while (supertypeToLookAt != null) {
435 List<ConcreteTypeMunger> itMungers = supertypeToLookAt.getInterTypeMungers();
436 for (ConcreteTypeMunger m : itMungers) {
437 if (m.getMunger() != null && m.getMunger().getKind() == ResolvedTypeMunger.PrivilegedAccess) {
440 ResolvedMember sig = m.getSignature();
442 continue; // we aren't interested in other kinds of munger
443 UnresolvedType dType = sig.getDeclaringType();
446 ResolvedType resolvedDeclaringType = dType.resolve(factory.getWorld());
447 ResolvedMember rm = AjcMemberMaker.interMethod(sig, m.getAspectType(), resolvedDeclaringType.isInterface());
448 if (ResolvedType.matches(rm, possiblyErroneousRm)) {
449 // match, so dont need to report a problem!
453 supertypeToLookAt = supertypeToLookAt.getSuperclass();
455 // report the error...
456 super.methodMustOverride(method,complianceLevel);
459 private String typesAsString(boolean isVarargs, TypeBinding[] types, boolean makeShort) {
460 StringBuffer buffer = new StringBuffer(10);
461 for (int i = 0, length = types.length; i < length; i++) {
463 buffer.append(", "); //$NON-NLS-1$
464 TypeBinding type = types[i];
465 boolean isVarargType = isVarargs && i == length - 1;
467 type = ((ArrayBinding) type).elementsType();
468 buffer.append(new String(makeShort ? type.shortReadableName() : type.readableName()));
470 buffer.append("..."); //$NON-NLS-1$
472 return buffer.toString();
475 public void visibilityConflict(MethodBinding currentMethod, MethodBinding inheritedMethod) {
476 // Not quite sure if the conditions on this test are right - basically I'm saying
477 // DONT WORRY if its ITDs since the error will be reported another way...
478 if (isIntertypeDeclaration(currentMethod) && isIntertypeDeclaration(inheritedMethod)
479 && Modifier.isPrivate(currentMethod.modifiers) && Modifier.isPrivate(inheritedMethod.modifiers)) {
482 super.visibilityConflict(currentMethod, inheritedMethod);
485 public void unusedPrivateType(TypeDeclaration typeDecl) {
486 // don't output unused type warnings for aspects!
487 if (typeDecl instanceof AspectDeclaration)
489 if (typeDecl.enclosingType != null && (typeDecl.enclosingType instanceof AspectDeclaration)) {
490 AspectDeclaration ad = (AspectDeclaration) typeDecl.enclosingType;
491 if (ad.concreteName != null) {
492 List<Declare> declares = ad.concreteName.declares;
493 for (Object dec : declares) {
494 if (dec instanceof DeclareParents) {
495 DeclareParents decp = (DeclareParents) dec;
496 TypePattern[] newparents = decp.getParents().getTypePatterns();
497 for (TypePattern pattern : newparents) {
498 UnresolvedType ut = pattern.getExactType();
501 if (CharOperation.compareWith(typeDecl.binding.signature(), ut.getSignature().toCharArray()) == 0)
508 super.unusedPrivateType(typeDecl);
511 private final static char[] thisJoinPointName = "thisJoinPoint".toCharArray();
512 private final static char[] thisJoinPointStaticPartName = "thisJoinPointStaticPart".toCharArray();
513 private final static char[] thisEnclosingJoinPointStaticPartName = "thisEnclosingJoinPointStaticPart".toCharArray();
514 private final static char[] thisAspectInstanceName = "thisAspectInstance".toCharArray();
517 public void uninitializedLocalVariable(LocalVariableBinding binding, ASTNode location, Scope scope) {
518 if (CharOperation.equals(binding.name, thisJoinPointName) ||
519 CharOperation.equals(binding.name, thisJoinPointStaticPartName) ||
520 CharOperation.equals(binding.name, thisAspectInstanceName) ||
521 CharOperation.equals(binding.name, thisEnclosingJoinPointStaticPartName)) {
522 // If in advice, this is not a problem
523 if (binding.declaringScope!=null && (binding.declaringScope.referenceContext() instanceof AdviceDeclaration ||
524 binding.declaringScope.referenceContext() instanceof IfMethodDeclaration)) {
528 super.uninitializedLocalVariable(binding, location, scope);
531 public void abstractMethodInConcreteClass(SourceTypeBinding type) {
532 if (type.scope!=null && type.scope.referenceContext instanceof AspectDeclaration) {
533 // TODO could put out an Aspect specific message here
536 super.abstractMethodInConcreteClass(type);
539 // Don't warn if there is an ITD method/ctor from a privileged aspect
540 public void unusedPrivateField(FieldDeclaration fieldDecl) {
541 if (fieldDecl!=null && fieldDecl.binding != null && fieldDecl.binding.declaringClass != null) {
542 ReferenceBinding type = fieldDecl.binding.declaringClass;
544 ResolvedType weaverType = null;
545 if (!type.isAnonymousType()) {
546 weaverType = factory.fromEclipse(type);
548 weaverType = factory.fromEclipse(type.superclass());
550 Set checked = new HashSet();
551 for (ConcreteTypeMunger m : weaverType.getInterTypeMungersIncludingSupers()) {
552 ResolvedType theAspect = m.getAspectType();
553 if (!checked.contains(theAspect)) {
554 TypeBinding tb = factory.makeTypeBinding(m.getAspectType());
555 // Let's check the privilegedHandler from that aspect
556 if (tb instanceof SourceTypeBinding) { // BinaryTypeBinding is also a SourceTypeBinding ;)
557 IPrivilegedHandler privilegedHandler = ((SourceTypeBinding) tb).privilegedHandler;
558 if (privilegedHandler != null) {
559 if (privilegedHandler.definesPrivilegedAccessToField(fieldDecl.binding)) {
562 } else if (theAspect instanceof ReferenceType) {
563 // ResolvedMember rm = factory.makeResolvedMember(fieldDecl.binding);
564 String fname = new String(fieldDecl.name);
565 Collection/* ResolvedMember */privvies = ((ReferenceType) theAspect).getPrivilegedAccesses();
566 // On an incremental compile the information is in the bcel delegate
567 if (privvies != null) {
568 for (Object privvy : privvies) {
569 ResolvedMember priv = (ResolvedMember) privvy;
570 if (priv.getName().equals(fname)) {
577 checked.add(theAspect);
581 super.unusedPrivateField(fieldDecl);
584 public void unusedPrivateMethod(AbstractMethodDeclaration methodDecl) {
585 // don't output unused warnings for pointcuts...
586 if (!(methodDecl instanceof PointcutDeclaration))
587 super.unusedPrivateMethod(methodDecl);
590 public void caseExpressionMustBeConstant(Expression expression) {
591 if (expression instanceof QualifiedNameReference) {
592 QualifiedNameReference qnr = (QualifiedNameReference) expression;
593 if (qnr.otherBindings != null && qnr.otherBindings.length > 0 && qnr.otherBindings[0] instanceof PrivilegedFieldBinding) {
594 super.signalError(expression.sourceStart, expression.sourceEnd,
595 "Fields accessible due to an aspect being privileged can not be used in switch statements");
596 referenceContext.tagAsHavingErrors();
600 super.caseExpressionMustBeConstant(expression);
603 public void unusedArgument(LocalDeclaration localDecl) {
604 // don't warn if this is an aj synthetic arg
605 String argType = new String(localDecl.type.resolvedType.signature());
606 if (argType.startsWith("Lorg/aspectj/runtime/internal"))
609 // If the unused argument is in a pointcut, don't report the problem (for now... pr148219)
610 if (localDecl instanceof Argument) {
611 Argument arg = (Argument) localDecl;
612 if (arg.binding != null && arg.binding.declaringScope != null) {
613 ReferenceContext context = arg.binding.declaringScope.referenceContext();
614 if (context != null && context instanceof PointcutDeclaration)
618 if (new String(localDecl.name).startsWith("ajc$")) {
619 // Do not report problems for infrastructure variables beyond the users control - pr195090
622 super.unusedArgument(localDecl);
626 * A side-effect of the way that we handle itds on default methods on top-most implementors of interfaces is that a class
627 * acquiring a final default ITD will erroneously report that it can't override its own member. This method detects that
630 public void finalMethodCannotBeOverridden(MethodBinding currentMethod, MethodBinding inheritedMethod) {
631 if (currentMethod == inheritedMethod)
633 super.finalMethodCannotBeOverridden(currentMethod, inheritedMethod);
637 * The method verifier is a bit 'keen' and doesn't cope well with ITDMs which are of course to be considered a 'default'
638 * implementation if the target type doesn't supply one. This test may not be complete - it is possible that it should read if
639 * *either* is an ITD...but I dont have a testcase that shows that is required. yet. (pr115788)
641 public void duplicateInheritedMethods(SourceTypeBinding type, MethodBinding inheritedMethod1, MethodBinding inheritedMethod2, boolean isJava8) {
642 if (inheritedMethod1 instanceof InterTypeMethodBinding || inheritedMethod2 instanceof InterTypeMethodBinding)
644 if ((inheritedMethod1 instanceof ParameterizedMethodBinding)
645 && ((ParameterizedMethodBinding) inheritedMethod1).original() instanceof InterTypeMethodBinding)
647 if ((inheritedMethod2 instanceof ParameterizedMethodBinding)
648 && ((ParameterizedMethodBinding) inheritedMethod2).original() instanceof InterTypeMethodBinding)
650 super.duplicateInheritedMethods(type, inheritedMethod1, inheritedMethod2, isJava8);
654 * All problems end up routed through here at some point...
656 public IProblem createProblem(char[] fileName, int problemId, String[] problemArguments, String[] messageArguments,
657 int severity, int problemStartPosition, int problemEndPosition, int lineNumber) {
658 IProblem problem = super.createProblem(fileName, problemId, problemArguments, messageArguments, severity,
659 problemStartPosition, problemEndPosition, lineNumber, 0);
660 if (factory.getWorld().isInPinpointMode()) {
661 MessageIssued ex = new MessageIssued();
662 ex.fillInStackTrace();
663 StringWriter sw = new StringWriter();
664 ex.printStackTrace(new PrintWriter(sw));
665 StringBuffer sb = new StringBuffer();
666 sb.append(CompilationAndWeavingContext.getCurrentContext());
667 sb.append(sw.toString());
668 problem = new PinpointedProblem(problem, sb.toString());
673 private static class MessageIssued extends RuntimeException {
674 public String getMessage() {
675 return "message issued...";
679 private static class PinpointedProblem implements IProblem {
681 private IProblem delegate;
682 private String message;
684 public PinpointedProblem(IProblem aProblem, String pinpoint) {
685 this.delegate = aProblem;
686 // if this was a problem that came via the weaver, it will already have
687 // pinpoint info, don't do it twice...
688 if (delegate.getMessage().indexOf("message issued...") == -1) {
689 this.message = delegate.getMessage() + "\n" + pinpoint;
691 this.message = delegate.getMessage();
695 public String[] getArguments() {
696 return delegate.getArguments();
700 return delegate.getID();
703 public String getMessage() {
707 public char[] getOriginatingFileName() {
708 return delegate.getOriginatingFileName();
711 public int getSourceEnd() {
712 return delegate.getSourceEnd();
715 public int getSourceLineNumber() {
716 return delegate.getSourceLineNumber();
719 public int getSourceStart() {
720 return delegate.getSourceStart();
723 public boolean isError() {
724 return delegate.isError();
727 public boolean isWarning() {
728 return delegate.isWarning();
731 public void setSourceEnd(int sourceEnd) {
732 delegate.setSourceEnd(sourceEnd);
735 public void setSourceLineNumber(int lineNumber) {
736 delegate.setSourceLineNumber(lineNumber);
739 public void setSourceStart(int sourceStart) {
740 delegate.setSourceStart(sourceStart);
743 public void setSeeAlsoProblems(IProblem[] problems) {
744 delegate.setSeeAlsoProblems(problems);
747 public IProblem[] seeAlso() {
748 return delegate.seeAlso();
751 public void setSupplementaryMessageInfo(String msg) {
752 delegate.setSupplementaryMessageInfo(msg);
755 public String getSupplementaryMessageInfo() {
756 return delegate.getSupplementaryMessageInfo();
760 public boolean isInfo() {
761 return delegate.isInfo();
765 public void duplicateMethodInType(AbstractMethodDeclaration methodDecl, boolean equalParameters, int severity) {
766 if (new String(methodDecl.selector).startsWith("ajc$interMethod")) {
767 // this is an ITD clash and will be reported in another way by AspectJ (173602)
770 super.duplicateMethodInType(methodDecl, equalParameters, severity);
773 // pr246393 - if we are going to complain about privileged, we clearly don't know what is going on, so don't
775 public void parseErrorInsertAfterToken(int start, int end, int currentKind, char[] errorTokenSource, String errorTokenName,
776 String expectedToken) {
777 if (expectedToken.equals("privileged") || expectedToken.equals("around")) {
778 super.parseErrorNoSuggestion(start, end, currentKind, errorTokenSource, errorTokenName);
780 super.parseErrorInsertAfterToken(start, end, currentKind, errorTokenSource, errorTokenName, expectedToken);
784 public void missingValueForAnnotationMember(Annotation annotation, char[] memberName) {
785 if (referenceContext instanceof DeclareAnnotationDeclaration) {
786 // If a remover then the values are not necessary
787 if (((DeclareAnnotationDeclaration) referenceContext).isRemover()) {
791 super.missingValueForAnnotationMember(annotation, memberName);