diff --git a/html4j/pom.xml b/html4j/pom.xml index bffacb498..4626c9ea4 100644 --- a/html4j/pom.xml +++ b/html4j/pom.xml @@ -74,12 +74,11 @@ generate-javascript-tests - build-test-javascript + testCompile - process-test-classes false - ${project.build.directory}/javascript-test + ${project.build.directory}/javascript-test true true @@ -87,13 +86,12 @@ generate-javascript-tck - build-test-javascript + testCompile - process-test-classes false true - ${project.build.directory}/javascript-tck + ${project.build.directory}/javascript-tck org.teavm.html4j.testing.KOTestAdapter org.teavm.javascript.NullPointerExceptionTransformer diff --git a/jso/apis/pom.xml b/jso/apis/pom.xml index fe2ced996..4ff751af4 100644 --- a/jso/apis/pom.xml +++ b/jso/apis/pom.xml @@ -21,6 +21,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs org.teavm teavm 0.4.0-SNAPSHOT + ../.. teavm-jso-apis diff --git a/jso/core/pom.xml b/jso/core/pom.xml index 89a011db5..f44fe2475 100644 --- a/jso/core/pom.xml +++ b/jso/core/pom.xml @@ -21,6 +21,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs org.teavm teavm 0.4.0-SNAPSHOT + ../.. teavm-jso diff --git a/jso/impl/pom.xml b/jso/impl/pom.xml index f2c9e9bf3..c596a2929 100644 --- a/jso/impl/pom.xml +++ b/jso/impl/pom.xml @@ -21,6 +21,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xs org.teavm teavm 0.4.0-SNAPSHOT + ../.. teavm-jso-impl diff --git a/pom.xml b/pom.xml index f84f2ee34..21282c232 100644 --- a/pom.xml +++ b/pom.xml @@ -70,6 +70,7 @@ 9.2.1.v20140609 1.7.7 2.47.2 + 2.6.2 @@ -81,6 +82,7 @@ html4j samples platform + tools/core tools/cli tools/maven tools/chrome-rdp @@ -176,6 +178,16 @@ selenium-remote-driver ${selenium.version} + + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} + + + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + diff --git a/samples/async/pom.xml b/samples/async/pom.xml index 001e04006..2ea775d90 100644 --- a/samples/async/pom.xml +++ b/samples/async/pom.xml @@ -57,9 +57,8 @@ web-client - prepare-package - build-javascript + compile ${project.build.directory}/generated/js/teavm diff --git a/samples/benchmark/pom.xml b/samples/benchmark/pom.xml index ed0590921..378ee7c83 100644 --- a/samples/benchmark/pom.xml +++ b/samples/benchmark/pom.xml @@ -111,9 +111,8 @@ web-client - prepare-package - build-javascript + compile ${project.build.directory}/generated/js/teavm diff --git a/samples/hello/pom.xml b/samples/hello/pom.xml index ed8128e63..ff9ea0b65 100644 --- a/samples/hello/pom.xml +++ b/samples/hello/pom.xml @@ -76,9 +76,8 @@ web-client - prepare-package - build-javascript + compile ${project.build.directory}/generated/js/teavm diff --git a/samples/kotlin/pom.xml b/samples/kotlin/pom.xml index f9fcc0606..1af5c380a 100644 --- a/samples/kotlin/pom.xml +++ b/samples/kotlin/pom.xml @@ -92,9 +92,8 @@ web-client - prepare-package - build-javascript + compile ${project.build.directory}/generated/js/teavm diff --git a/samples/pom.xml b/samples/pom.xml index fea836574..60292acad 100644 --- a/samples/pom.xml +++ b/samples/pom.xml @@ -36,6 +36,8 @@ video async kotlin + \ No newline at end of file diff --git a/samples/scala/pom.xml b/samples/scala/pom.xml index e1c2c61a0..f0837e8cc 100644 --- a/samples/scala/pom.xml +++ b/samples/scala/pom.xml @@ -67,9 +67,8 @@ web-client - prepare-package - build-javascript + compile ${project.build.directory}/generated/js/teavm diff --git a/samples/storage/pom.xml b/samples/storage/pom.xml index 70d0cc0bc..3537a4fce 100644 --- a/samples/storage/pom.xml +++ b/samples/storage/pom.xml @@ -78,12 +78,11 @@ web-client prepare-package - build-javascript + compile ${project.build.directory}/generated/js/teavm org.teavm.samples.storage.Application - SEPARATE false true true diff --git a/samples/video/pom.xml b/samples/video/pom.xml index 1f64bc021..77502485e 100644 --- a/samples/video/pom.xml +++ b/samples/video/pom.xml @@ -76,9 +76,8 @@ web-client - prepare-package - build-javascript + compile ${project.build.directory}/generated/js/teavm diff --git a/tests/pom.xml b/tests/pom.xml index 7614f5da9..8518a31dd 100644 --- a/tests/pom.xml +++ b/tests/pom.xml @@ -72,9 +72,8 @@ generate-javascript-tests - build-test-javascript + testCompile - process-test-classes false true diff --git a/tools/cli/pom.xml b/tools/cli/pom.xml index 7d1e838c8..51557637f 100644 --- a/tools/cli/pom.xml +++ b/tools/cli/pom.xml @@ -21,6 +21,7 @@ org.teavm teavm 0.4.0-SNAPSHOT + ../.. teavm-cli @@ -30,7 +31,7 @@ org.teavm - teavm-core + teavm-tooling ${project.version} diff --git a/tools/cli/src/main/java/org/teavm/cli/TeaVMTestRunner.java b/tools/cli/src/main/java/org/teavm/cli/TeaVMTestRunner.java index 32bf89b19..0a2a45328 100644 --- a/tools/cli/src/main/java/org/teavm/cli/TeaVMTestRunner.java +++ b/tools/cli/src/main/java/org/teavm/cli/TeaVMTestRunner.java @@ -19,11 +19,17 @@ import java.io.File; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; import java.util.Arrays; -import org.apache.commons.cli.*; +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.CommandLineParser; +import org.apache.commons.cli.HelpFormatter; +import org.apache.commons.cli.OptionBuilder; +import org.apache.commons.cli.Options; +import org.apache.commons.cli.ParseException; +import org.apache.commons.cli.PosixParser; import org.teavm.model.ClassHolderTransformer; import org.teavm.testing.TestAdapter; -import org.teavm.tooling.TeaVMTestTool; import org.teavm.tooling.TeaVMToolException; +import org.teavm.tooling.testing.TeaVMTestTool; /** * @@ -84,7 +90,7 @@ public final class TeaVMTestRunner { } TeaVMTestTool tool = new TeaVMTestTool(); - tool.setOutputDir(new File(commandLine.getOptionValue("d", "."))); + tool.setTargetDirectory(new File(commandLine.getOptionValue("d", "."))); tool.setMinifying(commandLine.hasOption("m")); try { tool.setNumThreads(Integer.parseInt(commandLine.getOptionValue("t", "1"))); diff --git a/tools/core/pom.xml b/tools/core/pom.xml new file mode 100644 index 000000000..7abaacfc8 --- /dev/null +++ b/tools/core/pom.xml @@ -0,0 +1,64 @@ + + + 4.0.0 + + + org.teavm + teavm + 0.4.0-SNAPSHOT + ../.. + + teavm-tooling + + TeaVM tooling core + TeaVM API that helps to create tooling + + + + org.teavm + teavm-core + ${project.version} + + + com.fasterxml.jackson.core + jackson-annotations + true + + + + + + + org.apache.maven.plugins + maven-checkstyle-plugin + + ../../checkstyle.xml + config_loc=${basedir}/../.. + + + + org.apache.maven.plugins + maven-source-plugin + + + org.apache.maven.plugins + maven-javadoc-plugin + + + + \ No newline at end of file diff --git a/tools/core/src/main/java/org/teavm/tooling/BaseTeaVMTool.java b/tools/core/src/main/java/org/teavm/tooling/BaseTeaVMTool.java new file mode 100644 index 000000000..b279ff85b --- /dev/null +++ b/tools/core/src/main/java/org/teavm/tooling/BaseTeaVMTool.java @@ -0,0 +1,50 @@ +/* + * 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; + +/** + * + * @author Alexey Andreev + */ +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 getTransformers(); + + void setLog(TeaVMToolLog log); + + void setClassLoader(ClassLoader classLoader); + + void addSourceFileProvider(SourceFileProvider sourceFileProvider); +} diff --git a/core/src/main/java/org/teavm/tooling/ClassAlias.java b/tools/core/src/main/java/org/teavm/tooling/ClassAlias.java similarity index 100% rename from core/src/main/java/org/teavm/tooling/ClassAlias.java rename to tools/core/src/main/java/org/teavm/tooling/ClassAlias.java diff --git a/core/src/main/java/org/teavm/tooling/EmptyTeaVMToolLog.java b/tools/core/src/main/java/org/teavm/tooling/EmptyTeaVMToolLog.java similarity index 100% rename from core/src/main/java/org/teavm/tooling/EmptyTeaVMToolLog.java rename to tools/core/src/main/java/org/teavm/tooling/EmptyTeaVMToolLog.java diff --git a/core/src/main/java/org/teavm/tooling/InstructionLocationReader.java b/tools/core/src/main/java/org/teavm/tooling/InstructionLocationReader.java similarity index 100% rename from core/src/main/java/org/teavm/tooling/InstructionLocationReader.java rename to tools/core/src/main/java/org/teavm/tooling/InstructionLocationReader.java diff --git a/core/src/main/java/org/teavm/tooling/MethodAlias.java b/tools/core/src/main/java/org/teavm/tooling/MethodAlias.java similarity index 100% rename from core/src/main/java/org/teavm/tooling/MethodAlias.java rename to tools/core/src/main/java/org/teavm/tooling/MethodAlias.java diff --git a/core/src/main/java/org/teavm/tooling/RuntimeCopyOperation.java b/tools/core/src/main/java/org/teavm/tooling/RuntimeCopyOperation.java similarity index 100% rename from core/src/main/java/org/teavm/tooling/RuntimeCopyOperation.java rename to tools/core/src/main/java/org/teavm/tooling/RuntimeCopyOperation.java diff --git a/core/src/main/java/org/teavm/tooling/TeaVMProblemRenderer.java b/tools/core/src/main/java/org/teavm/tooling/TeaVMProblemRenderer.java similarity index 100% rename from core/src/main/java/org/teavm/tooling/TeaVMProblemRenderer.java rename to tools/core/src/main/java/org/teavm/tooling/TeaVMProblemRenderer.java diff --git a/core/src/main/java/org/teavm/tooling/TeaVMTool.java b/tools/core/src/main/java/org/teavm/tooling/TeaVMTool.java similarity index 98% rename from core/src/main/java/org/teavm/tooling/TeaVMTool.java rename to tools/core/src/main/java/org/teavm/tooling/TeaVMTool.java index ae767fb16..5938e2e83 100644 --- a/core/src/main/java/org/teavm/tooling/TeaVMTool.java +++ b/tools/core/src/main/java/org/teavm/tooling/TeaVMTool.java @@ -29,6 +29,8 @@ import org.teavm.diagnostics.ProblemProvider; import org.teavm.javascript.RenderingContext; import org.teavm.model.*; import org.teavm.parsing.ClasspathClassHolderSource; +import org.teavm.tooling.sources.SourceFileProvider; +import org.teavm.tooling.sources.SourceFilesCopier; import org.teavm.vm.*; import org.teavm.vm.spi.AbstractRendererListener; @@ -36,7 +38,7 @@ import org.teavm.vm.spi.AbstractRendererListener; * * @author Alexey Andreev */ -public class TeaVMTool { +public class TeaVMTool implements BaseTeaVMTool { private File targetDirectory = new File("."); private String targetFileName = "classes.js"; private boolean minifying = true; @@ -69,6 +71,7 @@ public class TeaVMTool { return targetDirectory; } + @Override public void setTargetDirectory(File targetDirectory) { this.targetDirectory = targetDirectory; } @@ -85,6 +88,7 @@ public class TeaVMTool { return minifying; } + @Override public void setMinifying(boolean minifying) { this.minifying = minifying; } @@ -93,6 +97,7 @@ public class TeaVMTool { return incremental; } + @Override public void setIncremental(boolean incremental) { this.incremental = incremental; } @@ -133,6 +138,7 @@ public class TeaVMTool { return debugInformationGenerated; } + @Override public void setDebugInformationGenerated(boolean debugInformationGenerated) { this.debugInformationGenerated = debugInformationGenerated; } @@ -149,6 +155,7 @@ public class TeaVMTool { return sourceMapsFileGenerated; } + @Override public void setSourceMapsFileGenerated(boolean sourceMapsFileGenerated) { this.sourceMapsFileGenerated = sourceMapsFileGenerated; } @@ -157,14 +164,17 @@ public class TeaVMTool { return sourceFilesCopied; } + @Override public void setSourceFilesCopied(boolean sourceFilesCopied) { this.sourceFilesCopied = sourceFilesCopied; } + @Override public Properties getProperties() { return properties; } + @Override public List getTransformers() { return transformers; } @@ -181,6 +191,7 @@ public class TeaVMTool { return log; } + @Override public void setLog(TeaVMToolLog log) { this.log = log; } @@ -189,6 +200,7 @@ public class TeaVMTool { return classLoader; } + @Override public void setClassLoader(ClassLoader classLoader) { this.classLoader = classLoader; } @@ -245,6 +257,7 @@ public class TeaVMTool { return resources; } + @Override public void addSourceFileProvider(SourceFileProvider sourceFileProvider) { sourceFileProviders.add(sourceFileProvider); } diff --git a/core/src/main/java/org/teavm/tooling/TeaVMToolException.java b/tools/core/src/main/java/org/teavm/tooling/TeaVMToolException.java similarity index 100% rename from core/src/main/java/org/teavm/tooling/TeaVMToolException.java rename to tools/core/src/main/java/org/teavm/tooling/TeaVMToolException.java diff --git a/core/src/main/java/org/teavm/tooling/TeaVMToolLog.java b/tools/core/src/main/java/org/teavm/tooling/TeaVMToolLog.java similarity index 100% rename from core/src/main/java/org/teavm/tooling/TeaVMToolLog.java rename to tools/core/src/main/java/org/teavm/tooling/TeaVMToolLog.java diff --git a/core/src/main/java/org/teavm/tooling/DirectorySourceFileProvider.java b/tools/core/src/main/java/org/teavm/tooling/sources/DirectorySourceFileProvider.java similarity index 97% rename from core/src/main/java/org/teavm/tooling/DirectorySourceFileProvider.java rename to tools/core/src/main/java/org/teavm/tooling/sources/DirectorySourceFileProvider.java index 21841bed8..aaf0e2abc 100644 --- a/core/src/main/java/org/teavm/tooling/DirectorySourceFileProvider.java +++ b/tools/core/src/main/java/org/teavm/tooling/sources/DirectorySourceFileProvider.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.tooling; +package org.teavm.tooling.sources; import java.io.File; import java.io.FileInputStream; diff --git a/core/src/main/java/org/teavm/tooling/JarSourceFileProvider.java b/tools/core/src/main/java/org/teavm/tooling/sources/JarSourceFileProvider.java similarity index 98% rename from core/src/main/java/org/teavm/tooling/JarSourceFileProvider.java rename to tools/core/src/main/java/org/teavm/tooling/sources/JarSourceFileProvider.java index 88b747199..07269d76f 100644 --- a/core/src/main/java/org/teavm/tooling/JarSourceFileProvider.java +++ b/tools/core/src/main/java/org/teavm/tooling/sources/JarSourceFileProvider.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.tooling; +package org.teavm.tooling.sources; import java.io.File; import java.io.IOException; diff --git a/core/src/main/java/org/teavm/tooling/ProgramSourceAggregator.java b/tools/core/src/main/java/org/teavm/tooling/sources/ProgramSourceAggregator.java similarity index 99% rename from core/src/main/java/org/teavm/tooling/ProgramSourceAggregator.java rename to tools/core/src/main/java/org/teavm/tooling/sources/ProgramSourceAggregator.java index fd8997642..b9e2170a0 100644 --- a/core/src/main/java/org/teavm/tooling/ProgramSourceAggregator.java +++ b/tools/core/src/main/java/org/teavm/tooling/sources/ProgramSourceAggregator.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.tooling; +package org.teavm.tooling.sources; import java.util.List; import java.util.Set; diff --git a/core/src/main/java/org/teavm/tooling/SourceFileProvider.java b/tools/core/src/main/java/org/teavm/tooling/sources/SourceFileProvider.java similarity index 96% rename from core/src/main/java/org/teavm/tooling/SourceFileProvider.java rename to tools/core/src/main/java/org/teavm/tooling/sources/SourceFileProvider.java index c5567b036..c1dbebd9b 100644 --- a/core/src/main/java/org/teavm/tooling/SourceFileProvider.java +++ b/tools/core/src/main/java/org/teavm/tooling/sources/SourceFileProvider.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.tooling; +package org.teavm.tooling.sources; import java.io.IOException; import java.io.InputStream; diff --git a/core/src/main/java/org/teavm/tooling/SourceFilesCopier.java b/tools/core/src/main/java/org/teavm/tooling/sources/SourceFilesCopier.java similarity index 96% rename from core/src/main/java/org/teavm/tooling/SourceFilesCopier.java rename to tools/core/src/main/java/org/teavm/tooling/sources/SourceFilesCopier.java index f400c20bf..746f38bdf 100644 --- a/core/src/main/java/org/teavm/tooling/SourceFilesCopier.java +++ b/tools/core/src/main/java/org/teavm/tooling/sources/SourceFilesCopier.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.tooling; +package org.teavm.tooling.sources; import java.io.*; import java.util.HashSet; @@ -23,6 +23,8 @@ import org.apache.commons.io.IOUtils; import org.teavm.model.ClassReader; import org.teavm.model.ListableClassReaderSource; import org.teavm.model.MethodReader; +import org.teavm.tooling.EmptyTeaVMToolLog; +import org.teavm.tooling.TeaVMToolLog; /** * diff --git a/core/src/main/java/org/teavm/tooling/ExceptionHelper.java b/tools/core/src/main/java/org/teavm/tooling/testing/ExceptionHelper.java similarity index 95% rename from core/src/main/java/org/teavm/tooling/ExceptionHelper.java rename to tools/core/src/main/java/org/teavm/tooling/testing/ExceptionHelper.java index ac53214c3..1977a6c7b 100644 --- a/core/src/main/java/org/teavm/tooling/ExceptionHelper.java +++ b/tools/core/src/main/java/org/teavm/tooling/testing/ExceptionHelper.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.tooling; +package org.teavm.tooling.testing; /** * diff --git a/core/src/main/java/org/teavm/tooling/TeaVMTestTool.java b/tools/core/src/main/java/org/teavm/tooling/testing/TeaVMTestTool.java similarity index 83% rename from core/src/main/java/org/teavm/tooling/TeaVMTestTool.java rename to tools/core/src/main/java/org/teavm/tooling/testing/TeaVMTestTool.java index 2a73c839d..9f0903ddd 100644 --- a/core/src/main/java/org/teavm/tooling/TeaVMTestTool.java +++ b/tools/core/src/main/java/org/teavm/tooling/testing/TeaVMTestTool.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.tooling; +package org.teavm.tooling.testing; import java.io.File; import java.io.FileOutputStream; @@ -25,6 +25,7 @@ import java.io.Writer; import java.util.ArrayList; import java.util.List; import java.util.Properties; +import java.util.concurrent.atomic.AtomicInteger; import org.apache.commons.io.IOUtils; import org.teavm.common.FiniteExecutor; import org.teavm.common.SimpleFiniteExecutor; @@ -47,6 +48,13 @@ import org.teavm.model.ValueType; import org.teavm.parsing.ClasspathClassHolderSource; import org.teavm.testing.JUnitTestAdapter; import org.teavm.testing.TestAdapter; +import org.teavm.tooling.BaseTeaVMTool; +import org.teavm.tooling.EmptyTeaVMToolLog; +import org.teavm.tooling.TeaVMProblemRenderer; +import org.teavm.tooling.TeaVMToolException; +import org.teavm.tooling.TeaVMToolLog; +import org.teavm.tooling.sources.SourceFileProvider; +import org.teavm.tooling.sources.SourceFilesCopier; import org.teavm.vm.DirectoryBuildTarget; import org.teavm.vm.TeaVM; import org.teavm.vm.TeaVMBuilder; @@ -55,7 +63,7 @@ import org.teavm.vm.TeaVMBuilder; * * @author Alexey Andreev */ -public class TeaVMTestTool { +public class TeaVMTestTool implements BaseTeaVMTool { private File outputDir = new File("."); private boolean minifying = true; private int numThreads = 1; @@ -68,22 +76,25 @@ public class TeaVMTestTool { private ClassLoader classLoader = TeaVMTestTool.class.getClassLoader(); private TeaVMToolLog log = new EmptyTeaVMToolLog(); private boolean debugInformationGenerated; - private boolean sourceMapsGenerated; + private boolean sourceMapsFileGenerated; private boolean sourceFilesCopied; private boolean incremental; private List sourceFileProviders = new ArrayList<>(); private MethodNodeCache astCache; private ProgramCache programCache; private SourceFilesCopier sourceFilesCopier; - private List listeners = new ArrayList<>(); - private List testPlan = new ArrayList<>(); + private List testPlan = new ArrayList<>(); private int fileIndexGenerator; + private long startTime; + private int testCount; + private AtomicInteger testsBuilt = new AtomicInteger(); public File getOutputDir() { return outputDir; } - public void setOutputDir(File outputDir) { + @Override + public void setTargetDirectory(File outputDir) { this.outputDir = outputDir; } @@ -91,6 +102,7 @@ public class TeaVMTestTool { return minifying; } + @Override public void setMinifying(boolean minifying) { this.minifying = minifying; } @@ -111,6 +123,7 @@ public class TeaVMTestTool { this.adapter = adapter; } + @Override public List getTransformers() { return transformers; } @@ -119,6 +132,7 @@ public class TeaVMTestTool { return additionalScripts; } + @Override public Properties getProperties() { return properties; } @@ -131,6 +145,7 @@ public class TeaVMTestTool { return classLoader; } + @Override public void setClassLoader(ClassLoader classLoader) { this.classLoader = classLoader; } @@ -139,6 +154,7 @@ public class TeaVMTestTool { return log; } + @Override public void setLog(TeaVMToolLog log) { this.log = log; } @@ -147,6 +163,7 @@ public class TeaVMTestTool { return incremental; } + @Override public void setIncremental(boolean incremental) { this.incremental = incremental; } @@ -155,31 +172,36 @@ public class TeaVMTestTool { return debugInformationGenerated; } + @Override public void setDebugInformationGenerated(boolean debugInformationGenerated) { this.debugInformationGenerated = debugInformationGenerated; } - public boolean isSourceMapsGenerated() { - return sourceMapsGenerated; + public boolean isSourceMapsFileGenerated() { + return sourceMapsFileGenerated; } - public void setSourceMapsGenerated(boolean sourceMapsGenerated) { - this.sourceMapsGenerated = sourceMapsGenerated; + @Override + public void setSourceMapsFileGenerated(boolean sourceMapsFileGenerated) { + this.sourceMapsFileGenerated = sourceMapsFileGenerated; } public boolean isSourceFilesCopied() { return sourceFilesCopied; } + @Override public void setSourceFilesCopied(boolean sourceFilesCopied) { this.sourceFilesCopied = sourceFilesCopied; } + @Override public void addSourceFileProvider(SourceFileProvider sourceFileProvider) { sourceFileProviders.add(sourceFileProvider); } - public void generate() throws TeaVMToolException { + public TestPlan generate() throws TeaVMToolException { + testsBuilt.set(0); Runnable finalizer = null; try { new File(outputDir, "tests").mkdirs(); @@ -201,12 +223,17 @@ public class TeaVMTestTool { if (incremental) { classSource = new PreOptimizingClassHolderSource(classSource); } + + List groups = new ArrayList<>(); for (String testClass : testClasses) { ClassHolder classHolder = classSource.get(testClass); if (classHolder == null) { throw new TeaVMToolException("Could not find class " + testClass); } - findTests(classHolder); + TestGroup group = findTests(classHolder); + if (group != null) { + groups.add(group); + } } includeAdditionalScripts(classLoader); @@ -220,16 +247,21 @@ public class TeaVMTestTool { FiniteExecutor executor = new SimpleFiniteExecutor(); if (numThreads != 1) { int threads = numThreads != 0 ? numThreads : Runtime.getRuntime().availableProcessors(); - final ThreadPoolFiniteExecutor threadedExecutor = new ThreadPoolFiniteExecutor(threads); + ThreadPoolFiniteExecutor threadedExecutor = new ThreadPoolFiniteExecutor(threads); finalizer = () -> threadedExecutor.stop(); executor = threadedExecutor; } + startTime = System.currentTimeMillis(); int methodsGenerated = writeMethods(executor, classSource); if (sourceFilesCopied) { sourceFilesCopier.copy(new File(new File(outputDir, "tests"), "src")); } - log.info("Test files successfully generated for " + methodsGenerated + " method(s)."); + long timeSpent = System.currentTimeMillis() - startTime; + log.info("Test files successfully generated for " + methodsGenerated + " method(s) in " + + (timeSpent / 1000.0) + " seconds."); + + return new TestPlan("res/runtime.js", groups); } catch (IOException e) { throw new TeaVMToolException("IO error occured generating JavaScript files", e); } finally { @@ -245,7 +277,7 @@ public class TeaVMTestTool { allTestsWriter.write("prepare = function() {\n"); allTestsWriter.write(" return new JUnitServer(document.body).readTests(["); boolean first = true; - for (TeaVMTestClass testClass : testPlan) { + for (TestClassBuilder testClass : testPlan) { if (!first) { allTestsWriter.append(","); } @@ -253,7 +285,7 @@ public class TeaVMTestTool { allTestsWriter.append("\n { name : \"").append(testClass.getClassName()) .append("\", methods : ["); boolean firstMethod = true; - for (TeaVMTestMethod testMethod : testClass.getMethods()) { + for (TestMethodBuilder testMethod : testClass.getMethods()) { String scriptName = testMethod.getFileName(); if (!firstMethod) { allTestsWriter.append(","); @@ -289,13 +321,12 @@ public class TeaVMTestTool { log.info("Generating test files"); sourceFilesCopier = new SourceFilesCopier(sourceFileProviders); sourceFilesCopier.setLog(log); - for (TeaVMTestClass testClass : testPlan) { - for (TeaVMTestMethod testMethod : testClass.getMethods()) { - final ClassHolderSource builderClassSource = classSource; + for (TestClassBuilder testClass : testPlan) { + for (TestMethodBuilder testMethod : testClass.getMethods()) { executor.execute(() -> { log.debug("Building test for " + testMethod.getMethod()); try { - decompileClassesForTest(classLoader, new CopyClassHolderSource(builderClassSource), + decompileClassesForTest(classLoader, new CopyClassHolderSource(classSource), testMethod); } catch (IOException e) { log.error("Error generating JavaScript", e); @@ -316,8 +347,9 @@ public class TeaVMTestTool { } } - private void findTests(ClassHolder cls) { - TeaVMTestClass testClass = new TeaVMTestClass(cls.getName()); + private TestGroup findTests(ClassHolder cls) { + List cases = new ArrayList<>(); + TestClassBuilder testClass = new TestClassBuilder(cls.getName()); for (MethodHolder method : cls.getMethods()) { if (adapter.acceptMethod(method)) { MethodReference ref = new MethodReference(cls.getName(), method.getDescriptor()); @@ -328,12 +360,19 @@ public class TeaVMTestTool { exceptions.add(exception); } - TeaVMTestMethod testMethod = new TeaVMTestMethod(ref, fileName, exceptions); + TestMethodBuilder testMethod = new TestMethodBuilder(ref, fileName, exceptions); testClass.getMethods().add(testMethod); + + String debugTable = debugInformationGenerated ? testMethod.getFileName() + ".teavmdbg" : null; + cases.add(new TestCase(ref, testMethod.getFileName(), debugTable, testMethod.getExpectedExceptions())); + ++testCount; } } if (!testClass.getMethods().isEmpty()) { testPlan.add(testClass); + return new TestGroup(cls.getName(), cases); + } else { + return null; } } @@ -362,7 +401,7 @@ public class TeaVMTestTool { } private void decompileClassesForTest(ClassLoader classLoader, ClassHolderSource classSource, - TeaVMTestMethod testMethod) throws IOException { + TestMethodBuilder testMethod) throws IOException { String targetName = testMethod.getFileName(); TeaVM vm = new TeaVMBuilder() .setClassLoader(classLoader) @@ -380,7 +419,7 @@ public class TeaVMTestTool { } File file = new File(outputDir, testMethod.getFileName()); - DebugInformationBuilder debugInfoBuilder = sourceMapsGenerated || debugInformationGenerated + DebugInformationBuilder debugInfoBuilder = sourceMapsFileGenerated || debugInformationGenerated ? new DebugInformationBuilder() : null; MethodReference methodRef = testMethod.getMethod(); try (Writer innerWriter = new OutputStreamWriter(new FileOutputStream(file), "UTF-8")) { @@ -395,7 +434,7 @@ public class TeaVMTestTool { vm.build(innerWriter, new DirectoryBuildTarget(outputDir)); innerWriter.append("\n"); innerWriter.append("\nJUnitClient.run();"); - if (sourceMapsGenerated) { + if (sourceMapsFileGenerated) { String sourceMapsFileName = targetName.substring(targetName.lastIndexOf('/') + 1) + ".map"; innerWriter.append("\n//# sourceMappingURL=").append(sourceMapsFileName); } @@ -410,16 +449,15 @@ public class TeaVMTestTool { } } - File debugTableFile = null; if (debugInformationGenerated) { DebugInformation debugInfo = debugInfoBuilder.getDebugInformation(); - debugTableFile = new File(outputDir, targetName + ".teavmdbg"); + File debugTableFile = new File(outputDir, targetName + ".teavmdbg"); try (OutputStream debugInfoOut = new FileOutputStream(debugTableFile)) { debugInfo.write(debugInfoOut); } } - if (sourceMapsGenerated) { + if (sourceMapsFileGenerated) { DebugInformation debugInfo = debugInfoBuilder.getDebugInformation(); String sourceMapsFileName = targetName + ".map"; try (Writer sourceMapsOut = new OutputStreamWriter(new FileOutputStream( @@ -431,11 +469,19 @@ public class TeaVMTestTool { sourceFilesCopier.addClasses(vm.getWrittenClasses()); } - TeaVMTestCase testCase = new TeaVMTestCase(methodRef, new File(outputDir, "res/runtime.js"), - file, debugTableFile, testMethod.getExpectedExceptions()); - for (TeaVMTestToolListener listener : listeners) { - listener.testGenerated(testCase); + incrementCounter(); + } + + private void incrementCounter() { + int count = testsBuilt.incrementAndGet(); + if (count % 10 != 0) { + return; } + + long timeSpent = System.currentTimeMillis() - startTime; + + getLog().info(count + " of " + testCount + " tests built in " + (timeSpent / 1000.0) + " seconds (" + + String.format("%.2f", (double) count / timeSpent * 1000.0) + " tests per second avg.)"); } private void escapeString(String string, Writer writer) throws IOException { @@ -465,12 +511,4 @@ public class TeaVMTestTool { } writer.append('\"'); } - - public void addListener(TeaVMTestToolListener listener) { - listeners.add(listener); - } - - public void removeListener(TeaVMTestToolListener listener) { - listeners.remove(listener); - } } diff --git a/core/src/main/java/org/teavm/tooling/TeaVMTestToolListener.java b/tools/core/src/main/java/org/teavm/tooling/testing/TeaVMTestToolListener.java similarity index 89% rename from core/src/main/java/org/teavm/tooling/TeaVMTestToolListener.java rename to tools/core/src/main/java/org/teavm/tooling/testing/TeaVMTestToolListener.java index 68f87a267..4460b2575 100644 --- a/core/src/main/java/org/teavm/tooling/TeaVMTestToolListener.java +++ b/tools/core/src/main/java/org/teavm/tooling/testing/TeaVMTestToolListener.java @@ -13,12 +13,13 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.tooling; +package org.teavm.tooling.testing; + /** * * @author Alexey Andreev */ public interface TeaVMTestToolListener { - void testGenerated(TeaVMTestCase testCase); + void testGenerated(TestCase testCase); } diff --git a/core/src/main/java/org/teavm/tooling/TeaVMTestCase.java b/tools/core/src/main/java/org/teavm/tooling/testing/TestCase.java similarity index 64% rename from core/src/main/java/org/teavm/tooling/TeaVMTestCase.java rename to tools/core/src/main/java/org/teavm/tooling/testing/TestCase.java index 98ec0ffea..a534649b4 100644 --- a/core/src/main/java/org/teavm/tooling/TeaVMTestCase.java +++ b/tools/core/src/main/java/org/teavm/tooling/testing/TestCase.java @@ -13,9 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.tooling; +package org.teavm.tooling.testing; -import java.io.File; +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonGetter; +import com.fasterxml.jackson.annotation.JsonProperty; import java.util.ArrayList; import java.util.Collections; import java.util.List; @@ -25,38 +27,40 @@ import org.teavm.model.MethodReference; * * @author Alexey Andreev */ -public class TeaVMTestCase { +public class TestCase { private MethodReference testMethod; - private File runtimeScript; - private File testScript; - private File debugTable; + private String testScript; + private String debugTable; private List expectedExceptions = new ArrayList<>(); - public TeaVMTestCase(MethodReference testMethod, File runtimeScript, File testScript, File debugTable, - List expectedExceptions) { + @JsonCreator + public TestCase( + @JsonProperty("testMethod") MethodReference testMethod, + @JsonProperty("script") String testScript, + @JsonProperty("debugTable") String debugTable, + @JsonProperty("expectedExceptions") List expectedExceptions) { this.testMethod = testMethod; - this.runtimeScript = runtimeScript; this.testScript = testScript; this.debugTable = debugTable; this.expectedExceptions = Collections.unmodifiableList(new ArrayList<>(expectedExceptions)); } + @JsonGetter public MethodReference getTestMethod() { return testMethod; } - public File getRuntimeScript() { - return runtimeScript; - } - - public File getTestScript() { + @JsonGetter("script") + public String getTestScript() { return testScript; } - public File getDebugTable() { + @JsonGetter + public String getDebugTable() { return debugTable; } + @JsonGetter public List getExpectedExceptions() { return expectedExceptions; } diff --git a/core/src/main/java/org/teavm/tooling/TeaVMTestClass.java b/tools/core/src/main/java/org/teavm/tooling/testing/TestClassBuilder.java similarity index 77% rename from core/src/main/java/org/teavm/tooling/TeaVMTestClass.java rename to tools/core/src/main/java/org/teavm/tooling/testing/TestClassBuilder.java index b69d59126..d50e2b264 100644 --- a/core/src/main/java/org/teavm/tooling/TeaVMTestClass.java +++ b/tools/core/src/main/java/org/teavm/tooling/testing/TestClassBuilder.java @@ -13,19 +13,20 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.tooling; +package org.teavm.tooling.testing; +import java.util.ArrayList; import java.util.List; /** * * @author Alexey Andreev */ -class TeaVMTestClass { +class TestClassBuilder { private String className; - private List methods; + private List methods = new ArrayList<>(); - public TeaVMTestClass(String className) { + public TestClassBuilder(String className) { this.className = className; } @@ -33,7 +34,7 @@ class TeaVMTestClass { return className; } - public List getMethods() { + public List getMethods() { return methods; } } diff --git a/core/src/main/java/org/teavm/tooling/TestExceptionDependency.java b/tools/core/src/main/java/org/teavm/tooling/testing/TestExceptionDependency.java similarity index 98% rename from core/src/main/java/org/teavm/tooling/TestExceptionDependency.java rename to tools/core/src/main/java/org/teavm/tooling/testing/TestExceptionDependency.java index 9fa8acd60..e388e80f6 100644 --- a/core/src/main/java/org/teavm/tooling/TestExceptionDependency.java +++ b/tools/core/src/main/java/org/teavm/tooling/testing/TestExceptionDependency.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.tooling; +package org.teavm.tooling.testing; import org.teavm.dependency.AbstractDependencyListener; import org.teavm.dependency.DependencyAgent; diff --git a/core/src/main/java/org/teavm/tooling/TestExceptionPlugin.java b/tools/core/src/main/java/org/teavm/tooling/testing/TestExceptionPlugin.java similarity index 96% rename from core/src/main/java/org/teavm/tooling/TestExceptionPlugin.java rename to tools/core/src/main/java/org/teavm/tooling/testing/TestExceptionPlugin.java index 2ec7136c6..19a2c04a1 100644 --- a/core/src/main/java/org/teavm/tooling/TestExceptionPlugin.java +++ b/tools/core/src/main/java/org/teavm/tooling/testing/TestExceptionPlugin.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.tooling; +package org.teavm.tooling.testing; import org.teavm.vm.spi.TeaVMHost; import org.teavm.vm.spi.TeaVMPlugin; diff --git a/tools/core/src/main/java/org/teavm/tooling/testing/TestGroup.java b/tools/core/src/main/java/org/teavm/tooling/testing/TestGroup.java new file mode 100644 index 000000000..4ab9d5cbb --- /dev/null +++ b/tools/core/src/main/java/org/teavm/tooling/testing/TestGroup.java @@ -0,0 +1,49 @@ +/* + * 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.testing; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonGetter; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * + * @author Alexey Andreev + */ +public class TestGroup { + private String className; + private List testCases; + + @JsonCreator + public TestGroup(@JsonProperty("className") String className, + @JsonProperty("testCases") List testCases) { + this.className = className; + this.testCases = Collections.unmodifiableList(new ArrayList<>(testCases)); + } + + @JsonGetter("className") + public String getClassName() { + return className; + } + + @JsonGetter("testCases") + public List getTestCases() { + return testCases; + } +} diff --git a/core/src/main/java/org/teavm/tooling/TeaVMTestMethod.java b/tools/core/src/main/java/org/teavm/tooling/testing/TestMethodBuilder.java similarity index 88% rename from core/src/main/java/org/teavm/tooling/TeaVMTestMethod.java rename to tools/core/src/main/java/org/teavm/tooling/testing/TestMethodBuilder.java index a4adb7f39..3faa384d7 100644 --- a/core/src/main/java/org/teavm/tooling/TeaVMTestMethod.java +++ b/tools/core/src/main/java/org/teavm/tooling/testing/TestMethodBuilder.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package org.teavm.tooling; +package org.teavm.tooling.testing; import java.util.ArrayList; import java.util.Collections; @@ -24,12 +24,12 @@ import org.teavm.model.MethodReference; * * @author Alexey Andreev */ -class TeaVMTestMethod { +class TestMethodBuilder { private MethodReference method; private String fileName; private List expectedExceptions = new ArrayList<>(); - public TeaVMTestMethod(MethodReference method, String fileName, List expectedExceptions) { + public TestMethodBuilder(MethodReference method, String fileName, List expectedExceptions) { this.method = method; this.fileName = fileName; this.expectedExceptions = Collections.unmodifiableList(new ArrayList<>(expectedExceptions)); diff --git a/tools/core/src/main/java/org/teavm/tooling/testing/TestPlan.java b/tools/core/src/main/java/org/teavm/tooling/testing/TestPlan.java new file mode 100644 index 000000000..e5eefd289 --- /dev/null +++ b/tools/core/src/main/java/org/teavm/tooling/testing/TestPlan.java @@ -0,0 +1,47 @@ +/* + * 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.testing; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * + * @author Alexey Andreev + */ +public class TestPlan { + private String runtimeScript; + private List groups = new ArrayList<>(); + + @JsonCreator + public TestPlan( + @JsonProperty("runtimeScript") String runtimeScript, + @JsonProperty("groupList") List groups) { + this.runtimeScript = runtimeScript; + this.groups = Collections.unmodifiableList(new ArrayList<>(groups)); + } + + public String getRuntimeScript() { + return runtimeScript; + } + + public List getGroups() { + return groups; + } +} diff --git a/core/src/main/resources/org/teavm/tooling/main.html b/tools/core/src/main/resources/org/teavm/tooling/main.html similarity index 100% rename from core/src/main/resources/org/teavm/tooling/main.html rename to tools/core/src/main/resources/org/teavm/tooling/main.html diff --git a/core/src/main/resources/org/teavm/tooling/test/junit.html b/tools/core/src/main/resources/org/teavm/tooling/test/junit.html similarity index 100% rename from core/src/main/resources/org/teavm/tooling/test/junit.html rename to tools/core/src/main/resources/org/teavm/tooling/test/junit.html diff --git a/core/src/main/resources/org/teavm/tooling/test/res/class_obj.png b/tools/core/src/main/resources/org/teavm/tooling/test/res/class_obj.png similarity index 100% rename from core/src/main/resources/org/teavm/tooling/test/res/class_obj.png rename to tools/core/src/main/resources/org/teavm/tooling/test/res/class_obj.png diff --git a/core/src/main/resources/org/teavm/tooling/test/res/control-000-small.png b/tools/core/src/main/resources/org/teavm/tooling/test/res/control-000-small.png similarity index 100% rename from core/src/main/resources/org/teavm/tooling/test/res/control-000-small.png rename to tools/core/src/main/resources/org/teavm/tooling/test/res/control-000-small.png diff --git a/core/src/main/resources/org/teavm/tooling/test/res/junit-support.js b/tools/core/src/main/resources/org/teavm/tooling/test/res/junit-support.js similarity index 100% rename from core/src/main/resources/org/teavm/tooling/test/res/junit-support.js rename to tools/core/src/main/resources/org/teavm/tooling/test/res/junit-support.js diff --git a/core/src/main/resources/org/teavm/tooling/test/res/junit.css b/tools/core/src/main/resources/org/teavm/tooling/test/res/junit.css similarity index 100% rename from core/src/main/resources/org/teavm/tooling/test/res/junit.css rename to tools/core/src/main/resources/org/teavm/tooling/test/res/junit.css diff --git a/core/src/main/resources/org/teavm/tooling/test/res/methpub_obj.png b/tools/core/src/main/resources/org/teavm/tooling/test/res/methpub_obj.png similarity index 100% rename from core/src/main/resources/org/teavm/tooling/test/res/methpub_obj.png rename to tools/core/src/main/resources/org/teavm/tooling/test/res/methpub_obj.png diff --git a/core/src/main/resources/org/teavm/tooling/test/res/package_obj.png b/tools/core/src/main/resources/org/teavm/tooling/test/res/package_obj.png similarity index 100% rename from core/src/main/resources/org/teavm/tooling/test/res/package_obj.png rename to tools/core/src/main/resources/org/teavm/tooling/test/res/package_obj.png diff --git a/core/src/main/resources/org/teavm/tooling/test/res/tick-small-red.png b/tools/core/src/main/resources/org/teavm/tooling/test/res/tick-small-red.png similarity index 100% rename from core/src/main/resources/org/teavm/tooling/test/res/tick-small-red.png rename to tools/core/src/main/resources/org/teavm/tooling/test/res/tick-small-red.png diff --git a/core/src/main/resources/org/teavm/tooling/test/res/tick-small.png b/tools/core/src/main/resources/org/teavm/tooling/test/res/tick-small.png similarity index 100% rename from core/src/main/resources/org/teavm/tooling/test/res/tick-small.png rename to tools/core/src/main/resources/org/teavm/tooling/test/res/tick-small.png diff --git a/core/src/main/resources/org/teavm/tooling/test/res/toggle-small-expand.png b/tools/core/src/main/resources/org/teavm/tooling/test/res/toggle-small-expand.png similarity index 100% rename from core/src/main/resources/org/teavm/tooling/test/res/toggle-small-expand.png rename to tools/core/src/main/resources/org/teavm/tooling/test/res/toggle-small-expand.png diff --git a/core/src/main/resources/org/teavm/tooling/test/res/toggle-small.png b/tools/core/src/main/resources/org/teavm/tooling/test/res/toggle-small.png similarity index 100% rename from core/src/main/resources/org/teavm/tooling/test/res/toggle-small.png rename to tools/core/src/main/resources/org/teavm/tooling/test/res/toggle-small.png diff --git a/tools/eclipse/core-plugin/META-INF/MANIFEST.MF b/tools/eclipse/core-plugin/META-INF/MANIFEST.MF index 52513c7cb..a0133cc02 100644 --- a/tools/eclipse/core-plugin/META-INF/MANIFEST.MF +++ b/tools/eclipse/core-plugin/META-INF/MANIFEST.MF @@ -39,6 +39,7 @@ Bundle-ClassPath: ., lib/slf4j-api-1.7.7.jar, lib/teavm-chrome-rdp-0.4.0-SNAPSHOT.jar, lib/teavm-core-0.4.0-SNAPSHOT.jar, + lib/teavm-tooling-0.4.0-SNAPSHOT.jar, lib/websocket-api-9.2.1.v20140609.jar, lib/websocket-client-9.2.1.v20140609.jar, lib/websocket-common-9.2.1.v20140609.jar, diff --git a/tools/eclipse/core-plugin/build.properties b/tools/eclipse/core-plugin/build.properties index ea8d50c54..95269dd03 100644 --- a/tools/eclipse/core-plugin/build.properties +++ b/tools/eclipse/core-plugin/build.properties @@ -36,6 +36,7 @@ bin.includes = META-INF/,\ lib/slf4j-api-1.7.7.jar,\ lib/teavm-chrome-rdp-0.4.0-SNAPSHOT.jar,\ lib/teavm-core-0.4.0-SNAPSHOT.jar,\ + lib/teavm-tooling-0.4.0-SNAPSHOT.jar,\ lib/websocket-api-9.2.1.v20140609.jar,\ lib/websocket-client-9.2.1.v20140609.jar,\ lib/websocket-common-9.2.1.v20140609.jar,\ diff --git a/tools/eclipse/core-plugin/dep-pom.xml b/tools/eclipse/core-plugin/dep-pom.xml index 41fe15f28..52dd1023d 100644 --- a/tools/eclipse/core-plugin/dep-pom.xml +++ b/tools/eclipse/core-plugin/dep-pom.xml @@ -79,6 +79,11 @@ teavm-core ${project.version} + + org.teavm + teavm-tooling + ${project.version} + org.teavm teavm-chrome-rdp diff --git a/tools/eclipse/pom.xml b/tools/eclipse/pom.xml index 9d5cccf51..024fdcba6 100644 --- a/tools/eclipse/pom.xml +++ b/tools/eclipse/pom.xml @@ -21,6 +21,7 @@ org.teavm teavm 0.4.0-SNAPSHOT + ../.. teavm-eclipse pom diff --git a/tools/maven/plugin/pom.xml b/tools/maven/plugin/pom.xml index 24c18e8b2..34fe8454c 100644 --- a/tools/maven/plugin/pom.xml +++ b/tools/maven/plugin/pom.xml @@ -50,7 +50,7 @@ org.teavm - teavm-core + teavm-tooling ${project.version} @@ -68,7 +68,6 @@ com.fasterxml.jackson.core jackson-databind - 2.6.2 junit diff --git a/tools/maven/plugin/src/main/java/org/teavm/maven/AbstractJavascriptMojo.java b/tools/maven/plugin/src/main/java/org/teavm/maven/AbstractJavascriptMojo.java new file mode 100644 index 000000000..6446e3441 --- /dev/null +++ b/tools/maven/plugin/src/main/java/org/teavm/maven/AbstractJavascriptMojo.java @@ -0,0 +1,219 @@ +/* + * 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; + +/** + * + * @author Alexey Andreev + */ +public abstract class AbstractJavascriptMojo 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 remoteRepositories; + + @Parameter(readonly = true, defaultValue = "${plugin.artifacts}") + protected List pluginArtifacts; + + @Parameter(defaultValue = "${project.build.outputDirectory}") + protected File classFiles; + + @Parameter + protected List compileScopes; + + @Parameter + protected boolean minifying = true; + + @Parameter + protected String mainClass; + + @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 instantiateTransformers(ClassLoader classLoader) + throws MojoExecutionException { + List 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 transformerType = transformerRawType.asSubclass( + ClassHolderTransformer.class); + Constructor 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 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()]), + AbstractJavascriptMojo.class.getClassLoader()); + return classLoader; + } catch (MalformedURLException e) { + throw new MojoExecutionException("Error gathering classpath information", e); + } + } + + protected List 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 getSourceFileProviders() { + MavenSourceFileProviderLookup lookup = new MavenSourceFileProviderLookup(); + lookup.setMavenProject(project); + lookup.setRepositorySystem(repositorySystem); + lookup.setLocalRepository(localRepository); + lookup.setRemoteRepositories(remoteRepositories); + lookup.setPluginDependencies(pluginArtifacts); + return lookup.resolve(); + } +} diff --git a/tools/maven/plugin/src/main/java/org/teavm/maven/BuildJavascriptMojo.java b/tools/maven/plugin/src/main/java/org/teavm/maven/BuildJavascriptMojo.java index 42c47edbf..511dd0cb1 100644 --- a/tools/maven/plugin/src/main/java/org/teavm/maven/BuildJavascriptMojo.java +++ b/tools/maven/plugin/src/main/java/org/teavm/maven/BuildJavascriptMojo.java @@ -16,33 +16,16 @@ 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.Arrays; -import java.util.HashSet; -import java.util.List; -import java.util.Properties; -import java.util.Set; -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.LifecyclePhase; import org.apache.maven.plugins.annotations.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; -import org.apache.maven.project.MavenProject; -import org.apache.maven.repository.RepositorySystem; -import org.teavm.model.ClassHolderTransformer; import org.teavm.tooling.ClassAlias; import org.teavm.tooling.MethodAlias; import org.teavm.tooling.RuntimeCopyOperation; -import org.teavm.tooling.SourceFileProvider; import org.teavm.tooling.TeaVMTool; import org.teavm.tooling.TeaVMToolException; @@ -50,72 +33,25 @@ import org.teavm.tooling.TeaVMToolException; * * @author Alexey Andreev */ -@Mojo(name = "build-javascript", requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, - requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME) -public class BuildJavascriptMojo 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 remoteRepositories; - - @Parameter(readonly = true, defaultValue = "${plugin.artifacts}") - private List pluginArtifacts; - +@Mojo(name = "compile", requiresDependencyResolution = ResolutionScope.COMPILE_PLUS_RUNTIME, + requiresDependencyCollection = ResolutionScope.COMPILE_PLUS_RUNTIME, + defaultPhase = LifecyclePhase.PROCESS_CLASSES) +public class BuildJavascriptMojo extends AbstractJavascriptMojo { @Parameter(defaultValue = "${project.build.directory}/javascript") private File targetDirectory; - @Parameter(defaultValue = "${project.build.outputDirectory}") - private File classFiles; - - @Parameter - private List compileScopes; - @Parameter private String targetFileName = "classes.js"; - @Parameter - private boolean minifying = true; - @Parameter private String mainClass; - @Parameter - private RuntimeCopyOperation runtime = RuntimeCopyOperation.SEPARATE; - - @Parameter - private Properties properties; - @Parameter private boolean mainPageIncluded; @Parameter private boolean bytecodeLogging; - @Parameter - private boolean debugInformationGenerated; - - @Parameter - private boolean sourceMapsGenerated; - - @Parameter - private boolean sourceFilesCopied; - - @Parameter - private boolean incremental; - - @Parameter(defaultValue = "${project.build.directory}/teavm-cache") - private File cacheDirectory; - - @Parameter - private String[] transformers; - @Parameter private ClassAlias[] classAliases; @@ -125,152 +61,37 @@ public class BuildJavascriptMojo extends AbstractMojo { @Parameter private boolean stopOnErrors = true; + @Parameter + protected RuntimeCopyOperation runtime = RuntimeCopyOperation.SEPARATE; + + @Parameter(defaultValue = "${project.build.directory}/teavm-cache") + protected File cacheDirectory; + private TeaVMTool tool = new TeaVMTool(); - public void setProject(MavenProject project) { - this.project = project; - } - - public void setTargetDirectory(File targetDirectory) { - this.targetDirectory = targetDirectory; - } - - public void setTargetFileName(String targetFileName) { - this.targetFileName = targetFileName; - } - - public void setClassFiles(File classFiles) { - this.classFiles = classFiles; - } - - public void setMinifying(boolean minifying) { - this.minifying = minifying; - } - - public void setBytecodeLogging(boolean bytecodeLogging) { - this.bytecodeLogging = bytecodeLogging; - } - - public void setRuntimeCopy(RuntimeCopyOperation runtimeCopy) { - this.runtime = runtimeCopy; - } - - public void setMainPageIncluded(boolean mainPageIncluded) { - this.mainPageIncluded = mainPageIncluded; - } - - public void setCompileScopes(List compileScopes) { - this.compileScopes = compileScopes; - } - - public void setMainClass(String mainClass) { - this.mainClass = mainClass; - } - - public String[] getTransformers() { - return transformers; - } - - public void setTransformers(String[] transformers) { - this.transformers = transformers; - } - - public void setProperties(Properties properties) { - this.properties = properties; - } - - public void setClassAliases(ClassAlias[] classAliases) { - this.classAliases = classAliases; - } - - public void setMethodAliases(MethodAlias[] methodAliases) { - this.methodAliases = methodAliases; - } - - public boolean isDebugInformationGenerated() { - return debugInformationGenerated; - } - - public void setDebugInformationGenerated(boolean debugInformationGenerated) { - this.debugInformationGenerated = debugInformationGenerated; - } - - public boolean isSourceMapsGenerated() { - return sourceMapsGenerated; - } - - public void setSourceMapsGenerated(boolean sourceMapsGenerated) { - this.sourceMapsGenerated = sourceMapsGenerated; - } - - public boolean isSourceFilesCopied() { - return sourceFilesCopied; - } - - public void setSourceFilesCopied(boolean sourceFilesCopied) { - this.sourceFilesCopied = sourceFilesCopied; - } - - public boolean isIncremental() { - return incremental; - } - - public void setIncremental(boolean incremental) { - this.incremental = incremental; - } - - public void setStopOnErrors(boolean stopOnErrors) { - this.stopOnErrors = stopOnErrors; - } - - public File getCacheDirectory() { - return cacheDirectory; - } - - public void setCacheDirectory(File cacheDirectory) { - this.cacheDirectory = cacheDirectory; + @Override + protected File getTargetDirectory() { + return targetDirectory; } @Override public void execute() throws MojoExecutionException { Log log = getLog(); + setupTool(tool); tool.setLog(new MavenTeaVMToolLog(log)); try { - ClassLoader classLoader = prepareClassLoader(); - tool.setClassLoader(classLoader); tool.setBytecodeLogging(bytecodeLogging); tool.setMainClass(mainClass); tool.setMainPageIncluded(mainPageIncluded); - tool.setMinifying(minifying); tool.setRuntime(runtime); - tool.setTargetDirectory(targetDirectory); tool.setTargetFileName(targetFileName); - tool.getTransformers().addAll(instantiateTransformers(classLoader)); - if (sourceFilesCopied) { - MavenSourceFileProviderLookup lookup = new MavenSourceFileProviderLookup(); - lookup.setMavenProject(project); - lookup.setRepositorySystem(repositorySystem); - lookup.setLocalRepository(localRepository); - lookup.setRemoteRepositories(remoteRepositories); - lookup.setPluginDependencies(pluginArtifacts); - for (SourceFileProvider provider : lookup.resolve()) { - tool.addSourceFileProvider(provider); - } - } if (classAliases != null) { tool.getClassAliases().addAll(Arrays.asList(classAliases)); } if (methodAliases != null) { tool.getMethodAliases().addAll(Arrays.asList(methodAliases)); } - if (properties != null) { - tool.getProperties().putAll(properties); - } tool.setCacheDirectory(cacheDirectory); - tool.setIncremental(incremental); - tool.setDebugInformationGenerated(debugInformationGenerated); - tool.setSourceMapsFileGenerated(sourceMapsGenerated); - tool.setSourceFilesCopied(sourceFilesCopied); tool.generate(); if (stopOnErrors && !tool.getProblemProvider().getSevereProblems().isEmpty()) { throw new MojoExecutionException("Build error"); @@ -281,75 +102,4 @@ public class BuildJavascriptMojo extends AbstractMojo { throw new MojoExecutionException("IO error occured", e); } } - - private List instantiateTransformers(ClassLoader classLoader) - throws MojoExecutionException { - List 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 transformerType = transformerRawType.asSubclass( - ClassHolderTransformer.class); - Constructor 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; - } - - private ClassLoader prepareClassLoader() throws MojoExecutionException { - try { - Log log = getLog(); - log.info("Preparing classpath for JavaScript generation"); - List urls = new ArrayList<>(); - StringBuilder classpath = new StringBuilder(); - Set scopes; - if (compileScopes == null) { - scopes = new HashSet<>(Arrays.asList( - Artifact.SCOPE_COMPILE, Artifact.SCOPE_PROVIDED, Artifact.SCOPE_SYSTEM)); - } else { - scopes = new HashSet<>(compileScopes); - } - for (Artifact artifact : project.getArtifacts()) { - if (!scopes.contains(artifact.getScope())) { - 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()); - log.info("Using the following classpath for JavaScript generation: " + classpath); - return new URLClassLoader(urls.toArray(new URL[urls.size()]), BuildJavascriptMojo.class.getClassLoader()); - } catch (MalformedURLException e) { - throw new MojoExecutionException("Error gathering classpath information", e); - } - } } diff --git a/tools/maven/plugin/src/main/java/org/teavm/maven/BuildJavascriptTestMojo.java b/tools/maven/plugin/src/main/java/org/teavm/maven/BuildJavascriptTestMojo.java index 3f1ff546e..a5c702111 100644 --- a/tools/maven/plugin/src/main/java/org/teavm/maven/BuildJavascriptTestMojo.java +++ b/tools/maven/plugin/src/main/java/org/teavm/maven/BuildJavascriptTestMojo.java @@ -21,8 +21,6 @@ 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.Arrays; import java.util.Enumeration; import java.util.HashSet; @@ -33,55 +31,31 @@ import java.util.jar.JarEntry; import java.util.jar.JarFile; import org.apache.commons.io.FilenameUtils; 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.MojoFailureException; 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.Mojo; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.plugins.annotations.ResolutionScope; -import org.apache.maven.project.MavenProject; -import org.apache.maven.repository.RepositorySystem; -import org.teavm.model.ClassHolderTransformer; import org.teavm.testing.JUnitTestAdapter; import org.teavm.testing.TestAdapter; -import org.teavm.tooling.SourceFileProvider; -import org.teavm.tooling.TeaVMTestTool; import org.teavm.tooling.TeaVMToolException; +import org.teavm.tooling.testing.TeaVMTestTool; /** * * @author Alexey Andreev */ -@Mojo(name = "build-test-javascript", requiresDependencyResolution = ResolutionScope.TEST, - requiresDependencyCollection = ResolutionScope.TEST) -public class BuildJavascriptTestMojo extends AbstractMojo { +@Mojo(name = "testCompile", requiresDependencyResolution = ResolutionScope.TEST, + requiresDependencyCollection = ResolutionScope.TEST, + defaultPhase = LifecyclePhase.PROCESS_TEST_CLASSES) +public class BuildJavascriptTestMojo extends AbstractJavascriptMojo { private static Set testScopes = new HashSet<>(Arrays.asList( Artifact.SCOPE_COMPILE, Artifact.SCOPE_TEST, Artifact.SCOPE_SYSTEM, Artifact.SCOPE_RUNTIME, Artifact.SCOPE_PROVIDED)); - - @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 remoteRepositories; - - @Parameter(readonly = true, defaultValue = "${plugin.artifacts}") - private List pluginArtifacts; - @Parameter(defaultValue = "${project.build.directory}/javascript-test") - private File outputDir; - - @Parameter(defaultValue = "${project.build.outputDirectory}") - private File classFiles; + private File targetDirectory; @Parameter(defaultValue = "${project.build.testOutputDirectory}") private File testFiles; @@ -92,9 +66,6 @@ public class BuildJavascriptTestMojo extends AbstractMojo { @Parameter private String[] excludeWildcards = new String[0]; - @Parameter - private boolean minifying = true; - @Parameter private boolean scanDependencies; @@ -104,9 +75,6 @@ public class BuildJavascriptTestMojo extends AbstractMojo { @Parameter private String adapterClass = JUnitTestAdapter.class.getName(); - @Parameter - private String[] transformers; - @Parameter private String[] additionalScripts; @@ -116,15 +84,6 @@ public class BuildJavascriptTestMojo extends AbstractMojo { @Parameter private boolean incremental; - @Parameter - private boolean debugInformationGenerated; - - @Parameter - private boolean sourceMapsGenerated; - - @Parameter - private boolean sourceFilesCopied; - @Parameter private URL seleniumURL; @@ -132,86 +91,6 @@ public class BuildJavascriptTestMojo extends AbstractMojo { private TeaVMTestTool tool = new TeaVMTestTool(); - public void setProject(MavenProject project) { - this.project = project; - } - - public void setOutputDir(File outputDir) { - this.outputDir = outputDir; - } - - public void setClassFiles(File classFiles) { - this.classFiles = classFiles; - } - - public void setTestFiles(File testFiles) { - this.testFiles = testFiles; - } - - public void setMinifying(boolean minifying) { - this.minifying = minifying; - } - - public void setNumThreads(int numThreads) { - this.numThreads = numThreads; - } - - public void setAdapterClass(String adapterClass) { - this.adapterClass = adapterClass; - } - - public void setWildcards(String[] wildcards) { - this.wildcards = wildcards; - } - - public void setExcludeWildcards(String[] excludeWildcards) { - this.excludeWildcards = excludeWildcards; - } - - public String[] getTransformers() { - return transformers; - } - - public void setTransformers(String[] transformers) { - this.transformers = transformers; - } - - public void setProperties(Properties properties) { - this.properties = properties; - } - - public void setIncremental(boolean incremental) { - this.incremental = incremental; - } - - public boolean isDebugInformationGenerated() { - return debugInformationGenerated; - } - - public void setDebugInformationGenerated(boolean debugInformationGenerated) { - this.debugInformationGenerated = debugInformationGenerated; - } - - public boolean isSourceMapsGenerated() { - return sourceMapsGenerated; - } - - public void setSourceMapsGenerated(boolean sourceMapsGenerated) { - this.sourceMapsGenerated = sourceMapsGenerated; - } - - public boolean isSourceFilesCopied() { - return sourceFilesCopied; - } - - public void setSourceFilesCopied(boolean sourceFilesCopied) { - this.sourceFilesCopied = sourceFilesCopied; - } - - public void setSeleniumURL(URL seleniumURL) { - this.seleniumURL = seleniumURL; - } - @Override public void execute() throws MojoExecutionException, MojoFailureException { if (System.getProperty("maven.test.skip", "false").equals("true") || @@ -220,54 +99,21 @@ public class BuildJavascriptTestMojo extends AbstractMojo { return; } - seleniumRunner = new SeleniumTestRunner(); - seleniumRunner.setUrl(seleniumURL); - seleniumRunner.setLog(getLog()); - seleniumRunner.detectSelenium(); + setupTool(tool); try { - final ClassLoader classLoader = prepareClassLoader(); getLog().info("Searching for tests in the directory `" + testFiles.getAbsolutePath() + "'"); - tool.setClassLoader(classLoader); tool.setAdapter(createAdapter(classLoader)); findTestClasses(classLoader, testFiles, ""); if (scanDependencies) { findTestsInDependencies(classLoader); } - tool.getTransformers().addAll(instantiateTransformers(classLoader)); - tool.setLog(new MavenTeaVMToolLog(getLog())); - tool.setOutputDir(outputDir); tool.setNumThreads(numThreads); - tool.setMinifying(minifying); - tool.setIncremental(incremental); - tool.setDebugInformationGenerated(debugInformationGenerated); - tool.setSourceMapsGenerated(sourceMapsGenerated); - tool.setSourceFilesCopied(sourceFilesCopied); - if (sourceFilesCopied) { - MavenSourceFileProviderLookup lookup = new MavenSourceFileProviderLookup(); - lookup.setMavenProject(project); - lookup.setRepositorySystem(repositorySystem); - lookup.setLocalRepository(localRepository); - lookup.setRemoteRepositories(remoteRepositories); - lookup.setPluginDependencies(pluginArtifacts); - for (SourceFileProvider provider : lookup.resolve()) { - tool.addSourceFileProvider(provider); - } - } - if (properties != null) { - tool.getProperties().putAll(properties); - } if (additionalScripts != null) { tool.getAdditionalScripts().addAll(Arrays.asList(additionalScripts)); } - tool.addListener(testCase -> seleniumRunner.run(testCase)); tool.generate(); - seleniumRunner.stopSelenium(); - seleniumRunner.waitForSelenium(); - processReport(seleniumRunner.getReport()); } catch (TeaVMToolException e) { throw new MojoFailureException("Error occured generating JavaScript files", e); - } finally { - seleniumRunner.stopSelenium(); } } @@ -318,38 +164,6 @@ public class BuildJavascriptTestMojo extends AbstractMojo { } } - private ClassLoader prepareClassLoader() throws MojoExecutionException { - try { - Log log = getLog(); - log.info("Preparing classpath for JavaScript test generation"); - List urls = new ArrayList<>(); - StringBuilder classpath = new StringBuilder(); - for (Artifact artifact : project.getArtifacts()) { - if (!testScopes.contains(artifact.getScope())) { - 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(testFiles.getPath()); - urls.add(testFiles.toURI().toURL()); - classpath.append(':').append(classFiles.getPath()); - urls.add(classFiles.toURI().toURL()); - log.info("Using the following classpath for JavaScript test generation: " + classpath); - return new URLClassLoader(urls.toArray(new URL[urls.size()]), - BuildJavascriptTestMojo.class.getClassLoader()); - } catch (MalformedURLException e) { - throw new MojoExecutionException("Error gathering classpath information", e); - } - } - private void findTestsInDependencies(ClassLoader classLoader) throws MojoExecutionException { try { Log log = getLog(); @@ -430,40 +244,18 @@ public class BuildJavascriptTestMojo extends AbstractMojo { } } - - private List instantiateTransformers(ClassLoader classLoader) - throws MojoExecutionException { - List 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 transformerType = transformerRawType.asSubclass( - ClassHolderTransformer.class); - Constructor 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; + @Override + protected File getTargetDirectory() { + return targetDirectory; } + @Override + protected List getAdditionalClassPath() { + return Arrays.asList(testFiles); + } + + @Override + protected boolean isSupportedScope(String scope) { + return testScopes.contains(scope); + } } diff --git a/tools/maven/plugin/src/main/java/org/teavm/maven/MavenSourceFileProviderLookup.java b/tools/maven/plugin/src/main/java/org/teavm/maven/MavenSourceFileProviderLookup.java index 42887a97b..9d6567645 100644 --- a/tools/maven/plugin/src/main/java/org/teavm/maven/MavenSourceFileProviderLookup.java +++ b/tools/maven/plugin/src/main/java/org/teavm/maven/MavenSourceFileProviderLookup.java @@ -26,9 +26,9 @@ import org.apache.maven.artifact.resolver.ArtifactResolutionRequest; import org.apache.maven.artifact.resolver.ArtifactResolutionResult; import org.apache.maven.project.MavenProject; import org.apache.maven.repository.RepositorySystem; -import org.teavm.tooling.DirectorySourceFileProvider; -import org.teavm.tooling.JarSourceFileProvider; -import org.teavm.tooling.SourceFileProvider; +import org.teavm.tooling.sources.DirectorySourceFileProvider; +import org.teavm.tooling.sources.JarSourceFileProvider; +import org.teavm.tooling.sources.SourceFileProvider; /** * diff --git a/tools/maven/plugin/src/main/java/org/teavm/maven/RunTestsMojo.java b/tools/maven/plugin/src/main/java/org/teavm/maven/RunTestsMojo.java new file mode 100644 index 000000000..9b6f3df63 --- /dev/null +++ b/tools/maven/plugin/src/main/java/org/teavm/maven/RunTestsMojo.java @@ -0,0 +1,31 @@ +/* + * 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 org.apache.maven.plugins.annotations.LifecyclePhase; +import org.apache.maven.plugins.annotations.Mojo; +import org.apache.maven.plugins.annotations.Parameter; + +/** + * + * @author Alexey Andreev + */ +@Mojo(name = "run-tests", defaultPhase = LifecyclePhase.TEST) +public class RunTestsMojo { + @Parameter(defaultValue = "${project.build.directory}/javascript-tests") + private File targetDirectory; +} diff --git a/tools/maven/plugin/src/main/java/org/teavm/maven/SeleniumTestRunner.java b/tools/maven/plugin/src/main/java/org/teavm/maven/SeleniumTestRunner.java index bde8eef59..b42118682 100644 --- a/tools/maven/plugin/src/main/java/org/teavm/maven/SeleniumTestRunner.java +++ b/tools/maven/plugin/src/main/java/org/teavm/maven/SeleniumTestRunner.java @@ -35,7 +35,9 @@ import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebDriverException; import org.openqa.selenium.chrome.ChromeDriver; -import org.teavm.tooling.TeaVMTestCase; +import org.teavm.tooling.testing.TestCase; +import org.teavm.tooling.testing.TestGroup; +import org.teavm.tooling.testing.TestPlan; /** * @@ -43,13 +45,15 @@ import org.teavm.tooling.TeaVMTestCase; */ public class SeleniumTestRunner { private URL url; - private WebDriver webDriver; + private int numThreads = 1; + private ThreadLocal webDriver = new ThreadLocal<>(); private BlockingQueue seleniumTaskQueue = new LinkedBlockingQueue<>(); private CountDownLatch latch = new CountDownLatch(1); private volatile boolean seleniumStopped = false; private Log log; private List report = new CopyOnWriteArrayList<>(); private ThreadLocal> localReport = new ThreadLocal<>(); + private File directory = new File("."); public URL getUrl() { return url; @@ -63,28 +67,55 @@ public class SeleniumTestRunner { this.log = log; } - public void detectSelenium() { - if (url == null) { - return; - } - ChromeDriver driver = new ChromeDriver(); - webDriver = driver; - new Thread(() -> { - localReport.set(new ArrayList<>()); - while (!seleniumStopped) { - Runnable task; - try { - task = seleniumTaskQueue.poll(1, TimeUnit.SECONDS); - } catch (InterruptedException e) { - break; - } - if (task != null) { - task.run(); - } + public File getDirectory() { + return directory; + } + + public void setDirectory(File directory) { + this.directory = directory; + } + + public int getNumThreads() { + return numThreads; + } + + public void setNumThreads(int numThreads) { + this.numThreads = numThreads; + } + + public void run(TestPlan testPlan) { + initSelenium(); + for (TestGroup group : testPlan.getGroups()) { + for (TestCase testCase : group.getTestCases()) { + run(testPlan.getRuntimeScript(), testCase); } - report.addAll(localReport.get()); - localReport.remove(); - }).start(); + } + stopSelenium(); + waitForCompletion(); + } + + private void initSelenium() { + for (int i = 0; i < numThreads; ++i) { + new Thread(() -> { + ChromeDriver driver = new ChromeDriver(); + webDriver.set(driver); + localReport.set(new ArrayList<>()); + while (!seleniumStopped) { + Runnable task; + try { + task = seleniumTaskQueue.poll(1, TimeUnit.SECONDS); + } catch (InterruptedException e) { + break; + } + if (task != null) { + task.run(); + } + } + report.addAll(localReport.get()); + localReport.remove(); + webDriver.remove(); + }).start(); + } } private void addSeleniumTask(Runnable runnable) { @@ -93,14 +124,14 @@ public class SeleniumTestRunner { } } - public void stopSelenium() { + private void stopSelenium() { addSeleniumTask(() -> { seleniumStopped = true; latch.countDown(); }); } - public void waitForSelenium() { + private void waitForCompletion() { try { latch.await(); } catch (InterruptedException e) { @@ -108,21 +139,18 @@ public class SeleniumTestRunner { } } - public void run(TeaVMTestCase testCase) { - addSeleniumTask(() -> runImpl(testCase)); + private void run(String runtimeScript, TestCase testCase) { + addSeleniumTask(() -> runImpl(runtimeScript, testCase)); } - private void runImpl(TeaVMTestCase testCase) { - if (webDriver == null) { - return; - } - webDriver.manage().timeouts().setScriptTimeout(5, TimeUnit.SECONDS); + private void runImpl(String runtimeScript, TestCase testCase) { + webDriver.get().manage().timeouts().setScriptTimeout(2, TimeUnit.SECONDS); JavascriptExecutor js = (JavascriptExecutor) webDriver; try { String result = (String) js.executeAsyncScript( readResource("teavm-selenium.js"), - readFile(testCase.getRuntimeScript()), - readFile(testCase.getTestScript()), + readFile(new File(directory, runtimeScript)), + readFile(new File(directory, testCase.getTestScript())), readResource("teavm-selenium-adapter.js")); ObjectMapper mapper = new ObjectMapper(); ObjectNode resultObject = (ObjectNode) mapper.readTree(result); diff --git a/tools/maven/pom.xml b/tools/maven/pom.xml index 84507fd9b..f20bff3e7 100644 --- a/tools/maven/pom.xml +++ b/tools/maven/pom.xml @@ -21,6 +21,7 @@ org.teavm teavm 0.4.0-SNAPSHOT + ../.. teavm-maven