コード例 #1
0
  static JCExpression createFieldAccessor(
      TreeMaker maker, JavacNode field, FieldAccess fieldAccess, JCExpression receiver) {
    boolean lookForGetter = lookForGetter(field, fieldAccess);

    GetterMethod getter = lookForGetter ? findGetter(field) : null;
    JCVariableDecl fieldDecl = (JCVariableDecl) field.get();

    if (getter == null) {
      if (receiver == null) {
        if ((fieldDecl.mods.flags & Flags.STATIC) == 0) {
          receiver = maker.Ident(field.toName("this"));
        } else {
          JavacNode containerNode = field.up();
          if (containerNode != null && containerNode.get() instanceof JCClassDecl) {
            JCClassDecl container = (JCClassDecl) field.up().get();
            receiver = maker.Ident(container.name);
          }
        }
      }

      return receiver == null
          ? maker.Ident(fieldDecl.name)
          : maker.Select(receiver, fieldDecl.name);
    }

    if (receiver == null) receiver = maker.Ident(field.toName("this"));
    JCMethodInvocation call =
        maker.Apply(
            List.<JCExpression>nil(),
            maker.Select(receiver, getter.name),
            List.<JCExpression>nil());
    return call;
  }
コード例 #2
0
  @Override
  public boolean handle(
      AnnotationValues<Synchronized> annotation, JCAnnotation ast, Node annotationNode) {
    Node methodNode = annotationNode.up();

    if (methodNode == null
        || methodNode.getKind() != Kind.METHOD
        || !(methodNode.get() instanceof JCMethodDecl)) {
      annotationNode.addError("@Synchronized is legal only on methods.");
      return true;
    }

    JCMethodDecl method = (JCMethodDecl) methodNode.get();

    if ((method.mods.flags & Flags.ABSTRACT) != 0) {
      annotationNode.addError("@Synchronized is legal only on concrete methods.");
      return true;
    }
    boolean isStatic = (method.mods.flags & Flags.STATIC) != 0;
    String lockName = annotation.getInstance().value();
    boolean autoMake = false;
    if (lockName.length() == 0) {
      autoMake = true;
      lockName = isStatic ? STATIC_LOCK_NAME : INSTANCE_LOCK_NAME;
    }

    TreeMaker maker = methodNode.getTreeMaker();

    if (fieldExists(lockName, methodNode) == MemberExistsResult.NOT_EXISTS) {
      if (!autoMake) {
        annotationNode.addError("The field " + new String(lockName) + " does not exist.");
        return true;
      }
      JCExpression objectType = chainDots(maker, methodNode, "java", "lang", "Object");
      // We use 'new Object[0];' because quite unlike 'new Object();', empty arrays *ARE*
      // serializable!
      JCNewArray newObjectArray =
          maker.NewArray(
              chainDots(maker, methodNode, "java", "lang", "Object"),
              List.<JCExpression>of(maker.Literal(TypeTags.INT, 0)),
              null);
      JCVariableDecl fieldDecl =
          maker.VarDef(
              maker.Modifiers(Flags.FINAL | (isStatic ? Flags.STATIC : 0)),
              methodNode.toName(lockName),
              objectType,
              newObjectArray);
      injectField(methodNode.up(), fieldDecl);
    }

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

    JCExpression lockNode = maker.Ident(methodNode.toName(lockName));

    method.body = maker.Block(0, List.<JCStatement>of(maker.Synchronized(lockNode, method.body)));

    methodNode.rebuild();

    return true;
  }
コード例 #3
0
 public static JCExpression cloneSelfType(JavacNode field) {
   JavacNode typeNode = field;
   TreeMaker maker = field.getTreeMaker();
   while (typeNode != null && typeNode.getKind() != Kind.TYPE) typeNode = typeNode.up();
   if (typeNode != null && typeNode.get() instanceof JCClassDecl) {
     JCClassDecl type = (JCClassDecl) typeNode.get();
     ListBuffer<JCExpression> typeArgs = ListBuffer.lb();
     if (!type.typarams.isEmpty()) {
       for (JCTypeParameter tp : type.typarams) {
         typeArgs.append(maker.Ident(tp.name));
       }
       return maker.TypeApply(maker.Ident(type.name), typeArgs.toList());
     } else {
       return maker.Ident(type.name);
     }
   } else {
     return null;
   }
 }
