コード例 #1
0
ファイル: GrailsASTUtils.java プロジェクト: erdi/grails-core
 public static ClassNode getFurthestParent(ClassNode classNode) {
   ClassNode parent = classNode.getSuperClass();
   while (parent != null && !getFullName(parent).equals("java.lang.Object")) {
     classNode = parent;
     parent = parent.getSuperClass();
   }
   return classNode;
 }
コード例 #2
0
ファイル: GrailsASTUtils.java プロジェクト: erdi/grails-core
  public static ClassNode getFurthestUnresolvedParent(ClassNode classNode) {
    ClassNode parent = classNode.getSuperClass();

    while (parent != null
        && !getFullName(parent).equals("java.lang.Object")
        && !parent.isResolved()
        && !Modifier.isAbstract(parent.getModifiers())) {
      classNode = parent;
      parent = parent.getSuperClass();
    }
    return classNode;
  }
コード例 #3
0
ファイル: GrailsASTUtils.java プロジェクト: erdi/grails-core
  public static boolean hasOrInheritsProperty(ClassNode classNode, String propertyName) {
    if (hasProperty(classNode, propertyName)) {
      return true;
    }

    ClassNode parent = classNode.getSuperClass();
    while (parent != null && !getFullName(parent).equals("java.lang.Object")) {
      if (hasProperty(parent, propertyName)) {
        return true;
      }
      parent = parent.getSuperClass();
    }

    return false;
  }
コード例 #4
0
 /**
  * Snoops through the declaring class and all parents looking for methods
  *
  * <ul>
  *   <li><code>public String getMessage(java.lang.String)</code>
  *   <li><code>public String getMessage(java.lang.String, java.util.Locale)</code>
  *   <li><code>public String getMessage(java.lang.String, java.lang.Object[])</code>
  *   <li><code>public String getMessage(java.lang.String, java.lang.Object[], java.util.Locale)
  *       </code>
  *   <li><code>public String getMessage(java.lang.String, java.util.List)</code>
  *   <li><code>public String getMessage(java.lang.String, java.util.List, java.util.Locale)</code>
  *   <li><code>public String getMessage(java.lang.String, java.util.Map)</code>
  *   <li><code>public String getMessage(java.lang.String, java.util.Map, java.util.Locale)</code>
  *   <li><code>public String getMessage(java.lang.String, java.lang.String)</code>
  *   <li><code>public String getMessage(java.lang.String, java.lang.String, java.util.Locale)
  *       </code>
  *   <li><code>public String getMessage(java.lang.String, java.lang.Object[], java.lang.String)
  *       </code>
  *   <li><code>
  *       public String getMessage(java.lang.String, java.lang.Object[], java.lang.String, java.util.Locale)
  *       </code>
  *   <li><code>public String getMessage(java.lang.String, java.util.List, java.lang.String)</code>
  *   <li><code>
  *       public String getMessage(java.lang.String, java.util.List, java.lang.String, java.util.Locale)
  *       </code>
  *   <li><code>public String getMessage(java.lang.String, java.util.Map, java.lang.String)</code>
  *   <li><code>
  *       public String getMessage(java.lang.String, java.util.Map, java.lang.String, java.util.Locale)
  *       </code>
  * </ul>
  *
  * If any are defined all must be defined or a compilation error results.
  *
  * @param declaringClass the class to search
  * @param sourceUnit the source unit, for error reporting. {@code @NotNull}.
  * @return true if property change support should be added
  */
 protected static boolean needsMessageSource(ClassNode declaringClass, SourceUnit sourceUnit) {
   boolean found = false;
   ClassNode consideredClass = declaringClass;
   while (consideredClass != null) {
     for (MethodNode method : consideredClass.getMethods()) {
       // just check length, MOP will match it up
       found = method.getName().equals(METHOD_GET_MESSAGE) && method.getParameters().length == 1;
       found |= method.getName().equals(METHOD_GET_MESSAGE) && method.getParameters().length == 2;
       found |= method.getName().equals(METHOD_GET_MESSAGE) && method.getParameters().length == 3;
       found |= method.getName().equals(METHOD_GET_MESSAGE) && method.getParameters().length == 4;
       if (found) return false;
     }
     consideredClass = consideredClass.getSuperClass();
   }
   if (found) {
     sourceUnit
         .getErrorCollector()
         .addErrorAndContinue(
             new SimpleMessage(
                 "@MessageSourceAware cannot be processed on "
                     + declaringClass.getName()
                     + " because some but not all of variants of getMessage() were declared in the current class or super classes.",
                 sourceUnit));
     return false;
   }
   return true;
 }
