Пример #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();
              StringBuffer message = new StringBuffer();
              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();
            }
          }
        }
Пример #2
0
 public static void visitScriptCode(SourceUnit source, GroovyCodeVisitor transformer) {
   source.getAST().getStatementBlock().visit(transformer);
   for (Object method : source.getAST().getMethods()) {
     MethodNode methodNode = (MethodNode) method;
     methodNode.getCode().visit(transformer);
   }
 }
Пример #3
0
    @Override
    public void call(SourceUnit source, GeneratorContext context, ClassNode classNode)
        throws CompilationFailedException {

      ImportCustomizer importCustomizer = new ImportCustomizer();

      // Additional auto configuration
      for (CompilerAutoConfiguration autoConfiguration :
          GroovyCompiler.this.compilerAutoConfigurations) {
        if (autoConfiguration.matches(classNode)) {
          if (GroovyCompiler.this.configuration.isGuessImports()) {
            autoConfiguration.applyImports(importCustomizer);
            importCustomizer.call(source, context, classNode);
          }
          if (source.getAST().getClasses().size() > 0
              && classNode.equals(source.getAST().getClasses().get(0))) {
            autoConfiguration.applyToMainClass(
                GroovyCompiler.this.loader,
                GroovyCompiler.this.configuration,
                context,
                source,
                classNode);
          }
          autoConfiguration.apply(
              GroovyCompiler.this.loader,
              GroovyCompiler.this.configuration,
              context,
              source,
              classNode);
        }
      }
      importCustomizer.call(source, context, classNode);
    }
  private void verifyCompilePhase(AnnotationNode annotation, Class<?> klass) {
    GroovyASTTransformation transformationClass =
        klass.getAnnotation(GroovyASTTransformation.class);
    if (transformationClass != null) {
      CompilePhase specifiedCompilePhase = transformationClass.phase();
      if (specifiedCompilePhase.getPhaseNumber()
          < CompilePhase.SEMANTIC_ANALYSIS.getPhaseNumber()) {
        source
            .getErrorCollector()
            .addError(
                new SimpleMessage(
                    annotation.getClassNode().getName()
                        + " is defined to be run in compile phase "
                        + specifiedCompilePhase
                        + ". Local AST transformations must run in "
                        + CompilePhase.SEMANTIC_ANALYSIS
                        + " or later!",
                    source));
      }

    } else {
      source
          .getErrorCollector()
          .addError(
              new SimpleMessage(
                  "AST transformation implementation classes must be annotated with "
                      + GroovyASTTransformation.class.getName()
                      + ". "
                      + klass.getName()
                      + " lacks this annotation.",
                  source));
    }
  }
  public void visit(ASTNode[] nodes, SourceUnit source) {
    List<ClassNode> classes = source.getAST().getClasses();

    AnnotationNode annotation = null;
    for (ClassNode clazz : classes) {
      annotation = findAnnotation(clazz);
      if (annotation != null) {
        break;
      }
    }

    if (annotation == null) {
      return;
    }

    int[] array = extractLineNumberArray(annotation);
    if (array != null) {
      LineNumberVisitor visitor = new LineNumberVisitor(array);
      for (ClassNode clazz : classes) {
        visitor.visitClass(clazz);
      }
    }

    String sourceName = extractSourceName(annotation);
    if (sourceName != null) {
      source.getAST().setDescription(sourceName);
      // source.name = sourceName
      Field field = ReflectionUtils.findField(SourceUnit.class, "name");
      field.setAccessible(true);
      ReflectionUtils.setField(field, source, sourceName);
    }
  }
  @SuppressWarnings("unused")
  private List<String> getTransformClassNames(
      AnnotationNode annotation, Annotation transformClassAnnotation) {
    List<String> result = new ArrayList<String>();

    try {
      Method valueMethod = transformClassAnnotation.getClass().getMethod("value");
      String[] names = (String[]) valueMethod.invoke(transformClassAnnotation);
      result.addAll(Arrays.asList(names));

      Method classesMethod = transformClassAnnotation.getClass().getMethod("classes");
      Class[] classes = (Class[]) classesMethod.invoke(transformClassAnnotation);
      for (Class klass : classes) {
        result.add(klass.getName());
      }

      if (names.length > 0 && classes.length > 0) {
        source
            .getErrorCollector()
            .addError(
                new SimpleMessage(
                    "@GroovyASTTransformationClass in "
                        + annotation.getClassNode().getName()
                        + " should specify transforms only by class names or by classes and not by both",
                    source));
      }
    } catch (Exception e) {
      source.addException(e);
    }

    return result;
  }
