Пример #1
0
        public void call(SourceUnit source) throws CompilationFailedException {
          List<ClassNode> classes = source.ast.getClasses();
          for (ClassNode node : classes) {
            CompileUnit cu = node.getCompileUnit();
            for (Iterator iter = cu.iterateClassNodeToCompile(); iter.hasNext(); ) {
              String name = (String) iter.next();
              SourceUnit su = ast.getScriptSourceLocation(name);
              List<ClassNode> classesInSourceUnit = su.ast.getClasses();
              StringBuilder message = new StringBuilder();
              message
                  .append("Compilation incomplete: expected to find the class ")
                  .append(name)
                  .append(" in ")
                  .append(su.getName());
              if (classesInSourceUnit.isEmpty()) {
                message.append(", but the file seems not to contain any classes");
              } else {
                message.append(", but the file contains the classes: ");
                boolean first = true;
                for (ClassNode cn : classesInSourceUnit) {
                  if (!first) {
                    message.append(", ");
                  } else {
                    first = false;
                  }
                  message.append(cn.getName());
                }
              }

              getErrorCollector()
                  .addErrorAndContinue(new SimpleMessage(message.toString(), CompilationUnit.this));
              iter.remove();
            }
          }
        }
  public void visitInboundClassNode(ClassNode node) {
    if (!getCoverage().contains(node)) {
      getSelectedNodes().add(node);

      Node copy = getFactory().createClass(node.getName(), node.isConfirmed());
      getCopiedNodes().add(copy);
      copy.addDependency(currentNode);
    }
  }
  private FieldNode getKeyField(ClassNode target) {

    List<FieldNode> annotatedFields = getAnnotatedFieldsOfHierarchy(target, KEY_ANNOTATION);

    if (annotatedFields.isEmpty()) return null;

    if (annotatedFields.size() > 1) {
      addCompileError(
          String.format(
              "Found more than one key fields, only one is allowed in hierarchy (%s, %s)",
              getQualifiedName(annotatedFields.get(0)), getQualifiedName(annotatedFields.get(1))),
          annotatedFields.get(0));
      return null;
    }

    FieldNode result = annotatedFields.get(0);

    if (!result.getType().equals(ClassHelper.STRING_TYPE)) {
      addCompileError(
          String.format(
              "Key field '%s' must be of type String, but is '%s' instead",
              result.getName(), result.getType().getName()),
          result);
      return null;
    }

    ClassNode ancestor = ASTHelper.getHighestAncestorDSLObject(target);

    if (target.equals(ancestor)) return result;

    FieldNode firstKey = getKeyField(ancestor);

    if (firstKey == null) {
      addCompileError(
          String.format(
              "Inconsistent hierarchy: Toplevel class %s has no key, but child class %s defines '%s'.",
              ancestor.getName(), target.getName(), result.getName()),
          result);
      return null;
    }

    return result;
  }
Пример #4
0
 /**
  * Sets this instance as proxy for the given ClassNode.
  *
  * @param cn the class to redirect to. If set to null the redirect will be removed
  */
 public void setRedirect(ClassNode cn) {
   if (isPrimaryNode)
     throw new GroovyBugError(
         "tried to set a redirect for a primary ClassNode ("
             + getName()
             + "->"
             + cn.getName()
             + ").");
   if (cn != null) cn = cn.redirect();
   if (cn == this) return;
   redirect = cn;
 }
  private void injectToStringMethod(ClassNode classNode) {
    final boolean hasToString = /*GrailsASTUtils.*/ implementsZeroArgMethod(classNode, "toString");

    if (!hasToString) {
      GStringExpression ge = new GStringExpression(classNode.getName() + " : ${id}");
      ge.addString(new ConstantExpression(classNode.getName() + " : "));
      ge.addValue(new VariableExpression("id"));
      Statement s = new ReturnStatement(ge);
      MethodNode mn =
          new MethodNode(
              "toString",
              Modifier.PUBLIC,
              new ClassNode(String.class),
              new Parameter[0],
              new ClassNode[0],
              s);
      // if(LOG.isDebugEnabled()) {
      //    LOG.debug("[GrailsDomainInjector] Adding method [toString()] to class [" +
      // classNode.getName() + "]");
      // }
      classNode.addMethod(mn);
    }
  }