コード例 #4
0
  /**
   * In javac, dotted access of any kind, from {@code java.lang.String} to {@code var.methodName} is
   * represented by a fold-left of {@code Select} nodes with the leftmost string represented by a
   * {@code Ident} node. This method generates such an expression.
   *
   * <p>The position of the generated node(s) will be equal to the {@code pos} parameter.
   *
   * <p>For example, maker.Select(maker.Select(maker.Ident(NAME[java]), NAME[lang]), NAME[String]).
   *
   * @see com.sun.tools.javac.tree.JCTree.JCIdent
   * @see com.sun.tools.javac.tree.JCTree.JCFieldAccess
   */
  public static JCExpression chainDots(JavacNode node, int pos, String... elems) {
    assert elems != null;
    assert elems.length > 0;

    TreeMaker maker = node.getTreeMaker();
    if (pos != -1) maker = maker.at(pos);
    JCExpression e = maker.Ident(node.toName(elems[0]));
    for (int i = 1; i < elems.length; i++) {
      e = maker.Select(e, node.toName(elems[i]));
    }

    return e;
  }
コード例 #5
0
  private static JCExpression cloneType0(TreeMaker maker, JCTree in) {
    if (in == null) return null;

    if (in instanceof JCPrimitiveTypeTree) return (JCExpression) in;

    if (in instanceof JCIdent) {
      return maker.Ident(((JCIdent) in).name);
    }

    if (in instanceof JCFieldAccess) {
      JCFieldAccess fa = (JCFieldAccess) in;
      return maker.Select(cloneType0(maker, fa.selected), fa.name);
    }

    if (in instanceof JCArrayTypeTree) {
      JCArrayTypeTree att = (JCArrayTypeTree) in;
      return maker.TypeArray(cloneType0(maker, att.elemtype));
    }

    if (in instanceof JCTypeApply) {
      JCTypeApply ta = (JCTypeApply) in;
      ListBuffer<JCExpression> lb = ListBuffer.lb();
      for (JCExpression typeArg : ta.arguments) {
        lb.append(cloneType0(maker, typeArg));
      }
      return maker.TypeApply(cloneType0(maker, ta.clazz), lb.toList());
    }

    if (in instanceof JCWildcard) {
      JCWildcard w = (JCWildcard) in;
      JCExpression newInner = cloneType0(maker, w.inner);
      TypeBoundKind newKind;
      switch (w.getKind()) {
        case SUPER_WILDCARD:
          newKind = maker.TypeBoundKind(BoundKind.SUPER);
          break;
        case EXTENDS_WILDCARD:
          newKind = maker.TypeBoundKind(BoundKind.EXTENDS);
          break;
        default:
        case UNBOUNDED_WILDCARD:
          newKind = maker.TypeBoundKind(BoundKind.UNBOUND);
          break;
      }
      return maker.Wildcard(newKind, newInner);
    }

    // This is somewhat unsafe, but it's better than outright throwing an exception here. Returning
    // null will just cause an exception down the pipeline.
    return (JCExpression) in;
  }
