694b9df8756eb977fdfa96e7c5b3fd39fc4156da
[idea/community.git] / plugins / groovy / jps-plugin / src / org / jetbrains / jps / incremental / groovy / ForkedGroovyc.java
1 /*
2  * Copyright 2000-2015 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package org.jetbrains.jps.incremental.groovy;
17
18 import com.intellij.execution.process.BaseOSProcessHandler;
19 import com.intellij.execution.process.ProcessHandler;
20 import com.intellij.openapi.util.Key;
21 import com.intellij.util.ArrayUtil;
22 import com.intellij.util.Function;
23 import com.intellij.util.SystemProperties;
24 import com.intellij.util.containers.ContainerUtilRt;
25 import com.intellij.util.lang.UrlClassLoader;
26 import gnu.trove.THashMap;
27 import org.jetbrains.groovy.compiler.rt.GroovyRtConstants;
28 import org.jetbrains.jps.ModuleChunk;
29 import org.jetbrains.jps.cmdline.ClasspathBootstrap;
30 import org.jetbrains.jps.incremental.ExternalProcessUtil;
31 import org.jetbrains.jps.model.java.JpsJavaSdkType;
32 import org.jetbrains.jps.model.library.sdk.JpsSdk;
33 import org.jetbrains.jps.service.SharedThreadPool;
34
35 import java.io.File;
36 import java.util.ArrayList;
37 import java.util.Collection;
38 import java.util.Collections;
39 import java.util.List;
40 import java.util.concurrent.Future;
41
42 /**
43  * @author peter
44  */
45 class ForkedGroovyc implements GroovycFlavor {
46   private final boolean myOptimizeClassLoading;
47   private final ModuleChunk myChunk;
48
49   ForkedGroovyc(boolean optimizeClassLoading, ModuleChunk chunk) {
50     myOptimizeClassLoading = optimizeClassLoading;
51     myChunk = chunk;
52   }
53
54   @Override
55   public GroovycContinuation runGroovyc(Collection<String> compilationClassPath,
56                                         boolean forStubs,
57                                         JpsGroovySettings settings,
58                                         File tempFile,
59                                         final GroovycOutputParser parser)
60     throws Exception {
61     List<String> classpath = new ArrayList<String>();
62     if (myOptimizeClassLoading) {
63       classpath.addAll(GroovyBuilder.getGroovyRtRoots());
64       classpath.add(ClasspathBootstrap.getResourcePath(Function.class));
65       classpath.add(ClasspathBootstrap.getResourcePath(UrlClassLoader.class));
66       classpath.add(ClasspathBootstrap.getResourceFile(THashMap.class).getPath());
67     } else {
68       classpath.addAll(compilationClassPath);
69     }
70
71     List<String> vmParams = ContainerUtilRt.newArrayList();
72     vmParams.add("-Xmx" + System.getProperty("groovyc.heap.size", settings.heapSize) + "m");
73     vmParams.add("-Dfile.encoding=" + System.getProperty("file.encoding"));
74     //vmParams.add("-Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5239");
75     
76     if ("false".equals(System.getProperty(GroovyRtConstants.GROOVYC_ASM_RESOLVING_ONLY))) {
77       vmParams.add("-D" + GroovyRtConstants.GROOVYC_ASM_RESOLVING_ONLY + "=false");
78     }
79     String configScript = System.getProperty(GroovyRtConstants.GROOVYC_CONFIG_SCRIPT);
80     if (configScript != null) {
81       vmParams.add("-D" + GroovyRtConstants.GROOVYC_CONFIG_SCRIPT + "=" + configScript);
82     }
83
84     String grapeRoot = System.getProperty(GroovycOutputParser.GRAPE_ROOT);
85     if (grapeRoot != null) {
86       vmParams.add("-D" + GroovycOutputParser.GRAPE_ROOT + "=" + grapeRoot);
87     }
88
89     final List<String> cmd = ExternalProcessUtil.buildJavaCommandLine(
90       getJavaExecutable(myChunk),
91       "org.jetbrains.groovy.compiler.rt.GroovycRunner",
92       Collections.<String>emptyList(), classpath,
93       vmParams,
94       getProgramParams(tempFile, settings, forStubs)
95     );
96     final Process process = Runtime.getRuntime().exec(ArrayUtil.toStringArray(cmd));
97     ProcessHandler handler = new BaseOSProcessHandler(process, null, null) {
98       @Override
99       protected Future<?> executeOnPooledThread(Runnable task) {
100         return SharedThreadPool.getInstance().executeOnPooledThread(task);
101       }
102
103       @Override
104       public void notifyTextAvailable(String text, Key outputType) {
105         parser.notifyTextAvailable(text, outputType);
106       }
107     };
108
109     handler.startNotify();
110     handler.waitFor();
111     parser.notifyFinished(process.exitValue());
112     return null;
113   }
114
115   private List<String> getProgramParams(File tempFile, JpsGroovySettings settings, boolean forStubs) {
116     List<String> programParams = ContainerUtilRt.newArrayList(myOptimizeClassLoading ? GroovyRtConstants.OPTIMIZE : "do_not_optimize",
117                                                               forStubs ? "stubs" : "groovyc",
118                                                               tempFile.getPath());
119     if (settings.invokeDynamic) {
120       programParams.add("--indy");
121     }
122     return programParams;
123   }
124
125
126   private static String getJavaExecutable(ModuleChunk chunk) {
127     JpsSdk<?> sdk = GroovyBuilder.getJdk(chunk);
128     return sdk != null ? JpsJavaSdkType.getJavaExecutable(sdk) : SystemProperties.getJavaHome() + "/bin/java";
129   }
130
131 }