コード例 #1
0
ファイル: GrailsASTUtils.java プロジェクト: erdi/grails-core
  /**
   * Evaluates a constraints closure and returns metadata about the constraints configured in the
   * closure. The Map returned has property names as keys and the value associated with each of
   * those property names is a Map<String, Expression> which has constraint names as keys and the
   * Expression associated with that constraint as values
   *
   * @param closureExpression the closure expression to evaluate
   * @return the Map as described above
   */
  public static Map<String, Map<String, Expression>> getConstraintMetadata(
      final ClosureExpression closureExpression) {

    final List<MethodCallExpression> methodExpressions = new ArrayList<MethodCallExpression>();

    final Map<String, Map<String, Expression>> results =
        new LinkedHashMap<String, Map<String, Expression>>();
    final Statement closureCode = closureExpression.getCode();
    if (closureCode instanceof BlockStatement) {
      final List<Statement> closureStatements = ((BlockStatement) closureCode).getStatements();
      for (final Statement closureStatement : closureStatements) {
        if (closureStatement instanceof ExpressionStatement) {
          final Expression expression = ((ExpressionStatement) closureStatement).getExpression();
          if (expression instanceof MethodCallExpression) {
            methodExpressions.add((MethodCallExpression) expression);
          }
        } else if (closureStatement instanceof ReturnStatement) {
          final ReturnStatement returnStatement = (ReturnStatement) closureStatement;
          Expression expression = returnStatement.getExpression();
          if (expression instanceof MethodCallExpression) {
            methodExpressions.add((MethodCallExpression) expression);
          }
        }

        for (final MethodCallExpression methodCallExpression : methodExpressions) {
          final Expression objectExpression = methodCallExpression.getObjectExpression();
          if (objectExpression instanceof VariableExpression
              && "this".equals(((VariableExpression) objectExpression).getName())) {
            final Expression methodCallArguments = methodCallExpression.getArguments();
            if (methodCallArguments instanceof TupleExpression) {
              final List<Expression> methodCallArgumentExpressions =
                  ((TupleExpression) methodCallArguments).getExpressions();
              if (methodCallArgumentExpressions != null
                  && methodCallArgumentExpressions.size() == 1
                  && methodCallArgumentExpressions.get(0) instanceof NamedArgumentListExpression) {
                final Map<String, Expression> constraintNameToExpression =
                    new LinkedHashMap<String, Expression>();
                final List<MapEntryExpression> mapEntryExpressions =
                    ((NamedArgumentListExpression) methodCallArgumentExpressions.get(0))
                        .getMapEntryExpressions();
                for (final MapEntryExpression mapEntryExpression : mapEntryExpressions) {
                  final Expression keyExpression = mapEntryExpression.getKeyExpression();
                  if (keyExpression instanceof ConstantExpression) {
                    final Object value = ((ConstantExpression) keyExpression).getValue();
                    if (value instanceof String) {
                      constraintNameToExpression.put(
                          (String) value, mapEntryExpression.getValueExpression());
                    }
                  }
                }
                results.put(methodCallExpression.getMethodAsString(), constraintNameToExpression);
              }
            }
          }
        }
      }
    }
    return results;
  }
コード例 #2
0
 public void doit(SearchingCodeVisitor visitor, MethodCallExpression call) {
   // Recognize and handle <methodName>(..., <argName>: "<oldName>", ...)
   MapEntryExpression arg = SearchUtil.getNamedArgument(call, argName);
   if (arg != null) {
     final Expression valueExpression = arg.getValueExpression();
     String argValue = SearchUtil.getStringValue(valueExpression);
     if (oldValue.equals(argValue)) {
       matchFound(visitor, call, valueExpression);
     }
   }
 }
コード例 #3
0
 private List createPropertiesForHasManyExpression(Expression e, ClassNode classNode) {
   List properties = new ArrayList();
   if (e instanceof MapExpression) {
     MapExpression me = (MapExpression) e;
     List mapEntries = me.getMapEntryExpressions();
     for (Iterator j = mapEntries.iterator(); j.hasNext(); ) {
       MapEntryExpression mee = (MapEntryExpression) j.next();
       Expression keyExpression = mee.getKeyExpression();
       String key = keyExpression.getText();
       addAssociationForKey(key, properties, classNode);
     }
   }
   return properties;
 }