コード例 #6
0
 /**
  * Process a single compound annotation, returning its Attribute. Used from MemberEnter for
  * attaching the attributes to the annotated symbol.
  */
 Attribute.Compound enterAnnotation(JCAnnotation a, Type expected, Env<AttrContext> env) {
   // The annotation might have had its type attributed (but not checked)
   // by attr.attribAnnotationTypes during MemberEnter, in which case we do not
   // need to do it again.
   Type at =
       (a.annotationType.type != null
           ? a.annotationType.type
           : attr.attribType(a.annotationType, env));
   a.type = chk.checkType(a.annotationType.pos(), at, expected);
   if (a.type.isErroneous())
     return new Attribute.Compound(a.type, List.<Pair<MethodSymbol, Attribute>>nil());
   if ((a.type.tsym.flags() & Flags.ANNOTATION) == 0) {
     log.error(a.annotationType.pos(), "not.annotation.type", a.type.toString());
     return new Attribute.Compound(a.type, List.<Pair<MethodSymbol, Attribute>>nil());
   }
   List<JCExpression> args = a.args;
   if (args.length() == 1 && args.head.getTag() != JCTree.ASSIGN) {
     // special case: elided "value=" assumed
     args.head = make.at(args.head.pos).Assign(make.Ident(names.value), args.head);
   }
   ListBuffer<Pair<MethodSymbol, Attribute>> buf = new ListBuffer<Pair<MethodSymbol, Attribute>>();
   for (List<JCExpression> tl = args; tl.nonEmpty(); tl = tl.tail) {
     JCExpression t = tl.head;
     if (t.getTag() != JCTree.ASSIGN) {
       log.error(t.pos(), "annotation.value.must.be.name.value");
       continue;
     }
     JCAssign assign = (JCAssign) t;
     if (assign.lhs.getTag() != JCTree.IDENT) {
       log.error(t.pos(), "annotation.value.must.be.name.value");
       continue;
     }
     JCIdent left = (JCIdent) assign.lhs;
     Symbol method =
         rs.resolveQualifiedMethod(left.pos(), env, a.type, left.name, List.<Type>nil(), null);
     left.sym = method;
     left.type = method.type;
     if (method.owner != a.type.tsym)
       log.error(left.pos(), "no.annotation.member", left.name, a.type);
     Type result = method.type.getReturnType();
     Attribute value = enterAttributeValue(result, assign.rhs, env);
     if (!method.type.isErroneous())
       buf.append(new Pair<MethodSymbol, Attribute>((MethodSymbol) method, value));
     t.type = result;
   }
   return new Attribute.Compound(a.type, buf.toList());
 }
コード例 #7
0
 /**
  * Generates a new statement that checks if the given variable is null, and if so, throws a {@code
  * NullPointerException} with the variable name as message.
  */
 public static JCStatement generateNullCheck(TreeMaker treeMaker, JavacNode variable) {
   JCVariableDecl varDecl = (JCVariableDecl) variable.get();
   if (isPrimitive(varDecl.vartype)) return null;
   Name fieldName = varDecl.name;
   JCExpression npe = chainDots(variable, "java", "lang", "NullPointerException");
   JCTree exception =
       treeMaker.NewClass(
           null,
           List.<JCExpression>nil(),
           npe,
           List.<JCExpression>of(treeMaker.Literal(fieldName.toString())),
           null);
   JCStatement throwStatement = treeMaker.Throw(exception);
   return treeMaker.If(
       treeMaker.Binary(CTC_EQUAL, treeMaker.Ident(fieldName), treeMaker.Literal(CTC_BOT, null)),
       throwStatement,
       null);
 }
コード例 #8
0
ファイル: HandleSneakyThrows.java プロジェクト: Reder/lombok
  private JCStatement buildTryCatchBlock(
      JavacNode node, List<JCStatement> contents, String exception) {
    TreeMaker maker = node.getTreeMaker();

    JCBlock tryBlock = maker.Block(0, contents);

    JCExpression varType = chainDots(maker, node, exception.split("\\."));

    JCVariableDecl catchParam =
        maker.VarDef(maker.Modifiers(Flags.FINAL), node.toName("$ex"), varType, null);
    JCExpression lombokLombokSneakyThrowNameRef =
        chainDots(maker, node, "lombok", "Lombok", "sneakyThrow");
    JCBlock catchBody =
        maker.Block(
            0,
            List.<JCStatement>of(
                maker.Throw(
                    maker.Apply(
                        List.<JCExpression>nil(),
                        lombokLombokSneakyThrowNameRef,
                        List.<JCExpression>of(maker.Ident(node.toName("$ex")))))));

    return maker.Try(tryBlock, List.of(maker.Catch(catchParam, catchBody)), null);
  }