Пример #6
0
 /**
  * This exists to avoid a recursive definition of toString. The default toString in GenericsType
  * calls ClassNode.toString(), which calls GenericsType.toString(), etc.
  *
  * @param genericsType
  * @param showRedirect
  * @return the string representing the generic type
  */
 private String genericTypeAsString(GenericsType genericsType, boolean showRedirect) {
   String ret = genericsType.getName();
   if (genericsType.getUpperBounds() != null) {
     ret += " extends ";
     for (int i = 0; i < genericsType.getUpperBounds().length; i++) {
       ClassNode classNode = genericsType.getUpperBounds()[i];
       if (classNode.equals(this)) {
         ret += classNode.getName();
       } else {
         ret += classNode.toString(showRedirect);
       }
       if (i + 1 < genericsType.getUpperBounds().length) ret += " & ";
     }
   } else if (genericsType.getLowerBound() != null) {
     ClassNode classNode = genericsType.getLowerBound();
     if (classNode.equals(this)) {
       ret += " super " + classNode.getName();
     } else {
       ret += " super " + classNode;
     }
   }
   return ret;
 }
Пример #7
0
  private static void showDocument(Document doc) {
    StringBuffer content = new StringBuffer();
    Node node = doc.getChildNodes().item(0);
    ApplicationNode appNode = new ApplicationNode(node);

    content.append("Application \n");

    List<ClassNode> classes = appNode.getClasses();

    for (int i = 0; i < classes.size(); i++) {
      ClassNode classNode = classes.get(i);
      content.append(SPACE + "Class: " + classNode.getName() + " \n");

      List<MethodNode> methods = classNode.getMethods();

      for (int j = 0; j < methods.size(); j++) {
        MethodNode methodNode = methods.get(j);
        content.append(SPACE + SPACE + "Method: " + methodNode.getName() + " \n");
      }
    }

    System.out.println(content.toString());
  }
 private Expression findStaticMethodImportFromModule(Expression method, Expression args) {
   ModuleNode module = currentClass.getModule();
   if (module == null || !(method instanceof ConstantExpression)) return null;
   Map<String, ImportNode> importNodes = module.getStaticImports();
   ConstantExpression ce = (ConstantExpression) method;
   Expression expression;
   Object value = ce.getValue();
   // skip non-Strings, e.g. Integer
   if (!(value instanceof String)) return null;
   final String name = (String) value;
   // look for one of these:
   //   import static SomeClass.method [as otherName]
   // when resolving methodCall() or getProp() or setProp()
   if (importNodes.containsKey(name)) {
     ImportNode importNode = importNodes.get(name);
     expression = findStaticMethod(importNode.getType(), importNode.getFieldName(), args);
     if (expression != null) return expression;
     expression =
         findStaticPropertyAccessorGivenArgs(
             importNode.getType(), getPropNameForAccessor(importNode.getFieldName()), args);
     if (expression != null) {
       return new StaticMethodCallExpression(
           importNode.getType(), importNode.getFieldName(), args);
     }
   }
   // look for one of these:
   //   import static SomeClass.someProp [as otherName]
   // when resolving getProp() or setProp()
   if (validPropName(name)) {
     String propName = getPropNameForAccessor(name);
     if (importNodes.containsKey(propName)) {
       ImportNode importNode = importNodes.get(propName);
       expression =
           findStaticMethod(
               importNode.getType(), prefix(name) + capitalize(importNode.getFieldName()), args);
       if (expression != null) return expression;
       expression =
           findStaticPropertyAccessorGivenArgs(
               importNode.getType(), importNode.getFieldName(), args);
       if (expression != null) {
         return new StaticMethodCallExpression(
             importNode.getType(), prefix(name) + capitalize(importNode.getFieldName()), args);
       }
     }
   }
   Map<String, ImportNode> starImports = module.getStaticStarImports();
   ClassNode starImportType;
   if (currentClass.isEnum() && starImports.containsKey(currentClass.getName())) {
     ImportNode importNode = starImports.get(currentClass.getName());
     starImportType = importNode == null ? null : importNode.getType();
     expression = findStaticMethod(starImportType, name, args);
     if (expression != null) return expression;
   } else {
     for (ImportNode importNode : starImports.values()) {
       starImportType = importNode == null ? null : importNode.getType();
       expression = findStaticMethod(starImportType, name, args);
       if (expression != null) return expression;
       expression =
           findStaticPropertyAccessorGivenArgs(starImportType, getPropNameForAccessor(name), args);
       if (expression != null) {
         return new StaticMethodCallExpression(starImportType, name, args);
       }
     }
   }
   return null;
 }