コード例 #4
0
 private Expression transformMapEntryExpression(
     MapEntryExpression me, ClassNode constructorCallType) {
   Expression key = me.getKeyExpression();
   Expression value = me.getValueExpression();
   ModuleNode module = currentClass.getModule();
   if (module != null && key instanceof ConstantExpression) {
     Map<String, ImportNode> importNodes = module.getStaticImports();
     if (importNodes.containsKey(key.getText())) {
       ImportNode importNode = importNodes.get(key.getText());
       if (importNode.getType().equals(constructorCallType)) {
         String newKey = importNode.getFieldName();
         return new MapEntryExpression(
             new ConstantExpression(newKey), value.transformExpression(this));
       }
     }
   }
   return me;
 }
コード例 #5
0
  public List<IGroovyProposal> extraProposals(
      ClassNode declaringType, ResolverCache resolver, Expression expression) {
    // first find the arguments that are possible
    Map<String, ClassNode> availableParams = findAvailableParamNames(resolver);

    if (availableParams.isEmpty()) {
      return ProposalUtils.NO_PROPOSALS;
    }

    if (expression instanceof MethodCallExpression) {
      // next find out if there are any existing named args
      MethodCallExpression call = (MethodCallExpression) expression;
      Expression arguments = call.getArguments();
      if (arguments instanceof TupleExpression) {
        for (Expression maybeArg : ((TupleExpression) arguments).getExpressions()) {
          if (maybeArg instanceof MapExpression) {
            arguments = maybeArg;
            break;
          }
        }
      }

      // now remove the arguments that are already written
      if (arguments instanceof MapExpression) {
        // Do extra filtering to determine what parameters are still available
        MapExpression enclosingCallArgs = (MapExpression) arguments;
        for (MapEntryExpression entry : enclosingCallArgs.getMapEntryExpressions()) {
          String paramName = entry.getKeyExpression().getText();
          availableParams.remove(paramName);
        }
      }
    }

    List<IGroovyProposal> extraProposals = new ArrayList<IGroovyProposal>(availableParams.size());
    for (Entry<String, ClassNode> available : availableParams.entrySet()) {
      extraProposals.add(
          new GroovyNamedArgumentProposal(
              available.getKey(),
              available.getValue(),
              toMethod(declaringType.redirect(), resolver),
              provider));
    }
    return extraProposals;
  }
コード例 #6
0
  private Collection createPropertiesForBelongsToExpression(Expression e, ClassNode classNode) {
    List properties = new ArrayList();
    if (e instanceof MapExpression) {
      MapExpression me = (MapExpression) e;
      List mapEntries = me.getMapEntryExpressions();
      for (Iterator i = mapEntries.iterator(); i.hasNext(); ) {
        MapEntryExpression mme = (MapEntryExpression) i.next();
        String key = mme.getKeyExpression().getText();

        String type = mme.getValueExpression().getText();

        properties.add(
            new PropertyNode(
                key, Modifier.PUBLIC, ClassHelper.make(type), classNode, null, null, null));
      }
    }

    return properties;
  }
コード例 #7
0
    @Override
    public void visitMapEntryExpression(MapEntryExpression expression) {
      // LOG.debug "Transforming expression '${expression}':"

      if (expression.getLineNumber() >= 0 && expression.getLineNumber() < lineNumbers.length) {
        // LOG.debug "   start from ${expression.lineNumber} to ${lineNumbers[expression.lineNumber
        // - 1]}"
        expression.setLineNumber(lineNumbers[expression.getLineNumber() - 1]);
      }

      if (expression.getLastLineNumber() > 0
          && expression.getLastLineNumber() < lineNumbers.length) {
        // LOG.debug "   end from ${expression.lastLineNumber} to
        // ${lineNumbers[expression.lastLineNumber - 1]}"
        expression.setLastLineNumber(lineNumbers[expression.getLastLineNumber() - 1]);
      }
      super.visitMapEntryExpression(expression);
    }
コード例 #8
0
 public void visitMapEntryExpression(MapEntryExpression expression) {
   expression.getKeyExpression().visit(this);
   expression.getValueExpression().visit(this);
 }