Пример #1
0
  @Override
  public List<MethodNode> handleMissingMethod(
      final ClassNode receiver,
      final String name,
      final ArgumentListExpression argumentList,
      final ClassNode[] argumentTypes,
      final MethodCall call) {
    String[] decomposed = Traits.decomposeSuperCallName(name);
    if (decomposed != null) {
      return convertToDynamicCall(call, receiver, decomposed, argumentTypes);
    }
    if (call instanceof MethodCallExpression) {
      MethodCallExpression mce = (MethodCallExpression) call;
      if (mce.getReceiver() instanceof VariableExpression) {
        VariableExpression var = (VariableExpression) mce.getReceiver();

        // GROOVY-7322
        // static method call in trait?
        ClassNode type = null;
        if (isStaticTraitReceiver(receiver, var)) {
          type = receiver.getGenericsTypes()[0].getType();
        } else if (isThisTraitReceiver(var)) {
          type = receiver;
        }
        if (type != null && Traits.isTrait(type)) {
          ClassNode helper = Traits.findHelper(type);
          Parameter[] params = new Parameter[argumentTypes.length + 1];
          params[0] = new Parameter(ClassHelper.CLASS_Type.getPlainNodeReference(), "staticSelf");
          for (int i = 1; i < params.length; i++) {
            params[i] = new Parameter(argumentTypes[i - 1], "p" + i);
          }
          MethodNode method = helper.getDeclaredMethod(name, params);
          if (method != null) {
            return Collections.singletonList(makeDynamic(call, method.getReturnType()));
          }
        }
      }

      ClassNode dynamic = mce.getNodeMetaData(TraitASTTransformation.DO_DYNAMIC);
      if (dynamic != null) {
        return Collections.singletonList(makeDynamic(call, dynamic));
      }
    }
    return NOTFOUND;
  }
 /**
  * Given a method call, first checks that it's a static method call, and if it is, returns the
  * class node for the receiver. For example, with the following code: <code></code>Person.findAll
  * { ... }</code>, it would return the class node for <i>Person</i>. If it's not a static method
  * call, returns null.
  *
  * @param call a method call
  * @return null if it's not a static method call, or the class node for the receiver instead.
  */
 public ClassNode extractStaticReceiver(MethodCall call) {
   if (call instanceof StaticMethodCallExpression) {
     return ((StaticMethodCallExpression) call).getOwnerType();
   } else if (call instanceof MethodCallExpression) {
     Expression objectExpr = ((MethodCallExpression) call).getObjectExpression();
     if (objectExpr instanceof ClassExpression
         && ClassHelper.CLASS_Type.equals(objectExpr.getType())) {
       GenericsType[] genericsTypes = objectExpr.getType().getGenericsTypes();
       if (genericsTypes != null && genericsTypes.length == 1) {
         return genericsTypes[0].getType();
       }
     }
     if (objectExpr instanceof ClassExpression) {
       return objectExpr.getType();
     }
   }
   return null;
 }