コード例 #5
0
ファイル: GrailsASTUtils.java プロジェクト: erdi/grails-core
  @SuppressWarnings("rawtypes")
  public static boolean implementsOrInheritsZeroArgMethod(
      ClassNode classNode, String methodName, List ignoreClasses) {
    if (implementsZeroArgMethod(classNode, methodName)) {
      return true;
    }

    ClassNode parent = classNode.getSuperClass();
    while (parent != null && !getFullName(parent).equals("java.lang.Object")) {
      if (!ignoreClasses.contains(parent) && implementsZeroArgMethod(parent, methodName)) {
        return true;
      }
      parent = parent.getSuperClass();
    }
    return false;
  }
コード例 #6
0
  public boolean addGeneratedClosureConstructorCall(ConstructorCallExpression call) {
    ClassNode classNode = controller.getClassNode();
    if (!classNode.declaresInterface(ClassHelper.GENERATED_CLOSURE_Type)) return false;

    AsmClassGenerator acg = controller.getAcg();
    OperandStack operandStack = controller.getOperandStack();

    MethodVisitor mv = controller.getMethodVisitor();
    mv.visitVarInsn(ALOAD, 0);
    ClassNode callNode = classNode.getSuperClass();
    TupleExpression arguments = (TupleExpression) call.getArguments();
    if (arguments.getExpressions().size() != 2)
      throw new GroovyBugError(
          "expected 2 arguments for closure constructor super call, but got"
              + arguments.getExpressions().size());
    arguments.getExpression(0).visit(acg);
    operandStack.box();
    arguments.getExpression(1).visit(acg);
    operandStack.box();
    // TODO: replace with normal String, p not needed
    Parameter p = new Parameter(ClassHelper.OBJECT_TYPE, "_p");
    String descriptor =
        BytecodeHelper.getMethodDescriptor(ClassHelper.VOID_TYPE, new Parameter[] {p, p});
    mv.visitMethodInsn(
        INVOKESPECIAL, BytecodeHelper.getClassInternalName(callNode), "<init>", descriptor, false);
    operandStack.remove(2);
    return true;
  }
コード例 #7
0
  @Override
  public void visitConstructorCallExpression(final ConstructorCallExpression call) {
    super.visitConstructorCallExpression(call);

    MethodNode target = (MethodNode) call.getNodeMetaData(DIRECT_METHOD_CALL_TARGET);
    if (target == null && call.getLineNumber() > 0) {
      addError("Target constructor for constructor call expression hasn't been set", call);
    } else {
      if (target == null) {
        // try to find a target
        ArgumentListExpression argumentListExpression =
            InvocationWriter.makeArgumentList(call.getArguments());
        List<Expression> expressions = argumentListExpression.getExpressions();
        ClassNode[] args = new ClassNode[expressions.size()];
        for (int i = 0; i < args.length; i++) {
          args[i] = typeChooser.resolveType(expressions.get(i), classNode);
        }
        MethodNode constructor =
            findMethodOrFail(
                call, call.isSuperCall() ? classNode.getSuperClass() : classNode, "<init>", args);
        call.putNodeMetaData(DIRECT_METHOD_CALL_TARGET, constructor);
        target = constructor;
      }
    }
    if (target != null) {
      memorizeInitialExpressions(target);
    }
  }
コード例 #8
0
 private int getSuperClassCount(ClassNode element) {
   int count = 0;
   while (element != null) {
     count++;
     element = element.getSuperClass();
   }
   return count;
 }
コード例 #9
0
 /**
  * This methods creates a list of all methods with this name of the current class and of all super
  * classes
  *
  * @return the methods list
  * @see #getDeclaredMethods(String)
  */
 public List<MethodNode> getMethods(String name) {
   List<MethodNode> answer = new ArrayList<MethodNode>();
   ClassNode node = this;
   while (node != null) {
     answer.addAll(node.getDeclaredMethods(name));
     node = node.getSuperClass();
   }
   return answer;
 }
コード例 #10
0
 /**
  * Finds a field matching the given name in this class or a parent class.
  *
  * @param name the name of the field of interest
  * @return the method matching the given name and parameters or null
  */
 public FieldNode getField(String name) {
   ClassNode node = this;
   while (node != null) {
     FieldNode fn = node.getDeclaredField(name);
     if (fn != null) return fn;
     node = node.getSuperClass();
   }
   return null;
 }
