js: add ability so refer to local files in source maps. Add copying of source files to Gradle plugin.

This commit is contained in:
Alexey Andreev 2023-11-24 21:28:37 +01:00
parent 6543e68f8a
commit ac2c084290
18 changed files with 297 additions and 40 deletions

View File

@ -0,0 +1,22 @@
/*
* Copyright 2023 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.debugging.information;
import java.io.IOException;
public interface SourceFileResolver {
String resolveFile(String fileName) throws IOException;
}

View File

@ -17,9 +17,11 @@ package org.teavm.debugging.information;
import java.io.IOException; import java.io.IOException;
import java.io.Writer; import java.io.Writer;
import java.util.ArrayList;
import java.util.List;
import org.teavm.common.JsonUtil; import org.teavm.common.JsonUtil;
class SourceMapsWriter { public class SourceMapsWriter {
private static final String BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; private static final String BASE64_CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
private Writer output; private Writer output;
private int lastLine; private int lastLine;
@ -27,11 +29,16 @@ class SourceMapsWriter {
private int lastSourceLine; private int lastSourceLine;
private int lastSourceFile; private int lastSourceFile;
private boolean first; private boolean first;
private List<SourceFileResolver> sourceFileResolvers = new ArrayList<>();
public SourceMapsWriter(Writer output) { public SourceMapsWriter(Writer output) {
this.output = output; this.output = output;
} }
public void addSourceResolver(SourceFileResolver sourceFileResolver) {
sourceFileResolvers.add(sourceFileResolver);
}
public void write(String generatedFile, String sourceRoot, DebugInformation debugInfo) throws IOException { public void write(String generatedFile, String sourceRoot, DebugInformation debugInfo) throws IOException {
output.write("{\"version\":3"); output.write("{\"version\":3");
output.write(",\"file\":\""); output.write(",\"file\":\"");
@ -46,7 +53,15 @@ class SourceMapsWriter {
output.write(','); output.write(',');
} }
output.write("\""); output.write("\"");
JsonUtil.writeEscapedString(output, debugInfo.fileNames[i]); var name = debugInfo.fileNames[i];
for (var resolver : sourceFileResolvers) {
var resolvedName = resolver.resolveFile(name);
if (resolvedName != null) {
name = resolvedName;
break;
}
}
JsonUtil.writeEscapedString(output, name);
output.write("\""); output.write("\"");
} }
output.write("]"); output.write("]");

View File

@ -1,3 +1,5 @@
import org.teavm.gradle.api.SourceFilePolicy
/* /*
* Copyright 2023 Alexey Andreev. * Copyright 2023 Alexey Andreev.
* *
@ -28,4 +30,6 @@ dependencies {
teavm.js { teavm.js {
addedToWebApp = true addedToWebApp = true
mainClass = "org.teavm.samples.hello.Client" mainClass = "org.teavm.samples.hello.Client"
sourceMap = true
sourceFilePolicy = SourceFilePolicy.LINK_LOCAL_FILES
} }

View File

@ -0,0 +1,22 @@
/*
* Copyright 2023 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;
public enum TeaVMSourceFilePolicy {
DO_NOTHING,
COPY,
LINK_LOCAL_FILES
}

View File

@ -49,6 +49,7 @@ import org.teavm.cache.EmptyProgramCache;
import org.teavm.cache.FileSymbolTable; import org.teavm.cache.FileSymbolTable;
import org.teavm.debugging.information.DebugInformation; import org.teavm.debugging.information.DebugInformation;
import org.teavm.debugging.information.DebugInformationBuilder; import org.teavm.debugging.information.DebugInformationBuilder;
import org.teavm.debugging.information.SourceMapsWriter;
import org.teavm.dependency.DependencyInfo; import org.teavm.dependency.DependencyInfo;
import org.teavm.dependency.FastDependencyAnalyzer; import org.teavm.dependency.FastDependencyAnalyzer;
import org.teavm.dependency.PreciseDependencyAnalyzer; import org.teavm.dependency.PreciseDependencyAnalyzer;
@ -61,7 +62,6 @@ import org.teavm.model.ReferenceCache;
import org.teavm.model.transformation.AssertionRemoval; import org.teavm.model.transformation.AssertionRemoval;
import org.teavm.parsing.ClasspathClassHolderSource; import org.teavm.parsing.ClasspathClassHolderSource;
import org.teavm.tooling.sources.SourceFileProvider; import org.teavm.tooling.sources.SourceFileProvider;
import org.teavm.tooling.sources.SourceFilesCopier;
import org.teavm.vm.BuildTarget; import org.teavm.vm.BuildTarget;
import org.teavm.vm.DirectoryBuildTarget; import org.teavm.vm.DirectoryBuildTarget;
import org.teavm.vm.TeaVM; import org.teavm.vm.TeaVM;
@ -81,7 +81,7 @@ public class TeaVMTool {
private Properties properties = new Properties(); private Properties properties = new Properties();
private boolean debugInformationGenerated; private boolean debugInformationGenerated;
private boolean sourceMapsFileGenerated; private boolean sourceMapsFileGenerated;
private boolean sourceFilesCopied; private TeaVMSourceFilePolicy sourceFilePolicy = TeaVMSourceFilePolicy.DO_NOTHING;
private boolean incremental; private boolean incremental;
private File cacheDirectory = new File("./teavm-cache"); private File cacheDirectory = new File("./teavm-cache");
private List<String> transformers = new ArrayList<>(); private List<String> transformers = new ArrayList<>();
@ -177,12 +177,23 @@ public class TeaVMTool {
this.sourceMapsFileGenerated = sourceMapsFileGenerated; this.sourceMapsFileGenerated = sourceMapsFileGenerated;
} }
@Deprecated
public boolean isSourceFilesCopied() { public boolean isSourceFilesCopied() {
return sourceFilesCopied; return sourceFilePolicy == TeaVMSourceFilePolicy.COPY;
} }
@Deprecated
public void setSourceFilesCopied(boolean sourceFilesCopied) { public void setSourceFilesCopied(boolean sourceFilesCopied) {
this.sourceFilesCopied = sourceFilesCopied; if (isSourceFilesCopied() == sourceFilesCopied) {
return;
}
sourceFilePolicy = sourceFilesCopied
? TeaVMSourceFilePolicy.COPY
: TeaVMSourceFilePolicy.DO_NOTHING;
}
public void setSourceFilePolicy(TeaVMSourceFilePolicy sourceFilePolicy) {
this.sourceFilePolicy = sourceFilePolicy;
} }
public Properties getProperties() { public Properties getProperties() {
@ -527,14 +538,48 @@ public class TeaVMTool {
File sourceMapsFile = new File(targetDirectory, sourceMapsFileName); File sourceMapsFile = new File(targetDirectory, sourceMapsFileName);
try (Writer sourceMapsOut = new OutputStreamWriter(new FileOutputStream(sourceMapsFile), try (Writer sourceMapsOut = new OutputStreamWriter(new FileOutputStream(sourceMapsFile),
StandardCharsets.UTF_8)) { StandardCharsets.UTF_8)) {
debugInfo.writeAsSourceMaps(sourceMapsOut, "src", getResolvedTargetFileName()); writeSourceMaps(sourceMapsOut, debugInfo);
} }
generatedFiles.add(sourceMapsFile); generatedFiles.add(sourceMapsFile);
log.info("Source maps successfully written"); log.info("Source maps successfully written");
} }
if (sourceFilesCopied) { }
copySourceFiles();
log.info("Source files successfully written"); private void writeSourceMaps(Writer out, DebugInformation debugInfo) throws IOException {
var sourceMapWriter = new SourceMapsWriter(out);
for (var provider : sourceFileProviders) {
provider.open();
}
var targetDir = new File(targetDirectory, "src");
if (sourceFilePolicy != TeaVMSourceFilePolicy.DO_NOTHING) {
sourceMapWriter.addSourceResolver(fileName -> {
for (var provider : sourceFileProviders) {
var sourceFile = provider.getSourceFile(fileName);
if (sourceFile != null) {
if (sourceFilePolicy == TeaVMSourceFilePolicy.COPY || sourceFile.getFile() == null) {
var outputFile = new File(targetDir, fileName);
outputFile.getParentFile().mkdirs();
try (var input = sourceFile.open();
var output = new FileOutputStream(outputFile)) {
input.transferTo(output);
}
if (sourceFilePolicy == TeaVMSourceFilePolicy.LINK_LOCAL_FILES) {
return "file://" + outputFile.getCanonicalPath();
}
} else {
return "file://" + sourceFile.getFile().getCanonicalPath();
}
break;
}
}
return null;
});
}
sourceMapWriter.write(getResolvedTargetFileName(), "src", debugInfo);
for (var provider : sourceFileProviders) {
provider.close();
} }
} }
@ -554,16 +599,6 @@ public class TeaVMTool {
log.info("Methods compiled: " + methodCount); log.info("Methods compiled: " + methodCount);
} }
private void copySourceFiles() {
if (vm.getWrittenClasses() == null) {
return;
}
SourceFilesCopier copier = new SourceFilesCopier(sourceFileProviders, generatedFiles::add);
copier.addClasses(vm.getWrittenClasses());
copier.setLog(log);
copier.copy(new File(targetDirectory, "src"));
}
private List<ClassHolderTransformer> resolveTransformers() { private List<ClassHolderTransformer> resolveTransformers() {
List<ClassHolderTransformer> transformerInstances = new ArrayList<>(); List<ClassHolderTransformer> transformerInstances = new ArrayList<>();
if (transformers == null) { if (transformers == null) {

View File

@ -18,6 +18,7 @@ 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.backend.wasm.render.WasmBinaryVersion;
import org.teavm.tooling.TeaVMSourceFilePolicy;
import org.teavm.tooling.TeaVMTargetType; import org.teavm.tooling.TeaVMTargetType;
import org.teavm.tooling.TeaVMToolLog; import org.teavm.tooling.TeaVMToolLog;
import org.teavm.vm.TeaVMOptimizationLevel; import org.teavm.vm.TeaVMOptimizationLevel;
@ -46,8 +47,11 @@ public interface BuildStrategy {
void setDebugInformationGenerated(boolean debugInformationGenerated); void setDebugInformationGenerated(boolean debugInformationGenerated);
@Deprecated
void setSourceFilesCopied(boolean sourceFilesCopied); void setSourceFilesCopied(boolean sourceFilesCopied);
void setSourceFilePolicy(TeaVMSourceFilePolicy sourceFilePolicy);
void setProgressListener(TeaVMProgressListener progressListener); void setProgressListener(TeaVMProgressListener progressListener);
void setIncremental(boolean incremental); void setIncremental(boolean incremental);

View File

@ -30,6 +30,7 @@ import org.teavm.backend.wasm.render.WasmBinaryVersion;
import org.teavm.callgraph.CallGraph; import org.teavm.callgraph.CallGraph;
import org.teavm.diagnostics.ProblemProvider; import org.teavm.diagnostics.ProblemProvider;
import org.teavm.tooling.EmptyTeaVMToolLog; import org.teavm.tooling.EmptyTeaVMToolLog;
import org.teavm.tooling.TeaVMSourceFilePolicy;
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;
@ -55,7 +56,7 @@ public class InProcessBuildStrategy implements BuildStrategy {
private boolean strict; private boolean strict;
private boolean sourceMapsFileGenerated; private boolean sourceMapsFileGenerated;
private boolean debugInformationGenerated; private boolean debugInformationGenerated;
private boolean sourceFilesCopied; private TeaVMSourceFilePolicy sourceMapsSourcePolicy;
private String[] transformers = new String[0]; private String[] transformers = new String[0];
private String[] classesToPreserve = new String[0]; private String[] classesToPreserve = new String[0];
private WasmBinaryVersion wasmVersion = WasmBinaryVersion.V_0x1; private WasmBinaryVersion wasmVersion = WasmBinaryVersion.V_0x1;
@ -122,7 +123,17 @@ public class InProcessBuildStrategy implements BuildStrategy {
@Override @Override
public void setSourceFilesCopied(boolean sourceFilesCopied) { public void setSourceFilesCopied(boolean sourceFilesCopied) {
this.sourceFilesCopied = sourceFilesCopied; if ((sourceMapsSourcePolicy == TeaVMSourceFilePolicy.COPY) == sourceFilesCopied) {
return;
}
sourceMapsSourcePolicy = sourceFilesCopied
? TeaVMSourceFilePolicy.COPY
: TeaVMSourceFilePolicy.DO_NOTHING;
}
@Override
public void setSourceFilePolicy(TeaVMSourceFilePolicy sourceFilePolicy) {
this.sourceMapsSourcePolicy = sourceFilePolicy;
} }
@Override @Override
@ -233,7 +244,7 @@ public class InProcessBuildStrategy implements BuildStrategy {
tool.setSourceMapsFileGenerated(sourceMapsFileGenerated); tool.setSourceMapsFileGenerated(sourceMapsFileGenerated);
tool.setDebugInformationGenerated(debugInformationGenerated); tool.setDebugInformationGenerated(debugInformationGenerated);
tool.setSourceFilesCopied(sourceFilesCopied); tool.setSourceFilePolicy(sourceMapsSourcePolicy);
tool.setObfuscated(obfuscated); tool.setObfuscated(obfuscated);
tool.setStrict(strict); tool.setStrict(strict);

View File

@ -25,6 +25,7 @@ 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.tooling.EmptyTeaVMToolLog; import org.teavm.tooling.EmptyTeaVMToolLog;
import org.teavm.tooling.TeaVMSourceFilePolicy;
import org.teavm.tooling.TeaVMTargetType; import org.teavm.tooling.TeaVMTargetType;
import org.teavm.tooling.TeaVMToolLog; import org.teavm.tooling.TeaVMToolLog;
import org.teavm.tooling.daemon.RemoteBuildCallback; import org.teavm.tooling.daemon.RemoteBuildCallback;
@ -100,7 +101,14 @@ public class RemoteBuildStrategy implements BuildStrategy {
@Override @Override
public void setSourceFilesCopied(boolean sourceFilesCopied) { public void setSourceFilesCopied(boolean sourceFilesCopied) {
request.sourceFilesCopied = sourceFilesCopied; request.sourceFilePolicy = sourceFilesCopied
? TeaVMSourceFilePolicy.COPY.name()
: TeaVMSourceFilePolicy.DO_NOTHING.name();
}
@Override
public void setSourceFilePolicy(TeaVMSourceFilePolicy sourceFilePolicy) {
request.sourceFilePolicy = sourceFilePolicy.name();
} }
@Override @Override

View File

@ -37,6 +37,7 @@ 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.teavm.tooling.TeaVMSourceFilePolicy;
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;
@ -147,7 +148,9 @@ public class BuildDaemon extends UnicastRemoteObject implements RemoteBuildServi
tool.setSourceMapsFileGenerated(request.sourceMapsFileGenerated); tool.setSourceMapsFileGenerated(request.sourceMapsFileGenerated);
tool.setDebugInformationGenerated(request.debugInformationGenerated); tool.setDebugInformationGenerated(request.debugInformationGenerated);
tool.setSourceFilesCopied(request.sourceFilesCopied); if (request.sourceFilePolicy != null) {
tool.setSourceFilePolicy(TeaVMSourceFilePolicy.valueOf(request.sourceFilePolicy));
}
if (request.properties != null) { if (request.properties != null) {
tool.getProperties().putAll(request.properties); tool.getProperties().putAll(request.properties);
} }

View File

@ -20,6 +20,7 @@ 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.backend.wasm.render.WasmBinaryVersion;
import org.teavm.tooling.TeaVMSourceFilePolicy;
import org.teavm.tooling.TeaVMTargetType; import org.teavm.tooling.TeaVMTargetType;
import org.teavm.vm.TeaVMOptimizationLevel; import org.teavm.vm.TeaVMOptimizationLevel;
@ -36,7 +37,7 @@ public class RemoteBuildRequest implements Serializable {
public String tagetFileName = ""; public String tagetFileName = "";
public boolean sourceMapsFileGenerated; public boolean sourceMapsFileGenerated;
public boolean debugInformationGenerated; public boolean debugInformationGenerated;
public boolean sourceFilesCopied; public String sourceFilePolicy = TeaVMSourceFilePolicy.DO_NOTHING.name();
public boolean incremental; public boolean incremental;
public String cacheDirectory; public String cacheDirectory;
public boolean obfuscated; public boolean obfuscated;

View File

@ -38,7 +38,7 @@ public class DirectorySourceFileProvider implements SourceFileProvider {
@Override @Override
public SourceFileInfo getSourceFile(String fullPath) throws IOException { public SourceFileInfo getSourceFile(String fullPath) throws IOException {
File file = new File(baseDirectory, fullPath); File file = new File(baseDirectory, fullPath);
return file.exists() ? new DirectorySourceFile(file) : null; return file.isFile() ? new DirectorySourceFile(file) : null;
} }
static class DirectorySourceFile implements SourceFileInfo { static class DirectorySourceFile implements SourceFileInfo {
@ -57,5 +57,10 @@ public class DirectorySourceFileProvider implements SourceFileProvider {
public InputStream open() throws IOException { public InputStream open() throws IOException {
return new FileInputStream(file); return new FileInputStream(file);
} }
@Override
public File getFile() {
return file;
}
} }
} }

View File

@ -80,5 +80,10 @@ public class JarSourceFileProvider implements SourceFileProvider {
public InputStream open() throws IOException { public InputStream open() throws IOException {
return file.getInputStream(entry); return file.getInputStream(entry);
} }
@Override
public File getFile() {
return null;
}
} }
} }

View File

@ -15,6 +15,7 @@
*/ */
package org.teavm.tooling.sources; package org.teavm.tooling.sources;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
@ -22,4 +23,6 @@ public interface SourceFileInfo {
long lastModified(); long lastModified();
InputStream open() throws IOException; InputStream open() throws IOException;
File getFile();
} }