Пример #9
0
        public void call(SourceUnit source, GeneratorContext context, ClassNode classNode)
            throws CompilationFailedException {

          optimizer.visitClass(
              classNode, source); // GROOVY-4272: repositioned it here from staticImport

          if (!classNode.isSynthetic()) {
            GenericsVisitor genericsVisitor = new GenericsVisitor(source);
            genericsVisitor.visitClass(classNode);
          }
          //
          // Run the Verifier on the outer class
          //
          try {
            verifier.visitClass(classNode);
          } catch (GroovyRuntimeException rpe) {
            ASTNode node = rpe.getNode();
            getErrorCollector()
                .addError(
                    new SyntaxException(
                        rpe.getMessage(),
                        node.getLineNumber(),
                        node.getColumnNumber(),
                        node.getLastLineNumber(),
                        node.getLastColumnNumber()),
                    source);
          }

          LabelVerifier lv = new LabelVerifier(source);
          lv.visitClass(classNode);

          ClassCompletionVerifier completionVerifier = new ClassCompletionVerifier(source);
          completionVerifier.visitClass(classNode);

          ExtendedVerifier xverifier = new ExtendedVerifier(source);
          xverifier.visitClass(classNode);

          // because the class may be generated even if a error was found
          // and that class may have an invalid format we fail here if needed
          getErrorCollector().failIfErrors();

          //
          // Prep the generator machinery
          //
          ClassVisitor visitor = createClassVisitor();

          String sourceName =
              (source == null ? classNode.getModule().getDescription() : source.getName());
          // only show the file name and its extension like javac does in its stacktraces rather
          // than the full path
          // also takes care of both \ and / depending on the host compiling environment
          if (sourceName != null)
            sourceName =
                sourceName.substring(
                    Math.max(sourceName.lastIndexOf('\\'), sourceName.lastIndexOf('/')) + 1);
          AsmClassGenerator generator = new AsmClassGenerator(source, context, visitor, sourceName);

          //
          // Run the generation and create the class (if required)
          //
          // GRECLIPSE: if there are errors, don't generate code.
          // code gen can fail unexpectedly if there was an earlier error.
          if (!source.getErrorCollector().hasErrors()) {
            // end
            generator.visitClass(classNode);

            byte[] bytes = ((ClassWriter) visitor).toByteArray();
            /// GRECLIPSE: start: added classNode, sourceUnit
            /*old{
            generatedClasses.add(new GroovyClass(classNode.getName(), bytes));
            }*/
            // newcode
            generatedClasses.add(new GroovyClass(classNode.getName(), bytes, classNode, source));
            // end

            //
            // Handle any callback that's been set
            //
            if (CompilationUnit.this.classgenCallback != null) {
              classgenCallback.call(visitor, classNode);
            }

            //
            // Recurse for inner classes
            //
            LinkedList innerClasses = generator.getInnerClasses();
            while (!innerClasses.isEmpty()) {
              classgen.call(source, context, (ClassNode) innerClasses.removeFirst());
            }
            // GRECLIPSE: if there are errors, don't generate code
          }
          // end
        }
  private void createMapOfDSLObjectMethods(
      FieldNode fieldNode, ClassNode keyType, ClassNode elementType) {
    if (getKeyField(elementType) == null) {
      addCompileError(
          String.format(
              "Value type of map %s (%s) has no key field",
              fieldNode.getName(), elementType.getName()),
          fieldNode);
      return;
    }

    MethodBuilder.createPublicMethod(fieldNode.getName())
        .closureParam("closure")
        .assignS(propX(varX("closure"), "delegate"), varX("this"))
        .assignS(
            propX(varX("closure"), "resolveStrategy"),
            propX(classX(ClassHelper.CLOSURE_TYPE), "DELEGATE_FIRST"))
        .callMethod("closure", "call")
        .addTo(annotatedClass);

    String methodName = getElementNameForCollectionField(fieldNode);
    String targetOwner = getOwnerFieldName(elementType);

    if (!ASTHelper.isAbstract(elementType)) {
      MethodBuilder.createPublicMethod(methodName)
          .returning(elementType)
          .namedParams("values")
          .param(keyType, "key")
          .delegatingClosureParam(elementType)
          .declareVariable("created", callX(classX(elementType), "newInstance", args("key")))
          .callMethod("created", "copyFromTemplate")
          .optionalAssignThisToPropertyS("created", targetOwner, targetOwner)
          .callMethod(fieldNode.getName(), "put", args(varX("key"), varX("created")))
          .callMethod("created", "apply", args("values", "closure"))
          .callValidationOn("created")
          .doReturn("created")
          .addTo(annotatedClass);
      MethodBuilder.createPublicMethod(methodName)
          .returning(elementType)
          .param(keyType, "key")
          .delegatingClosureParam(elementType)
          .declareVariable("created", callX(classX(elementType), "newInstance", args("key")))
          .callMethod("created", "copyFromTemplate")
          .optionalAssignThisToPropertyS("created", targetOwner, targetOwner)
          .callMethod(fieldNode.getName(), "put", args(varX("key"), varX("created")))
          .callMethod("created", "apply", varX("closure"))
          .callValidationOn("created")
          .doReturn("created")
          .addTo(annotatedClass);
    }

    if (!isFinal(elementType)) {
      MethodBuilder.createPublicMethod(methodName)
          .returning(elementType)
          .namedParams("values")
          .classParam("typeToCreate", elementType)
          .param(keyType, "key")
          .delegatingClosureParam(elementType)
          .declareVariable("created", callX(varX("typeToCreate"), "newInstance", args("key")))
          .callMethod("created", "copyFromTemplate")
          .callMethod(fieldNode.getName(), "put", args(varX("key"), varX("created")))
          .optionalAssignThisToPropertyS("created", targetOwner, targetOwner)
          .callMethod("created", "apply", args("values", "closure"))
          .callValidationOn("created")
          .doReturn("created")
          .addTo(annotatedClass);
      MethodBuilder.createPublicMethod(methodName)
          .returning(elementType)
          .classParam("typeToCreate", elementType)
          .param(keyType, "key")
          .delegatingClosureParam(elementType)
          .declareVariable("created", callX(varX("typeToCreate"), "newInstance", args("key")))
          .callMethod("created", "copyFromTemplate")
          .callMethod(fieldNode.getName(), "put", args(varX("key"), varX("created")))
          .optionalAssignThisToPropertyS("created", targetOwner, targetOwner)
          .callMethod("created", "apply", varX("closure"))
          .callValidationOn("created")
          .doReturn("created")
          .addTo(annotatedClass);
    }

    //noinspection ConstantConditions
    MethodBuilder.createPublicMethod(methodName)
        .param(elementType, "value")
        .callMethod(
            fieldNode.getName(),
            "put",
            args(propX(varX("value"), getKeyField(elementType).getName()), varX("value")))
        .optionalAssignThisToPropertyS("value", targetOwner, targetOwner)
        .addTo(annotatedClass);
  }
 public void visitClassNode(ClassNode node) {
   currentNode = getFactory().createClass(node.getName(), node.isConfirmed());
 }
Пример #12
0
 /*
  * Constructor used by makeArray() if no real class is available
  */
 private ClassNode(ClassNode componentType) {
   this(componentType.getName() + "[]", ACC_PUBLIC, ClassHelper.OBJECT_TYPE);
   this.componentType = componentType.redirect();
   isPrimaryNode = false;
 }