relax check
[fedora-idea.git] / plugins / groovy / rt / src / org / jetbrains / groovy / compiler / rt / GroovycRunner.java
blob7a9e61af06186c2e9f15c3097989d46b0bd3bd27
1 /*
2 * Copyright 2000-2007 JetBrains s.r.o.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
7 * http://www.apache.org/licenses/LICENSE-2.0
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
16 package org.jetbrains.groovy.compiler.rt;
18 import groovy.lang.GroovyClassLoader;
19 import org.codehaus.groovy.ast.ClassNode;
20 import org.codehaus.groovy.classgen.GeneratorContext;
21 import org.codehaus.groovy.control.*;
22 import org.codehaus.groovy.control.messages.WarningMessage;
23 import org.codehaus.groovy.tools.javac.JavaAwareResolveVisitor;
24 import org.codehaus.groovy.tools.javac.JavaStubGenerator;
26 import java.io.*;
27 import java.net.MalformedURLException;
28 import java.net.URL;
29 import java.security.AccessController;
30 import java.security.PrivilegedAction;
31 import java.util.*;
33 /**
34 * @author: Dmitry.Krasilschikov
35 * @date: 16.04.2007
36 * @noinspection UseOfSystemOutOrSystemErr,CallToPrintStackTrace
39 public class GroovycRunner {
41 public static final String PATCHERS = "patchers";
42 public static final String ENCODING = "encoding";
43 public static final String OUTPUTPATH = "outputpath";
44 public static final String FINAL_OUTPUTPATH = "final_outputpath";
45 public static final String END = "end";
47 public static final String SRC_FILE = "src_file";
48 public static final String COMPILED_START = "%%c";
50 public static final String COMPILED_END = "/%c";
51 public static final String TO_RECOMPILE_START = "%%rc";
53 public static final String TO_RECOMPILE_END = "/%rc";
54 public static final String MESSAGES_START = "%%m";
56 public static final String MESSAGES_END = "/%m";
57 public static final String SEPARATOR = "#%%#%%%#%%%%%%%%%#";
59 //public static final Controller ourController = initController();
60 public static final String PRESENTABLE_MESSAGE = "@#$%@# Presentable:";
61 public static final String CLEAR_PRESENTABLE = "$@#$%^ CLEAR_PRESENTABLE";
63 private GroovycRunner() {
67 private static Controller initController() {
68 if (!"true".equals(System.getProperty("profile.groovy.compiler"))) {
69 return null;
72 try {
73 return new Controller();
75 catch (Exception ex) {
76 ex.printStackTrace();
77 return null;
83 public static void main(String[] args) {
85 if (ourController != null) {
86 try {
87 ourController.startCPUProfiling(ProfilingModes.CPU_SAMPLING, null);
89 catch (Exception e) {
90 e.printStackTrace();
95 if (args.length != 2) {
96 System.err.println("There is no arguments for groovy compiler");
97 return;
100 final boolean forStubs = "stubs".equals(args[0]);
101 final File argsFile = new File(args[1]);
103 if (!argsFile.exists()) {
104 System.err.println("Arguments file for groovy compiler not found");
105 return;
108 try {
109 final CompilerConfiguration compilerConfiguration = new CompilerConfiguration();
110 compilerConfiguration.setOutput(new PrintWriter(System.err));
111 compilerConfiguration.setWarningLevel(WarningMessage.PARANOIA);
113 final List compilerMessages = new ArrayList();
114 final List patchers = new ArrayList();
115 final List srcFiles = new ArrayList();
116 final Map class2File = new HashMap();
118 final String[] finalOutput = new String[1];
119 fillFromArgsFile(argsFile, compilerConfiguration, patchers, compilerMessages, srcFiles, class2File, finalOutput);
120 if (srcFiles.isEmpty()) return;
122 System.out.println(PRESENTABLE_MESSAGE + "Groovy compiler: loading sources...");
123 final CompilationUnit unit = createCompilationUnit(forStubs, compilerConfiguration, finalOutput[0]);
124 addSources(forStubs, srcFiles, unit);
125 runPatchers(patchers, compilerMessages, class2File, unit);
127 System.out.println(PRESENTABLE_MESSAGE + "Groovyc: compiling...");
128 final List compiledFiles = GroovyCompilerWrapper.compile(compilerMessages, forStubs, unit);
129 System.out.println(CLEAR_PRESENTABLE);
131 System.out.println();
132 reportCompiledItems(compiledFiles);
134 System.out.println();
135 if (compiledFiles.isEmpty()) {
136 reportNotCompiledItems(srcFiles);
139 int errorCount = 0;
140 for (int i = 0; i < compilerMessages.size(); i++) {
141 CompilerMessage message = (CompilerMessage)compilerMessages.get(i);
143 if (message.getCategory() == CompilerMessage.ERROR) {
144 if (errorCount > 100) {
145 continue;
147 errorCount++;
150 printMessage(message);
153 catch (Throwable e) {
154 e.printStackTrace();
157 finally {
158 if (ourController != null) {
159 try {
160 ourController.captureSnapshot(ProfilingModes.SNAPSHOT_WITHOUT_HEAP);
161 ourController.stopCPUProfiling();
163 catch (Exception e) {
164 e.printStackTrace();
171 private static String fillFromArgsFile(File argsFile, CompilerConfiguration compilerConfiguration, List patchers, List compilerMessages,
172 List srcFiles, Map class2File, String[] finalOutput) {
173 String moduleClasspath = null;
175 BufferedReader reader = null;
176 FileInputStream stream;
178 try {
179 stream = new FileInputStream(argsFile);
180 reader = new BufferedReader(new InputStreamReader(stream));
182 String line;
184 while ((line = reader.readLine()) != null && !line.equals(OUTPUTPATH)) {
185 if (SRC_FILE.equals(line)) {
186 final File file = new File(reader.readLine());
187 srcFiles.add(file);
188 String s;
189 while (!END.equals(s = reader.readLine())) {
190 class2File.put(s, file);
195 while (line != null) {
196 if (line.startsWith(PATCHERS)) {
197 String s;
198 while (!END.equals(s = reader.readLine())) {
199 try {
200 final CompilationUnitPatcher patcher = (CompilationUnitPatcher)Class.forName(s).newInstance();
201 patchers.add(patcher);
203 catch (InstantiationException e) {
204 addExceptionInfo(compilerMessages, e, "Couldn't instantiate " + s);
206 catch (IllegalAccessException e) {
207 addExceptionInfo(compilerMessages, e, "Couldn't instantiate " + s);
209 catch (ClassNotFoundException e) {
210 addExceptionInfo(compilerMessages, e, "Couldn't instantiate " + s);
214 else if (line.startsWith(ENCODING)) {
215 compilerConfiguration.setSourceEncoding(reader.readLine());
217 else if (line.startsWith(OUTPUTPATH)) {
218 compilerConfiguration.setTargetDirectory(reader.readLine());
220 else if (line.startsWith(FINAL_OUTPUTPATH)) {
221 finalOutput[0] = reader.readLine();
224 line = reader.readLine();
228 catch (FileNotFoundException e) {
229 e.printStackTrace();
231 catch (IOException e) {
232 e.printStackTrace();
234 finally {
235 try {
236 reader.close();
238 catch (IOException e) {
239 e.printStackTrace();
241 finally {
242 argsFile.delete();
245 return moduleClasspath;
248 private static void addSources(boolean forStubs, List srcFiles, final CompilationUnit unit) {
249 for (int i = 0; i < srcFiles.size(); i++) {
250 final File file = (File)srcFiles.get(i);
251 if (forStubs && file.getName().endsWith(".java")) {
252 // unit.addSources(new File[]{file});
253 continue;
256 unit.addSource(new SourceUnit(file, unit.getConfiguration(), unit.getClassLoader(), unit.getErrorCollector()) {
257 public void parse() throws CompilationFailedException {
258 System.out.println(PRESENTABLE_MESSAGE + "Parsing " + file.getName() + "...");
259 super.parse();
260 System.out.println(CLEAR_PRESENTABLE);
266 private static void runPatchers(List patchers, List compilerMessages, Map class2File, CompilationUnit unit) {
267 if (!patchers.isEmpty()) {
268 final PsiAwareResourceLoader loader = new PsiAwareResourceLoader(class2File);
269 for (int i = 0; i < patchers.size(); i++) {
270 final CompilationUnitPatcher patcher = (CompilationUnitPatcher)patchers.get(i);
271 try {
272 patcher.patchCompilationUnit(unit, loader);
274 catch (LinkageError e) {
275 addExceptionInfo(compilerMessages, e, "Couldn't run " + patcher.getClass().getName());
281 private static void reportNotCompiledItems(Collection toRecompile) {
282 for (Iterator iterator = toRecompile.iterator(); iterator.hasNext();) {
283 File file = (File)iterator.next();
284 System.out.print(TO_RECOMPILE_START);
285 System.out.print(file.getAbsolutePath());
286 System.out.print(TO_RECOMPILE_END);
287 System.out.println();
291 private static void reportCompiledItems(List compiledFiles) {
292 for (int i = 0; i < compiledFiles.size(); i++) {
294 * output path
295 * source file
296 * output root directory
298 GroovyCompilerWrapper.OutputItem compiledOutputItem = (GroovyCompilerWrapper.OutputItem)compiledFiles.get(i);
299 System.out.print(COMPILED_START);
300 System.out.print(compiledOutputItem.getOutputPath());
301 System.out.print(SEPARATOR);
302 System.out.print(compiledOutputItem.getSourceFile());
303 System.out.print(SEPARATOR);
304 System.out.print(compiledOutputItem.getOutputRootDirectory());
305 System.out.print(COMPILED_END);
306 System.out.println();
310 private static void printMessage(CompilerMessage message) {
311 System.out.print(MESSAGES_START);
312 System.out.print(message.getCategory());
313 System.out.print(SEPARATOR);
314 System.out.print(message.getMessage());
315 System.out.print(SEPARATOR);
316 System.out.print(message.getUrl());
317 System.out.print(SEPARATOR);
318 System.out.print(message.getLineNum());
319 System.out.print(SEPARATOR);
320 System.out.print(message.getColumnNum());
321 System.out.print(SEPARATOR);
322 System.out.print(MESSAGES_END);
323 System.out.println();
326 private static void addExceptionInfo(List compilerMessages, Throwable e, String message) {
327 final StringWriter writer = new StringWriter();
328 e.printStackTrace(new PrintWriter(writer));
329 compilerMessages.add(new CompilerMessage(CompilerMessage.WARNING, message + ":\n" + writer, "<exception>", -1, -1));
332 private static CompilationUnit createCompilationUnit(final boolean forStubs, final CompilerConfiguration config, final String finalOutput) {
333 config.setClasspathList(Collections.EMPTY_LIST);
335 final GroovyClassLoader classLoader = buildClassLoaderFor(config);
337 final GroovyClassLoader transformLoader = new GroovyClassLoader(classLoader) {
338 public Enumeration getResources(String name) throws IOException {
339 if (forStubs) {
340 //return Collections.enumeration(Collections.EMPTY_LIST);
343 if (name.endsWith("org.codehaus.groovy.transform.ASTTransformation")) {
344 final Enumeration resources = super.getResources(name);
345 final ArrayList list = Collections.list(resources);
346 for (Iterator iterator = list.iterator(); iterator.hasNext();) {
347 final String file = ((URL)iterator.next()).getFile();
348 if (file.contains(finalOutput)) {
349 iterator.remove();
352 return Collections.enumeration(list);
354 return super.getResources(name);
357 final CompilationUnit unit = new CompilationUnit(config, null, classLoader, transformLoader) {
359 public void gotoPhase(int phase) throws CompilationFailedException {
360 super.gotoPhase(phase);
361 if (phase <= Phases.ALL) {
362 System.out.println(PRESENTABLE_MESSAGE + (forStubs ? "Groovy stub generator: " : "Groovy compiler: ") + getPhaseDescription());
366 if (forStubs) {
367 //todo reuse JavaStubCompilationUnit in groovy 1.7
368 boolean useJava5 = config.getTargetBytecode().equals(CompilerConfiguration.POST_JDK5);
369 final JavaStubGenerator stubGenerator = new JavaStubGenerator(config.getTargetDirectory(), false, useJava5);
371 //but JavaStubCompilationUnit doesn't have this...
372 unit.addPhaseOperation(new CompilationUnit.PrimaryClassNodeOperation() {
373 public void call(SourceUnit source, GeneratorContext context, ClassNode node) throws CompilationFailedException {
374 new JavaAwareResolveVisitor(unit).startResolving(node, source);
376 },Phases.CONVERSION);
378 unit.addPhaseOperation(new CompilationUnit.PrimaryClassNodeOperation() {
379 public void call(final SourceUnit source, final GeneratorContext context, final ClassNode node) throws CompilationFailedException {
380 final String name = node.getNameWithoutPackage();
381 if ("package-info".equals(name)) {
382 return;
385 System.out.println(PRESENTABLE_MESSAGE + "Generating stub for " + name);
386 try {
387 stubGenerator.generateClass(node);
389 catch (FileNotFoundException e) {
390 source.addException(e);
393 },Phases.CONVERSION);
395 return unit;
398 static GroovyClassLoader buildClassLoaderFor(final CompilerConfiguration compilerConfiguration) {
399 return (GroovyClassLoader) AccessController.doPrivileged(new PrivilegedAction() {
400 public Object run() {
401 return new GroovyClassLoader(getClass().getClassLoader(), compilerConfiguration) {
402 public Class loadClass(String name, boolean lookupScriptFiles, boolean preferClassOverScript)
403 throws ClassNotFoundException, CompilationFailedException {
404 try {
405 return super.loadClass(name, lookupScriptFiles, preferClassOverScript);
407 catch (NoClassDefFoundError e) {
408 final String ncdfe = e.getMessage();
410 throw new RuntimeException("Groovyc error: " + ncdfe + " class not found while resolving class " + name + "; try compiling " + ncdfe + " explicitly", e);
412 catch (LinkageError e) {
413 throw new RuntimeException("Problem loading class " + name, e);