Пример #7
0
        public void call(SourceUnit source) throws CompilationFailedException {
          source.convert();
          CompilationUnit.this.ast.addModule(source.getAST());

          if (CompilationUnit.this.progressCallback != null) {
            CompilationUnit.this.progressCallback.call(source, CompilationUnit.this.phase);
          }
        }
Пример #8
0
 public static ClassNode getScriptClass(SourceUnit source) {
   if (source.getAST().getStatementBlock().getStatements().isEmpty()
       && source.getAST().getMethods().isEmpty()) {
     // There is no script class when there are no statements or methods declared in the script
     return null;
   }
   return source.getAST().getClasses().get(0);
 }
Пример #9
0
        public void call(SourceUnit source) throws CompilationFailedException {
          if (source.phase < phase) {
            source.gotoPhase(phase);
          }

          if (source.phase == phase && phaseComplete && !source.phaseComplete) {
            source.completePhase();
          }
        }
 // GRECLIPSE start
 protected void addTypeError(String msg, ClassNode expr) {
   int line = expr.getLineNumber();
   int col = expr.getColumnNumber();
   SourceUnit source = getSourceUnit();
   source
       .getErrorCollector()
       .addErrorAndContinue(
           // GRECLIPSE: start
           new SyntaxErrorMessage(
               new PreciseSyntaxException(
                   msg + '\n', line, col, expr.getNameStart(), expr.getNameEnd()),
               source)
           // end
           );
 }
 @Override
 public void call(SourceUnit source) {
   if (!source.getAST().getMethods().isEmpty()) {
     hasMethods = true;
   }
   emptyScript = isEmpty(source);
 }
 /**
  * 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;
 }
  private void addTransformsToClassNode(
      AnnotationNode annotation, String[] transformClassNames, Class[] transformClasses) {

    if (transformClassNames.length == 0 && transformClasses.length == 0) {
      source
          .getErrorCollector()
          .addError(
              new SimpleMessage(
                  "@GroovyASTTransformationClass in "
                      + annotation.getClassNode().getName()
                      + " does not specify any transform class names/classes",
                  source));
    }

    if (transformClassNames.length > 0 && transformClasses.length > 0) {
      source
          .getErrorCollector()
          .addError(
              new SimpleMessage(
                  "@GroovyASTTransformationClass in "
                      + annotation.getClassNode().getName()
                      + " should specify transforms only by class names or by classes and not by both",
                  source));
    }

    for (String transformClass : transformClassNames) {
      try {
        Class klass = transformLoader.loadClass(transformClass, false, true, false);
        verifyAndAddTransform(annotation, klass);

      } catch (ClassNotFoundException e) {
        source
            .getErrorCollector()
            .addErrorAndContinue(
                new SimpleMessage(
                    "Could not find class for Transformation Processor "
                        + transformClass
                        + " declared by "
                        + annotation.getClassNode().getName(),
                    source));
      }
    }
    for (Class klass : transformClasses) {
      verifyAndAddTransform(annotation, klass);
    }
  }
Пример #14
0
 public static boolean isVisible(SourceUnit source, String className) {
   try {
     source.getClassLoader().loadClass(className);
     return true;
   } catch (ClassNotFoundException e) {
     return false;
   }
 }
  private Class[] getTransformClasses(ClassNode classNode) {
    if (!classNode.hasClass()) {
      List<AnnotationNode> annotations = classNode.getAnnotations();
      AnnotationNode transformAnnotation = null;
      for (AnnotationNode anno : annotations) {
        if (anno.getClassNode().getName().equals(GroovyASTTransformationClass.class.getName())) {
          transformAnnotation = anno;
          break;
        }
      }
      if (transformAnnotation != null) {
        Expression expr = (Expression) transformAnnotation.getMember("classes");
        if (expr == null) {
          return NO_CLASSES;
        }
        Class<?>[] values = NO_CLASSES;
        // Will need to extract the classnames
        if (expr instanceof ListExpression) {
          List<Class<?>> loadedClasses = new ArrayList<Class<?>>();
          ListExpression expression = (ListExpression) expr;
          List<Expression> expressions = expression.getExpressions();
          for (Expression oneExpr : expressions) {
            String classname = ((ClassExpression) oneExpr).getType().getName();
            try {
              Class<?> clazz = Class.forName(classname, false, transformLoader);
              loadedClasses.add(clazz);
            } catch (ClassNotFoundException cnfe) {
              source
                  .getErrorCollector()
                  .addError(
                      new SimpleMessage(
                          "Ast transform processing, cannot find " + classname, source));
            }
          }
          if (loadedClasses.size() != 0) {
            values = loadedClasses.toArray(new Class<?>[loadedClasses.size()]);
          }
          return values;
        } else {

        }

        throw new RuntimeException(
            "nyi implemented in eclipse: need to support: "
                + expr
                + " (class="
                + expr.getClass()
                + ")");
      }
      return null;
    } else {
      Annotation transformClassAnnotation = getTransformClassAnnotation(classNode);
      if (transformClassAnnotation == null) {
        return null;
      }
      return getTransformClasses(transformClassAnnotation);
    }
  }
  private boolean addCollectedAnnotations(
      List<AnnotationNode> collected, AnnotationNode aliasNode, AnnotatedNode origin) {
    ClassNode classNode = aliasNode.getClassNode();
    boolean ret = false;
    for (AnnotationNode annotation : classNode.getAnnotations()) {
      if (annotation.getClassNode().getName().equals(AnnotationCollector.class.getName())) {
        Expression processorExp = annotation.getMember("processor");
        AnnotationCollectorTransform act = null;
        assertStringConstant(processorExp);
        if (processorExp != null) {
          String className = (String) ((ConstantExpression) processorExp).getValue();
          Class klass = loadTransformClass(className, aliasNode);
          if (klass != null) {
            try {
              act = (AnnotationCollectorTransform) klass.newInstance();
            } catch (InstantiationException e) {
              source.getErrorCollector().addErrorAndContinue(new ExceptionMessage(e, true, source));
            } catch (IllegalAccessException e) {
              source.getErrorCollector().addErrorAndContinue(new ExceptionMessage(e, true, source));
            }
          }
        } else {
          act = new AnnotationCollectorTransform();
        }
        if (act != null) {
          // GRECLIPSE edit
          // collected.addAll(act.visit(annotation, aliasNode, origin, source));
          // original annotation added to metadata to prevent import organizer from deleting its
          // import
          List<AnnotationNode> visitResult = act.visit(annotation, aliasNode, origin, source);
          for (AnnotationNode annotationNode : visitResult) {
            Set<AnnotationNode> aliases = annotationNode.getNodeMetaData("AnnotationCollector");
            if (aliases == null)
              annotationNode.setNodeMetaData("AnnotationCollector", (aliases = new HashSet(1)));

            aliases.add(aliasNode);
          }
          collected.addAll(visitResult);
          // GRECLIPSE end
        }
        ret = true;
      }
    }
    return ret;
  }
 private Class[] getTransformClasses(Annotation transformClassAnnotation) {
   try {
     Method classesMethod = transformClassAnnotation.getClass().getMethod("classes");
     return (Class[]) classesMethod.invoke(transformClassAnnotation);
   } catch (Exception e) {
     source.addException(e);
     return new Class[0];
   }
 }
 private String[] getTransformClassNames(Annotation transformClassAnnotation) {
   try {
     Method valueMethod = transformClassAnnotation.getClass().getMethod("value");
     return (String[]) valueMethod.invoke(transformClassAnnotation);
   } catch (Exception e) {
     source.addException(e);
     return new String[0];
   }
 }
Пример #19
0
 private void changeBugText(GroovyBugError e, SourceUnit context) {
   e.setBugText(
       "exception in phase '"
           + getPhaseDescription()
           + "' in source unit '"
           + ((context != null) ? context.getName() : "?")
           + "' "
           + e.getBugText());
 }
Пример #20
0
  /**
   * Attempts to parse the specified code with the specified tolerance. Updates the <code>parser
   * </code> and <code>error</code> members appropriately. Returns true if the text parsed, false
   * otherwise. The attempts to identify and suppress errors resulting from the unfinished source
   * text.
   *
   * <p><b>Note:</b> taken from {@link groovy.ui.InteractiveShell}.
   */
  private static boolean parse(final String code, final int tolerance) {
    assert code != null;

    boolean parsed = false;

    // Create the parser and attempt to parse the text as a top-level statement.
    try {
      SourceUnit parser = SourceUnit.create("vrl-script", code, tolerance);
      parser.parse();
      parsed = true;
    } // We report errors other than unexpected EOF to the user.
    catch (CompilationFailedException e) {
      //
    } catch (Exception e) {
      //
    }

    return parsed;
  }