コード例 #11
0
 private void changeBaseScriptTypeFromClass(final ClassNode parent, final AnnotationNode node) {
   //        Expression value = node.getMember("value");
   //        if (!(value instanceof ClassExpression)) {
   //            addError("Annotation " + MY_TYPE_NAME + " member 'value' should be a class
   // literal.", value);
   //            return;
   //        }
   changeBaseScriptType(parent, parent, parent.getSuperClass());
 }
コード例 #12
0
 public static List<MethodNode> getAllMethods(ClassNode type) {
   ClassNode node = type;
   List<MethodNode> result = new ArrayList<MethodNode>();
   while (node != null) {
     result.addAll(node.getMethods());
     node = node.getSuperClass();
   }
   return result;
 }
コード例 #13
0
 private static boolean classNodeUsesReferences(ClassNode classNode) {
   boolean ret = classNode.getSuperClass() == ClassHelper.CLOSURE_TYPE;
   if (ret) return ret;
   if (classNode instanceof InnerClassNode) {
     InnerClassNode inner = (InnerClassNode) classNode;
     return inner.isAnonymous();
   }
   return false;
 }
コード例 #14
0
 public static List<PropertyNode> getAllProperties(ClassNode type) {
   ClassNode node = type;
   List<PropertyNode> result = new ArrayList<PropertyNode>();
   while (node != null) {
     result.addAll(node.getProperties());
     node = node.getSuperClass();
   }
   return result;
 }
コード例 #15
0
 private void checkClassForOverwritingFinal(ClassNode cn) {
   ClassNode superCN = cn.getSuperClass();
   if (superCN == null) return;
   if (!isFinal(superCN.getModifiers())) return;
   StringBuilder msg = new StringBuilder();
   msg.append("You are not allowed to overwrite the final ");
   msg.append(getDescription(superCN));
   msg.append(".");
   addError(msg.toString(), cn);
 }
コード例 #16
0
 private boolean hasStaticProperty(ClassNode staticImportType, String propName) {
   ClassNode classNode = staticImportType;
   while (classNode != null) {
     for (PropertyNode pn : classNode.getProperties()) {
       if (pn.getName().equals(propName) && pn.isStatic()) return true;
     }
     classNode = classNode.getSuperClass();
   }
   return false;
 }
コード例 #17
0
 /**
  * @param classNode the class node for the interface
  * @return true if this class or any base class implements the given interface
  */
 public boolean implementsInterface(ClassNode classNode) {
   ClassNode node = redirect();
   do {
     if (node.declaresInterface(classNode)) {
       return true;
     }
     node = node.getSuperClass();
   } while (node != null);
   return false;
 }
コード例 #18
0
ファイル: GrailsASTUtils.java プロジェクト: erdi/grails-core
  /**
   * Determines if the class or interface represented by the superClass argument is either the same
   * as, or is a superclass or superinterface of, the class or interface represented by the
   * specified subClass parameter.
   *
   * @param superClass The super class to check
   * @param childClass The sub class the check
   * @return true if the childClass is either equal to or a sub class of the specified superClass
   */
  private static boolean isAssignableFrom(ClassNode superClass, ClassNode childClass) {
    ClassNode currentSuper = childClass;
    while (currentSuper != null) {
      if (currentSuper.equals(superClass)) {
        return true;
      }

      currentSuper = currentSuper.getSuperClass();
    }
    return false;
  }
コード例 #19
0
 private void createKeyConstructor() {
   annotatedClass.addConstructor(
       ACC_PUBLIC,
       params(param(STRING_TYPE, "key")),
       NO_EXCEPTIONS,
       block(
           ASTHelper.isDSLObject(annotatedClass.getSuperClass())
               ? ctorSuperS(args("key"))
               : ctorSuperS(),
           assignS(propX(varX("this"), keyField.getName()), varX("key"))));
 }
コード例 #20
0
 private void checkMethodForWeakerAccessPrivileges(MethodNode mn, ClassNode cn) {
   Parameter[] params = mn.getParameters();
   for (MethodNode superMethod : cn.getSuperClass().getMethods(mn.getName())) {
     Parameter[] superParams = superMethod.getParameters();
     if (!hasEqualParameterTypes(params, superParams)) continue;
     if ((mn.isPrivate() && !superMethod.isPrivate())
         || (mn.isProtected() && superMethod.isPublic())) {
       addWeakerAccessError(cn, mn, params, superMethod);
       return;
     }
   }
 }