View File

@ -16,10 +16,16 @@
package org.teavm.gradle; package org.teavm.gradle;
import java.io.File; import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import javax.inject.Inject; import javax.inject.Inject;
import org.gradle.api.Plugin; import org.gradle.api.Plugin;
import org.gradle.api.Project; import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.component.ModuleComponentIdentifier;
import org.gradle.api.artifacts.component.ProjectComponentIdentifier;
import org.gradle.api.artifacts.result.ResolvedDependencyResult;
import org.gradle.api.file.DuplicatesStrategy; import org.gradle.api.file.DuplicatesStrategy;
import org.gradle.api.model.ObjectFactory; import org.gradle.api.model.ObjectFactory;
import org.gradle.api.plugins.JavaPlugin; import org.gradle.api.plugins.JavaPlugin;
@ -83,15 +89,17 @@ public class TeaVMPlugin implements Plugin<Project> {
} }
private void registerSourceSet(Project project) { private void registerSourceSet(Project project) {
var sourceSets = project.getExtensions().getByType(SourceSetContainer.class); var sourceSets = project.getExtensions().findByType(SourceSetContainer.class);
var sourceSet = sourceSets.create(SOURCE_SET_NAME); if (sourceSets != null) {
var main = sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME).getOutput(); var sourceSet = sourceSets.create(SOURCE_SET_NAME);
sourceSet.setRuntimeClasspath(sourceSet.getRuntimeClasspath().plus(main) var main = sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME).getOutput();
.plus(project.getConfigurations().getByName(CLASSPATH_CONFIGURATION_NAME))); sourceSet.setRuntimeClasspath(sourceSet.getRuntimeClasspath().plus(main)
sourceSet.setCompileClasspath(sourceSet.getCompileClasspath().plus(main) .plus(project.getConfigurations().getByName(CLASSPATH_CONFIGURATION_NAME)));
.plus(project.getConfigurations().getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME))); sourceSet.setCompileClasspath(sourceSet.getCompileClasspath().plus(main)
sourceSet.java(java -> { }); .plus(project.getConfigurations().getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME)));
project.getDependencies().add(JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME, sourceSet.getOutput()); sourceSet.java(java -> { });
project.getDependencies().add(JavaPlugin.TEST_IMPLEMENTATION_CONFIGURATION_NAME, sourceSet.getOutput());
}
} }
private void registerTasks(Project project) { private void registerTasks(Project project) {
@ -113,9 +121,59 @@ public class TeaVMPlugin implements Plugin<Project> {
task.getTargetFileName().convention(js.getTargetFileName()); task.getTargetFileName().convention(js.getTargetFileName());
task.getStrict().convention(js.getStrict()); task.getStrict().convention(js.getStrict());
task.getEntryPointName().convention(js.getEntryPointName()); task.getEntryPointName().convention(js.getEntryPointName());
task.getSourceFilePolicy().convention(js.getSourceFilePolicy());
task.getSourceFiles().from(project.provider(() -> {
var result = new ArrayList<File>();
addSourceDirs(project, result);
return result;
}));
task.getSourceFiles().from(project.provider(() -> {
var dependencies = project.getConfigurations()
.getByName(JavaPlugin.COMPILE_CLASSPATH_CONFIGURATION_NAME)
.getIncoming()
.getResolutionResult()
.getAllDependencies();
var result = new ArrayList<File>();
for (var dependencyResult : dependencies) {
if (!(dependencyResult instanceof ResolvedDependencyResult)) {
continue;
}
var id = ((ResolvedDependencyResult) dependencyResult).getSelected().getId();
if (id instanceof ProjectComponentIdentifier) {
var path = ((ProjectComponentIdentifier) id).getProjectPath();
var refProject = project.getRootProject().findProject(path);
if (refProject != null) {
addSourceDirs(refProject, result);
}
} else if (id instanceof ModuleComponentIdentifier) {
var moduleId = (ModuleComponentIdentifier) id;
var sourcesDep = project.getDependencies().create(Map.of(
"group", moduleId.getGroup(),
"name", moduleId.getModuleIdentifier().getName(),
"version", moduleId.getVersion(),
"classifier", "sources"
));
var tmpConfig = project.getConfigurations().detachedConfiguration(sourcesDep);
tmpConfig.setTransitive(false);
result.addAll(tmpConfig.getFiles());
}
}
return result;
}));
}); });
} }
private void addSourceDirs(Project project, List<File> result) {
var sourceSets = project.getExtensions().findByType(SourceSetContainer.class);
if (sourceSets != null) {
for (var sourceSet : sourceSets) {
result.addAll(sourceSet.getAllJava().getSourceDirectories().getFiles());
}
}
}
private void registerWasmTask(Project project, Configuration configuration) { private void registerWasmTask(Project project, Configuration configuration) {
var extension = project.getExtensions().getByType(TeaVMExtension.class); var extension = project.getExtensions().getByType(TeaVMExtension.class);
project.getTasks().create(WASM_TASK_NAME, GenerateWasmTask.class, task -> { project.getTasks().create(WASM_TASK_NAME, GenerateWasmTask.class, task -> {
@ -202,8 +260,10 @@ public class TeaVMPlugin implements Plugin<Project> {
var project = task.getProject(); var project = task.getProject();
var sourceSets = project.getExtensions().getByType(SourceSetContainer.class); var sourceSets = project.getExtensions().findByType(SourceSetContainer.class);
task.getClasspath().from(sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME).getOutput()); if (sourceSets != null) {
task.getClasspath().from(sourceSets.getByName(SOURCE_SET_NAME).getOutput()); task.getClasspath().from(sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME).getOutput());
task.getClasspath().from(sourceSets.getByName(SOURCE_SET_NAME).getOutput());
}
} }
} }

View File

@ -0,0 +1,22 @@
/*
* Copyright 2023 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.gradle.api;
public enum SourceFilePolicy {
DO_NOTHING,
COPY,
LINK_LOCAL_FILES
}

View File

@ -27,4 +27,6 @@ public interface TeaVMJSConfiguration extends TeaVMWebConfiguration {
Property<String> getEntryPointName(); Property<String> getEntryPointName();
Property<String> getTargetFileName(); Property<String> getTargetFileName();
Property<SourceFilePolicy> getSourceFilePolicy();
} }

View File

@ -15,9 +15,13 @@
*/ */
package org.teavm.gradle.tasks; package org.teavm.gradle.tasks;
import org.gradle.api.file.ConfigurableFileCollection;
import org.gradle.api.provider.Property; import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input; import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFiles;
import org.gradle.api.tasks.Optional; import org.gradle.api.tasks.Optional;
import org.teavm.gradle.api.SourceFilePolicy;
import org.teavm.tooling.TeaVMSourceFilePolicy;
import org.teavm.tooling.TeaVMTargetType; import org.teavm.tooling.TeaVMTargetType;
import org.teavm.tooling.builder.BuildStrategy; import org.teavm.tooling.builder.BuildStrategy;
@ -26,6 +30,7 @@ public abstract class GenerateJavaScriptTask extends TeaVMTask {
getObfuscated().convention(true); getObfuscated().convention(true);
getStrict().convention(false); getStrict().convention(false);
getSourceMap().convention(false); getSourceMap().convention(false);
getSourceFilePolicy().convention(SourceFilePolicy.DO_NOTHING);
getEntryPointName().convention("main"); getEntryPointName().convention("main");
} }
@ -45,6 +50,13 @@ public abstract class GenerateJavaScriptTask extends TeaVMTask {
@Optional @Optional
public abstract Property<String> getEntryPointName(); public abstract Property<String> getEntryPointName();
@InputFiles
public abstract ConfigurableFileCollection getSourceFiles();
@Input
@Optional
public abstract Property<SourceFilePolicy> getSourceFilePolicy();
@Override @Override
protected void setupBuilder(BuildStrategy builder) { protected void setupBuilder(BuildStrategy builder) {
builder.setTargetType(TeaVMTargetType.JAVASCRIPT); builder.setTargetType(TeaVMTargetType.JAVASCRIPT);
@ -52,5 +64,25 @@ public abstract class GenerateJavaScriptTask extends TeaVMTask {
builder.setStrict(getStrict().get()); builder.setStrict(getStrict().get());
builder.setSourceMapsFileGenerated(getSourceMap().get()); builder.setSourceMapsFileGenerated(getSourceMap().get());
builder.setEntryPointName(getEntryPointName().get()); builder.setEntryPointName(getEntryPointName().get());
for (var file : getSourceFiles()) {
if (file.isFile()) {
if (file.getName().endsWith(".jar") || file.getName().endsWith(".zip")) {
builder.addSourcesJar(file.getAbsolutePath());
}
} else if (file.isDirectory()) {
builder.addSourcesDirectory(file.getAbsolutePath());
}
}
switch (getSourceFilePolicy().get()) {
case DO_NOTHING:
builder.setSourceFilePolicy(TeaVMSourceFilePolicy.DO_NOTHING);
break;
case COPY:
builder.setSourceFilePolicy(TeaVMSourceFilePolicy.COPY);
break;
case LINK_LOCAL_FILES:
builder.setSourceFilePolicy(TeaVMSourceFilePolicy.LINK_LOCAL_FILES);
break;
}
} }
} }