Пример #21
0
 /**
  * Generates a fatal compilation error
  *
  * @param sourceUnit the SourceUnit
  * @param astNode the ASTNode which caused the error
  * @param message The error message
  * @param fatal indicates if this is a fatal error
  */
 public static void error(
     final SourceUnit sourceUnit,
     final ASTNode astNode,
     final String message,
     final boolean fatal) {
   final SyntaxException syntaxException =
       new SyntaxException(message, astNode.getLineNumber(), astNode.getColumnNumber());
   final SyntaxErrorMessage syntaxErrorMessage =
       new SyntaxErrorMessage(syntaxException, sourceUnit);
   sourceUnit.getErrorCollector().addError(syntaxErrorMessage, fatal);
 }
    private boolean isEmpty(SourceUnit source) {
      List<Statement> statements = source.getAST().getStatementBlock().getStatements();
      for (Statement statement : statements) {
        if (AstUtils.mayHaveAnEffect(statement)) {
          return false;
        }
      }

      // No statements, or no statements that have an effect
      return true;
    }
Пример #23
0
 /** Adds a SourceUnit to the unit. */
 public SourceUnit addSource(SourceUnit source) {
   String name = source.getName();
   source.setClassLoader(this.classLoader);
   for (SourceUnit su : queuedSources) {
     if (name.equals(su.getName())) return su;
   }
   // GRECLIPSE: start
   if (iterating) {
     GroovyBugError gbe =
         new GroovyBugError(
             "Queuing new source whilst already iterating.  Queued source is '"
                 + source.getName()
                 + "'");
     gbe.printStackTrace();
     throw gbe;
   }
   // end
   queuedSources.add(source);
   return source;
 }
 private void verifyClass(AnnotationNode annotation, Class klass) {
   if (!ASTTransformation.class.isAssignableFrom(klass)) {
     source
         .getErrorCollector()
         .addError(
             new SimpleMessage(
                 "Not an ASTTransformation: "
                     + klass.getName()
                     + " declared by "
                     + annotation.getClassNode().getName(),
                 source));
   }
 }
 private void assertStringConstant(Expression exp) {
   if (exp == null) return;
   if (!(exp instanceof ConstantExpression)) {
     source
         .getErrorCollector()
         .addErrorAndContinue(
             new SyntaxErrorMessage(
                 new SyntaxException(
                     "Expected a String constant.", exp.getLineNumber(), exp.getColumnNumber()),
                 source));
   }
   ConstantExpression ce = (ConstantExpression) exp;
   if (!(ce.getValue() instanceof String)) {
     source
         .getErrorCollector()
         .addErrorAndContinue(
             new SyntaxErrorMessage(
                 new SyntaxException(
                     "Expected a String constant.", exp.getLineNumber(), exp.getColumnNumber()),
                 source));
   }
 }
  protected void addError(String msg, ASTNode expr) {
    int line = expr.getLineNumber();
    int col = expr.getColumnNumber();
    // GRECLIPSE
    int start = expr.getStart();
    int end = expr.getEnd() - 1;
    if (expr instanceof ClassNode) {
      // assume we have a class declaration
      ClassNode cn = (ClassNode) expr;
      if (cn.getNameEnd() > 0) {
        start = cn.getNameStart();
        end = cn.getNameEnd();
      } else if (cn.getComponentType() != null) {
        // avoid extra whitespace after closing ]
        end--;
      }

    } else if (expr instanceof DeclarationExpression) {
      // assume that we just want to underline the variable declaration
      DeclarationExpression decl = (DeclarationExpression) expr;
      Expression lhs = decl.getLeftExpression();
      start = lhs.getStart();
      // avoid extra space before = if a variable
      end =
          lhs instanceof VariableExpression ? start + lhs.getText().length() - 1 : lhs.getEnd() - 1;
    }
    // end

    SourceUnit source = getSourceUnit();
    source
        .getErrorCollector()
        .addErrorAndContinue(
            // GRECLIPSE: start
            new SyntaxErrorMessage(
                new PreciseSyntaxException(msg + '\n', line, col, start, end), source)
            // end
            );
  }