コード例 #21
0
 private void checkMethodsForOverridingFinal(ClassNode cn) {
   for (MethodNode method : cn.getMethods()) {
     Parameter[] params = method.getParameters();
     for (MethodNode superMethod : cn.getSuperClass().getMethods(method.getName())) {
       Parameter[] superParams = superMethod.getParameters();
       if (!hasEqualParameterTypes(params, superParams)) continue;
       if (!superMethod.isFinal()) break;
       addInvalidUseOfFinalError(method, params, superMethod.getDeclaringClass());
       return;
     }
   }
 }
コード例 #22
0
 public static Set<ClassNode> getInterfacesAndSuperInterfaces(ClassNode type) {
   Set<ClassNode> res = new HashSet<ClassNode>();
   if (type.isInterface()) {
     res.add(type);
     return res;
   }
   ClassNode next = type;
   while (next != null) {
     Collections.addAll(res, next.getInterfaces());
     next = next.getSuperClass();
   }
   return res;
 }
コード例 #23
0
  private void changeBaseScriptType(
      final AnnotatedNode parent, final ClassNode cNode, final ClassNode baseScriptType) {
    if (!cNode.isScriptBody()) {
      addError("Annotation " + MY_TYPE_NAME + " can only be used within a Script.", parent);
      return;
    }

    if (!baseScriptType.isScript()) {
      addError(
          "Declared type " + baseScriptType + " does not extend groovy.lang.Script class!", parent);
      return;
    }

    cNode.setSuperClass(baseScriptType);

    // Method in base script that will contain the script body code.
    MethodNode runScriptMethod = ClassHelper.findSAM(baseScriptType);

    // If they want to use a name other than than "run", then make the change.
    if (isCustomScriptBodyMethod(runScriptMethod)) {
      MethodNode defaultMethod = cNode.getDeclaredMethod("run", Parameter.EMPTY_ARRAY);
      // GROOVY-6706: Sometimes an NPE is thrown here.
      // The reason is that our transform is getting called more than once sometimes.
      if (defaultMethod != null) {
        cNode.removeMethod(defaultMethod);
        MethodNode methodNode =
            new MethodNode(
                runScriptMethod.getName(),
                runScriptMethod.getModifiers() & ~ACC_ABSTRACT,
                runScriptMethod.getReturnType(),
                runScriptMethod.getParameters(),
                runScriptMethod.getExceptions(),
                defaultMethod.getCode());
        // The AST node metadata has the flag that indicates that this method is a script body.
        // It may also be carrying data for other AST transforms.
        methodNode.copyNodeMetaData(defaultMethod);
        cNode.addMethod(methodNode);
      }
    }

    // If the new script base class does not have a contextual constructor (g.l.Binding), then we
    // won't either.
    // We have to do things this way (and rely on just default constructors) because the logic that
    // generates
    // the constructors for our script class have already run.
    if (cNode.getSuperClass().getDeclaredConstructor(CONTEXT_CTOR_PARAMETERS) == null) {
      ConstructorNode orphanedConstructor = cNode.getDeclaredConstructor(CONTEXT_CTOR_PARAMETERS);
      cNode.removeConstructor(orphanedConstructor);
    }
  }
コード例 #24
0
 public static List<FieldNode> getSuperNonPropertyFields(ClassNode cNode) {
   final List<FieldNode> result;
   if (cNode == ClassHelper.OBJECT_TYPE) {
     result = new ArrayList<FieldNode>();
   } else {
     result = getSuperNonPropertyFields(cNode.getSuperClass());
   }
   for (FieldNode fNode : cNode.getFields()) {
     if (!fNode.isStatic() && cNode.getProperty(fNode.getName()) == null) {
       result.add(fNode);
     }
   }
   return result;
 }
コード例 #25
0
 public static List<FieldNode> getSuperPropertyFields(ClassNode cNode) {
   final List<FieldNode> result;
   if (cNode == ClassHelper.OBJECT_TYPE) {
     result = new ArrayList<FieldNode>();
   } else {
     result = getSuperPropertyFields(cNode.getSuperClass());
   }
   for (PropertyNode pNode : cNode.getProperties()) {
     if (!pNode.isStatic()) {
       result.add(pNode.getField());
     }
   }
   return result;
 }
