]> source.dussan.org Git - aspectj.git/commitdiff
fix for pr62606 - raises a lint warning when itdc does not contain an explicit call...
authoracolyer <acolyer>
Thu, 3 Nov 2005 17:12:01 +0000 (17:12 +0000)
committeracolyer <acolyer>
Thu, 3 Nov 2005 17:12:01 +0000 (17:12 +0000)
org.aspectj.ajdt.core/src/org/aspectj/ajdt/internal/compiler/ast/InterTypeConstructorDeclaration.java

index 2decb4cc0470582f0b55db63e226151274c9b1c6..fec16738335090afcd52ed7e08c052b205d0cf9f 100644 (file)
@@ -15,7 +15,10 @@ package org.aspectj.ajdt.internal.compiler.ast;
 
 import java.lang.reflect.Modifier;
 import org.aspectj.ajdt.internal.compiler.lookup.*;
+import org.aspectj.bridge.ISourceLocation;
 import org.aspectj.weaver.*;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.MarkerAnnotation;
+import org.aspectj.org.eclipse.jdt.internal.compiler.ast.StringLiteral;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ClassFile;
 import org.aspectj.org.eclipse.jdt.internal.compiler.CompilationResult;
 import org.aspectj.org.eclipse.jdt.internal.compiler.ast.*;
@@ -32,6 +35,8 @@ import org.aspectj.org.eclipse.jdt.internal.compiler.parser.Parser;
  * @author Jim Hugunin
  */
 public class InterTypeConstructorDeclaration extends InterTypeDeclaration {    
+       private static final String SUPPRESSAJWARNINGS = "Lorg/aspectj/lang/annotation/SuppressAjWarnings;";
+       private static final String NOEXPLICITCONSTRUCTORCALL = "noExplicitConstructorCall";
        private MethodDeclaration preMethod;
        private ExplicitConstructorCall explicitConstructorCall = null;
        
@@ -69,8 +74,53 @@ public class InterTypeConstructorDeclaration extends InterTypeDeclaration {
                        this.arguments);
                        
                super.resolve(upperScope);
+               
+               // after annotations have been resolved...
+               if (explicitConstructorCall == null) {
+                       raiseNoFieldInitializersWarning();
+               }
        }
 
+       /**
+        * Warning added in response to PR 62606 - if an ITD constructor does not make an explicit constructor
+        * call then field initializers in the target class will not be executed leading to unexpected behaviour.
+        */
+       private void raiseNoFieldInitializersWarning() {
+               if (suppressingNoExplicitConstructorCall()) return;
+               EclipseFactory world = EclipseFactory.fromScopeLookupEnvironment(scope);
+               ISourceLocation location =
+                       new EclipseSourceLocation(scope.problemReporter().referenceContext.compilationResult(),
+                                                                       sourceStart(),sourceEnd());
+               world.getWorld().getLint().noExplicitConstructorCall.signal(null, location);
+       }
+       
+       /**
+        * true iff constructor has @SuppressAjWarnings or @SuppressAjWarnings("xyz,noExplicitConstructorCall,def,...")
+        * @return
+        */
+       private boolean suppressingNoExplicitConstructorCall() {
+               if (this.annotations == null) return false;
+               for (int i = 0; i < this.annotations.length; i++) {
+                       if (new String(this.annotations[i].resolvedType.signature()).equals(SUPPRESSAJWARNINGS)) {
+                               if (this.annotations[i] instanceof MarkerAnnotation) {
+                                       return true;
+                               } else if (this.annotations[i] instanceof SingleMemberAnnotation){
+                                       SingleMemberAnnotation sma = (SingleMemberAnnotation) this.annotations[i];
+                                       if (sma.memberValue instanceof ArrayInitializer) {
+                                               ArrayInitializer memberValue = (ArrayInitializer) sma.memberValue;
+                                               for (int j = 0; j < memberValue.expressions.length; j++) {
+                                                       if (memberValue.expressions[j] instanceof StringLiteral) {
+                                                               StringLiteral val = (StringLiteral) memberValue.expressions[j];
+                                                               if (new String(val.source()).equals(NOEXPLICITCONSTRUCTORCALL)) return true;
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+               return false;
+       }
+       
        private MethodDeclaration makePreMethod(ClassScope scope, 
                                                                                        ExplicitConstructorCall explicitConstructorCall)
        {