Пример #27
0
  private Class doParseClass(GroovyCodeSource codeSource) {
    validate(codeSource);
    Class answer; // Was neither already loaded nor compiling, so compile and add to cache.
    CompilationUnit unit = createCompilationUnit(config, codeSource.getCodeSource());
    if (recompile != null && recompile || recompile == null && config.getRecompileGroovySource()) {
      unit.addFirstPhaseOperation(
          TimestampAdder.INSTANCE, CompilePhase.CLASS_GENERATION.getPhaseNumber());
    }
    SourceUnit su = null;
    File file = codeSource.getFile();
    if (file != null) {
      su = unit.addSource(file);
    } else {
      URL url = codeSource.getURL();
      if (url != null) {
        su = unit.addSource(url);
      } else {
        su = unit.addSource(codeSource.getName(), codeSource.getScriptText());
      }
    }

    ClassCollector collector = createCollector(unit, su);
    unit.setClassgenCallback(collector);
    int goalPhase = Phases.CLASS_GENERATION;
    if (config != null && config.getTargetDirectory() != null) goalPhase = Phases.OUTPUT;
    unit.compile(goalPhase);

    answer = collector.generatedClass;
    String mainClass = su.getAST().getMainClassName();
    for (Object o : collector.getLoadedClasses()) {
      Class clazz = (Class) o;
      String clazzName = clazz.getName();
      definePackage(clazzName);
      setClassCacheEntry(clazz);
      if (clazzName.equals(mainClass)) answer = clazz;
    }
    return answer;
  }