コード例 #26
0
 /**
  * @param type the ClassNode of interest
  * @return true if this node is derived from the given ClassNode
  */
 public boolean isDerivedFrom(ClassNode type) {
   if (this.equals(ClassHelper.VOID_TYPE)) {
     return type.equals(ClassHelper.VOID_TYPE);
   }
   if (type.equals(ClassHelper.OBJECT_TYPE)) return true;
   ClassNode node = this;
   while (node != null) {
     if (type.equals(node)) {
       return true;
     }
     node = node.getSuperClass();
   }
   return false;
 }
コード例 #27
0
 private void checkImplementsAndExtends(ClassNode node) {
   ClassNode cn = node.getSuperClass();
   if (cn.isInterface() && !node.isInterface()) {
     addError(
         "You are not allowed to extend the " + getDescription(cn) + ", use implements instead.",
         node);
   }
   for (ClassNode anInterface : node.getInterfaces()) {
     cn = anInterface;
     if (!cn.isInterface()) {
       addError(
           "You are not allowed to implement the " + getDescription(cn) + ", use extends instead.",
           node);
     }
   }
 }
コード例 #28
0
  private Parameter[] selectAccessibleConstructorFromSuper(ConstructorNode node) {
    ClassNode type = node.getDeclaringClass();
    ClassNode superType = type.getSuperClass();

    for (ConstructorNode c : superType.getDeclaredConstructors()) {
      // Only look at things we can actually call
      if (c.isPublic() || c.isProtected()) {
        return c.getParameters();
      }
    }

    // fall back for parameterless constructor
    if (superType.isPrimaryClassNode()) {
      return Parameter.EMPTY_ARRAY;
    }

    return null;
  }
コード例 #29
0
  public MethodNode tryFindPossibleMethod(String name, Expression arguments) {
    int count = 0;

    if (arguments instanceof TupleExpression) {
      TupleExpression tuple = (TupleExpression) arguments;
      // TODO this won't strictly be true when using list expansion in argument calls
      count = tuple.getExpressions().size();
    } else return null;

    MethodNode res = null;
    ClassNode node = this;
    TupleExpression args = (TupleExpression) arguments;
    do {
      for (MethodNode method : node.getMethods(name)) {
        if (method.getParameters().length == count) {
          boolean match = true;
          for (int i = 0; i != count; ++i)
            if (!args.getType().isDerivedFrom(method.getParameters()[i].getType())) {
              match = false;
              break;
            }

          if (match) {
            if (res == null) res = method;
            else {
              if (res.getParameters().length != count) return null;
              if (node.equals(this)) return null;

              match = true;
              for (int i = 0; i != count; ++i)
                if (!res.getParameters()[i].getType().equals(method.getParameters()[i].getType())) {
                  match = false;
                  break;
                }
              if (!match) return null;
            }
          }
        }
      }
      node = node.getSuperClass();
    } while (node != null);

    return res;
  }
コード例 #30
0
 boolean makeGetField(
     final Expression receiver,
     final ClassNode receiverType,
     final String fieldName,
     final boolean implicitThis,
     final boolean samePackage) {
   FieldNode field = receiverType.getField(fieldName);
   // direct access is allowed if we are in the same class as the declaring class
   // or we are in an inner class
   if (field != null && isDirectAccessAllowed(field, controller.getClassNode(), samePackage)) {
     CompileStack compileStack = controller.getCompileStack();
     MethodVisitor mv = controller.getMethodVisitor();
     if (field.isStatic()) {
       mv.visitFieldInsn(
           GETSTATIC,
           BytecodeHelper.getClassInternalName(field.getOwner()),
           fieldName,
           BytecodeHelper.getTypeDescription(field.getOriginType()));
       controller.getOperandStack().push(field.getOriginType());
     } else {
       if (implicitThis) {
         compileStack.pushImplicitThis(implicitThis);
       }
       receiver.visit(controller.getAcg());
       if (implicitThis) compileStack.popImplicitThis();
       if (!controller.getOperandStack().getTopOperand().isDerivedFrom(field.getOwner())) {
         mv.visitTypeInsn(CHECKCAST, BytecodeHelper.getClassInternalName(field.getOwner()));
       }
       mv.visitFieldInsn(
           GETFIELD,
           BytecodeHelper.getClassInternalName(field.getOwner()),
           fieldName,
           BytecodeHelper.getTypeDescription(field.getOriginType()));
     }
     controller.getOperandStack().replace(field.getOriginType());
     return true;
   }
   ClassNode superClass = receiverType.getSuperClass();
   if (superClass != null) {
     return makeGetField(receiver, superClass, fieldName, implicitThis, false);
   }
   return false;
 }