예제 #1
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;
  }
예제 #2
0
 /** Adds a set of source files to the unit. */
 public void addSources(File[] files) {
   for (File file : files) {
     addSource(file);
   }
 }
예제 #3
0
    public void compile() {
        if (compiledTemplate == null) {
            try {
                long start = System.currentTimeMillis();

                TClassLoader tClassLoader = new TClassLoader();

                // Let's compile the groovy source
                final List<GroovyClass> groovyClassesForThisTemplate = new ArrayList<GroovyClass>();
                // ~~~ Please !
                CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
                compilerConfiguration.setSourceEncoding("utf-8"); // ouf
                CompilationUnit compilationUnit = new CompilationUnit(compilerConfiguration);
                compilationUnit.addSource(new SourceUnit(name, compiledSource, compilerConfiguration, tClassLoader, compilationUnit.getErrorCollector()));
                Field phasesF = compilationUnit.getClass().getDeclaredField("phaseOperations");
                phasesF.setAccessible(true);
                LinkedList[] phases = (LinkedList[]) phasesF.get(compilationUnit);
                LinkedList<GroovyClassOperation> output = new LinkedList<GroovyClassOperation>();
                phases[Phases.OUTPUT] = output;
                output.add(new GroovyClassOperation() {
                    public void call(GroovyClass gclass) {
                        groovyClassesForThisTemplate.add(gclass);
                    }
                });
                compilationUnit.compile();
                // ouf 

                // Define script classes
                StringBuilder sb = new StringBuilder();
                sb.append("LINESMATRIX" + "\n");
                sb.append(Codec.encodeBASE64(Java.serialize(linesMatrix)).replaceAll("\\s", ""));
                sb.append("\n");
                sb.append("DOBODYLINES" + "\n");
                sb.append(Codec.encodeBASE64(Java.serialize(doBodyLines)).replaceAll("\\s", ""));
                sb.append("\n");
                for (GroovyClass gclass : groovyClassesForThisTemplate) {
                    tClassLoader.defineTemplate(gclass.getName(), gclass.getBytes());
                    sb.append(gclass.getName() + "\n");
                    sb.append(Codec.encodeBASE64(gclass.getBytes()).replaceAll("\\s", ""));
                    sb.append("\n");
                }
                // Cache
                BytecodeCache.cacheBytecode(sb.toString().getBytes("utf-8"), name, source);
                compiledTemplate = tClassLoader.loadClass(groovyClassesForThisTemplate.get(0).getName());
                if (System.getProperty("precompile") != null) {
                    try {
                        // emit bytecode to standard class layout as well
                        File f = Play.getFile("precompiled/templates/" + name.replaceAll("\\{(.*)\\}", "from_$1").replace(":", "_").replace("..", "parent"));
                        f.getParentFile().mkdirs();
                        FileOutputStream fos = new FileOutputStream(f);
                        fos.write(sb.toString().getBytes("utf-8"));
                        fos.close();
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }

                Logger.trace("%sms to compile template %s to %d classes", System.currentTimeMillis() - start, name, groovyClassesForThisTemplate.size());

            } catch (MultipleCompilationErrorsException e) {
                if (e.getErrorCollector().getLastError() != null) {
                    SyntaxErrorMessage errorMessage = (SyntaxErrorMessage) e.getErrorCollector().getLastError();
                    SyntaxException syntaxException = errorMessage.getCause();
                    Integer line = this.linesMatrix.get(syntaxException.getLine());
                    if (line == null) {
                        line = 0;
                    }
                    String message = syntaxException.getMessage();
                    if (message.indexOf("@") > 0) {
                        message = message.substring(0, message.lastIndexOf("@"));
                    }
                    throw new TemplateCompilationException(this, line, message);
                }
                throw new UnexpectedException(e);
            } catch (Exception e) {
                throw new UnexpectedException(e);
            }
        }
        compiledTemplateName = compiledTemplate.getName();
    }
예제 #4
0
 /** Adds a set of file paths to the unit. */
 public void addSources(String[] paths) {
   for (String path : paths) {
     addSource(new File(path));
   }
 }
예제 #5
0
    @Override
    protected CompilationUnit createCompilationUnit(
        CompilerConfiguration configuration, CodeSource source) {
      CompilationUnit cu = super.createCompilationUnit(configuration, source);
      LocalData local = getLocalData().get();
      local.cu = cu;
      final StringSetMap cache = local.dependencyCache;

      // "." is used to transfer compilation dependencies, which will be
      // recollected later during compilation
      for (String depSourcePath : cache.get(".")) {
        try {
          cu.addSource(getResourceConnection(depSourcePath).getURL());
        } catch (ResourceException e) {
          /* ignore */
        }
      }

      // remove all old entries including the "." entry
      cache.clear();
      cu.addPhaseOperation(
          new CompilationUnit.PrimaryClassNodeOperation() {
            @Override
            public void call(final SourceUnit source, GeneratorContext context, ClassNode classNode)
                throws CompilationFailedException {
              // GROOVY-4013: If it is an inner class, tracking its dependencies doesn't really
              // serve any purpose and also interferes with the caching done to track dependencies
              if (classNode instanceof InnerClassNode) return;
              DependencyTracker dt = new DependencyTracker(source, cache);
              dt.visitClass(classNode);
            }
          },
          Phases.CLASS_GENERATION);

      cu.setClassNodeResolver(
          new ClassNodeResolver() {
            @Override
            public LookupResult findClassNode(String origName, CompilationUnit compilationUnit) {
              CompilerConfiguration cc = compilationUnit.getConfiguration();
              String name = origName.replace('.', '/');
              for (String ext : cc.getScriptExtensions()) {
                try {
                  String finalName = name + "." + ext;
                  URLConnection conn = rc.getResourceConnection(finalName);
                  URL url = conn.getURL();
                  String path = url.toExternalForm();
                  ScriptCacheEntry entry = scriptCache.get(path);
                  Class clazz = null;
                  if (entry != null) clazz = entry.scriptClass;
                  try {
                    if (GroovyScriptEngine.this.isSourceNewer(entry)) {
                      // String encoding = conn.getContentEncoding() != null ?
                      // conn.getContentEncoding() : "UTF-8";
                      SourceUnit su = compilationUnit.addSource(url);
                      return new LookupResult(su, null);
                    }
                  } finally {
                    forceClose(conn);
                  }
                  if (clazz != null) {
                    ClassNode cn = new ClassNode(clazz);
                    return new LookupResult(null, cn);
                  }
                } catch (ResourceException re) {
                  // skip
                }
              }
              return super.findClassNode(origName, compilationUnit);
            }
          });

      final List<CompilationCustomizer> customizers = config.getCompilationCustomizers();
      if (customizers != null) {
        // GROOVY-4813 : apply configuration customizers
        for (CompilationCustomizer customizer : customizers) {
          cu.addPhaseOperation(customizer, customizer.getPhase().getPhaseNumber());
        }
      }

      return cu;
    }