mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Add Maven option to run TeaVM in a separate process
This commit is contained in:
parent
0f951f8c86
commit
fc799afcda
|
@ -1,14 +1,15 @@
|
||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="IDEA JPS Debug" type="Remote" factoryName="Remote">
|
<configuration default="false" name="IDEA JPS Debug" type="Remote">
|
||||||
<option name="USE_SOCKET_TRANSPORT" value="true" />
|
<option name="USE_SOCKET_TRANSPORT" value="true" />
|
||||||
<option name="SERVER_MODE" value="false" />
|
<option name="SERVER_MODE" value="false" />
|
||||||
<option name="SHMEM_ADDRESS" value="javadebug" />
|
<option name="SHMEM_ADDRESS" />
|
||||||
<option name="HOST" value="localhost" />
|
<option name="HOST" value="localhost" />
|
||||||
<option name="PORT" value="5005" />
|
<option name="PORT" value="5005" />
|
||||||
|
<option name="AUTO_RESTART" value="false" />
|
||||||
<RunnerSettings RunnerId="Debug">
|
<RunnerSettings RunnerId="Debug">
|
||||||
<option name="DEBUG_PORT" value="5005" />
|
<option name="DEBUG_PORT" value="5005" />
|
||||||
<option name="LOCAL" value="false" />
|
<option name="LOCAL" value="false" />
|
||||||
</RunnerSettings>
|
</RunnerSettings>
|
||||||
<method />
|
<method v="2" />
|
||||||
</configuration>
|
</configuration>
|
||||||
</component>
|
</component>
|
|
@ -48,6 +48,7 @@
|
||||||
<groupId>org.teavm</groupId>
|
<groupId>org.teavm</groupId>
|
||||||
<artifactId>teavm-core</artifactId>
|
<artifactId>teavm-core</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.teavm</groupId>
|
<groupId>org.teavm</groupId>
|
||||||
|
@ -77,6 +78,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.ow2.asm</groupId>
|
<groupId>org.ow2.asm</groupId>
|
||||||
<artifactId>asm-util</artifactId>
|
<artifactId>asm-util</artifactId>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.google.code.gson</groupId>
|
<groupId>com.google.code.gson</groupId>
|
||||||
|
|
|
@ -33,6 +33,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs
|
||||||
<groupId>org.teavm</groupId>
|
<groupId>org.teavm</groupId>
|
||||||
<artifactId>teavm-core</artifactId>
|
<artifactId>teavm-core</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.teavm</groupId>
|
<groupId>org.teavm</groupId>
|
||||||
|
|
|
@ -38,6 +38,7 @@
|
||||||
<groupId>org.teavm</groupId>
|
<groupId>org.teavm</groupId>
|
||||||
<artifactId>teavm-core</artifactId>
|
<artifactId>teavm-core</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.teavm</groupId>
|
<groupId>org.teavm</groupId>
|
||||||
|
|
|
@ -34,6 +34,7 @@
|
||||||
<groupId>org.teavm</groupId>
|
<groupId>org.teavm</groupId>
|
||||||
<artifactId>teavm-core</artifactId>
|
<artifactId>teavm-core</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.teavm</groupId>
|
<groupId>org.teavm</groupId>
|
||||||
|
|
|
@ -1,46 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2015 Alexey Andreev.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.teavm.tooling;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Properties;
|
|
||||||
import org.teavm.model.ClassHolderTransformer;
|
|
||||||
import org.teavm.tooling.sources.SourceFileProvider;
|
|
||||||
|
|
||||||
public interface BaseTeaVMTool {
|
|
||||||
void setTargetDirectory(File targetDirectory);
|
|
||||||
|
|
||||||
void setMinifying(boolean minifying);
|
|
||||||
|
|
||||||
void setIncremental(boolean incremental);
|
|
||||||
|
|
||||||
void setDebugInformationGenerated(boolean debugInformationGenerated);
|
|
||||||
|
|
||||||
void setSourceMapsFileGenerated(boolean sourceMapsFileGenerated);
|
|
||||||
|
|
||||||
void setSourceFilesCopied(boolean sourceFilesCopied);
|
|
||||||
|
|
||||||
Properties getProperties();
|
|
||||||
|
|
||||||
List<ClassHolderTransformer> getTransformers();
|
|
||||||
|
|
||||||
void setLog(TeaVMToolLog log);
|
|
||||||
|
|
||||||
void setClassLoader(ClassLoader classLoader);
|
|
||||||
|
|
||||||
void addSourceFileProvider(SourceFileProvider sourceFileProvider);
|
|
||||||
}
|
|
|
@ -21,6 +21,7 @@ import org.teavm.callgraph.CallGraphNode;
|
||||||
import org.teavm.callgraph.CallSite;
|
import org.teavm.callgraph.CallSite;
|
||||||
import org.teavm.diagnostics.DefaultProblemTextConsumer;
|
import org.teavm.diagnostics.DefaultProblemTextConsumer;
|
||||||
import org.teavm.diagnostics.Problem;
|
import org.teavm.diagnostics.Problem;
|
||||||
|
import org.teavm.diagnostics.ProblemProvider;
|
||||||
import org.teavm.model.CallLocation;
|
import org.teavm.model.CallLocation;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
import org.teavm.model.TextLocation;
|
import org.teavm.model.TextLocation;
|
||||||
|
@ -31,9 +32,12 @@ public final class TeaVMProblemRenderer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void describeProblems(TeaVM vm, TeaVMToolLog log) {
|
public static void describeProblems(TeaVM vm, TeaVMToolLog log) {
|
||||||
CallGraph cg = vm.getDependencyInfo().getCallGraph();
|
describeProblems(vm.getDependencyInfo().getCallGraph(), vm.getProblemProvider(), log);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void describeProblems(CallGraph cg, ProblemProvider problems, TeaVMToolLog log) {
|
||||||
DefaultProblemTextConsumer consumer = new DefaultProblemTextConsumer();
|
DefaultProblemTextConsumer consumer = new DefaultProblemTextConsumer();
|
||||||
for (Problem problem : vm.getProblemProvider().getProblems()) {
|
for (Problem problem : problems.getProblems()) {
|
||||||
consumer.clear();
|
consumer.clear();
|
||||||
problem.render(consumer);
|
problem.render(consumer);
|
||||||
StringBuilder sb = new StringBuilder();
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
|
@ -22,6 +22,8 @@ import java.io.IOException;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
import java.lang.reflect.Constructor;
|
||||||
|
import java.lang.reflect.InvocationTargetException;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -61,7 +63,7 @@ import org.teavm.vm.TeaVMOptimizationLevel;
|
||||||
import org.teavm.vm.TeaVMProgressListener;
|
import org.teavm.vm.TeaVMProgressListener;
|
||||||
import org.teavm.vm.TeaVMTarget;
|
import org.teavm.vm.TeaVMTarget;
|
||||||
|
|
||||||
public class TeaVMTool implements BaseTeaVMTool {
|
public class TeaVMTool {
|
||||||
private File targetDirectory = new File(".");
|
private File targetDirectory = new File(".");
|
||||||
private TeaVMTargetType targetType = TeaVMTargetType.JAVASCRIPT;
|
private TeaVMTargetType targetType = TeaVMTargetType.JAVASCRIPT;
|
||||||
private String targetFileName = "";
|
private String targetFileName = "";
|
||||||
|
@ -73,7 +75,7 @@ public class TeaVMTool implements BaseTeaVMTool {
|
||||||
private boolean sourceFilesCopied;
|
private boolean sourceFilesCopied;
|
||||||
private boolean incremental;
|
private boolean incremental;
|
||||||
private File cacheDirectory = new File("./teavm-cache");
|
private File cacheDirectory = new File("./teavm-cache");
|
||||||
private List<ClassHolderTransformer> transformers = new ArrayList<>();
|
private List<String> transformers = new ArrayList<>();
|
||||||
private List<String> classesToPreserve = new ArrayList<>();
|
private List<String> classesToPreserve = new ArrayList<>();
|
||||||
private TeaVMToolLog log = new EmptyTeaVMToolLog();
|
private TeaVMToolLog log = new EmptyTeaVMToolLog();
|
||||||
private ClassLoader classLoader = TeaVMTool.class.getClassLoader();
|
private ClassLoader classLoader = TeaVMTool.class.getClassLoader();
|
||||||
|
@ -99,7 +101,6 @@ public class TeaVMTool implements BaseTeaVMTool {
|
||||||
return targetDirectory;
|
return targetDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setTargetDirectory(File targetDirectory) {
|
public void setTargetDirectory(File targetDirectory) {
|
||||||
this.targetDirectory = targetDirectory;
|
this.targetDirectory = targetDirectory;
|
||||||
}
|
}
|
||||||
|
@ -116,7 +117,6 @@ public class TeaVMTool implements BaseTeaVMTool {
|
||||||
return minifying;
|
return minifying;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setMinifying(boolean minifying) {
|
public void setMinifying(boolean minifying) {
|
||||||
this.minifying = minifying;
|
this.minifying = minifying;
|
||||||
}
|
}
|
||||||
|
@ -125,7 +125,6 @@ public class TeaVMTool implements BaseTeaVMTool {
|
||||||
return incremental;
|
return incremental;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setIncremental(boolean incremental) {
|
public void setIncremental(boolean incremental) {
|
||||||
this.incremental = incremental;
|
this.incremental = incremental;
|
||||||
}
|
}
|
||||||
|
@ -142,7 +141,6 @@ public class TeaVMTool implements BaseTeaVMTool {
|
||||||
return debugInformationGenerated;
|
return debugInformationGenerated;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setDebugInformationGenerated(boolean debugInformationGenerated) {
|
public void setDebugInformationGenerated(boolean debugInformationGenerated) {
|
||||||
this.debugInformationGenerated = debugInformationGenerated;
|
this.debugInformationGenerated = debugInformationGenerated;
|
||||||
}
|
}
|
||||||
|
@ -159,7 +157,6 @@ public class TeaVMTool implements BaseTeaVMTool {
|
||||||
return sourceMapsFileGenerated;
|
return sourceMapsFileGenerated;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSourceMapsFileGenerated(boolean sourceMapsFileGenerated) {
|
public void setSourceMapsFileGenerated(boolean sourceMapsFileGenerated) {
|
||||||
this.sourceMapsFileGenerated = sourceMapsFileGenerated;
|
this.sourceMapsFileGenerated = sourceMapsFileGenerated;
|
||||||
}
|
}
|
||||||
|
@ -168,18 +165,15 @@ public class TeaVMTool implements BaseTeaVMTool {
|
||||||
return sourceFilesCopied;
|
return sourceFilesCopied;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSourceFilesCopied(boolean sourceFilesCopied) {
|
public void setSourceFilesCopied(boolean sourceFilesCopied) {
|
||||||
this.sourceFilesCopied = sourceFilesCopied;
|
this.sourceFilesCopied = sourceFilesCopied;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public Properties getProperties() {
|
public Properties getProperties() {
|
||||||
return properties;
|
return properties;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
public List<String> getTransformers() {
|
||||||
public List<ClassHolderTransformer> getTransformers() {
|
|
||||||
return transformers;
|
return transformers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,7 +185,6 @@ public class TeaVMTool implements BaseTeaVMTool {
|
||||||
return log;
|
return log;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setLog(TeaVMToolLog log) {
|
public void setLog(TeaVMToolLog log) {
|
||||||
this.log = log;
|
this.log = log;
|
||||||
}
|
}
|
||||||
|
@ -220,7 +213,6 @@ public class TeaVMTool implements BaseTeaVMTool {
|
||||||
return classLoader;
|
return classLoader;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setClassLoader(ClassLoader classLoader) {
|
public void setClassLoader(ClassLoader classLoader) {
|
||||||
this.classLoader = classLoader;
|
this.classLoader = classLoader;
|
||||||
}
|
}
|
||||||
|
@ -289,7 +281,6 @@ public class TeaVMTool implements BaseTeaVMTool {
|
||||||
return resources;
|
return resources;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void addSourceFileProvider(SourceFileProvider sourceFileProvider) {
|
public void addSourceFileProvider(SourceFileProvider sourceFileProvider) {
|
||||||
sourceFileProviders.add(sourceFileProvider);
|
sourceFileProviders.add(sourceFileProvider);
|
||||||
}
|
}
|
||||||
|
@ -377,7 +368,7 @@ public class TeaVMTool implements BaseTeaVMTool {
|
||||||
vm.setOptimizationLevel(optimizationLevel);
|
vm.setOptimizationLevel(optimizationLevel);
|
||||||
|
|
||||||
vm.installPlugins();
|
vm.installPlugins();
|
||||||
for (ClassHolderTransformer transformer : transformers) {
|
for (ClassHolderTransformer transformer : resolveTransformers(classLoader)) {
|
||||||
vm.add(transformer);
|
vm.add(transformer);
|
||||||
}
|
}
|
||||||
if (mainClass != null) {
|
if (mainClass != null) {
|
||||||
|
@ -402,10 +393,8 @@ public class TeaVMTool implements BaseTeaVMTool {
|
||||||
log.info("Output file successfully built");
|
log.info("Output file successfully built");
|
||||||
} else if (problemProvider.getSevereProblems().isEmpty()) {
|
} else if (problemProvider.getSevereProblems().isEmpty()) {
|
||||||
log.info("Output file built with warnings");
|
log.info("Output file built with warnings");
|
||||||
TeaVMProblemRenderer.describeProblems(vm, log);
|
|
||||||
} else {
|
} else {
|
||||||
log.info("Output file built with errors");
|
log.info("Output file built with errors");
|
||||||
TeaVMProblemRenderer.describeProblems(vm, log);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
File outputFile = new File(targetDirectory, outputName);
|
File outputFile = new File(targetDirectory, outputName);
|
||||||
|
@ -507,4 +496,41 @@ public class TeaVMTool implements BaseTeaVMTool {
|
||||||
copier.setLog(log);
|
copier.setLog(log);
|
||||||
copier.copy(new File(targetDirectory, "src"));
|
copier.copy(new File(targetDirectory, "src"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private List<ClassHolderTransformer> resolveTransformers(ClassLoader classLoader) {
|
||||||
|
List<ClassHolderTransformer> transformerInstances = new ArrayList<>();
|
||||||
|
if (transformers == null) {
|
||||||
|
return transformerInstances;
|
||||||
|
}
|
||||||
|
for (String transformerName : transformers) {
|
||||||
|
Class<?> transformerRawType;
|
||||||
|
try {
|
||||||
|
transformerRawType = Class.forName(transformerName, true, classLoader);
|
||||||
|
} catch (ClassNotFoundException e) {
|
||||||
|
log.error("Transformer not found: " + transformerName, e);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (!ClassHolderTransformer.class.isAssignableFrom(transformerRawType)) {
|
||||||
|
log.error("Transformer " + transformerName + " is not subtype of "
|
||||||
|
+ ClassHolderTransformer.class.getName());
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
Class<? extends ClassHolderTransformer> transformerType = transformerRawType.asSubclass(
|
||||||
|
ClassHolderTransformer.class);
|
||||||
|
Constructor<? extends ClassHolderTransformer> ctor;
|
||||||
|
try {
|
||||||
|
ctor = transformerType.getConstructor();
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
log.error("Transformer " + transformerName + " has no default constructor");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
ClassHolderTransformer transformer = ctor.newInstance();
|
||||||
|
transformerInstances.add(transformer);
|
||||||
|
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
||||||
|
log.error("Error instantiating transformer " + transformerName, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return transformerInstances;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.tooling.builder;
|
||||||
|
|
||||||
|
public class BuildException extends Exception {
|
||||||
|
public BuildException(Throwable cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2017 Alexey Andreev.
|
* Copyright 2018 Alexey Andreev.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -13,19 +13,15 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.idea.jps.model;
|
package org.teavm.tooling.builder;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import org.teavm.callgraph.CallGraph;
|
import org.teavm.callgraph.CallGraph;
|
||||||
import org.teavm.diagnostics.ProblemProvider;
|
import org.teavm.diagnostics.ProblemProvider;
|
||||||
|
|
||||||
public interface TeaVMBuildResult {
|
public interface BuildResult {
|
||||||
CallGraph getCallGraph();
|
CallGraph getCallGraph();
|
||||||
|
|
||||||
boolean isErrorOccurred();
|
|
||||||
|
|
||||||
String getStackTrace();
|
|
||||||
|
|
||||||
ProblemProvider getProblems();
|
ProblemProvider getProblems();
|
||||||
|
|
||||||
Collection<String> getUsedResources();
|
Collection<String> getUsedResources();
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2017 Alexey Andreev.
|
* Copyright 2018 Alexey Andreev.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -13,16 +13,21 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.idea.jps.model;
|
package org.teavm.tooling.builder;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import org.teavm.backend.wasm.render.WasmBinaryVersion;
|
||||||
import org.teavm.tooling.TeaVMTargetType;
|
import org.teavm.tooling.TeaVMTargetType;
|
||||||
|
import org.teavm.tooling.TeaVMToolLog;
|
||||||
|
import org.teavm.vm.TeaVMOptimizationLevel;
|
||||||
import org.teavm.vm.TeaVMProgressListener;
|
import org.teavm.vm.TeaVMProgressListener;
|
||||||
|
|
||||||
public interface TeaVMBuildStrategy {
|
public interface BuildStrategy {
|
||||||
void init();
|
void init();
|
||||||
|
|
||||||
|
void setLog(TeaVMToolLog log);
|
||||||
|
|
||||||
void addSourcesDirectory(String directory);
|
void addSourcesDirectory(String directory);
|
||||||
|
|
||||||
void addSourcesJar(String jarFile);
|
void addSourcesJar(String jarFile);
|
||||||
|
@ -45,7 +50,21 @@ public interface TeaVMBuildStrategy {
|
||||||
|
|
||||||
void setIncremental(boolean incremental);
|
void setIncremental(boolean incremental);
|
||||||
|
|
||||||
|
void setMinifying(boolean minifying);
|
||||||
|
|
||||||
void setProperties(Properties properties);
|
void setProperties(Properties properties);
|
||||||
|
|
||||||
TeaVMBuildResult build();
|
void setTransformers(String[] transformers);
|
||||||
|
|
||||||
|
void setOptimizationLevel(TeaVMOptimizationLevel level);
|
||||||
|
|
||||||
|
void setTargetFileName(String targetFileName);
|
||||||
|
|
||||||
|
void setClassesToPreserve(String[] classesToPreserve);
|
||||||
|
|
||||||
|
void setCacheDirectory(String cacheDirectory);
|
||||||
|
|
||||||
|
void setWasmVersion(WasmBinaryVersion wasmVersion);
|
||||||
|
|
||||||
|
BuildResult build() throws BuildException;
|
||||||
}
|
}
|
|
@ -0,0 +1,22 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.tooling.builder;
|
||||||
|
|
||||||
|
import java.net.URL;
|
||||||
|
|
||||||
|
public interface ClassLoaderFactory {
|
||||||
|
ClassLoader create(URL[] urls, ClassLoader innerClassLoader);
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2017 Alexey Andreev.
|
* Copyright 2018 Alexey Andreev.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -13,48 +13,56 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.idea.jps;
|
package org.teavm.tooling.builder;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.net.MalformedURLException;
|
import java.net.MalformedURLException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import org.jetbrains.jps.incremental.CompileContext;
|
import org.teavm.backend.wasm.render.WasmBinaryVersion;
|
||||||
import org.jetbrains.jps.incremental.messages.CompilerMessage;
|
|
||||||
import org.teavm.callgraph.CallGraph;
|
import org.teavm.callgraph.CallGraph;
|
||||||
import org.teavm.diagnostics.ProblemProvider;
|
import org.teavm.diagnostics.ProblemProvider;
|
||||||
import org.teavm.idea.jps.model.TeaVMBuildResult;
|
|
||||||
import org.teavm.idea.jps.model.TeaVMBuildStrategy;
|
|
||||||
import org.teavm.idea.jps.util.ExceptionUtil;
|
|
||||||
import org.teavm.tooling.EmptyTeaVMToolLog;
|
import org.teavm.tooling.EmptyTeaVMToolLog;
|
||||||
import org.teavm.tooling.TeaVMTargetType;
|
import org.teavm.tooling.TeaVMTargetType;
|
||||||
import org.teavm.tooling.TeaVMTool;
|
import org.teavm.tooling.TeaVMTool;
|
||||||
import org.teavm.tooling.TeaVMToolException;
|
import org.teavm.tooling.TeaVMToolException;
|
||||||
|
import org.teavm.tooling.TeaVMToolLog;
|
||||||
import org.teavm.tooling.sources.DirectorySourceFileProvider;
|
import org.teavm.tooling.sources.DirectorySourceFileProvider;
|
||||||
import org.teavm.tooling.sources.JarSourceFileProvider;
|
import org.teavm.tooling.sources.JarSourceFileProvider;
|
||||||
import org.teavm.tooling.sources.SourceFileProvider;
|
import org.teavm.tooling.sources.SourceFileProvider;
|
||||||
|
import org.teavm.vm.TeaVMOptimizationLevel;
|
||||||
import org.teavm.vm.TeaVMProgressListener;
|
import org.teavm.vm.TeaVMProgressListener;
|
||||||
|
|
||||||
public class InProcessBuildStrategy implements TeaVMBuildStrategy {
|
public class InProcessBuildStrategy implements BuildStrategy {
|
||||||
private final CompileContext context;
|
private final ClassLoaderFactory classLoaderFactory;
|
||||||
private List<String> classPathEntries = new ArrayList<>();
|
private List<String> classPathEntries = new ArrayList<>();
|
||||||
private TeaVMTargetType targetType;
|
private TeaVMTargetType targetType;
|
||||||
private String mainClass;
|
private String mainClass;
|
||||||
private String targetDirectory;
|
private String targetDirectory;
|
||||||
|
private String targetFileName = "";
|
||||||
|
private boolean incremental;
|
||||||
|
private String cacheDirectory;
|
||||||
|
private TeaVMOptimizationLevel optimizationLevel = TeaVMOptimizationLevel.ADVANCED;
|
||||||
|
private boolean minifying;
|
||||||
private boolean sourceMapsFileGenerated;
|
private boolean sourceMapsFileGenerated;
|
||||||
private boolean debugInformationGenerated;
|
private boolean debugInformationGenerated;
|
||||||
private boolean sourceFilesCopied;
|
private boolean sourceFilesCopied;
|
||||||
|
private String[] transformers = new String[0];
|
||||||
|
private String[] classesToPreserve = new String[0];
|
||||||
|
private WasmBinaryVersion wasmVersion = WasmBinaryVersion.V_0x1;
|
||||||
private final List<SourceFileProvider> sourceFileProviders = new ArrayList<>();
|
private final List<SourceFileProvider> sourceFileProviders = new ArrayList<>();
|
||||||
private TeaVMProgressListener progressListener;
|
private TeaVMProgressListener progressListener;
|
||||||
private Properties properties = new Properties();
|
private Properties properties = new Properties();
|
||||||
|
private TeaVMToolLog log = new EmptyTeaVMToolLog();
|
||||||
|
|
||||||
public InProcessBuildStrategy(CompileContext context) {
|
public InProcessBuildStrategy(ClassLoaderFactory classLoaderFactory) {
|
||||||
this.context = context;
|
this.classLoaderFactory = classLoaderFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -115,6 +123,7 @@ public class InProcessBuildStrategy implements TeaVMBuildStrategy {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setIncremental(boolean incremental) {
|
public void setIncremental(boolean incremental) {
|
||||||
|
this.incremental = incremental;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -124,20 +133,67 @@ public class InProcessBuildStrategy implements TeaVMBuildStrategy {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TeaVMBuildResult build() {
|
public void setLog(TeaVMToolLog log) {
|
||||||
|
this.log = log;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMinifying(boolean minifying) {
|
||||||
|
this.minifying = minifying;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTransformers(String[] transformers) {
|
||||||
|
this.transformers = transformers.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOptimizationLevel(TeaVMOptimizationLevel level) {
|
||||||
|
this.optimizationLevel = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTargetFileName(String targetFileName) {
|
||||||
|
this.targetFileName = targetFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setClassesToPreserve(String[] classesToPreserve) {
|
||||||
|
this.classesToPreserve = classesToPreserve.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCacheDirectory(String cacheDirectory) {
|
||||||
|
this.cacheDirectory = cacheDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setWasmVersion(WasmBinaryVersion wasmVersion) {
|
||||||
|
this.wasmVersion = wasmVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BuildResult build() throws BuildException {
|
||||||
TeaVMTool tool = new TeaVMTool();
|
TeaVMTool tool = new TeaVMTool();
|
||||||
tool.setProgressListener(progressListener);
|
tool.setProgressListener(progressListener);
|
||||||
tool.setLog(new EmptyTeaVMToolLog());
|
tool.setLog(log);
|
||||||
tool.setTargetType(targetType);
|
tool.setTargetType(targetType);
|
||||||
tool.setMainClass(mainClass);
|
tool.setMainClass(mainClass);
|
||||||
tool.setTargetDirectory(new File(targetDirectory));
|
tool.setTargetDirectory(new File(targetDirectory));
|
||||||
|
tool.setTargetFileName(targetFileName);
|
||||||
tool.setClassLoader(buildClassLoader());
|
tool.setClassLoader(buildClassLoader());
|
||||||
|
tool.setOptimizationLevel(optimizationLevel);
|
||||||
|
|
||||||
tool.setSourceMapsFileGenerated(sourceMapsFileGenerated);
|
tool.setSourceMapsFileGenerated(sourceMapsFileGenerated);
|
||||||
tool.setDebugInformationGenerated(debugInformationGenerated);
|
tool.setDebugInformationGenerated(debugInformationGenerated);
|
||||||
tool.setSourceFilesCopied(sourceFilesCopied);
|
tool.setSourceFilesCopied(sourceFilesCopied);
|
||||||
|
|
||||||
tool.setMinifying(false);
|
tool.setMinifying(minifying);
|
||||||
|
tool.setIncremental(incremental);
|
||||||
|
tool.getTransformers().addAll(Arrays.asList(transformers));
|
||||||
|
tool.getClassesToPreserve().addAll(Arrays.asList(classesToPreserve));
|
||||||
|
tool.setCacheDirectory(cacheDirectory != null ? new File(cacheDirectory) : null);
|
||||||
|
tool.setWasmVersion(wasmVersion);
|
||||||
|
|
||||||
tool.getProperties().putAll(properties);
|
tool.getProperties().putAll(properties);
|
||||||
|
|
||||||
|
@ -145,22 +201,17 @@ public class InProcessBuildStrategy implements TeaVMBuildStrategy {
|
||||||
tool.addSourceFileProvider(fileProvider);
|
tool.addSourceFileProvider(fileProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean errorOccurred = false;
|
|
||||||
String stackTrace = null;
|
|
||||||
try {
|
try {
|
||||||
tool.generate();
|
tool.generate();
|
||||||
} catch (TeaVMToolException | RuntimeException | Error e) {
|
} catch (TeaVMToolException | RuntimeException | Error e) {
|
||||||
e.printStackTrace(System.err);
|
throw new BuildException(e);
|
||||||
stackTrace = ExceptionUtil.exceptionToString(e);
|
|
||||||
context.processMessage(new CompilerMessage("TeaVM", e));
|
|
||||||
errorOccurred = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Set<String> generatedFiles = tool.getGeneratedFiles().stream()
|
Set<String> generatedFiles = tool.getGeneratedFiles().stream()
|
||||||
.map(File::getAbsolutePath)
|
.map(File::getAbsolutePath)
|
||||||
.collect(Collectors.toSet());
|
.collect(Collectors.toSet());
|
||||||
|
|
||||||
return new InProcessBuildResult(tool.getDependencyInfo().getCallGraph(), errorOccurred, stackTrace,
|
return new InProcessBuildResult(tool.getDependencyInfo().getCallGraph(),
|
||||||
tool.getProblemProvider(), tool.getClasses(), tool.getUsedResources(), generatedFiles);
|
tool.getProblemProvider(), tool.getClasses(), tool.getUsedResources(), generatedFiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,26 +224,19 @@ public class InProcessBuildStrategy implements TeaVMBuildStrategy {
|
||||||
}
|
}
|
||||||
}).toArray(URL[]::new);
|
}).toArray(URL[]::new);
|
||||||
|
|
||||||
RenamingClassLoader classLoader = new RenamingClassLoader(urls, TeaVMBuilder.class.getClassLoader());
|
return classLoaderFactory.create(urls, InProcessBuildStrategy.class.getClassLoader());
|
||||||
classLoader.rename("org/objectweb/asm/", "org/teavm/asm/");
|
|
||||||
return classLoader;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static class InProcessBuildResult implements TeaVMBuildResult {
|
static class InProcessBuildResult implements BuildResult {
|
||||||
private CallGraph callGraph;
|
private CallGraph callGraph;
|
||||||
private boolean errorOccurred;
|
|
||||||
private String stackTrace;
|
|
||||||
private ProblemProvider problemProvider;
|
private ProblemProvider problemProvider;
|
||||||
private Collection<String> classes;
|
private Collection<String> classes;
|
||||||
private Collection<String> usedResources;
|
private Collection<String> usedResources;
|
||||||
private Collection<String> generatedFiles;
|
private Collection<String> generatedFiles;
|
||||||
|
|
||||||
InProcessBuildResult(CallGraph callGraph, boolean errorOccurred, String stackTrace,
|
InProcessBuildResult(CallGraph callGraph, ProblemProvider problemProvider,
|
||||||
ProblemProvider problemProvider, Collection<String> classes, Collection<String> usedResources,
|
Collection<String> classes, Collection<String> usedResources, Collection<String> generatedFiles) {
|
||||||
Collection<String> generatedFiles) {
|
|
||||||
this.callGraph = callGraph;
|
this.callGraph = callGraph;
|
||||||
this.errorOccurred = errorOccurred;
|
|
||||||
this.stackTrace = stackTrace;
|
|
||||||
this.problemProvider = problemProvider;
|
this.problemProvider = problemProvider;
|
||||||
this.classes = classes;
|
this.classes = classes;
|
||||||
this.usedResources = usedResources;
|
this.usedResources = usedResources;
|
||||||
|
@ -204,16 +248,6 @@ public class InProcessBuildStrategy implements TeaVMBuildStrategy {
|
||||||
return callGraph;
|
return callGraph;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isErrorOccurred() {
|
|
||||||
return errorOccurred;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getStackTrace() {
|
|
||||||
return stackTrace;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ProblemProvider getProblems() {
|
public ProblemProvider getProblems() {
|
||||||
return problemProvider;
|
return problemProvider;
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2017 Alexey Andreev.
|
* Copyright 2018 Alexey Andreev.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -13,39 +13,44 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.idea.jps;
|
package org.teavm.tooling.builder;
|
||||||
|
|
||||||
import java.rmi.RemoteException;
|
import java.rmi.RemoteException;
|
||||||
import java.rmi.server.UnicastRemoteObject;
|
import java.rmi.server.UnicastRemoteObject;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import org.teavm.backend.wasm.render.WasmBinaryVersion;
|
||||||
import org.teavm.callgraph.CallGraph;
|
import org.teavm.callgraph.CallGraph;
|
||||||
import org.teavm.diagnostics.Problem;
|
import org.teavm.diagnostics.Problem;
|
||||||
import org.teavm.diagnostics.ProblemProvider;
|
import org.teavm.diagnostics.ProblemProvider;
|
||||||
import org.teavm.idea.jps.model.TeaVMBuildResult;
|
import org.teavm.tooling.EmptyTeaVMToolLog;
|
||||||
import org.teavm.idea.jps.model.TeaVMBuildStrategy;
|
|
||||||
import org.teavm.idea.jps.remote.TeaVMRemoteBuildCallback;
|
|
||||||
import org.teavm.idea.jps.remote.TeaVMRemoteBuildRequest;
|
|
||||||
import org.teavm.idea.jps.remote.TeaVMRemoteBuildResponse;
|
|
||||||
import org.teavm.idea.jps.remote.TeaVMRemoteBuildService;
|
|
||||||
import org.teavm.tooling.TeaVMTargetType;
|
import org.teavm.tooling.TeaVMTargetType;
|
||||||
|
import org.teavm.tooling.TeaVMToolLog;
|
||||||
|
import org.teavm.tooling.daemon.RemoteBuildCallback;
|
||||||
|
import org.teavm.tooling.daemon.RemoteBuildRequest;
|
||||||
|
import org.teavm.tooling.daemon.RemoteBuildResponse;
|
||||||
|
import org.teavm.tooling.daemon.RemoteBuildService;
|
||||||
|
import org.teavm.vm.TeaVMOptimizationLevel;
|
||||||
import org.teavm.vm.TeaVMPhase;
|
import org.teavm.vm.TeaVMPhase;
|
||||||
import org.teavm.vm.TeaVMProgressFeedback;
|
import org.teavm.vm.TeaVMProgressFeedback;
|
||||||
import org.teavm.vm.TeaVMProgressListener;
|
import org.teavm.vm.TeaVMProgressListener;
|
||||||
|
|
||||||
public class RemoteBuildStrategy implements TeaVMBuildStrategy {
|
public class RemoteBuildStrategy implements BuildStrategy {
|
||||||
private TeaVMRemoteBuildRequest request;
|
private RemoteBuildRequest request;
|
||||||
private TeaVMRemoteBuildService buildService;
|
private RemoteBuildService buildService;
|
||||||
private TeaVMProgressListener progressListener;
|
private TeaVMProgressListener progressListener;
|
||||||
|
private TeaVMToolLog log = new EmptyTeaVMToolLog();
|
||||||
|
|
||||||
public RemoteBuildStrategy(TeaVMRemoteBuildService buildService) {
|
public RemoteBuildStrategy(RemoteBuildService buildService) {
|
||||||
this.buildService = buildService;
|
this.buildService = buildService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init() {
|
public void init() {
|
||||||
request = new TeaVMRemoteBuildRequest();
|
request = new RemoteBuildRequest();
|
||||||
|
request.optimizationLevel = TeaVMOptimizationLevel.ADVANCED;
|
||||||
|
request.wasmVersion = WasmBinaryVersion.V_0x1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -110,14 +115,57 @@ public class RemoteBuildStrategy implements TeaVMBuildStrategy {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TeaVMBuildResult build() {
|
public void setLog(TeaVMToolLog log) {
|
||||||
TeaVMRemoteBuildResponse response;
|
this.log = log;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setMinifying(boolean minifying) {
|
||||||
|
request.minifying = minifying;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTransformers(String[] transformers) {
|
||||||
|
request.transformers = transformers.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setOptimizationLevel(TeaVMOptimizationLevel level) {
|
||||||
|
request.optimizationLevel = level;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setTargetFileName(String targetFileName) {
|
||||||
|
request.tagetFileName = targetFileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setClassesToPreserve(String[] classesToPreserve) {
|
||||||
|
request.classesToPreserve = classesToPreserve.clone();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setCacheDirectory(String cacheDirectory) {
|
||||||
|
request.cacheDirectory = cacheDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setWasmVersion(WasmBinaryVersion wasmVersion) {
|
||||||
|
request.wasmVersion = wasmVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public BuildResult build() throws BuildException {
|
||||||
|
RemoteBuildResponse response;
|
||||||
try {
|
try {
|
||||||
response = buildService.build(request, new CallbackImpl(progressListener));
|
response = buildService.build(request, new CallbackImpl(progressListener, log));
|
||||||
} catch (Throwable e) {
|
} catch (Throwable e) {
|
||||||
throw new RuntimeException(e);
|
throw new BuildException(e);
|
||||||
}
|
}
|
||||||
return new TeaVMBuildResult() {
|
if (response.exception != null) {
|
||||||
|
throw new BuildException(response.exception);
|
||||||
|
}
|
||||||
|
return new BuildResult() {
|
||||||
private ProblemProvider problems = new ProblemProvider() {
|
private ProblemProvider problems = new ProblemProvider() {
|
||||||
@Override
|
@Override
|
||||||
public List<Problem> getProblems() {
|
public List<Problem> getProblems() {
|
||||||
|
@ -135,16 +183,6 @@ public class RemoteBuildStrategy implements TeaVMBuildStrategy {
|
||||||
return response.callGraph;
|
return response.callGraph;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean isErrorOccurred() {
|
|
||||||
return response.errorOccurred;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getStackTrace() {
|
|
||||||
return response.stackTrace;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ProblemProvider getProblems() {
|
public ProblemProvider getProblems() {
|
||||||
return problems;
|
return problems;
|
||||||
|
@ -167,22 +205,54 @@ public class RemoteBuildStrategy implements TeaVMBuildStrategy {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
static class CallbackImpl extends UnicastRemoteObject implements TeaVMRemoteBuildCallback {
|
static class CallbackImpl extends UnicastRemoteObject implements RemoteBuildCallback {
|
||||||
private TeaVMProgressListener listener;
|
private TeaVMProgressListener listener;
|
||||||
|
private TeaVMToolLog log;
|
||||||
|
|
||||||
public CallbackImpl(TeaVMProgressListener listener) throws RemoteException {
|
public CallbackImpl(TeaVMProgressListener listener, TeaVMToolLog log) throws RemoteException {
|
||||||
super();
|
super();
|
||||||
this.listener = listener;
|
this.listener = listener;
|
||||||
|
this.log = log;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TeaVMProgressFeedback phaseStarted(TeaVMPhase phase, int count) throws RemoteException {
|
public TeaVMProgressFeedback phaseStarted(TeaVMPhase phase, int count) {
|
||||||
return listener.phaseStarted(phase, count);
|
return listener != null ? listener.phaseStarted(phase, count) : TeaVMProgressFeedback.CONTINUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TeaVMProgressFeedback progressReached(int progress) throws RemoteException {
|
public TeaVMProgressFeedback progressReached(int progress) {
|
||||||
return listener.progressReached(progress);
|
return listener != null ? listener.progressReached(progress) : TeaVMProgressFeedback.CONTINUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void errorReported(String message, Throwable e) {
|
||||||
|
log.error(message, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void errorReported(String message) {
|
||||||
|
log.error(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void warningReported(String message, Throwable e) {
|
||||||
|
log.warning(message, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void warningReported(String message) {
|
||||||
|
log.warning(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void infoReported(String message, Throwable e) {
|
||||||
|
log.info(message, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void infoReported(String message) {
|
||||||
|
log.info(message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2017 Alexey Andreev.
|
* Copyright 2018 Alexey Andreev.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -13,11 +13,8 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.idea.daemon;
|
package org.teavm.tooling.daemon;
|
||||||
|
|
||||||
import com.intellij.ide.plugins.IdeaPluginDescriptor;
|
|
||||||
import com.intellij.ide.plugins.PluginManager;
|
|
||||||
import com.intellij.openapi.extensions.PluginId;
|
|
||||||
import java.io.BufferedReader;
|
import java.io.BufferedReader;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
@ -34,22 +31,12 @@ import java.rmi.registry.Registry;
|
||||||
import java.rmi.server.UnicastRemoteObject;
|
import java.rmi.server.UnicastRemoteObject;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.function.Function;
|
import java.util.function.Function;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
import org.apache.commons.io.FileUtils;
|
import org.apache.commons.io.FileUtils;
|
||||||
import org.apache.commons.io.IOUtils;
|
import org.apache.commons.io.IOUtils;
|
||||||
import org.apache.commons.logging.Log;
|
|
||||||
import org.apache.commons.logging.LogFactory;
|
|
||||||
import org.teavm.idea.jps.remote.TeaVMRemoteBuildCallback;
|
|
||||||
import org.teavm.idea.jps.remote.TeaVMRemoteBuildRequest;
|
|
||||||
import org.teavm.idea.jps.remote.TeaVMRemoteBuildResponse;
|
|
||||||
import org.teavm.idea.jps.remote.TeaVMRemoteBuildService;
|
|
||||||
import org.teavm.idea.jps.util.ExceptionUtil;
|
|
||||||
import org.teavm.tooling.EmptyTeaVMToolLog;
|
|
||||||
import org.teavm.tooling.TeaVMTool;
|
import org.teavm.tooling.TeaVMTool;
|
||||||
import org.teavm.tooling.TeaVMToolException;
|
import org.teavm.tooling.TeaVMToolException;
|
||||||
import org.teavm.tooling.sources.DirectorySourceFileProvider;
|
import org.teavm.tooling.sources.DirectorySourceFileProvider;
|
||||||
|
@ -58,15 +45,12 @@ import org.teavm.vm.TeaVMPhase;
|
||||||
import org.teavm.vm.TeaVMProgressFeedback;
|
import org.teavm.vm.TeaVMProgressFeedback;
|
||||||
import org.teavm.vm.TeaVMProgressListener;
|
import org.teavm.vm.TeaVMProgressListener;
|
||||||
|
|
||||||
public class TeaVMBuildDaemon extends UnicastRemoteObject implements TeaVMRemoteBuildService {
|
public class BuildDaemon extends UnicastRemoteObject implements RemoteBuildService {
|
||||||
private static final int MIN_PORT = 10000;
|
private static final int MIN_PORT = 10000;
|
||||||
private static final int MAX_PORT = 1 << 16;
|
private static final int MAX_PORT = 1 << 16;
|
||||||
private static final Set<String> KOTLIN_FILES = new HashSet<>(Arrays.asList("teavm-jps-common.jar",
|
|
||||||
"teavm-plugin.jar", "teavm.jar"));
|
|
||||||
private static final String DAEMON_CLASS = TeaVMBuildDaemon.class.getName().replace('.', '/') + ".class";
|
|
||||||
private static final int DAEMON_CLASS_DEPTH;
|
|
||||||
private static final String DAEMON_MESSAGE_PREFIX = "TeaVM daemon port: ";
|
private static final String DAEMON_MESSAGE_PREFIX = "TeaVM daemon port: ";
|
||||||
private static final String INCREMENTAL_PROPERTY = "teavm.daemon.incremental";
|
private static final String INCREMENTAL_PROPERTY = "teavm.daemon.incremental";
|
||||||
|
private static final String DEBUG_PORT_PROPERTY = "teavm.daemon.debug.port";
|
||||||
private boolean incremental;
|
private boolean incremental;
|
||||||
private int port;
|
private int port;
|
||||||
private Registry registry;
|
private Registry registry;
|
||||||
|
@ -74,17 +58,7 @@ public class TeaVMBuildDaemon extends UnicastRemoteObject implements TeaVMRemote
|
||||||
private ClassLoader lastJarClassLoader;
|
private ClassLoader lastJarClassLoader;
|
||||||
private List<String> lastJarClassPath;
|
private List<String> lastJarClassPath;
|
||||||
|
|
||||||
static {
|
BuildDaemon(boolean incremental) throws RemoteException {
|
||||||
int depth = 0;
|
|
||||||
for (int i = 0; i < DAEMON_CLASS.length(); ++i) {
|
|
||||||
if (DAEMON_CLASS.charAt(i) == '/') {
|
|
||||||
depth++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DAEMON_CLASS_DEPTH = depth;
|
|
||||||
}
|
|
||||||
|
|
||||||
TeaVMBuildDaemon(boolean incremental) throws RemoteException {
|
|
||||||
super();
|
super();
|
||||||
this.incremental = incremental;
|
this.incremental = incremental;
|
||||||
Random random = new Random();
|
Random random = new Random();
|
||||||
|
@ -96,7 +70,7 @@ public class TeaVMBuildDaemon extends UnicastRemoteObject implements TeaVMRemote
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
registry.bind(TeaVMRemoteBuildService.ID, this);
|
registry.bind(RemoteBuildService.ID, this);
|
||||||
} catch (RemoteException | AlreadyBoundException e) {
|
} catch (RemoteException | AlreadyBoundException e) {
|
||||||
throw new IllegalStateException("Could not bind remote build assistant service", e);
|
throw new IllegalStateException("Could not bind remote build assistant service", e);
|
||||||
}
|
}
|
||||||
|
@ -139,7 +113,7 @@ public class TeaVMBuildDaemon extends UnicastRemoteObject implements TeaVMRemote
|
||||||
|
|
||||||
public static void main(String[] args) throws RemoteException {
|
public static void main(String[] args) throws RemoteException {
|
||||||
boolean incremental = Boolean.parseBoolean(System.getProperty(INCREMENTAL_PROPERTY, "false"));
|
boolean incremental = Boolean.parseBoolean(System.getProperty(INCREMENTAL_PROPERTY, "false"));
|
||||||
TeaVMBuildDaemon daemon = new TeaVMBuildDaemon(incremental);
|
BuildDaemon daemon = new BuildDaemon(incremental);
|
||||||
System.out.println(DAEMON_MESSAGE_PREFIX + daemon.port);
|
System.out.println(DAEMON_MESSAGE_PREFIX + daemon.port);
|
||||||
if (daemon.incrementalCache != null) {
|
if (daemon.incrementalCache != null) {
|
||||||
System.out.println("Incremental cache set up in " + daemon.incrementalCache);
|
System.out.println("Incremental cache set up in " + daemon.incrementalCache);
|
||||||
|
@ -147,8 +121,7 @@ public class TeaVMBuildDaemon extends UnicastRemoteObject implements TeaVMRemote
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TeaVMRemoteBuildResponse build(TeaVMRemoteBuildRequest request, TeaVMRemoteBuildCallback callback)
|
public RemoteBuildResponse build(RemoteBuildRequest request, RemoteBuildCallback callback) {
|
||||||
throws RemoteException {
|
|
||||||
System.out.println("Build started");
|
System.out.println("Build started");
|
||||||
|
|
||||||
if (!request.incremental && incremental) {
|
if (!request.incremental && incremental) {
|
||||||
|
@ -163,21 +136,34 @@ public class TeaVMBuildDaemon extends UnicastRemoteObject implements TeaVMRemote
|
||||||
TeaVMTool tool = new TeaVMTool();
|
TeaVMTool tool = new TeaVMTool();
|
||||||
tool.setIncremental(incremental && request.incremental);
|
tool.setIncremental(incremental && request.incremental);
|
||||||
if (tool.isIncremental()) {
|
if (tool.isIncremental()) {
|
||||||
tool.setCacheDirectory(incrementalCache);
|
tool.setCacheDirectory(request.cacheDirectory != null
|
||||||
|
? new File(request.cacheDirectory)
|
||||||
|
: incrementalCache);
|
||||||
}
|
}
|
||||||
tool.setProgressListener(createProgressListener(callback));
|
tool.setProgressListener(createProgressListener(callback));
|
||||||
tool.setLog(new EmptyTeaVMToolLog());
|
tool.setLog(new RemoteBuildLog(callback));
|
||||||
|
if (request.transformers != null) {
|
||||||
|
tool.getTransformers().addAll(Arrays.asList(request.transformers));
|
||||||
|
}
|
||||||
|
if (request.classesToPreserve != null) {
|
||||||
|
tool.getClassesToPreserve().addAll(Arrays.asList(request.classesToPreserve));
|
||||||
|
}
|
||||||
tool.setTargetType(request.targetType);
|
tool.setTargetType(request.targetType);
|
||||||
tool.setMainClass(request.mainClass);
|
tool.setMainClass(request.mainClass);
|
||||||
tool.setTargetDirectory(new File(request.targetDirectory));
|
tool.setTargetDirectory(new File(request.targetDirectory));
|
||||||
|
tool.setTargetFileName(request.tagetFileName);
|
||||||
tool.setClassLoader(buildClassLoader(request.classPath, incremental && request.incremental));
|
tool.setClassLoader(buildClassLoader(request.classPath, incremental && request.incremental));
|
||||||
|
|
||||||
tool.setSourceMapsFileGenerated(request.sourceMapsFileGenerated);
|
tool.setSourceMapsFileGenerated(request.sourceMapsFileGenerated);
|
||||||
tool.setDebugInformationGenerated(request.debugInformationGenerated);
|
tool.setDebugInformationGenerated(request.debugInformationGenerated);
|
||||||
tool.setSourceFilesCopied(request.sourceFilesCopied);
|
tool.setSourceFilesCopied(request.sourceFilesCopied);
|
||||||
tool.getProperties().putAll(request.properties);
|
if (request.properties != null) {
|
||||||
|
tool.getProperties().putAll(request.properties);
|
||||||
|
}
|
||||||
|
|
||||||
tool.setMinifying(false);
|
tool.setOptimizationLevel(request.optimizationLevel);
|
||||||
|
tool.setMinifying(request.minifying);
|
||||||
|
tool.setWasmVersion(request.wasmVersion);
|
||||||
|
|
||||||
for (String sourceDirectory : request.sourceDirectories) {
|
for (String sourceDirectory : request.sourceDirectories) {
|
||||||
tool.addSourceFileProvider(new DirectorySourceFileProvider(new File(sourceDirectory)));
|
tool.addSourceFileProvider(new DirectorySourceFileProvider(new File(sourceDirectory)));
|
||||||
|
@ -186,27 +172,24 @@ public class TeaVMBuildDaemon extends UnicastRemoteObject implements TeaVMRemote
|
||||||
tool.addSourceFileProvider(new JarSourceFileProvider(new File(sourceJar)));
|
tool.addSourceFileProvider(new JarSourceFileProvider(new File(sourceJar)));
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean errorOccurred = false;
|
RemoteBuildResponse response = new RemoteBuildResponse();
|
||||||
String stackTrace = null;
|
|
||||||
try {
|
try {
|
||||||
tool.generate();
|
tool.generate();
|
||||||
System.out.println("Build complete");
|
System.out.println("Build complete");
|
||||||
} catch (TeaVMToolException | RuntimeException | Error e) {
|
} catch (TeaVMToolException | RuntimeException | Error e) {
|
||||||
stackTrace = ExceptionUtil.exceptionToString(e);
|
response.exception = e;
|
||||||
errorOccurred = true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TeaVMRemoteBuildResponse response = new TeaVMRemoteBuildResponse();
|
if (response.exception == null) {
|
||||||
response.errorOccurred = errorOccurred;
|
response.callGraph = tool.getDependencyInfo().getCallGraph();
|
||||||
response.stackTrace = stackTrace;
|
response.problems.addAll(tool.getProblemProvider().getProblems());
|
||||||
response.callGraph = tool.getDependencyInfo().getCallGraph();
|
response.severeProblems.addAll(tool.getProblemProvider().getSevereProblems());
|
||||||
response.problems.addAll(tool.getProblemProvider().getProblems());
|
response.classes.addAll(tool.getClasses());
|
||||||
response.severeProblems.addAll(tool.getProblemProvider().getSevereProblems());
|
response.usedResources.addAll(tool.getUsedResources());
|
||||||
response.classes.addAll(tool.getClasses());
|
response.generatedFiles.addAll(tool.getGeneratedFiles().stream()
|
||||||
response.usedResources.addAll(tool.getUsedResources());
|
.map(File::getAbsolutePath)
|
||||||
response.generatedFiles.addAll(tool.getGeneratedFiles().stream()
|
.collect(Collectors.toSet()));
|
||||||
.map(File::getAbsolutePath)
|
}
|
||||||
.collect(Collectors.toSet()));
|
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
@ -254,7 +237,7 @@ public class TeaVMBuildDaemon extends UnicastRemoteObject implements TeaVMRemote
|
||||||
return new URLClassLoader(urls, jarClassLoader);
|
return new URLClassLoader(urls, jarClassLoader);
|
||||||
}
|
}
|
||||||
|
|
||||||
private TeaVMProgressListener createProgressListener(TeaVMRemoteBuildCallback callback) {
|
private TeaVMProgressListener createProgressListener(RemoteBuildCallback callback) {
|
||||||
return new TeaVMProgressListener() {
|
return new TeaVMProgressListener() {
|
||||||
private long lastReportedTime;
|
private long lastReportedTime;
|
||||||
|
|
||||||
|
@ -283,18 +266,26 @@ public class TeaVMBuildDaemon extends UnicastRemoteObject implements TeaVMRemote
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public static TeaVMDaemonInfo start(boolean incremental, int daemonMemory) throws IOException {
|
public static DaemonInfo start(boolean incremental, int daemonMemory, DaemonLog log,
|
||||||
|
String... classPathEntries) throws IOException {
|
||||||
String javaHome = System.getProperty("java.home");
|
String javaHome = System.getProperty("java.home");
|
||||||
String javaCommand = javaHome + "/bin/java";
|
String javaCommand = javaHome + "/bin/java";
|
||||||
String classPath = String.join(File.pathSeparator, detectClassPath());
|
String classPath = String.join(File.pathSeparator, classPathEntries);
|
||||||
ProcessBuilder builder = new ProcessBuilder(javaCommand, "-cp", classPath,
|
List<String> arguments = new ArrayList<>();
|
||||||
|
|
||||||
|
arguments.addAll(Arrays.asList(javaCommand, "-cp", classPath,
|
||||||
"-D" + INCREMENTAL_PROPERTY + "=" + incremental,
|
"-D" + INCREMENTAL_PROPERTY + "=" + incremental,
|
||||||
"-Xmx" + daemonMemory + "m",
|
"-Xmx" + daemonMemory + "m"));
|
||||||
TeaVMBuildDaemon.class.getName());
|
|
||||||
|
String debugPort = System.getProperty(DEBUG_PORT_PROPERTY);
|
||||||
|
if (debugPort != null) {
|
||||||
|
arguments.add("-agentlib:jdwp=transport=dt_socket,quiet=y,server=y,address=" + debugPort + ",suspend=y");
|
||||||
|
}
|
||||||
|
|
||||||
|
arguments.add(BuildDaemon.class.getName());
|
||||||
|
|
||||||
|
ProcessBuilder builder = new ProcessBuilder(arguments.toArray(new String[0]));
|
||||||
Process process = builder.start();
|
Process process = builder.start();
|
||||||
|
|
||||||
Log log = LogFactory.getLog(TeaVMBuildDaemon.class);
|
|
||||||
|
|
||||||
BufferedReader stdoutReader = new BufferedReader(new InputStreamReader(process.getInputStream(),
|
BufferedReader stdoutReader = new BufferedReader(new InputStreamReader(process.getInputStream(),
|
||||||
StandardCharsets.UTF_8));
|
StandardCharsets.UTF_8));
|
||||||
BufferedReader stderrReader = new BufferedReader(new InputStreamReader(process.getErrorStream(),
|
BufferedReader stderrReader = new BufferedReader(new InputStreamReader(process.getErrorStream(),
|
||||||
|
@ -311,6 +302,7 @@ public class TeaVMBuildDaemon extends UnicastRemoteObject implements TeaVMRemote
|
||||||
}
|
}
|
||||||
IOUtils.closeQuietly(stderrReader);
|
IOUtils.closeQuietly(stderrReader);
|
||||||
IOUtils.closeQuietly(stdoutReader);
|
IOUtils.closeQuietly(stdoutReader);
|
||||||
|
process.destroy();
|
||||||
throw new IllegalStateException("Could not start daemon. Stderr: " + sb);
|
throw new IllegalStateException("Could not start daemon. Stderr: " + sb);
|
||||||
}
|
}
|
||||||
int port = Integer.parseInt(line.substring(DAEMON_MESSAGE_PREFIX.length()));
|
int port = Integer.parseInt(line.substring(DAEMON_MESSAGE_PREFIX.length()));
|
||||||
|
@ -318,7 +310,7 @@ public class TeaVMBuildDaemon extends UnicastRemoteObject implements TeaVMRemote
|
||||||
daemonThread(new DaemonProcessOutputWatcher(log, stdoutReader, "stdout", false)).start();
|
daemonThread(new DaemonProcessOutputWatcher(log, stdoutReader, "stdout", false)).start();
|
||||||
daemonThread(new DaemonProcessOutputWatcher(log, stderrReader, "stderr", true)).start();
|
daemonThread(new DaemonProcessOutputWatcher(log, stderrReader, "stderr", true)).start();
|
||||||
|
|
||||||
return new TeaVMDaemonInfo(port, process);
|
return new DaemonInfo(port, process);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Thread daemonThread(Runnable runnable) {
|
private static Thread daemonThread(Runnable runnable) {
|
||||||
|
@ -328,12 +320,12 @@ public class TeaVMBuildDaemon extends UnicastRemoteObject implements TeaVMRemote
|
||||||
}
|
}
|
||||||
|
|
||||||
static class DaemonProcessOutputWatcher implements Runnable {
|
static class DaemonProcessOutputWatcher implements Runnable {
|
||||||
private Log log;
|
private DaemonLog log;
|
||||||
private BufferedReader reader;
|
private BufferedReader reader;
|
||||||
private String name;
|
private String name;
|
||||||
private boolean isError;
|
private boolean isError;
|
||||||
|
|
||||||
public DaemonProcessOutputWatcher(Log log, BufferedReader reader, String name, boolean isError) {
|
DaemonProcessOutputWatcher(DaemonLog log, BufferedReader reader, String name, boolean isError) {
|
||||||
this.log = log;
|
this.log = log;
|
||||||
this.reader = reader;
|
this.reader = reader;
|
||||||
this.name = name;
|
this.name = name;
|
||||||
|
@ -359,30 +351,4 @@ public class TeaVMBuildDaemon extends UnicastRemoteObject implements TeaVMRemote
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static List<String> detectClassPath() {
|
|
||||||
IdeaPluginDescriptor plugin = PluginManager.getPlugin(PluginId.getId("org.teavm.idea"));
|
|
||||||
Set<File> visited = new HashSet<>();
|
|
||||||
List<String> classPath = new ArrayList<>();
|
|
||||||
findInHierarchy(plugin.getPath(), classPath, visited);
|
|
||||||
return classPath;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void findInHierarchy(File file, List<String> targetFiles, Set<File> visited) {
|
|
||||||
if (!visited.add(file)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (file.isFile() && KOTLIN_FILES.contains(file.getName())) {
|
|
||||||
targetFiles.add(file.getAbsolutePath());
|
|
||||||
} else if (file.getPath().endsWith(DAEMON_CLASS)) {
|
|
||||||
for (int i = 0; i <= DAEMON_CLASS_DEPTH; ++i) {
|
|
||||||
file = file.getParentFile();
|
|
||||||
}
|
|
||||||
targetFiles.add(file.getAbsolutePath());
|
|
||||||
} else if (file.isDirectory()) {
|
|
||||||
for (File childFile : file.listFiles()) {
|
|
||||||
findInHierarchy(childFile, targetFiles, visited);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2017 Alexey Andreev.
|
* Copyright 2018 Alexey Andreev.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -13,13 +13,13 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.idea.daemon;
|
package org.teavm.tooling.daemon;
|
||||||
|
|
||||||
public class TeaVMDaemonInfo {
|
public class DaemonInfo {
|
||||||
private int port;
|
private int port;
|
||||||
private Process process;
|
private Process process;
|
||||||
|
|
||||||
TeaVMDaemonInfo(int port, Process process) {
|
DaemonInfo(int port, Process process) {
|
||||||
this.port = port;
|
this.port = port;
|
||||||
this.process = process;
|
this.process = process;
|
||||||
}
|
}
|
|
@ -0,0 +1,24 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.tooling.daemon;
|
||||||
|
|
||||||
|
public interface DaemonLog {
|
||||||
|
void error(String message);
|
||||||
|
|
||||||
|
void error(String message, Throwable e);
|
||||||
|
|
||||||
|
void info(String message);
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2017 Alexey Andreev.
|
* Copyright 2018 Alexey Andreev.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -13,15 +13,27 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.idea.jps.remote;
|
package org.teavm.tooling.daemon;
|
||||||
|
|
||||||
import java.rmi.Remote;
|
import java.rmi.Remote;
|
||||||
import java.rmi.RemoteException;
|
import java.rmi.RemoteException;
|
||||||
import org.teavm.vm.TeaVMPhase;
|
import org.teavm.vm.TeaVMPhase;
|
||||||
import org.teavm.vm.TeaVMProgressFeedback;
|
import org.teavm.vm.TeaVMProgressFeedback;
|
||||||
|
|
||||||
public interface TeaVMRemoteBuildCallback extends Remote {
|
public interface RemoteBuildCallback extends Remote {
|
||||||
TeaVMProgressFeedback phaseStarted(TeaVMPhase phase, int count) throws RemoteException;
|
TeaVMProgressFeedback phaseStarted(TeaVMPhase phase, int count) throws RemoteException;
|
||||||
|
|
||||||
TeaVMProgressFeedback progressReached(int progress) throws RemoteException;
|
TeaVMProgressFeedback progressReached(int progress) throws RemoteException;
|
||||||
|
|
||||||
|
void errorReported(String message, Throwable e) throws RemoteException;
|
||||||
|
|
||||||
|
void errorReported(String message) throws RemoteException;
|
||||||
|
|
||||||
|
void warningReported(String message, Throwable e) throws RemoteException;
|
||||||
|
|
||||||
|
void warningReported(String message) throws RemoteException;
|
||||||
|
|
||||||
|
void infoReported(String message, Throwable e) throws RemoteException;
|
||||||
|
|
||||||
|
void infoReported(String message) throws RemoteException;
|
||||||
}
|
}
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.tooling.daemon;
|
||||||
|
|
||||||
|
import java.rmi.RemoteException;
|
||||||
|
import org.teavm.tooling.TeaVMToolLog;
|
||||||
|
|
||||||
|
class RemoteBuildLog implements TeaVMToolLog {
|
||||||
|
private RemoteBuildCallback callback;
|
||||||
|
|
||||||
|
RemoteBuildLog(RemoteBuildCallback callback) {
|
||||||
|
this.callback = callback;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void info(String text) {
|
||||||
|
try {
|
||||||
|
callback.infoReported(text);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void debug(String text) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void warning(String text) {
|
||||||
|
try {
|
||||||
|
callback.warningReported(text);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(String text) {
|
||||||
|
try {
|
||||||
|
callback.errorReported(text);
|
||||||
|
} catch (RemoteException e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void info(String text, Throwable e) {
|
||||||
|
try {
|
||||||
|
callback.infoReported(text, e);
|
||||||
|
} catch (RemoteException e2) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void debug(String text, Throwable e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void warning(String text, Throwable e) {
|
||||||
|
try {
|
||||||
|
callback.warningReported(text, e);
|
||||||
|
} catch (RemoteException e2) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(String text, Throwable e) {
|
||||||
|
try {
|
||||||
|
callback.errorReported(text, e);
|
||||||
|
} catch (RemoteException e2) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2017 Alexey Andreev.
|
* Copyright 2018 Alexey Andreev.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -13,24 +13,33 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.idea.jps.remote;
|
package org.teavm.tooling.daemon;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
|
import org.teavm.backend.wasm.render.WasmBinaryVersion;
|
||||||
import org.teavm.tooling.TeaVMTargetType;
|
import org.teavm.tooling.TeaVMTargetType;
|
||||||
|
import org.teavm.vm.TeaVMOptimizationLevel;
|
||||||
|
|
||||||
public class TeaVMRemoteBuildRequest implements Serializable {
|
public class RemoteBuildRequest implements Serializable {
|
||||||
public final List<String> sourceDirectories = new ArrayList<>();
|
public final List<String> sourceDirectories = new ArrayList<>();
|
||||||
public final List<String> sourceJarFiles = new ArrayList<>();
|
public final List<String> sourceJarFiles = new ArrayList<>();
|
||||||
public final List<String> classPath = new ArrayList<>();
|
public final List<String> classPath = new ArrayList<>();
|
||||||
|
public String[] transformers;
|
||||||
|
public String[] classesToPreserve;
|
||||||
public TeaVMTargetType targetType;
|
public TeaVMTargetType targetType;
|
||||||
public String mainClass;
|
public String mainClass;
|
||||||
public String targetDirectory;
|
public String targetDirectory;
|
||||||
|
public String tagetFileName = "";
|
||||||
public boolean sourceMapsFileGenerated;
|
public boolean sourceMapsFileGenerated;
|
||||||
public boolean debugInformationGenerated;
|
public boolean debugInformationGenerated;
|
||||||
public boolean sourceFilesCopied;
|
public boolean sourceFilesCopied;
|
||||||
public boolean incremental;
|
public boolean incremental;
|
||||||
|
public String cacheDirectory;
|
||||||
|
public boolean minifying;
|
||||||
public Properties properties;
|
public Properties properties;
|
||||||
|
public TeaVMOptimizationLevel optimizationLevel;
|
||||||
|
public WasmBinaryVersion wasmVersion;
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2017 Alexey Andreev.
|
* Copyright 2018 Alexey Andreev.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -13,7 +13,7 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.idea.jps.remote;
|
package org.teavm.tooling.daemon;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -23,13 +23,12 @@ import java.util.Set;
|
||||||
import org.teavm.callgraph.CallGraph;
|
import org.teavm.callgraph.CallGraph;
|
||||||
import org.teavm.diagnostics.Problem;
|
import org.teavm.diagnostics.Problem;
|
||||||
|
|
||||||
public class TeaVMRemoteBuildResponse implements Serializable {
|
public class RemoteBuildResponse implements Serializable {
|
||||||
public CallGraph callGraph;
|
public CallGraph callGraph;
|
||||||
public boolean errorOccurred;
|
|
||||||
public final List<Problem> problems = new ArrayList<>();
|
public final List<Problem> problems = new ArrayList<>();
|
||||||
public final List<Problem> severeProblems = new ArrayList<>();
|
public final List<Problem> severeProblems = new ArrayList<>();
|
||||||
public final Set<String> usedResources = new HashSet<>();
|
public final Set<String> usedResources = new HashSet<>();
|
||||||
public final Set<String> classes = new HashSet<>();
|
public final Set<String> classes = new HashSet<>();
|
||||||
public final Set<String> generatedFiles = new HashSet<>();
|
public final Set<String> generatedFiles = new HashSet<>();
|
||||||
public String stackTrace;
|
public Throwable exception;
|
||||||
}
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2017 Alexey Andreev.
|
* Copyright 2018 Alexey Andreev.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
@ -13,15 +13,14 @@
|
||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
package org.teavm.idea.jps.remote;
|
package org.teavm.tooling.daemon;
|
||||||
|
|
||||||
import java.rmi.Remote;
|
import java.rmi.Remote;
|
||||||
import java.rmi.RemoteException;
|
import java.rmi.RemoteException;
|
||||||
|
|
||||||
public interface TeaVMRemoteBuildService extends Remote {
|
public interface RemoteBuildService extends Remote {
|
||||||
String REMOTE_PORT = "teavm.daemon.remote-port";
|
String REMOTE_PORT = "teavm.daemon.remote-port";
|
||||||
String ID = "TeaVM-Daemon";
|
String ID = "TeaVM-Daemon";
|
||||||
|
|
||||||
TeaVMRemoteBuildResponse build(TeaVMRemoteBuildRequest request, TeaVMRemoteBuildCallback callback)
|
RemoteBuildResponse build(RemoteBuildRequest request, RemoteBuildCallback callback) throws RemoteException;
|
||||||
throws RemoteException;
|
|
||||||
}
|
}
|
|
@ -157,9 +157,7 @@ public class TeaVMProjectBuilder extends IncrementalProjectBuilder {
|
||||||
String cacheDir = profile.getCacheDirectory();
|
String cacheDir = profile.getCacheDirectory();
|
||||||
tool.setCacheDirectory(!cacheDir.isEmpty() ?
|
tool.setCacheDirectory(!cacheDir.isEmpty() ?
|
||||||
new File(varManager.performStringSubstitution(cacheDir, false)) : null);
|
new File(varManager.performStringSubstitution(cacheDir, false)) : null);
|
||||||
for (ClassHolderTransformer transformer : instantiateTransformers(profile, classLoader)) {
|
tool.getTransformers().addAll(Arrays.asList(profile.getTransformers()));
|
||||||
tool.getTransformers().add(transformer);
|
|
||||||
}
|
|
||||||
tool.getClassesToPreserve().addAll(profile.getClassesToPreserve());
|
tool.getClassesToPreserve().addAll(profile.getClassesToPreserve());
|
||||||
for (SourceFileProvider provider : sourceProviders) {
|
for (SourceFileProvider provider : sourceProviders) {
|
||||||
tool.addSourceFileProvider(provider);
|
tool.addSourceFileProvider(provider);
|
||||||
|
@ -540,42 +538,6 @@ public class TeaVMProjectBuilder extends IncrementalProjectBuilder {
|
||||||
return projects;
|
return projects;
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<ClassHolderTransformer> instantiateTransformers(TeaVMProfile profile, ClassLoader classLoader)
|
|
||||||
throws CoreException{
|
|
||||||
List<ClassHolderTransformer> transformerInstances = new ArrayList<>();
|
|
||||||
for (String transformerName : profile.getTransformers()) {
|
|
||||||
Class<?> transformerRawType;
|
|
||||||
try {
|
|
||||||
transformerRawType = Class.forName(transformerName, true, classLoader);
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
putConfigMarker("Transformer not found: " + transformerName);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!ClassHolderTransformer.class.isAssignableFrom(transformerRawType)) {
|
|
||||||
putConfigMarker("Transformer " + transformerName + " is not a subtype of " +
|
|
||||||
ClassHolderTransformer.class.getName());
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
Class<? extends ClassHolderTransformer> transformerType = transformerRawType.asSubclass(
|
|
||||||
ClassHolderTransformer.class);
|
|
||||||
Constructor<? extends ClassHolderTransformer> ctor;
|
|
||||||
try {
|
|
||||||
ctor = transformerType.getConstructor();
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
putConfigMarker("Transformer " + transformerName + " has no default constructor");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
ClassHolderTransformer transformer = ctor.newInstance();
|
|
||||||
transformerInstances.add(transformer);
|
|
||||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
|
||||||
putConfigMarker("Error instantiating transformer " + transformerName);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return transformerInstances;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void putConfigMarker(String message) throws CoreException {
|
private void putConfigMarker(String message) throws CoreException {
|
||||||
IMarker marker = getProject().createMarker(TeaVMEclipsePlugin.CONFIG_MARKER_ID);
|
IMarker marker = getProject().createMarker(TeaVMEclipsePlugin.CONFIG_MARKER_ID);
|
||||||
marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
|
marker.setAttribute(IMarker.SEVERITY, IMarker.SEVERITY_ERROR);
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2018 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.idea.jps.util;
|
||||||
|
|
||||||
|
import com.intellij.ide.plugins.IdeaPluginDescriptor;
|
||||||
|
import com.intellij.ide.plugins.PluginManager;
|
||||||
|
import com.intellij.openapi.extensions.PluginId;
|
||||||
|
import java.io.File;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import org.teavm.tooling.daemon.BuildDaemon;
|
||||||
|
|
||||||
|
public final class DaemonUtil {
|
||||||
|
private static final Set<String> PLUGIN_FILES = new HashSet<>(Arrays.asList("teavm-jps-common.jar",
|
||||||
|
"teavm-plugin.jar", "teavm.jar"));
|
||||||
|
private static final String DAEMON_CLASS = BuildDaemon.class.getName().replace('.', '/') + ".class";
|
||||||
|
private static final int DAEMON_CLASS_DEPTH;
|
||||||
|
|
||||||
|
static {
|
||||||
|
int depth = 0;
|
||||||
|
for (int i = 0; i < DAEMON_CLASS.length(); ++i) {
|
||||||
|
if (DAEMON_CLASS.charAt(i) == '/') {
|
||||||
|
depth++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
DAEMON_CLASS_DEPTH = depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
private DaemonUtil() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static List<String> detectClassPath() {
|
||||||
|
IdeaPluginDescriptor plugin = PluginManager.getPlugin(PluginId.getId("org.teavm.idea"));
|
||||||
|
Set<File> visited = new HashSet<>();
|
||||||
|
List<String> classPath = new ArrayList<>();
|
||||||
|
findInHierarchy(plugin.getPath(), classPath, visited);
|
||||||
|
return classPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void findInHierarchy(File file, List<String> targetFiles, Set<File> visited) {
|
||||||
|
if (!visited.add(file)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (file.isFile() && PLUGIN_FILES.contains(file.getName())) {
|
||||||
|
targetFiles.add(file.getAbsolutePath());
|
||||||
|
} else if (file.getPath().endsWith(DAEMON_CLASS)) {
|
||||||
|
for (int i = 0; i <= DAEMON_CLASS_DEPTH; ++i) {
|
||||||
|
file = file.getParentFile();
|
||||||
|
}
|
||||||
|
targetFiles.add(file.getAbsolutePath());
|
||||||
|
} else if (file.isDirectory()) {
|
||||||
|
for (File childFile : file.listFiles()) {
|
||||||
|
findInHierarchy(childFile, targetFiles, visited);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2017 Alexey Andreev.
|
* Copyright 2018 Alexey Andreev.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2017 Alexey Andreev.
|
* Copyright 2018 Alexey Andreev.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
|
|
|
@ -22,6 +22,7 @@ import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStreamReader;
|
import java.io.InputStreamReader;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayDeque;
|
import java.util.ArrayDeque;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
@ -57,8 +58,6 @@ import org.teavm.common.IntegerArray;
|
||||||
import org.teavm.diagnostics.DefaultProblemTextConsumer;
|
import org.teavm.diagnostics.DefaultProblemTextConsumer;
|
||||||
import org.teavm.diagnostics.Problem;
|
import org.teavm.diagnostics.Problem;
|
||||||
import org.teavm.diagnostics.ProblemProvider;
|
import org.teavm.diagnostics.ProblemProvider;
|
||||||
import org.teavm.idea.jps.model.TeaVMBuildResult;
|
|
||||||
import org.teavm.idea.jps.model.TeaVMBuildStrategy;
|
|
||||||
import org.teavm.idea.jps.model.TeaVMJpsConfiguration;
|
import org.teavm.idea.jps.model.TeaVMJpsConfiguration;
|
||||||
import org.teavm.idea.jps.model.TeaVMProperty;
|
import org.teavm.idea.jps.model.TeaVMProperty;
|
||||||
import org.teavm.idea.jps.remote.TeaVMBuilderAssistant;
|
import org.teavm.idea.jps.remote.TeaVMBuilderAssistant;
|
||||||
|
@ -67,6 +66,9 @@ import org.teavm.model.CallLocation;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
import org.teavm.model.TextLocation;
|
import org.teavm.model.TextLocation;
|
||||||
import org.teavm.model.ValueType;
|
import org.teavm.model.ValueType;
|
||||||
|
import org.teavm.tooling.builder.BuildException;
|
||||||
|
import org.teavm.tooling.builder.BuildResult;
|
||||||
|
import org.teavm.tooling.builder.BuildStrategy;
|
||||||
import org.teavm.vm.TeaVMPhase;
|
import org.teavm.vm.TeaVMPhase;
|
||||||
import org.teavm.vm.TeaVMProgressFeedback;
|
import org.teavm.vm.TeaVMProgressFeedback;
|
||||||
import org.teavm.vm.TeaVMProgressListener;
|
import org.teavm.vm.TeaVMProgressListener;
|
||||||
|
@ -79,10 +81,10 @@ class TeaVMBuild {
|
||||||
private final TeaVMBuilderAssistant assistant;
|
private final TeaVMBuilderAssistant assistant;
|
||||||
private final Map<String, File> sourceFileCache = new HashMap<>();
|
private final Map<String, File> sourceFileCache = new HashMap<>();
|
||||||
private final Map<File, int[]> fileLineCache = new HashMap<>();
|
private final Map<File, int[]> fileLineCache = new HashMap<>();
|
||||||
private TeaVMBuildStrategy buildStrategy;
|
private BuildStrategy buildStrategy;
|
||||||
private BuildOutputConsumer outputConsumer;
|
private BuildOutputConsumer outputConsumer;
|
||||||
|
|
||||||
TeaVMBuild(CompileContext context, TeaVMBuilderAssistant assistant, TeaVMBuildStrategy buildStrategy,
|
TeaVMBuild(CompileContext context, TeaVMBuilderAssistant assistant, BuildStrategy buildStrategy,
|
||||||
BuildOutputConsumer outputConsumer) {
|
BuildOutputConsumer outputConsumer) {
|
||||||
this.context = context;
|
this.context = context;
|
||||||
this.assistant = assistant;
|
this.assistant = assistant;
|
||||||
|
@ -90,7 +92,7 @@ class TeaVMBuild {
|
||||||
this.outputConsumer = outputConsumer;
|
this.outputConsumer = outputConsumer;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean perform(JpsModule module, TeaVMBuildTarget target) throws IOException {
|
boolean perform(JpsModule module, TeaVMBuildTarget target) throws IOException, BuildException {
|
||||||
TeaVMStorageProvider storageProvider = new TeaVMStorageProvider(
|
TeaVMStorageProvider storageProvider = new TeaVMStorageProvider(
|
||||||
target.getConfiguration().getTargetType().name());
|
target.getConfiguration().getTargetType().name());
|
||||||
storage = context.getProjectDescriptor().dataManager.getStorage(target, storageProvider);
|
storage = context.getProjectDescriptor().dataManager.getStorage(target, storageProvider);
|
||||||
|
@ -128,24 +130,16 @@ class TeaVMBuild {
|
||||||
}
|
}
|
||||||
buildStrategy.setProperties(properties);
|
buildStrategy.setProperties(properties);
|
||||||
|
|
||||||
TeaVMBuildResult buildResult = buildStrategy.build();
|
BuildResult buildResult = buildStrategy.build();
|
||||||
|
|
||||||
if (!buildResult.isErrorOccurred() && buildResult.getProblems().getSevereProblems().isEmpty()) {
|
if (!buildResult.getProblems().getSevereProblems().isEmpty()) {
|
||||||
updateStorage(buildResult);
|
updateStorage(buildResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
reportProblems(buildResult.getProblems(), buildResult.getCallGraph());
|
reportProblems(buildResult.getProblems(), buildResult.getCallGraph());
|
||||||
|
|
||||||
if (!buildResult.isErrorOccurred()) {
|
for (String fileName : buildResult.getGeneratedFiles()) {
|
||||||
for (String fileName : buildResult.getGeneratedFiles()) {
|
outputConsumer.registerOutputFile(new File(fileName), Collections.emptyList());
|
||||||
outputConsumer.registerOutputFile(new File(fileName), Collections.emptyList());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (buildResult.getStackTrace() != null) {
|
|
||||||
context.processMessage(new CompilerMessage("TeaVM", BuildMessage.Kind.ERROR,
|
|
||||||
"Compiler crashed:\n" + buildResult.getStackTrace(), "",
|
|
||||||
-1, -1, -1, -1, -1));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -390,7 +384,7 @@ class TeaVMBuild {
|
||||||
|
|
||||||
private int[] getLineOffsetsCacheMiss(File file) {
|
private int[] getLineOffsetsCacheMiss(File file) {
|
||||||
IntegerArray lines = new IntegerArray(50);
|
IntegerArray lines = new IntegerArray(50);
|
||||||
try (Reader reader = new InputStreamReader(new FileInputStream(file), "UTF-8")) {
|
try (Reader reader = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8)) {
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
lines.add(0);
|
lines.add(0);
|
||||||
|
|
||||||
|
@ -450,10 +444,9 @@ class TeaVMBuild {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateStorage(TeaVMBuildResult buildResult) {
|
private void updateStorage(BuildResult buildResult) {
|
||||||
Set<String> resources = Stream.concat(buildResult.getClasses().stream()
|
Set<String> resources = Stream.concat(buildResult.getClasses().stream()
|
||||||
.map(cls -> cls.replace('.', '/') + ".class"), buildResult.getUsedResources().stream())
|
.map(cls -> cls.replace('.', '/') + ".class"), buildResult.getUsedResources().stream())
|
||||||
.sorted()
|
|
||||||
.collect(toSet());
|
.collect(toSet());
|
||||||
List<TeaVMStorage.Entry> participatingFiles = resources.stream()
|
List<TeaVMStorage.Entry> participatingFiles = resources.stream()
|
||||||
.map(path -> {
|
.map(path -> {
|
||||||
|
|
|
@ -16,7 +16,6 @@
|
||||||
package org.teavm.idea.jps;
|
package org.teavm.idea.jps;
|
||||||
|
|
||||||
import static org.teavm.idea.jps.remote.TeaVMBuilderAssistant.REMOTE_PORT;
|
import static org.teavm.idea.jps.remote.TeaVMBuilderAssistant.REMOTE_PORT;
|
||||||
import java.io.IOException;
|
|
||||||
import java.rmi.NotBoundException;
|
import java.rmi.NotBoundException;
|
||||||
import java.rmi.RemoteException;
|
import java.rmi.RemoteException;
|
||||||
import java.rmi.registry.LocateRegistry;
|
import java.rmi.registry.LocateRegistry;
|
||||||
|
@ -27,17 +26,19 @@ import org.jetbrains.jps.builders.BuildOutputConsumer;
|
||||||
import org.jetbrains.jps.builders.BuildRootDescriptor;
|
import org.jetbrains.jps.builders.BuildRootDescriptor;
|
||||||
import org.jetbrains.jps.builders.DirtyFilesHolder;
|
import org.jetbrains.jps.builders.DirtyFilesHolder;
|
||||||
import org.jetbrains.jps.incremental.CompileContext;
|
import org.jetbrains.jps.incremental.CompileContext;
|
||||||
import org.jetbrains.jps.incremental.ProjectBuildException;
|
|
||||||
import org.jetbrains.jps.incremental.TargetBuilder;
|
import org.jetbrains.jps.incremental.TargetBuilder;
|
||||||
import org.jetbrains.jps.incremental.messages.BuildMessage;
|
import org.jetbrains.jps.incremental.messages.BuildMessage;
|
||||||
import org.jetbrains.jps.incremental.messages.CompilerMessage;
|
import org.jetbrains.jps.incremental.messages.CompilerMessage;
|
||||||
import org.teavm.idea.jps.model.TeaVMBuildStrategy;
|
|
||||||
import org.teavm.idea.jps.remote.TeaVMBuilderAssistant;
|
import org.teavm.idea.jps.remote.TeaVMBuilderAssistant;
|
||||||
import org.teavm.idea.jps.remote.TeaVMRemoteBuildService;
|
import org.teavm.tooling.builder.BuildException;
|
||||||
|
import org.teavm.tooling.builder.BuildStrategy;
|
||||||
|
import org.teavm.tooling.builder.InProcessBuildStrategy;
|
||||||
|
import org.teavm.tooling.builder.RemoteBuildStrategy;
|
||||||
|
import org.teavm.tooling.daemon.RemoteBuildService;
|
||||||
|
|
||||||
public class TeaVMBuilder extends TargetBuilder<BuildRootDescriptor, TeaVMBuildTarget> {
|
public class TeaVMBuilder extends TargetBuilder<BuildRootDescriptor, TeaVMBuildTarget> {
|
||||||
private TeaVMBuilderAssistant assistant;
|
private TeaVMBuilderAssistant assistant;
|
||||||
private TeaVMRemoteBuildService buildService;
|
private RemoteBuildService buildService;
|
||||||
|
|
||||||
public TeaVMBuilder() {
|
public TeaVMBuilder() {
|
||||||
super(Collections.singletonList(TeaVMBuildTargetType.INSTANCE));
|
super(Collections.singletonList(TeaVMBuildTargetType.INSTANCE));
|
||||||
|
@ -52,11 +53,11 @@ public class TeaVMBuilder extends TargetBuilder<BuildRootDescriptor, TeaVMBuildT
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String daemonPortString = System.getProperty(TeaVMRemoteBuildService.REMOTE_PORT);
|
String daemonPortString = System.getProperty(RemoteBuildService.REMOTE_PORT);
|
||||||
if (daemonPortString != null) {
|
if (daemonPortString != null) {
|
||||||
try {
|
try {
|
||||||
Registry registry = LocateRegistry.getRegistry(Integer.parseInt(daemonPortString));
|
Registry registry = LocateRegistry.getRegistry(Integer.parseInt(daemonPortString));
|
||||||
buildService = (TeaVMRemoteBuildService) registry.lookup(TeaVMRemoteBuildService.ID);
|
buildService = (RemoteBuildService) registry.lookup(RemoteBuildService.ID);
|
||||||
} catch (NumberFormatException | RemoteException | NotBoundException e) {
|
} catch (NumberFormatException | RemoteException | NotBoundException e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
}
|
}
|
||||||
|
@ -66,19 +67,32 @@ public class TeaVMBuilder extends TargetBuilder<BuildRootDescriptor, TeaVMBuildT
|
||||||
@Override
|
@Override
|
||||||
public void build(@NotNull TeaVMBuildTarget target,
|
public void build(@NotNull TeaVMBuildTarget target,
|
||||||
@NotNull DirtyFilesHolder<BuildRootDescriptor, TeaVMBuildTarget> holder,
|
@NotNull DirtyFilesHolder<BuildRootDescriptor, TeaVMBuildTarget> holder,
|
||||||
@NotNull BuildOutputConsumer outputConsumer, @NotNull CompileContext context) throws ProjectBuildException,
|
@NotNull BuildOutputConsumer outputConsumer, @NotNull CompileContext context) {
|
||||||
IOException {
|
|
||||||
if (assistant == null) {
|
if (assistant == null) {
|
||||||
context.processMessage(new CompilerMessage("TeaVM", BuildMessage.Kind.WARNING,
|
context.processMessage(new CompilerMessage("TeaVM", BuildMessage.Kind.WARNING,
|
||||||
"No TeaVM builder assistant available. Diagnostic messages will be less informative"));
|
"No TeaVM builder assistant available. Diagnostic messages will be less informative"));
|
||||||
}
|
}
|
||||||
|
|
||||||
TeaVMBuildStrategy buildStrategy = buildService != null
|
try {
|
||||||
? new RemoteBuildStrategy(buildService)
|
BuildStrategy buildStrategy = buildService != null
|
||||||
: new InProcessBuildStrategy(context);
|
? new RemoteBuildStrategy(buildService)
|
||||||
TeaVMBuild build = new TeaVMBuild(context, assistant, buildStrategy, outputConsumer);
|
: createInProcessBuilder();
|
||||||
|
TeaVMBuild build = new TeaVMBuild(context, assistant, buildStrategy, outputConsumer);
|
||||||
|
|
||||||
build.perform(target.getModule(), target);
|
build.perform(target.getModule(), target);
|
||||||
|
} catch (BuildException e) {
|
||||||
|
context.processMessage(CompilerMessage.createInternalBuilderError("TeaVM", e.getCause()));
|
||||||
|
} catch (Exception e) {
|
||||||
|
context.processMessage(CompilerMessage.createInternalBuilderError("TeaVM", e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private BuildStrategy createInProcessBuilder() {
|
||||||
|
return new InProcessBuildStrategy((urls, innerClassLoader) -> {
|
||||||
|
RenamingClassLoader loader = new RenamingClassLoader(urls, innerClassLoader);
|
||||||
|
loader.rename("org/objectweb/asm/", "org/teavm/asm/");
|
||||||
|
return loader;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|
|
@ -25,6 +25,7 @@ import java.io.InputStreamReader;
|
||||||
import java.io.OutputStreamWriter;
|
import java.io.OutputStreamWriter;
|
||||||
import java.io.Reader;
|
import java.io.Reader;
|
||||||
import java.io.Writer;
|
import java.io.Writer;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.jetbrains.jps.incremental.storage.StorageOwner;
|
import org.jetbrains.jps.incremental.storage.StorageOwner;
|
||||||
|
@ -39,7 +40,7 @@ public class TeaVMStorage implements StorageOwner {
|
||||||
this.file = file;
|
this.file = file;
|
||||||
if (file.exists()) {
|
if (file.exists()) {
|
||||||
participatingFiles = new ArrayList<>();
|
participatingFiles = new ArrayList<>();
|
||||||
try (Reader innerReader = new InputStreamReader(new FileInputStream(file), "UTF-8");
|
try (Reader innerReader = new InputStreamReader(new FileInputStream(file), StandardCharsets.UTF_8);
|
||||||
BufferedReader reader = new BufferedReader(innerReader)) {
|
BufferedReader reader = new BufferedReader(innerReader)) {
|
||||||
while (true) {
|
while (true) {
|
||||||
String line = reader.readLine();
|
String line = reader.readLine();
|
||||||
|
@ -82,7 +83,7 @@ public class TeaVMStorage implements StorageOwner {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void clean() throws IOException {
|
public void clean() {
|
||||||
file.delete();
|
file.delete();
|
||||||
participatingFiles = null;
|
participatingFiles = null;
|
||||||
}
|
}
|
||||||
|
@ -95,7 +96,7 @@ public class TeaVMStorage implements StorageOwner {
|
||||||
file.delete();
|
file.delete();
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try (Writer innerWriter = new OutputStreamWriter(new FileOutputStream(file), "UTF-8");
|
try (Writer innerWriter = new OutputStreamWriter(new FileOutputStream(file), StandardCharsets.UTF_8);
|
||||||
BufferedWriter writer = new BufferedWriter(innerWriter)) {
|
BufferedWriter writer = new BufferedWriter(innerWriter)) {
|
||||||
for (Entry participatingFile : participatingFiles) {
|
for (Entry participatingFile : participatingFiles) {
|
||||||
writer.append(participatingFile.path + ":" + participatingFile.timestamp);
|
writer.append(participatingFile.path + ":" + participatingFile.timestamp);
|
||||||
|
|
|
@ -18,13 +18,17 @@ package org.teavm.idea;
|
||||||
import com.intellij.openapi.components.ApplicationComponent;
|
import com.intellij.openapi.components.ApplicationComponent;
|
||||||
import com.intellij.openapi.components.ServiceManager;
|
import com.intellij.openapi.components.ServiceManager;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import org.apache.commons.logging.Log;
|
||||||
|
import org.apache.commons.logging.LogFactory;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.teavm.idea.daemon.TeaVMBuildDaemon;
|
|
||||||
import org.teavm.idea.daemon.TeaVMDaemonInfo;
|
|
||||||
import org.teavm.idea.jps.model.TeaVMJpsWorkspaceConfiguration;
|
import org.teavm.idea.jps.model.TeaVMJpsWorkspaceConfiguration;
|
||||||
|
import org.teavm.idea.jps.util.DaemonUtil;
|
||||||
|
import org.teavm.tooling.daemon.BuildDaemon;
|
||||||
|
import org.teavm.tooling.daemon.DaemonInfo;
|
||||||
|
import org.teavm.tooling.daemon.DaemonLog;
|
||||||
|
|
||||||
public class TeaVMDaemonComponent implements ApplicationComponent {
|
public class TeaVMDaemonComponent implements ApplicationComponent {
|
||||||
private TeaVMDaemonInfo daemonInfo;
|
private DaemonInfo daemonInfo;
|
||||||
private boolean incremental;
|
private boolean incremental;
|
||||||
private int daemonMemory;
|
private int daemonMemory;
|
||||||
|
|
||||||
|
@ -64,7 +68,9 @@ public class TeaVMDaemonComponent implements ApplicationComponent {
|
||||||
public void startDaemon() {
|
public void startDaemon() {
|
||||||
if (daemonInfo == null) {
|
if (daemonInfo == null) {
|
||||||
try {
|
try {
|
||||||
daemonInfo = TeaVMBuildDaemon.start(incremental, daemonMemory);
|
Log log = LogFactory.getLog(TeaVMDaemonComponent.class);
|
||||||
|
daemonInfo = BuildDaemon.start(incremental, daemonMemory, new LogWrapper(log),
|
||||||
|
DaemonUtil.detectClassPath().toArray(new String[0]));
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
|
@ -116,4 +122,27 @@ public class TeaVMDaemonComponent implements ApplicationComponent {
|
||||||
public String getComponentName() {
|
public String getComponentName() {
|
||||||
return "TeaVM daemon";
|
return "TeaVM daemon";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class LogWrapper implements DaemonLog {
|
||||||
|
private Log log;
|
||||||
|
|
||||||
|
public LogWrapper(Log log) {
|
||||||
|
this.log = log;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(String s) {
|
||||||
|
log.error(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(String s, Throwable throwable) {
|
||||||
|
log.error(s, throwable);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void info(String s) {
|
||||||
|
log.info(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,7 +20,7 @@ import com.intellij.compiler.server.BuildProcessParametersProvider;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.teavm.idea.jps.remote.TeaVMRemoteBuildService;
|
import org.teavm.tooling.daemon.RemoteBuildService;
|
||||||
|
|
||||||
public class TeaVMJPSConfigurator extends BuildProcessParametersProvider {
|
public class TeaVMJPSConfigurator extends BuildProcessParametersProvider {
|
||||||
private TeaVMJPSRemoteService remoteService;
|
private TeaVMJPSRemoteService remoteService;
|
||||||
|
@ -37,7 +37,7 @@ public class TeaVMJPSConfigurator extends BuildProcessParametersProvider {
|
||||||
List<String> result = new ArrayList<>();
|
List<String> result = new ArrayList<>();
|
||||||
result.add("-D" + REMOTE_PORT + "=" + remoteService.getPort());
|
result.add("-D" + REMOTE_PORT + "=" + remoteService.getPort());
|
||||||
if (daemonComponent.isDaemonRunning()) {
|
if (daemonComponent.isDaemonRunning()) {
|
||||||
result.add("-D" + TeaVMRemoteBuildService.REMOTE_PORT + "=" + daemonComponent.getDaemonPort());
|
result.add("-D" + RemoteBuildService.REMOTE_PORT + "=" + daemonComponent.getDaemonPort());
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
|
@ -99,8 +99,7 @@ public class TeaVMJPSRemoteService extends UnicastRemoteObject implements Applic
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public TeaVMElementLocation getMethodLocation(String className, String methodName, String methodDesc)
|
public TeaVMElementLocation getMethodLocation(String className, String methodName, String methodDesc) {
|
||||||
throws RemoteException {
|
|
||||||
TeaVMElementLocation[] resultHolder = new TeaVMElementLocation[1];
|
TeaVMElementLocation[] resultHolder = new TeaVMElementLocation[1];
|
||||||
|
|
||||||
ApplicationManager.getApplication().runReadAction(() -> {
|
ApplicationManager.getApplication().runReadAction(() -> {
|
||||||
|
|
|
@ -1,217 +0,0 @@
|
||||||
/*
|
|
||||||
* Copyright 2015 Alexey Andreev.
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*/
|
|
||||||
package org.teavm.maven;
|
|
||||||
|
|
||||||
import java.io.File;
|
|
||||||
import java.lang.reflect.Constructor;
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
|
||||||
import java.net.MalformedURLException;
|
|
||||||
import java.net.URL;
|
|
||||||
import java.net.URLClassLoader;
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Properties;
|
|
||||||
import org.apache.maven.artifact.Artifact;
|
|
||||||
import org.apache.maven.artifact.repository.MavenArtifactRepository;
|
|
||||||
import org.apache.maven.plugin.AbstractMojo;
|
|
||||||
import org.apache.maven.plugin.MojoExecutionException;
|
|
||||||
import org.apache.maven.plugin.logging.Log;
|
|
||||||
import org.apache.maven.plugins.annotations.Component;
|
|
||||||
import org.apache.maven.plugins.annotations.Parameter;
|
|
||||||
import org.apache.maven.project.MavenProject;
|
|
||||||
import org.apache.maven.repository.RepositorySystem;
|
|
||||||
import org.teavm.model.ClassHolderTransformer;
|
|
||||||
import org.teavm.tooling.BaseTeaVMTool;
|
|
||||||
import org.teavm.tooling.sources.SourceFileProvider;
|
|
||||||
|
|
||||||
public abstract class AbstractTeaVMMojo extends AbstractMojo {
|
|
||||||
@Component
|
|
||||||
protected MavenProject project;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
protected RepositorySystem repositorySystem;
|
|
||||||
|
|
||||||
@Parameter(required = true, readonly = true, defaultValue = "${localRepository}")
|
|
||||||
protected MavenArtifactRepository localRepository;
|
|
||||||
|
|
||||||
@Parameter(required = true, readonly = true, defaultValue = "${project.remoteArtifactRepositories}")
|
|
||||||
protected List<MavenArtifactRepository> remoteRepositories;
|
|
||||||
|
|
||||||
@Parameter(readonly = true, defaultValue = "${plugin.artifacts}")
|
|
||||||
protected List<Artifact> pluginArtifacts;
|
|
||||||
|
|
||||||
@Parameter(defaultValue = "${project.build.outputDirectory}")
|
|
||||||
protected File classFiles;
|
|
||||||
|
|
||||||
@Parameter
|
|
||||||
protected List<String> compileScopes;
|
|
||||||
|
|
||||||
@Parameter
|
|
||||||
protected boolean minifying = true;
|
|
||||||
|
|
||||||
@Parameter
|
|
||||||
protected Properties properties;
|
|
||||||
|
|
||||||
@Parameter
|
|
||||||
protected boolean debugInformationGenerated;
|
|
||||||
|
|
||||||
@Parameter
|
|
||||||
protected boolean sourceMapsGenerated;
|
|
||||||
|
|
||||||
@Parameter
|
|
||||||
protected boolean sourceFilesCopied;
|
|
||||||
|
|
||||||
@Parameter
|
|
||||||
protected boolean incremental;
|
|
||||||
|
|
||||||
@Parameter
|
|
||||||
protected String[] transformers;
|
|
||||||
|
|
||||||
protected ClassLoader classLoader;
|
|
||||||
|
|
||||||
protected abstract File getTargetDirectory();
|
|
||||||
|
|
||||||
protected final List<ClassHolderTransformer> instantiateTransformers(ClassLoader classLoader)
|
|
||||||
throws MojoExecutionException {
|
|
||||||
List<ClassHolderTransformer> transformerInstances = new ArrayList<>();
|
|
||||||
if (transformers == null) {
|
|
||||||
return transformerInstances;
|
|
||||||
}
|
|
||||||
for (String transformerName : transformers) {
|
|
||||||
Class<?> transformerRawType;
|
|
||||||
try {
|
|
||||||
transformerRawType = Class.forName(transformerName, true, classLoader);
|
|
||||||
} catch (ClassNotFoundException e) {
|
|
||||||
throw new MojoExecutionException("Transformer not found: " + transformerName, e);
|
|
||||||
}
|
|
||||||
if (!ClassHolderTransformer.class.isAssignableFrom(transformerRawType)) {
|
|
||||||
throw new MojoExecutionException("Transformer " + transformerName + " is not subtype of "
|
|
||||||
+ ClassHolderTransformer.class.getName());
|
|
||||||
}
|
|
||||||
Class<? extends ClassHolderTransformer> transformerType = transformerRawType.asSubclass(
|
|
||||||
ClassHolderTransformer.class);
|
|
||||||
Constructor<? extends ClassHolderTransformer> ctor;
|
|
||||||
try {
|
|
||||||
ctor = transformerType.getConstructor();
|
|
||||||
} catch (NoSuchMethodException e) {
|
|
||||||
throw new MojoExecutionException("Transformer " + transformerName + " has no default constructor");
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
ClassHolderTransformer transformer = ctor.newInstance();
|
|
||||||
transformerInstances.add(transformer);
|
|
||||||
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
|
|
||||||
throw new MojoExecutionException("Error instantiating transformer " + transformerName, e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return transformerInstances;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void setupTool(BaseTeaVMTool tool) throws MojoExecutionException {
|
|
||||||
tool.setLog(new MavenTeaVMToolLog(getLog()));
|
|
||||||
try {
|
|
||||||
ClassLoader classLoader = prepareClassLoader();
|
|
||||||
tool.setClassLoader(classLoader);
|
|
||||||
tool.setMinifying(minifying);
|
|
||||||
tool.setTargetDirectory(getTargetDirectory());
|
|
||||||
tool.getTransformers().addAll(instantiateTransformers(classLoader));
|
|
||||||
if (sourceFilesCopied) {
|
|
||||||
for (SourceFileProvider provider : getSourceFileProviders()) {
|
|
||||||
tool.addSourceFileProvider(provider);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (properties != null) {
|
|
||||||
tool.getProperties().putAll(properties);
|
|
||||||
}
|
|
||||||
tool.setIncremental(incremental);
|
|
||||||
tool.setDebugInformationGenerated(debugInformationGenerated);
|
|
||||||
tool.setSourceMapsFileGenerated(sourceMapsGenerated);
|
|
||||||
tool.setSourceFilesCopied(sourceFilesCopied);
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
throw new MojoExecutionException("Unexpected error occured", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final ClassLoader prepareClassLoader() throws MojoExecutionException {
|
|
||||||
try {
|
|
||||||
Log log = getLog();
|
|
||||||
log.info("Preparing classpath for JavaScript generation");
|
|
||||||
List<URL> urls = new ArrayList<>();
|
|
||||||
StringBuilder classpath = new StringBuilder();
|
|
||||||
for (Artifact artifact : project.getArtifacts()) {
|
|
||||||
if (!filterByScope(artifact)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
File file = artifact.getFile();
|
|
||||||
if (classpath.length() > 0) {
|
|
||||||
classpath.append(':');
|
|
||||||
}
|
|
||||||
classpath.append(file.getPath());
|
|
||||||
urls.add(file.toURI().toURL());
|
|
||||||
}
|
|
||||||
if (classpath.length() > 0) {
|
|
||||||
classpath.append(':');
|
|
||||||
}
|
|
||||||
classpath.append(classFiles.getPath());
|
|
||||||
urls.add(classFiles.toURI().toURL());
|
|
||||||
for (File additionalEntry : getAdditionalClassPath()) {
|
|
||||||
classpath.append(':').append(additionalEntry.getPath());
|
|
||||||
urls.add(additionalEntry.toURI().toURL());
|
|
||||||
}
|
|
||||||
log.info("Using the following classpath for JavaScript generation: " + classpath);
|
|
||||||
classLoader = new URLClassLoader(urls.toArray(new URL[urls.size()]),
|
|
||||||
AbstractTeaVMMojo.class.getClassLoader());
|
|
||||||
return classLoader;
|
|
||||||
} catch (MalformedURLException e) {
|
|
||||||
throw new MojoExecutionException("Error gathering classpath information", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected List<File> getAdditionalClassPath() {
|
|
||||||
return Collections.emptyList();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean filterByScope(Artifact artifact) {
|
|
||||||
return compileScopes == null ? isSupportedScope(artifact.getScope())
|
|
||||||
: compileScopes.contains(artifact.getScope());
|
|
||||||
}
|
|
||||||
|
|
||||||
protected boolean isSupportedScope(String scope) {
|
|
||||||
switch (scope) {
|
|
||||||
case Artifact.SCOPE_COMPILE:
|
|
||||||
case Artifact.SCOPE_PROVIDED:
|
|
||||||
case Artifact.SCOPE_SYSTEM:
|
|
||||||
return true;
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected final List<SourceFileProvider> getSourceFileProviders() {
|
|
||||||
MavenSourceFileProviderLookup lookup = new MavenSourceFileProviderLookup();
|
|
||||||
lookup.setMavenProject(project);
|
|
||||||
lookup.setRepositorySystem(repositorySystem);
|
|
||||||
lookup.setLocalRepository(localRepository);
|
|
||||||
lookup.setRemoteRepositories(remoteRepositories);
|
|
||||||
lookup.setPluginDependencies(pluginArtifacts);
|
|
||||||
List<SourceFileProvider> providers = lookup.resolve();
|
|
||||||
addSourceProviders(providers);
|
|
||||||
return providers;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void addSourceProviders(@SuppressWarnings("unused") List<SourceFileProvider> providers) {
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -26,9 +26,7 @@ import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
|
||||||
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
|
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
|
||||||
import org.apache.maven.project.MavenProject;
|
import org.apache.maven.project.MavenProject;
|
||||||
import org.apache.maven.repository.RepositorySystem;
|
import org.apache.maven.repository.RepositorySystem;
|
||||||
import org.teavm.tooling.sources.DirectorySourceFileProvider;
|
import org.teavm.tooling.builder.BuildStrategy;
|
||||||
import org.teavm.tooling.sources.JarSourceFileProvider;
|
|
||||||
import org.teavm.tooling.sources.SourceFileProvider;
|
|
||||||
|
|
||||||
public class MavenSourceFileProviderLookup {
|
public class MavenSourceFileProviderLookup {
|
||||||
private MavenProject mavenProject;
|
private MavenProject mavenProject;
|
||||||
|
@ -57,7 +55,7 @@ public class MavenSourceFileProviderLookup {
|
||||||
this.pluginDependencies = pluginDependencies;
|
this.pluginDependencies = pluginDependencies;
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<SourceFileProvider> resolve() {
|
public void resolve(BuildStrategy builder) {
|
||||||
List<Artifact> initialArtifacts = new ArrayList<>();
|
List<Artifact> initialArtifacts = new ArrayList<>();
|
||||||
initialArtifacts.addAll(mavenProject.getArtifacts());
|
initialArtifacts.addAll(mavenProject.getArtifacts());
|
||||||
if (pluginDependencies != null) {
|
if (pluginDependencies != null) {
|
||||||
|
@ -74,7 +72,6 @@ public class MavenSourceFileProviderLookup {
|
||||||
}
|
}
|
||||||
|
|
||||||
artifacts.addAll(initialArtifacts);
|
artifacts.addAll(initialArtifacts);
|
||||||
List<SourceFileProvider> providers = new ArrayList<>();
|
|
||||||
for (Artifact artifact : artifacts) {
|
for (Artifact artifact : artifacts) {
|
||||||
ArtifactResolutionRequest request = new ArtifactResolutionRequest()
|
ArtifactResolutionRequest request = new ArtifactResolutionRequest()
|
||||||
.setLocalRepository(localRepository)
|
.setLocalRepository(localRepository)
|
||||||
|
@ -85,16 +82,15 @@ public class MavenSourceFileProviderLookup {
|
||||||
if (resolvedArtifact.getFile() != null) {
|
if (resolvedArtifact.getFile() != null) {
|
||||||
File file = resolvedArtifact.getFile();
|
File file = resolvedArtifact.getFile();
|
||||||
if (!file.isDirectory()) {
|
if (!file.isDirectory()) {
|
||||||
providers.add(new JarSourceFileProvider(file));
|
builder.addSourcesJar(file.getAbsolutePath());
|
||||||
} else {
|
} else {
|
||||||
providers.add(new DirectorySourceFileProvider(file));
|
builder.addSourcesDirectory(file.getAbsolutePath());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for (String sourceRoot : mavenProject.getCompileSourceRoots()) {
|
for (String sourceRoot : mavenProject.getCompileSourceRoots()) {
|
||||||
providers.add(new DirectorySourceFileProvider(new File(sourceRoot)));
|
builder.addSourcesDirectory(new File(sourceRoot).getAbsolutePath());
|
||||||
}
|
}
|
||||||
return providers;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,26 +16,88 @@
|
||||||
package org.teavm.maven;
|
package org.teavm.maven;
|
||||||
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Arrays;
|
import java.net.URLClassLoader;
|
||||||
|
import java.rmi.NotBoundException;
|
||||||
|
import java.rmi.RemoteException;
|
||||||
|
import java.rmi.registry.LocateRegistry;
|
||||||
|
import java.rmi.registry.Registry;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Properties;
|
||||||
|
import org.apache.maven.artifact.Artifact;
|
||||||
|
import org.apache.maven.artifact.repository.MavenArtifactRepository;
|
||||||
|
import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
|
||||||
|
import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
|
||||||
|
import org.apache.maven.plugin.AbstractMojo;
|
||||||
import org.apache.maven.plugin.MojoExecutionException;
|
import org.apache.maven.plugin.MojoExecutionException;
|
||||||
import org.apache.maven.plugin.logging.Log;
|
import org.apache.maven.plugin.logging.Log;
|
||||||
|
import org.apache.maven.plugins.annotations.Component;
|
||||||
import org.apache.maven.plugins.annotations.LifecyclePhase;
|
import org.apache.maven.plugins.annotations.LifecyclePhase;
|
||||||
import org.apache.maven.plugins.annotations.Mojo;
|
import org.apache.maven.plugins.annotations.Mojo;
|
||||||
import org.apache.maven.plugins.annotations.Parameter;
|
import org.apache.maven.plugins.annotations.Parameter;
|
||||||
import org.apache.maven.plugins.annotations.ResolutionScope;
|
import org.apache.maven.plugins.annotations.ResolutionScope;
|
||||||
|
import org.apache.maven.project.MavenProject;
|
||||||
|
import org.apache.maven.repository.RepositorySystem;
|
||||||
import org.teavm.backend.wasm.render.WasmBinaryVersion;
|
import org.teavm.backend.wasm.render.WasmBinaryVersion;
|
||||||
|
import org.teavm.tooling.TeaVMProblemRenderer;
|
||||||
import org.teavm.tooling.TeaVMTargetType;
|
import org.teavm.tooling.TeaVMTargetType;
|
||||||
import org.teavm.tooling.TeaVMTool;
|
import org.teavm.tooling.builder.BuildException;
|
||||||
import org.teavm.tooling.TeaVMToolException;
|
import org.teavm.tooling.builder.BuildResult;
|
||||||
import org.teavm.tooling.sources.DirectorySourceFileProvider;
|
import org.teavm.tooling.builder.BuildStrategy;
|
||||||
import org.teavm.tooling.sources.SourceFileProvider;
|
import org.teavm.tooling.builder.InProcessBuildStrategy;
|
||||||
|
import org.teavm.tooling.builder.RemoteBuildStrategy;
|
||||||
|
import org.teavm.tooling.daemon.BuildDaemon;
|
||||||
|
import org.teavm.tooling.daemon.DaemonInfo;
|
||||||
|
import org.teavm.tooling.daemon.DaemonLog;
|
||||||
|
import org.teavm.tooling.daemon.RemoteBuildService;
|
||||||
import org.teavm.vm.TeaVMOptimizationLevel;
|
import org.teavm.vm.TeaVMOptimizationLevel;
|
||||||
|
|
||||||
@Mojo(name = "compile", requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME,
|
@Mojo(name = "compile", requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME,
|
||||||
requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME,
|
requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME,
|
||||||
defaultPhase = LifecyclePhase.PROCESS_CLASSES)
|
defaultPhase = LifecyclePhase.PROCESS_CLASSES)
|
||||||
public class TeaVMCompileMojo extends AbstractTeaVMMojo {
|
public class TeaVMCompileMojo extends AbstractMojo {
|
||||||
|
@Component
|
||||||
|
private MavenProject project;
|
||||||
|
|
||||||
|
@Component
|
||||||
|
private RepositorySystem repositorySystem;
|
||||||
|
|
||||||
|
@Parameter(required = true, readonly = true, defaultValue = "${localRepository}")
|
||||||
|
private MavenArtifactRepository localRepository;
|
||||||
|
|
||||||
|
@Parameter(required = true, readonly = true, defaultValue = "${project.remoteArtifactRepositories}")
|
||||||
|
private List<MavenArtifactRepository> remoteRepositories;
|
||||||
|
|
||||||
|
@Parameter(readonly = true, defaultValue = "${plugin.artifacts}")
|
||||||
|
private List<Artifact> pluginArtifacts;
|
||||||
|
|
||||||
|
@Parameter(defaultValue = "${project.build.outputDirectory}")
|
||||||
|
private File classFiles;
|
||||||
|
|
||||||
|
@Parameter
|
||||||
|
private List<String> compileScopes;
|
||||||
|
|
||||||
|
@Parameter
|
||||||
|
private boolean minifying = true;
|
||||||
|
|
||||||
|
@Parameter
|
||||||
|
private Properties properties;
|
||||||
|
|
||||||
|
@Parameter
|
||||||
|
private boolean debugInformationGenerated;
|
||||||
|
|
||||||
|
@Parameter
|
||||||
|
private boolean sourceMapsGenerated;
|
||||||
|
|
||||||
|
@Parameter
|
||||||
|
private boolean sourceFilesCopied;
|
||||||
|
|
||||||
|
@Parameter
|
||||||
|
private boolean incremental;
|
||||||
|
|
||||||
|
@Parameter
|
||||||
|
private String[] transformers;
|
||||||
|
|
||||||
@Parameter(defaultValue = "${project.build.directory}/javascript")
|
@Parameter(defaultValue = "${project.build.directory}/javascript")
|
||||||
private File targetDirectory;
|
private File targetDirectory;
|
||||||
|
|
||||||
|
@ -61,48 +123,197 @@ public class TeaVMCompileMojo extends AbstractTeaVMMojo {
|
||||||
private TeaVMTargetType targetType = TeaVMTargetType.JAVASCRIPT;
|
private TeaVMTargetType targetType = TeaVMTargetType.JAVASCRIPT;
|
||||||
|
|
||||||
@Parameter(defaultValue = "${project.build.directory}/teavm-cache")
|
@Parameter(defaultValue = "${project.build.directory}/teavm-cache")
|
||||||
protected File cacheDirectory;
|
private File cacheDirectory;
|
||||||
|
|
||||||
private TeaVMTool tool = new TeaVMTool();
|
|
||||||
|
|
||||||
@Parameter
|
@Parameter
|
||||||
private WasmBinaryVersion wasmVersion = WasmBinaryVersion.V_0x1;
|
private WasmBinaryVersion wasmVersion = WasmBinaryVersion.V_0x1;
|
||||||
|
|
||||||
@Override
|
@Parameter(property = "teavm.outOfProcess", defaultValue = "false")
|
||||||
protected File getTargetDirectory() {
|
private boolean outOfProcess;
|
||||||
return targetDirectory;
|
|
||||||
|
@Parameter(property = "teavm.processMemory", defaultValue = "512")
|
||||||
|
private int processMemory;
|
||||||
|
|
||||||
|
private void setupBuilder(BuildStrategy builder) throws MojoExecutionException {
|
||||||
|
builder.setLog(new MavenTeaVMToolLog(getLog()));
|
||||||
|
try {
|
||||||
|
builder.setClassPathEntries(prepareClassPath());
|
||||||
|
builder.setMinifying(minifying);
|
||||||
|
builder.setTargetDirectory(targetDirectory.getAbsolutePath());
|
||||||
|
if (transformers != null) {
|
||||||
|
builder.setTransformers(transformers);
|
||||||
|
}
|
||||||
|
if (sourceFilesCopied) {
|
||||||
|
getSourceFileProviders(builder);
|
||||||
|
builder.addSourcesDirectory(sourceDirectory.getAbsolutePath());
|
||||||
|
}
|
||||||
|
if (properties != null) {
|
||||||
|
builder.setProperties(properties);
|
||||||
|
}
|
||||||
|
builder.setIncremental(incremental);
|
||||||
|
builder.setDebugInformationGenerated(debugInformationGenerated);
|
||||||
|
builder.setSourceMapsFileGenerated(sourceMapsGenerated);
|
||||||
|
builder.setSourceFilesCopied(sourceFilesCopied);
|
||||||
|
} catch (RuntimeException e) {
|
||||||
|
throw new MojoExecutionException("Unexpected error occurred", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> prepareClassPath() {
|
||||||
|
Log log = getLog();
|
||||||
|
log.info("Preparing classpath for JavaScript generation");
|
||||||
|
List<String> paths = new ArrayList<>();
|
||||||
|
StringBuilder classpath = new StringBuilder();
|
||||||
|
for (Artifact artifact : project.getArtifacts()) {
|
||||||
|
if (!filterByScope(artifact)) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
File file = artifact.getFile();
|
||||||
|
if (classpath.length() > 0) {
|
||||||
|
classpath.append(':');
|
||||||
|
}
|
||||||
|
classpath.append(file.getPath());
|
||||||
|
paths.add(file.getAbsolutePath());
|
||||||
|
}
|
||||||
|
if (classpath.length() > 0) {
|
||||||
|
classpath.append(':');
|
||||||
|
}
|
||||||
|
classpath.append(classFiles.getPath());
|
||||||
|
paths.add(classFiles.getAbsolutePath());
|
||||||
|
log.info("Using the following classpath for JavaScript generation: " + classpath);
|
||||||
|
return paths;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean filterByScope(Artifact artifact) {
|
||||||
|
return compileScopes == null ? isSupportedScope(artifact.getScope())
|
||||||
|
: compileScopes.contains(artifact.getScope());
|
||||||
|
}
|
||||||
|
|
||||||
|
protected boolean isSupportedScope(String scope) {
|
||||||
|
switch (scope) {
|
||||||
|
case Artifact.SCOPE_COMPILE:
|
||||||
|
case Artifact.SCOPE_PROVIDED:
|
||||||
|
case Artifact.SCOPE_SYSTEM:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getSourceFileProviders(BuildStrategy builder) {
|
||||||
|
MavenSourceFileProviderLookup lookup = new MavenSourceFileProviderLookup();
|
||||||
|
lookup.setMavenProject(project);
|
||||||
|
lookup.setRepositorySystem(repositorySystem);
|
||||||
|
lookup.setLocalRepository(localRepository);
|
||||||
|
lookup.setRemoteRepositories(remoteRepositories);
|
||||||
|
lookup.setPluginDependencies(pluginArtifacts);
|
||||||
|
lookup.resolve(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void execute() throws MojoExecutionException {
|
public void execute() throws MojoExecutionException {
|
||||||
Log log = getLog();
|
if (outOfProcess) {
|
||||||
setupTool(tool);
|
executeInSeparateProcess();
|
||||||
tool.setLog(new MavenTeaVMToolLog(log));
|
} else {
|
||||||
try {
|
executeWithBuilder(new InProcessBuildStrategy(URLClassLoader::new));
|
||||||
tool.setMainClass(mainClass);
|
|
||||||
if (!targetFileName.isEmpty()) {
|
|
||||||
tool.setTargetFileName(targetFileName);
|
|
||||||
}
|
|
||||||
tool.setOptimizationLevel(optimizationLevel);
|
|
||||||
if (classesToPreserve != null) {
|
|
||||||
tool.getClassesToPreserve().addAll(Arrays.asList(classesToPreserve));
|
|
||||||
}
|
|
||||||
tool.setCacheDirectory(cacheDirectory);
|
|
||||||
tool.setTargetType(targetType);
|
|
||||||
tool.setWasmVersion(wasmVersion);
|
|
||||||
tool.generate();
|
|
||||||
if (stopOnErrors && !tool.getProblemProvider().getSevereProblems().isEmpty()) {
|
|
||||||
throw new MojoExecutionException("Build error");
|
|
||||||
}
|
|
||||||
} catch (RuntimeException e) {
|
|
||||||
throw new MojoExecutionException("Unexpected error occured", e);
|
|
||||||
} catch (TeaVMToolException e) {
|
|
||||||
throw new MojoExecutionException("IO error occured", e);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
private void executeInSeparateProcess() throws MojoExecutionException {
|
||||||
protected void addSourceProviders(List<SourceFileProvider> providers) {
|
DaemonInfo daemon;
|
||||||
providers.add(new DirectorySourceFileProvider(sourceDirectory));
|
try {
|
||||||
|
daemon = BuildDaemon.start(false, processMemory, new DaemonLogImpl(), createDaemonClassPath());
|
||||||
|
} catch (Throwable e) {
|
||||||
|
throw new MojoExecutionException("Error starting TeaVM process", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
RemoteBuildService buildService;
|
||||||
|
try {
|
||||||
|
Registry registry = LocateRegistry.getRegistry(daemon.getPort());
|
||||||
|
buildService = (RemoteBuildService) registry.lookup(RemoteBuildService.ID);
|
||||||
|
} catch (RemoteException | NotBoundException e) {
|
||||||
|
throw new MojoExecutionException("Error connecting TeaVM process", e);
|
||||||
|
}
|
||||||
|
|
||||||
|
RemoteBuildStrategy builder = new RemoteBuildStrategy(buildService);
|
||||||
|
executeWithBuilder(builder);
|
||||||
|
} finally {
|
||||||
|
daemon.getProcess().destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void executeWithBuilder(BuildStrategy builder) throws MojoExecutionException {
|
||||||
|
builder.init();
|
||||||
|
Log log = getLog();
|
||||||
|
setupBuilder(builder);
|
||||||
|
MavenTeaVMToolLog toolLog = new MavenTeaVMToolLog(log);
|
||||||
|
builder.setLog(toolLog);
|
||||||
|
try {
|
||||||
|
builder.setMainClass(mainClass);
|
||||||
|
if (!targetFileName.isEmpty()) {
|
||||||
|
builder.setTargetFileName(targetFileName);
|
||||||
|
}
|
||||||
|
builder.setOptimizationLevel(optimizationLevel);
|
||||||
|
if (classesToPreserve != null) {
|
||||||
|
builder.setClassesToPreserve(classesToPreserve);
|
||||||
|
}
|
||||||
|
builder.setCacheDirectory(cacheDirectory.getAbsolutePath());
|
||||||
|
builder.setTargetType(targetType);
|
||||||
|
builder.setWasmVersion(wasmVersion);
|
||||||
|
BuildResult result;
|
||||||
|
result = builder.build();
|
||||||
|
TeaVMProblemRenderer.describeProblems(result.getCallGraph(), result.getProblems(), toolLog);
|
||||||
|
if (stopOnErrors && !result.getProblems().getSevereProblems().isEmpty()) {
|
||||||
|
throw new MojoExecutionException("Build error");
|
||||||
|
}
|
||||||
|
} catch (BuildException e) {
|
||||||
|
throw new MojoExecutionException("Unexpected error occurred", e.getCause());
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new MojoExecutionException("Unexpected error occurred", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String[] createDaemonClassPath() {
|
||||||
|
Artifact toolArtifact = pluginArtifacts.stream()
|
||||||
|
.filter(artifact -> artifact.getGroupId().equals("org.teavm")
|
||||||
|
&& artifact.getArtifactId().equals("teavm-tooling"))
|
||||||
|
.findFirst()
|
||||||
|
.orElse(null);
|
||||||
|
if (toolArtifact == null) {
|
||||||
|
return new String[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
ArtifactResolutionResult resolutionResult = repositorySystem.resolve(new ArtifactResolutionRequest()
|
||||||
|
.setLocalRepository(localRepository)
|
||||||
|
.setRemoteRepositories(new ArrayList<>(remoteRepositories))
|
||||||
|
.setResolveTransitively(true)
|
||||||
|
.setResolveRoot(true)
|
||||||
|
.setArtifact(toolArtifact));
|
||||||
|
|
||||||
|
if (!resolutionResult.isSuccess()) {
|
||||||
|
return new String[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
return resolutionResult.getArtifacts().stream()
|
||||||
|
.map(artifact -> artifact.getFile().getAbsolutePath())
|
||||||
|
.toArray(String[]::new);
|
||||||
|
}
|
||||||
|
|
||||||
|
class DaemonLogImpl implements DaemonLog {
|
||||||
|
@Override
|
||||||
|
public void error(String message) {
|
||||||
|
getLog().error(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void error(String message, Throwable e) {
|
||||||
|
getLog().error(message, e);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void info(String message) {
|
||||||
|
getLog().info(message);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user