Beispiel #1
0
 private void configureAnnotationFromDefinition(AnnotationNode definition, AnnotationNode root) {
   ClassNode type = definition.getClassNode();
   if (!type.isResolved()) return;
   Class clazz = type.getTypeClass();
   if (clazz == Retention.class) {
     Expression exp = definition.getMember("value");
     if (!(exp instanceof PropertyExpression)) return;
     PropertyExpression pe = (PropertyExpression) exp;
     String name = pe.getPropertyAsString();
     RetentionPolicy policy = RetentionPolicy.valueOf(name);
     setRetentionPolicy(policy, root);
   } else if (clazz == Target.class) {
     Expression exp = definition.getMember("value");
     if (!(exp instanceof ListExpression)) return;
     ListExpression le = (ListExpression) exp;
     int bitmap = 0;
     for (Expression e : le.getExpressions()) {
       PropertyExpression element = (PropertyExpression) e;
       String name = element.getPropertyAsString();
       ElementType value = ElementType.valueOf(name);
       bitmap |= getElementCode(value);
     }
     root.setAllowedTargets(bitmap);
   }
 }
  protected Expression transformPropertyExpression(PropertyExpression pe) {
    boolean oldInPropertyExpression = inPropertyExpression;
    Expression oldFoundArgs = foundArgs;
    Expression oldFoundConstant = foundConstant;
    inPropertyExpression = true;
    foundArgs = null;
    foundConstant = null;
    Expression objectExpression = transform(pe.getObjectExpression());
    boolean candidate = false;
    if (objectExpression instanceof MethodCallExpression) {
      candidate = ((MethodCallExpression) objectExpression).isImplicitThis();
    }

    if (foundArgs != null && foundConstant != null && candidate) {
      Expression result = findStaticMethodImportFromModule(foundConstant, foundArgs);
      if (result != null) {
        objectExpression = result;
        objectExpression.setSourcePosition(pe);
      }
    }
    inPropertyExpression = oldInPropertyExpression;
    foundArgs = oldFoundArgs;
    foundConstant = oldFoundConstant;
    pe.setObjectExpression(objectExpression);
    return pe;
  }
 @Override
 public void visitPropertyExpression(final PropertyExpression pexp) {
   super.visitPropertyExpression(pexp);
   Object dynamic = pexp.getNodeMetaData(StaticTypesMarker.DYNAMIC_RESOLUTION);
   if (dynamic != null) {
     pexp.getObjectExpression()
         .putNodeMetaData(StaticCompilationMetadataKeys.RECEIVER_OF_DYNAMIC_PROPERTY, dynamic);
   }
 }
 public void visitPropertyExpression(PropertyExpression expression) {
   boolean ipe = inPropertyExpression;
   inPropertyExpression = true;
   expression.getObjectExpression().visit(this);
   inPropertyExpression = false;
   expression.getProperty().visit(this);
   checkPropertyOnExplicitThis(expression);
   inPropertyExpression = ipe;
 }
 /**
  * a property on "this", like this.x is transformed to a direct field access, so we need to check
  * the static context here
  *
  * @param pe the property expression to check
  */
 private void checkPropertyOnExplicitThis(PropertyExpression pe) {
   if (!currentScope.isInStaticContext()) return;
   Expression object = pe.getObjectExpression();
   if (!(object instanceof VariableExpression)) return;
   VariableExpression ve = (VariableExpression) object;
   if (!ve.getName().equals("this")) return;
   String name = pe.getPropertyAsString();
   if (name == null || name.equals("class")) return;
   Variable member = findClassMember(currentClass, name);
   if (member == null) return;
   checkVariableContextAccess(member, pe);
 }
  private Expression transformInlineConstants(Expression exp) {
    if (exp instanceof PropertyExpression) {
      PropertyExpression pe = (PropertyExpression) exp;
      if (pe.getObjectExpression() instanceof ClassExpression) {
        ClassExpression ce = (ClassExpression) pe.getObjectExpression();
        ClassNode type = ce.getType();
        if (type.isEnum()) return exp;
        Expression constant = findConstant(type.getField(pe.getPropertyAsString()));
        // GRECLIPSE edit
        // if (constant != null) return constant;
        if (constant != null) {
          String name = pe.getText().replace('$', '.');
          Object alias = pe.getNodeMetaData("static.import.alias");
          if (alias != null && !alias.equals(pe.getPropertyAsString())) {
            name += " as " + alias;
          }
          // store the qualified name to facilitate organizing static imports
          constant.setNodeMetaData("static.import", name);

          return constant;
        }
        // GRECLIPSE end
      }
    } else if (exp instanceof ListExpression) {
      ListExpression le = (ListExpression) exp;
      ListExpression result = new ListExpression();
      for (Expression e : le.getExpressions()) {
        result.addExpression(transformInlineConstants(e));
      }
      return result;
    }

    return exp;
  }
  @SuppressWarnings("unchecked")
  public <T extends Enum> T getEnumMemberValue(
      AnnotationNode node, String name, Class<T> type, T defaultValue) {
    if (node == null) return defaultValue;

    final PropertyExpression member = (PropertyExpression) node.getMember(name);
    if (member == null) return defaultValue;

    if (!type.equals(member.getObjectExpression().getType().getTypeClass())) return defaultValue;

    try {
      String value = member.getPropertyAsString();
      Method fromString = type.getMethod("valueOf", String.class);
      return (T) fromString.invoke(null, value);
    } catch (Exception e) {
      return defaultValue;
    }
  }
  private Expression transformInlineConstants(Expression exp) {
    if (exp instanceof PropertyExpression) {
      PropertyExpression pe = (PropertyExpression) exp;
      if (pe.getObjectExpression() instanceof ClassExpression) {
        ClassExpression ce = (ClassExpression) pe.getObjectExpression();
        ClassNode type = ce.getType();
        if (type.isEnum()) return exp;
        Expression constant = findConstant(type.getField(pe.getPropertyAsString()));
        if (constant != null) return constant;
      }
    } else if (exp instanceof ListExpression) {
      ListExpression le = (ListExpression) exp;
      ListExpression result = new ListExpression();
      for (Expression e : le.getExpressions()) {
        result.addExpression(transformInlineConstants(e));
      }
      return result;
    }

    return exp;
  }
  @Override
  protected boolean existsProperty(
      final PropertyExpression pexp,
      final boolean checkForReadOnly,
      final ClassCodeVisitorSupport visitor) {
    Expression objectExpression = pexp.getObjectExpression();
    ClassNode objectExpressionType = getType(objectExpression);
    final Reference<ClassNode> rType = new Reference<ClassNode>(objectExpressionType);
    ClassCodeVisitorSupport receiverMemoizer =
        new ClassCodeVisitorSupport() {
          @Override
          protected SourceUnit getSourceUnit() {
            return null;
          }

          public void visitField(final FieldNode node) {
            if (visitor != null) visitor.visitField(node);
            ClassNode declaringClass = node.getDeclaringClass();
            if (declaringClass != null) rType.set(declaringClass);
          }

          public void visitMethod(final MethodNode node) {
            if (visitor != null) visitor.visitMethod(node);
            ClassNode declaringClass = node.getDeclaringClass();
            if (declaringClass != null) rType.set(declaringClass);
          }

          @Override
          public void visitProperty(final PropertyNode node) {
            if (visitor != null) visitor.visitProperty(node);
            ClassNode declaringClass = node.getDeclaringClass();
            if (declaringClass != null) rType.set(declaringClass);
          }
        };
    boolean exists = super.existsProperty(pexp, checkForReadOnly, receiverMemoizer);
    if (exists) {
      if (objectExpression.getNodeMetaData(StaticCompilationMetadataKeys.PROPERTY_OWNER) == null) {
        objectExpression.putNodeMetaData(StaticCompilationMetadataKeys.PROPERTY_OWNER, rType.get());
      }
      if (StaticTypeCheckingSupport.implementsInterfaceOrIsSubclassOf(
          objectExpressionType, ClassHelper.LIST_TYPE)) {
        objectExpression.putNodeMetaData(
            COMPONENT_TYPE, inferComponentType(objectExpressionType, ClassHelper.int_TYPE));
      }
    }
    return exists;
  }
  protected Expression transformPropertyExpression(PropertyExpression pe) {
    if (currentMethod != null
        && currentMethod.isStatic()
        && pe.getObjectExpression() instanceof VariableExpression
        && ((VariableExpression) pe.getObjectExpression()).isSuperExpression()) {
      PropertyExpression pexp =
          new PropertyExpression(
              new ClassExpression(currentClass.getSuperClass()), transform(pe.getProperty()));
      pexp.setSourcePosition(pe);
      return pexp;
    }
    boolean oldInPropertyExpression = inPropertyExpression;
    Expression oldFoundArgs = foundArgs;
    Expression oldFoundConstant = foundConstant;
    inPropertyExpression = true;
    foundArgs = null;
    foundConstant = null;
    Expression objectExpression = transform(pe.getObjectExpression());
    boolean candidate = false;
    if (objectExpression instanceof MethodCallExpression) {
      candidate = ((MethodCallExpression) objectExpression).isImplicitThis();
    }

    if (foundArgs != null && foundConstant != null && candidate) {
      Expression result = findStaticMethodImportFromModule(foundConstant, foundArgs);
      if (result != null) {
        objectExpression = result;
        objectExpression.setSourcePosition(pe);
      }
    }
    inPropertyExpression = oldInPropertyExpression;
    foundArgs = oldFoundArgs;
    foundConstant = oldFoundConstant;
    pe.setObjectExpression(objectExpression);
    return pe;
  }
  private void writeListDotProperty(
      final Expression receiver,
      final String methodName,
      final MethodVisitor mv,
      final boolean safe) {
    ClassNode componentType =
        (ClassNode) receiver.getNodeMetaData(StaticCompilationMetadataKeys.COMPONENT_TYPE);
    if (componentType == null) {
      componentType = OBJECT_TYPE;
    }
    // for lists, replace list.foo with:
    // def result = new ArrayList(list.size())
    // for (e in list) { result.add (e.foo) }
    // result
    CompileStack compileStack = controller.getCompileStack();

    Label exit = new Label();
    if (safe) {
      receiver.visit(controller.getAcg());
      Label doGet = new Label();
      mv.visitJumpInsn(IFNONNULL, doGet);
      controller.getOperandStack().remove(1);
      mv.visitInsn(ACONST_NULL);
      mv.visitJumpInsn(GOTO, exit);
      mv.visitLabel(doGet);
    }

    Variable tmpList = new VariableExpression("tmpList", make(ArrayList.class));
    int var = compileStack.defineTemporaryVariable(tmpList, false);
    Variable iterator = new VariableExpression("iterator", Iterator_TYPE);
    int it = compileStack.defineTemporaryVariable(iterator, false);
    Variable nextVar = new VariableExpression("next", componentType);
    final int next = compileStack.defineTemporaryVariable(nextVar, false);

    mv.visitTypeInsn(NEW, "java/util/ArrayList");
    mv.visitInsn(DUP);
    receiver.visit(controller.getAcg());
    mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "size", "()I", true);
    controller.getOperandStack().remove(1);
    mv.visitMethodInsn(INVOKESPECIAL, "java/util/ArrayList", "<init>", "(I)V", false);
    mv.visitVarInsn(ASTORE, var);
    Label l1 = new Label();
    mv.visitLabel(l1);
    receiver.visit(controller.getAcg());
    mv.visitMethodInsn(
        INVOKEINTERFACE, "java/util/List", "iterator", "()Ljava/util/Iterator;", true);
    controller.getOperandStack().remove(1);
    mv.visitVarInsn(ASTORE, it);
    Label l2 = new Label();
    mv.visitLabel(l2);
    mv.visitVarInsn(ALOAD, it);
    mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "hasNext", "()Z", true);
    Label l3 = new Label();
    mv.visitJumpInsn(IFEQ, l3);
    mv.visitVarInsn(ALOAD, it);
    mv.visitMethodInsn(INVOKEINTERFACE, "java/util/Iterator", "next", "()Ljava/lang/Object;", true);
    mv.visitTypeInsn(CHECKCAST, BytecodeHelper.getClassInternalName(componentType));
    mv.visitVarInsn(ASTORE, next);
    Label l4 = new Label();
    mv.visitLabel(l4);
    mv.visitVarInsn(ALOAD, var);
    final ClassNode finalComponentType = componentType;
    PropertyExpression pexp =
        new PropertyExpression(
            new BytecodeExpression() {
              @Override
              public void visit(final MethodVisitor mv) {
                mv.visitVarInsn(ALOAD, next);
              }

              @Override
              public ClassNode getType() {
                return finalComponentType;
              }
            },
            methodName);
    pexp.visit(controller.getAcg());
    controller.getOperandStack().box();
    controller.getOperandStack().remove(1);
    mv.visitMethodInsn(INVOKEINTERFACE, "java/util/List", "add", "(Ljava/lang/Object;)Z", true);
    mv.visitInsn(POP);
    Label l5 = new Label();
    mv.visitLabel(l5);
    mv.visitJumpInsn(GOTO, l2);
    mv.visitLabel(l3);
    mv.visitVarInsn(ALOAD, var);
    if (safe) {
      mv.visitLabel(exit);
    }
    controller.getOperandStack().push(make(ArrayList.class));
    controller.getCompileStack().removeVar(next);
    controller.getCompileStack().removeVar(it);
    controller.getCompileStack().removeVar(var);
  }
 /**
  * Set the source position of toSet including its property expression if it has one.
  *
  * @param toSet resulting node
  * @param origNode original node
  */
 private void setSourcePosition(Expression toSet, Expression origNode) {
   toSet.setSourcePosition(origNode);
   if (toSet instanceof PropertyExpression) {
     ((PropertyExpression) toSet).getProperty().setSourcePosition(origNode);
   }
 }