Пример #28
0
 private void changeBaseScriptTypeFromPackageOrImport(
     final SourceUnit source, final AnnotatedNode 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;
   }
   List<ClassNode> classes = source.getAST().getClasses();
   for (ClassNode classNode : classes) {
     if (classNode.isScriptBody()) {
       changeBaseScriptType(parent, classNode, value.getType());
     }
   }
 }
Пример #29
0
 public static void filterAndTransformStatements(
     SourceUnit source, FilteredTransformer<? extends Statement, ? super Statement> transformer) {
   ListIterator<Statement> statementIterator =
       source.getAST().getStatementBlock().getStatements().listIterator();
   while (statementIterator.hasNext()) {
     Statement statement = statementIterator.next();
     if (transformer.getSpec().isSatisfiedBy(statement)) {
       Statement transformed = transformer.getTransformer().transform(statement);
       statementIterator.set(transformed);
     } else {
       statementIterator.remove();
     }
   }
 }
Пример #30
0
 /**
  * Dequeues any source units add through addSource and resets the compiler phase to
  * initialization.
  *
  * <p>Note: this does not mean a file is recompiled. If a SourceUnit has already passed a phase it
  * is skipped until a higher phase is reached.
  *
  * @return true if there was a queued source
  * @throws CompilationFailedException
  */
 protected boolean dequeued() throws CompilationFailedException {
   boolean dequeue = !queuedSources.isEmpty();
   while (!queuedSources.isEmpty()) {
     SourceUnit su = queuedSources.removeFirst();
     String name = su.getName();
     // GRECLIPSE: start
     if (iterating) {
       GroovyBugError gbe =
           new GroovyBugError(
               "Damaging 'names' whilst already iterating.  Name getting added is '"
                   + su.getName()
                   + "'");
       gbe.printStackTrace();
       throw gbe;
     }
     // end
     names.add(name);
     sources.put(name, su);
   }
   if (dequeue) {
     gotoPhase(Phases.INITIALIZATION);
   }
   return dequeue;
 }