/** Adapted from {@link TypeDeclaration#traverse}. */
 private void traverse(TypeDeclaration type) {
   // Don't visit javadoc.
   // Don't visit annotations.
   if (type.superclass != null) {
     type.superclass.traverse(this, type.scope);
   }
   if (type.superInterfaces != null) {
     int length = type.superInterfaces.length;
     for (int i = 0; i < length; i++) {
       type.superInterfaces[i].traverse(this, type.scope);
     }
   }
   if (type.typeParameters != null) {
     int length = type.typeParameters.length;
     for (int i = 0; i < length; i++) {
       type.typeParameters[i].traverse(this, type.scope);
     }
   }
   if (type.memberTypes != null) {
     int length = type.memberTypes.length;
     for (int i = 0; i < length; i++) {
       type.memberTypes[i].traverse(this, type.scope);
     }
   }
   if (type.fields != null) {
     int length = type.fields.length;
     for (int i = 0; i < length; i++) {
       FieldDeclaration field;
       if ((field = type.fields[i]).isStatic()) {
         field.traverse(this, type.staticInitializerScope);
       } else {
         field.traverse(this, type.initializerScope);
       }
     }
   }
   if (type.methods != null) {
     int length = type.methods.length;
     for (int i = 0; i < length; i++) {
       type.methods[i].traverse(this, type.scope);
     }
   }
 }
Beispiel #2
0
 public Constant constant() {
   Constant fieldConstant = this.constant;
   if (fieldConstant == null) {
     if (isFinal()) {
       // The field has not been yet type checked.
       // It also means that the field is not coming from a class that
       // has already been compiled. It can only be from a class within
       // compilation units to process. Thus the field is NOT from a BinaryTypeBinbing
       FieldBinding originalField = original();
       if (originalField.declaringClass instanceof SourceTypeBinding) {
         SourceTypeBinding sourceType = (SourceTypeBinding) originalField.declaringClass;
         if (sourceType.scope != null) {
           TypeDeclaration typeDecl = sourceType.scope.referenceContext;
           FieldDeclaration fieldDecl = typeDecl.declarationOf(originalField);
           MethodScope initScope =
               originalField.isStatic()
                   ? typeDecl.staticInitializerScope
                   : typeDecl.initializerScope;
           boolean old = initScope.insideTypeAnnotation;
           try {
             initScope.insideTypeAnnotation = false;
             fieldDecl.resolve(initScope); // side effect on binding
           } finally {
             initScope.insideTypeAnnotation = old;
           }
           fieldConstant =
               originalField.constant == null ? Constant.NotAConstant : originalField.constant;
         } else {
           fieldConstant =
               Constant.NotAConstant; // shouldn't occur per construction (paranoid null check)
         }
       } else {
         fieldConstant =
             Constant.NotAConstant; // shouldn't occur per construction (paranoid null check)
       }
     } else {
       fieldConstant = Constant.NotAConstant;
     }
     this.constant = fieldConstant;
   }
   return fieldConstant;
 }
Beispiel #3
0
 /* API
  * Answer the receiver's binding type from Binding.BindingID.
  */
 public FieldBinding(
     FieldDeclaration field, TypeBinding type, int modifiers, ReferenceBinding declaringClass) {
   this(field.name, type, modifiers, declaringClass, null);
   field.binding = this; // record binding in declaration
 }
Beispiel #4
0
  @Override
  public boolean handle(
      AnnotationValues<Synchronized> annotation, Annotation source, EclipseNode annotationNode) {
    int p1 = source.sourceStart - 1;
    int p2 = source.sourceStart - 2;
    long pos = (((long) p1) << 32) | p2;
    EclipseNode methodNode = annotationNode.up();
    if (methodNode == null
        || methodNode.getKind() != Kind.METHOD
        || !(methodNode.get() instanceof MethodDeclaration)) {
      annotationNode.addError("@Synchronized is legal only on methods.");
      return true;
    }

    MethodDeclaration method = (MethodDeclaration) methodNode.get();
    if (method.isAbstract()) {
      annotationNode.addError("@Synchronized is legal only on concrete methods.");
      return true;
    }

    char[] lockName = annotation.getInstance().value().toCharArray();
    boolean autoMake = false;
    if (lockName.length == 0) {
      autoMake = true;
      lockName = method.isStatic() ? STATIC_LOCK_NAME : INSTANCE_LOCK_NAME;
    }

    if (fieldExists(new String(lockName), methodNode) == MemberExistsResult.NOT_EXISTS) {
      if (!autoMake) {
        annotationNode.addError("The field " + new String(lockName) + " does not exist.");
        return true;
      }
      FieldDeclaration fieldDecl = new FieldDeclaration(lockName, 0, -1);
      Eclipse.setGeneratedBy(fieldDecl, source);
      fieldDecl.declarationSourceEnd = -1;

      fieldDecl.modifiers =
          (method.isStatic() ? Modifier.STATIC : 0) | Modifier.FINAL | Modifier.PRIVATE;

      // We use 'new Object[0];' because quite unlike 'new Object();', empty arrays *ARE*
      // serializable!
      ArrayAllocationExpression arrayAlloc = new ArrayAllocationExpression();
      Eclipse.setGeneratedBy(arrayAlloc, source);
      arrayAlloc.dimensions = new Expression[] {new IntLiteral(new char[] {'0'}, 0, 0)};
      Eclipse.setGeneratedBy(arrayAlloc.dimensions[0], source);
      arrayAlloc.type =
          new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, new long[] {0, 0, 0});
      Eclipse.setGeneratedBy(arrayAlloc.type, source);
      fieldDecl.type =
          new QualifiedTypeReference(TypeConstants.JAVA_LANG_OBJECT, new long[] {0, 0, 0});
      Eclipse.setGeneratedBy(fieldDecl.type, source);
      fieldDecl.initialization = arrayAlloc;
      injectFieldSuppressWarnings(annotationNode.up().up(), fieldDecl);
    }

    if (method.statements == null) return false;

    Block block = new Block(0);
    Eclipse.setGeneratedBy(block, source);
    block.statements = method.statements;
    Expression lockVariable;
    if (method.isStatic())
      lockVariable =
          new QualifiedNameReference(
              new char[][] {methodNode.up().getName().toCharArray(), lockName},
              new long[] {pos, pos},
              p1,
              p2);
    else {
      lockVariable = new FieldReference(lockName, pos);
      ThisReference thisReference = new ThisReference(p1, p2);
      Eclipse.setGeneratedBy(thisReference, source);
      ((FieldReference) lockVariable).receiver = thisReference;
    }
    Eclipse.setGeneratedBy(lockVariable, source);

    method.statements = new Statement[] {new SynchronizedStatement(lockVariable, block, 0, 0)};
    Eclipse.setGeneratedBy(method.statements[0], source);

    methodNode.rebuild();

    return true;
  }