Refactory
[phpeclipse.git] / net.sourceforge.phpeclipse / src / net / sourceforge / phpdt / internal / compiler / ast / Annotation.java
diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/Annotation.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/ast/Annotation.java
deleted file mode 100644 (file)
index 7c35c84..0000000
+++ /dev/null
@@ -1,407 +0,0 @@
-/*******************************************************************************
- * Copyright (c) 2000, 2008 IBM Corporation and others.
- * All rights reserved. This program and the accompanying materials
- * are made available under the terms of the Eclipse Public License v1.0
- * which accompanies this distribution, and is available at
- * http://www.eclipse.org/legal/epl-v10.html
- *
- * Contributors:
- *     IBM Corporation - initial API and implementation
- *******************************************************************************/
-package net.sourceforge.phpdt.internal.compiler.ast;
-
-import net.sourceforge.phpdt.core.compiler.CharOperation;
-import net.sourceforge.phpdt.internal.compiler.ASTVisitor;
-import net.sourceforge.phpdt.internal.compiler.classfmt.ClassFileConstants;
-import net.sourceforge.phpdt.internal.compiler.impl.CompilerOptions;
-import net.sourceforge.phpdt.internal.compiler.impl.Constant;
-import net.sourceforge.phpdt.internal.compiler.lookup.*;
-
-/**
- * Annotation
- */
-public abstract class Annotation extends Expression {
-       
-       final static MemberValuePair[] NoValuePairs = new MemberValuePair[0];
-       public int declarationSourceEnd;
-       public Binding recipient;
-       
-       public TypeReference type;
-       /** 
-        *  The representation of this annotation in the type system. 
-        */
-       private AnnotationBinding compilerAnnotation = null;
-       
-       public static long getRetentionPolicy(char[] policyName) {
-               if (policyName == null || policyName.length == 0)
-                       return 0;
-               switch(policyName[0]) {
-                       case 'C' :
-                               if (CharOperation.equals(policyName, TypeConstants.UPPER_CLASS)) 
-                                       return TagBits.AnnotationClassRetention;
-                               break;
-                       case 'S' :
-                               if (CharOperation.equals(policyName, TypeConstants.UPPER_SOURCE)) 
-                                       return TagBits.AnnotationSourceRetention;
-                               break;
-                       case 'R' :
-                               if (CharOperation.equals(policyName, TypeConstants.UPPER_RUNTIME)) 
-                                       return TagBits.AnnotationRuntimeRetention;
-                               break;
-               }
-               return 0; // unknown
-       }
-       
-       public static long getTargetElementType(char[] elementName) {
-               if (elementName == null || elementName.length == 0)
-                       return 0;
-               switch(elementName[0]) {
-                       case 'A' :
-                               if (CharOperation.equals(elementName, TypeConstants.UPPER_ANNOTATION_TYPE)) 
-                                       return TagBits.AnnotationForAnnotationType;
-                               break;
-                       case 'C' :
-                               if (CharOperation.equals(elementName, TypeConstants.UPPER_CONSTRUCTOR)) 
-                                       return TagBits.AnnotationForConstructor;
-                               break;
-                       case 'F' :
-                               if (CharOperation.equals(elementName, TypeConstants.UPPER_FIELD)) 
-                                       return TagBits.AnnotationForField;
-                               break;
-                       case 'L' :
-                               if (CharOperation.equals(elementName, TypeConstants.UPPER_LOCAL_VARIABLE)) 
-                                       return TagBits.AnnotationForLocalVariable;
-                               break;
-                       case 'M' :
-                               if (CharOperation.equals(elementName, TypeConstants.UPPER_METHOD)) 
-                                       return TagBits.AnnotationForMethod;
-                               break;
-                       case 'P' :
-                               if (CharOperation.equals(elementName, TypeConstants.UPPER_PARAMETER)) 
-                                       return TagBits.AnnotationForParameter;
-                               else if (CharOperation.equals(elementName, TypeConstants.UPPER_PACKAGE)) 
-                                       return TagBits.AnnotationForPackage;
-                               break;
-                       case 'T' :
-                               if (CharOperation.equals(elementName, TypeConstants.TYPE)) 
-                                       return TagBits.AnnotationForType;
-                               break;
-               }
-               return 0; // unknown
-       }               
-
-       public ElementValuePair[] computeElementValuePairs() {
-               return Binding.NO_ELEMENT_VALUE_PAIRS;
-       }
-
-       /**
-        * Compute the bit pattern for recognized standard annotations the compiler may need to act upon
-        */
-       private long detectStandardAnnotation(Scope scope, ReferenceBinding annotationType, MemberValuePair valueAttribute) {
-               long tagBits = 0;
-               switch (annotationType.id) {
-                       // retention annotation
-                       case TypeIds.T_JavaLangAnnotationRetention :
-                               if (valueAttribute != null) {
-                                       Expression expr = valueAttribute.value;
-                                       if ((expr.bits & Binding.VARIABLE) == Binding.FIELD) {
-                                               FieldBinding field = ((Reference)expr).fieldBinding();
-                                               if (field != null && field.declaringClass.id == T_JavaLangAnnotationRetentionPolicy) {
-                                                       tagBits |= getRetentionPolicy(field.name);
-                                               }
-                                       }
-                               }
-                               break;
-                       // target annotation
-                       case TypeIds.T_JavaLangAnnotationTarget :               
-                               tagBits |= TagBits.AnnotationTarget; // target specified (could be empty)
-                               if (valueAttribute != null) {
-                                       Expression expr = valueAttribute.value;
-                                       if (expr instanceof ArrayInitializer) {
-                                               ArrayInitializer initializer = (ArrayInitializer) expr;
-                                               final Expression[] expressions = initializer.expressions;
-                                               if (expressions != null) {
-                                                       for (int i = 0, length = expressions.length; i < length; i++) {
-                                                               Expression initExpr = expressions[i];
-                                                               if ((initExpr.bits & Binding.VARIABLE) == Binding.FIELD) {
-                                                                       FieldBinding field = ((Reference) initExpr).fieldBinding();
-                                                                       if (field != null && field.declaringClass.id == T_JavaLangAnnotationElementType) {
-                                                                               long element = getTargetElementType(field.name);
-                                                                               if ((tagBits & element) != 0) {
-                                                                                       scope.problemReporter().duplicateTargetInTargetAnnotation(annotationType, (NameReference)initExpr);
-                                                                               } else {
-                                                                                       tagBits |= element;
-                                                                               }
-                                                                       }                                                       
-                                                               }
-                                                       }
-                                               }
-                                       } else if ((expr.bits & Binding.VARIABLE) == Binding.FIELD) {
-                                               FieldBinding field = ((Reference) expr).fieldBinding();
-                                               if (field != null && field.declaringClass.id == T_JavaLangAnnotationElementType) {
-                                                       tagBits |= getTargetElementType(field.name);
-                                               }
-                                       }
-                               }
-                               break;
-                       // marker annotations
-                       case TypeIds.T_JavaLangDeprecated :
-                               tagBits |= TagBits.AnnotationDeprecated;
-                               break;
-                       case TypeIds.T_JavaLangAnnotationDocumented :
-                               tagBits |= TagBits.AnnotationDocumented;
-                               break;
-                       case TypeIds.T_JavaLangAnnotationInherited :
-                               tagBits |= TagBits.AnnotationInherited;
-                               break;
-                       case TypeIds.T_JavaLangOverride :
-                               tagBits |= TagBits.AnnotationOverride;
-                               break;
-                       case TypeIds.T_JavaLangSuppressWarnings :
-                               tagBits |= TagBits.AnnotationSuppressWarnings;
-                               break;
-               }
-               return tagBits;
-       }
-
-       public AnnotationBinding getCompilerAnnotation() {
-               return this.compilerAnnotation;
-       }
-
-       public abstract MemberValuePair[] memberValuePairs();
-       
-       public StringBuffer printExpression(int indent, StringBuffer output) {
-               output.append('@');
-               this.type.printExpression(0, output);
-               return output;
-       }
-       
-       public void recordSuppressWarnings(Scope scope, int startSuppresss, int endSuppress, boolean isSuppressingWarnings) {
-               long suppressWarningIrritants = 0;
-               MemberValuePair[] pairs = this.memberValuePairs();
-               pairLoop: for (int i = 0, length = pairs.length; i < length; i++) {
-                       MemberValuePair pair = pairs[i];
-                       if (CharOperation.equals(pair.name, TypeConstants.VALUE)) {
-                               Expression value = pair.value;
-                               if (value instanceof ArrayInitializer) {
-                                       ArrayInitializer initializer = (ArrayInitializer) value;
-                                       Expression[] inits = initializer.expressions;
-                                       if (inits != null) {
-                                               for (int j = 0, initsLength = inits.length; j < initsLength; j++) {
-                                                       Constant cst = inits[j].constant;
-                                                       if (cst != Constant.NotAConstant && cst.typeID() == T_JavaLangString) {
-                                                               long irritants = CompilerOptions.warningTokenToIrritants(cst.stringValue());
-                                                               if (irritants != 0) {
-                                                                       if ((suppressWarningIrritants & irritants) == irritants) {
-                                                                               scope.problemReporter().unusedWarningToken(inits[j]);
-                                                                       } else {
-                                                                               suppressWarningIrritants |= irritants;
-                                                                       }
-                                                               } else {
-                                                                       scope.problemReporter().unhandledWarningToken(inits[j]);
-                                                               }
-                                                       }
-                                               }
-                                       }
-                               } else {
-                                       Constant cst = value.constant;
-                                       if (cst != Constant.NotAConstant && cst.typeID() == T_JavaLangString) {
-                                               long irritants = CompilerOptions.warningTokenToIrritants(cst.stringValue());
-                                               if (irritants != 0) {
-                                                       suppressWarningIrritants |= irritants;
-                                               } else {
-                                                       scope.problemReporter().unhandledWarningToken(value);
-                                               }
-                                       }       
-                               }
-                               break pairLoop;
-                       }
-               }
-               if (isSuppressingWarnings && suppressWarningIrritants != 0) {
-                       scope.referenceCompilationUnit().recordSuppressWarnings(suppressWarningIrritants, this, startSuppresss, endSuppress);
-               }
-       }
-       
-       public TypeBinding resolveType(BlockScope scope) {
-
-               if (this.compilerAnnotation != null)
-                       return this.resolvedType;
-               this.constant = Constant.NotAConstant;
-               
-               TypeBinding typeBinding = this.type.resolveType(scope);
-               if (typeBinding == null) {
-                       return null;
-               }
-               this.resolvedType = typeBinding;
-               // ensure type refers to an annotation type
-               if (!typeBinding.isAnnotationType() && typeBinding.isValidBinding()) {
-                       scope.problemReporter().typeMismatchError(typeBinding, scope.getJavaLangAnnotationAnnotation(), this.type, null);
-                       return null;
-               }
-
-               ReferenceBinding annotationType = (ReferenceBinding) this.resolvedType;
-               MethodBinding[] methods = annotationType.methods();
-               // clone valuePairs to keep track of unused ones
-               MemberValuePair[] originalValuePairs = memberValuePairs();
-               MemberValuePair valueAttribute = null; // remember the first 'value' pair
-               MemberValuePair[] pairs;
-               int pairsLength = originalValuePairs.length;
-               if (pairsLength > 0) {
-                       System.arraycopy(originalValuePairs, 0, pairs = new MemberValuePair[pairsLength], 0, pairsLength);
-               } else {
-                       pairs = originalValuePairs;
-               }               
-               
-               nextMember: for (int i = 0, requiredLength = methods.length; i < requiredLength; i++) {
-                       MethodBinding method = methods[i];
-                       char[] selector = method.selector;
-                       boolean foundValue = false;
-                       nextPair: for (int j = 0; j < pairsLength; j++) {
-                               MemberValuePair pair = pairs[j];
-                               if (pair == null) continue nextPair;
-                               char[] name = pair.name;
-                               if (CharOperation.equals(name, selector)) {
-                                       if (valueAttribute == null && CharOperation.equals(name, TypeConstants.VALUE)) {
-                                               valueAttribute = pair;
-                                       }
-                                       pair.binding = method;
-                                       pair.resolveTypeExpecting(scope, method.returnType);
-                                       pairs[j] = null; // consumed
-                                       foundValue = true;
-                                       
-                                       // check duplicates
-                                       boolean foundDuplicate = false;
-                                       for (int k = j+1; k < pairsLength; k++) {
-                                               MemberValuePair otherPair = pairs[k];
-                                               if (otherPair == null) continue;
-                                               if (CharOperation.equals(otherPair.name, selector)) {
-                                                       foundDuplicate = true;
-                                                       scope.problemReporter().duplicateAnnotationValue(annotationType, otherPair);
-                                                       otherPair.binding = method;
-                                                       otherPair.resolveTypeExpecting(scope, method.returnType);
-                                                       pairs[k] = null;
-                                               }
-                                       }
-                                       if (foundDuplicate) {
-                                               scope.problemReporter().duplicateAnnotationValue(annotationType, pair);
-                                               continue nextMember;
-                                       }
-                               }
-                       }
-                       if (!foundValue &&
-                                       (method.modifiers & ClassFileConstants.AccAnnotationDefault) == 0 &&
-                                       (this.bits & IsRecovered) == 0) {
-                               scope.problemReporter().missingValueForAnnotationMember(this, selector);
-                       }
-               }
-               // check unused pairs
-               for (int i = 0; i < pairsLength; i++) {
-                       if (pairs[i] != null) {
-                               scope.problemReporter().undefinedAnnotationValue(annotationType, pairs[i]);
-                               pairs[i].resolveTypeExpecting(scope, null); // resilient
-                       }
-               }
-//             if (scope.compilerOptions().storeAnnotations)
-               this.compilerAnnotation = scope.environment().createAnnotation((ReferenceBinding) this.resolvedType, this.computeElementValuePairs());
-               // recognize standard annotations ?
-               long tagBits = detectStandardAnnotation(scope, annotationType, valueAttribute);
-
-               // record annotation positions in the compilation result
-               scope.referenceCompilationUnit().recordSuppressWarnings(CompilerOptions.NonExternalizedString, null, this.sourceStart, this.declarationSourceEnd);
-               if (this.recipient != null) {
-                       if (tagBits != 0) {
-                               // tag bits onto recipient
-                               switch (this.recipient.kind()) {
-                                       case Binding.PACKAGE :
-                                               ((PackageBinding)this.recipient).tagBits |= tagBits;
-                                               break;
-                                       case Binding.TYPE :
-                                       case Binding.GENERIC_TYPE :
-                                               SourceTypeBinding sourceType = (SourceTypeBinding) this.recipient;
-                                               sourceType.tagBits |= tagBits;
-                                               if ((tagBits & TagBits.AnnotationSuppressWarnings) != 0) {
-                                                       TypeDeclaration typeDeclaration =  sourceType.scope.referenceContext;
-                                                       int start;
-                                                       if (scope.referenceCompilationUnit().types[0] == typeDeclaration) {
-                                                               start = 0;
-                                                       } else {
-                                                               start = typeDeclaration.declarationSourceStart;
-                                                       }
-                                                       recordSuppressWarnings(scope, start, typeDeclaration.declarationSourceEnd, scope.compilerOptions().suppressWarnings);
-                                               }
-                                               break;
-                                       case Binding.METHOD :
-                                               MethodBinding sourceMethod = (MethodBinding) this.recipient;
-                                               sourceMethod.tagBits |= tagBits;
-                                               if ((tagBits & TagBits.AnnotationSuppressWarnings) != 0) {
-                                                       sourceType = (SourceTypeBinding) sourceMethod.declaringClass;
-                                                       AbstractMethodDeclaration methodDeclaration = sourceType.scope.referenceContext.declarationOf(sourceMethod);
-                                                       recordSuppressWarnings(scope, methodDeclaration.declarationSourceStart, methodDeclaration.declarationSourceEnd, scope.compilerOptions().suppressWarnings);
-                                               }
-                                               break;
-                                       case Binding.FIELD :
-                                               FieldBinding sourceField = (FieldBinding) this.recipient;
-                                               sourceField.tagBits |= tagBits;
-                                               if ((tagBits & TagBits.AnnotationSuppressWarnings) != 0) {
-                                                       sourceType = (SourceTypeBinding) sourceField.declaringClass;
-                                                       FieldDeclaration fieldDeclaration = sourceType.scope.referenceContext.declarationOf(sourceField);
-                                                       recordSuppressWarnings(scope, fieldDeclaration.declarationSourceStart, fieldDeclaration.declarationSourceEnd, scope.compilerOptions().suppressWarnings);
-                                               }                                               
-                                               break;
-                                       case Binding.LOCAL :
-                                               LocalVariableBinding variable = (LocalVariableBinding) this.recipient;
-                                               variable.tagBits |= tagBits;
-                                               if ((tagBits & TagBits.AnnotationSuppressWarnings) != 0) {
-                                                        LocalDeclaration localDeclaration = variable.declaration;
-                                                       recordSuppressWarnings(scope, localDeclaration.declarationSourceStart, localDeclaration.declarationSourceEnd, scope.compilerOptions().suppressWarnings);
-                                               }                                                                       
-                                               break;
-                               }                       
-                       }
-                       // check (meta)target compatibility
-                       checkTargetCompatibility: {
-                               long metaTagBits = annotationType.getAnnotationTagBits(); // could be forward reference
-                               if ((metaTagBits & TagBits.AnnotationTargetMASK) == 0) // does not specify any target restriction
-                                       break checkTargetCompatibility;
-                                       
-                               switch (recipient.kind()) {
-                                       case Binding.PACKAGE :
-                                               if ((metaTagBits & TagBits.AnnotationForPackage) != 0)
-                                                       break checkTargetCompatibility;
-                                               break;
-                                       case Binding.TYPE :
-                                       case Binding.GENERIC_TYPE :
-                                               if (((ReferenceBinding)this.recipient).isAnnotationType()) {
-                                                       if ((metaTagBits & (TagBits.AnnotationForAnnotationType|TagBits.AnnotationForType)) != 0)
-                                                       break checkTargetCompatibility;
-                                               } else if ((metaTagBits & TagBits.AnnotationForType) != 0) 
-                                                       break checkTargetCompatibility;
-                                               break;
-                                       case Binding.METHOD :
-                                               if (((MethodBinding)this.recipient).isConstructor()) {
-                                                       if ((metaTagBits & TagBits.AnnotationForConstructor) != 0)
-                                                               break checkTargetCompatibility;
-                                               } else  if ((metaTagBits & TagBits.AnnotationForMethod) != 0)
-                                                       break checkTargetCompatibility;
-                                               break;
-                                       case Binding.FIELD :
-                                               if ((metaTagBits & TagBits.AnnotationForField) != 0)
-                                                       break checkTargetCompatibility;
-                                               break;
-                                       case Binding.LOCAL :
-                                               if ((((LocalVariableBinding)this.recipient).tagBits & TagBits.IsArgument) != 0) {
-                                                       if ((metaTagBits & TagBits.AnnotationForParameter) != 0)
-                                                               break checkTargetCompatibility;
-                                               } else  if ((annotationType.tagBits & TagBits.AnnotationForLocalVariable) != 0)
-                                                       break checkTargetCompatibility;
-                                               break;
-                               }                       
-                               scope.problemReporter().disallowedTargetForAnnotation(this);
-                       }
-               }
-               return this.resolvedType;
-       }
-       
-       public abstract void traverse(ASTVisitor visitor, BlockScope scope);
-       
-}