View File

@ -39,6 +39,7 @@ import org.apache.maven.project.MavenProject;
import org.apache.maven.repository.RepositorySystem; 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.TeaVMProblemRenderer;
import org.teavm.tooling.TeaVMSourceFilePolicy;
import org.teavm.tooling.TeaVMTargetType; import org.teavm.tooling.TeaVMTargetType;
import org.teavm.tooling.builder.BuildException; import org.teavm.tooling.builder.BuildException;
import org.teavm.tooling.builder.BuildResult; import org.teavm.tooling.builder.BuildResult;
@ -177,7 +178,9 @@ public class TeaVMCompileMojo extends AbstractMojo {
builder.setIncremental(incremental); builder.setIncremental(incremental);
builder.setDebugInformationGenerated(debugInformationGenerated); builder.setDebugInformationGenerated(debugInformationGenerated);
builder.setSourceMapsFileGenerated(sourceMapsGenerated); builder.setSourceMapsFileGenerated(sourceMapsGenerated);
builder.setSourceFilesCopied(sourceFilesCopied); builder.setSourceFilePolicy(sourceFilesCopied
? TeaVMSourceFilePolicy.COPY
: TeaVMSourceFilePolicy.DO_NOTHING);
builder.setMinHeapSize(minHeapSize * 1024 * 1024); builder.setMinHeapSize(minHeapSize * 1024 * 1024);
builder.setMaxHeapSize(maxHeapSize * 1024 * 1024); builder.setMaxHeapSize(maxHeapSize * 1024 * 1024);
builder.setShortFileNames(shortFileNames); builder.setShortFileNames(shortFileNames);