IDEA: fix building multi-platform projects (JS, WebAssembly)

This commit is contained in:
Alexey Andreev 2016-11-15 23:07:25 +03:00
parent df95588d51
commit 8e2814f984
8 changed files with 114 additions and 47 deletions

View File

@ -0,0 +1,14 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="IDEA JPS Debug" type="Remote" factoryName="Remote">
<option name="USE_SOCKET_TRANSPORT" value="true" />
<option name="SERVER_MODE" value="false" />
<option name="SHMEM_ADDRESS" value="javadebug" />
<option name="HOST" value="localhost" />
<option name="PORT" value="5005" />
<RunnerSettings RunnerId="Debug">
<option name="DEBUG_PORT" value="5005" />
<option name="LOCAL" value="false" />
</RunnerSettings>
<method />
</configuration>
</component>

View File

@ -0,0 +1,26 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="JPS repack" type="MavenRunConfiguration" factoryName="Maven">
<MavenSettings>
<option name="myGeneralSettings" />
<option name="myRunnerSettings" />
<option name="myRunnerParameters">
<MavenRunnerParameters>
<option name="profiles">
<set />
</option>
<option name="goals">
<list>
<option value="package" />
</list>
</option>
<option name="profilesMap">
<map />
</option>
<option name="resolveToWorkspace" value="false" />
<option name="workingDirPath" value="$PROJECT_DIR$/tools/idea/jps-common" />
</MavenRunnerParameters>
</option>
</MavenSettings>
<method />
</configuration>
</component>

View File

@ -16,6 +16,9 @@
package org.teavm.idea.jps.model;
import com.intellij.util.xmlb.annotations.Transient;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.model.JpsElementChildRole;
import org.jetbrains.jps.model.ex.JpsElementBase;
@ -24,8 +27,11 @@ import org.jetbrains.jps.model.module.JpsModule;
import org.teavm.tooling.TeaVMTargetType;
public class TeaVMJpsConfiguration extends JpsElementBase<TeaVMJpsConfiguration> {
static final JpsElementChildRole<TeaVMJpsConfiguration> ROLE = JpsElementChildRoleBase.create(
"TeaVM configuration");
static final JpsElementChildRole<TeaVMJpsConfiguration> JS_ROLE = JpsElementChildRoleBase.create(
"TeaVM configuration (JS)");
static final JpsElementChildRole<TeaVMJpsConfiguration> WEBASSEMBLY_ROLE = JpsElementChildRoleBase.create(
"TeaVM configuration (WebAssembly)");
@Transient
private TeaVMTargetType targetType;
@ -84,12 +90,15 @@ public class TeaVMJpsConfiguration extends JpsElementBase<TeaVMJpsConfiguration>
this.sourceFilesCopied = sourceFilesCopied;
}
public static TeaVMJpsConfiguration get(JpsModule module) {
return module.getContainer().getChild(ROLE);
public static List<TeaVMJpsConfiguration> getAll(JpsModule module) {
List<TeaVMJpsConfiguration> configurations = new ArrayList<>();
for (JpsElementChildRole<TeaVMJpsConfiguration> role : Arrays.asList(JS_ROLE, WEBASSEMBLY_ROLE)) {
TeaVMJpsConfiguration configuration = module.getContainer().getChild(role);
if (configuration != null) {
configurations.add(configuration);
}
public void setTo(JpsModule module) {
module.getContainer().setChild(ROLE, this);
}
return configurations;
}
@NotNull

View File

@ -20,7 +20,9 @@ import java.util.Arrays;
import java.util.List;
import org.jdom.Element;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jps.model.JpsElement;
import org.jetbrains.jps.model.JpsElementChildRole;
import org.jetbrains.jps.model.module.JpsModule;
import org.jetbrains.jps.model.serialization.JpsModelSerializerExtension;
import org.jetbrains.jps.model.serialization.facet.JpsFacetConfigurationSerializer;
@ -33,35 +35,32 @@ public class TeaVMModelSerializerService extends JpsModelSerializerExtension {
return Arrays.asList(jsSerializer, wasmSerializer);
}
JpsFacetConfigurationSerializer<TeaVMJpsConfiguration> jsSerializer =
new JpsFacetConfigurationSerializer<TeaVMJpsConfiguration>(TeaVMJpsConfiguration.ROLE,
"teavm-js", "TeaVM (JS)") {
private TeaVMFacetSerializer jsSerializer = new TeaVMFacetSerializer(TeaVMJpsConfiguration.JS_ROLE,
"teavm-js", "TeaVM (JS)", TeaVMTargetType.JAVASCRIPT);
private TeaVMFacetSerializer wasmSerializer = new TeaVMFacetSerializer(TeaVMJpsConfiguration.WEBASSEMBLY_ROLE,
"teavm-wasm", "TeaVM (WebAssembly)", TeaVMTargetType.WEBASSEMBLY);
private class TeaVMFacetSerializer
extends JpsFacetConfigurationSerializer<TeaVMJpsConfiguration> {
private TeaVMTargetType targetType;
public TeaVMFacetSerializer(JpsElementChildRole<TeaVMJpsConfiguration> role, String facetTypeId,
@Nullable String facetName, TeaVMTargetType targetType) {
super(role, facetTypeId, facetName);
this.targetType = targetType;
}
@Override
protected TeaVMJpsConfiguration loadExtension(@NotNull Element element, String s, JpsElement jpsElement,
JpsModule jpsModule) {
TeaVMJpsConfiguration configuration = XmlSerializer.deserialize(element, TeaVMJpsConfiguration.class);
configuration.setTargetType(TeaVMTargetType.JAVASCRIPT);
configuration.setTargetType(targetType);
return configuration;
}
@Override
protected void saveExtension(TeaVMJpsConfiguration configuration, Element element, JpsModule jpsModule) {
}
};
JpsFacetConfigurationSerializer<TeaVMJpsConfiguration> wasmSerializer =
new JpsFacetConfigurationSerializer<TeaVMJpsConfiguration>(TeaVMJpsConfiguration.ROLE,
"teavm-wasm", "TeaVM (WebAssembly)") {
@Override
protected TeaVMJpsConfiguration loadExtension(@NotNull Element element, String s, JpsElement jpsElement,
JpsModule jpsModule) {
TeaVMJpsConfiguration configuration = XmlSerializer.deserialize(element, TeaVMJpsConfiguration.class);
configuration.setTargetType(TeaVMTargetType.WEBASSEMBLY);
return configuration;
}
@Override
protected void saveExtension(TeaVMJpsConfiguration configuration, Element element, JpsModule jpsModule) {
}
};
}

View File

@ -68,6 +68,7 @@ import org.teavm.model.MethodReference;
import org.teavm.model.TextLocation;
import org.teavm.model.ValueType;
import org.teavm.tooling.EmptyTeaVMToolLog;
import org.teavm.tooling.TeaVMTargetType;
import org.teavm.tooling.TeaVMTool;
import org.teavm.tooling.TeaVMToolException;
import org.teavm.tooling.sources.DirectorySourceFileProvider;
@ -79,10 +80,11 @@ import org.teavm.vm.TeaVMProgressListener;
class TeaVMBuild {
private final CompileContext context;
private final TeaVMStorageProvider storageProvider = new TeaVMStorageProvider();
private final TeaVMStorageProvider jsStorageProvider = new TeaVMStorageProvider("js");
private final TeaVMStorageProvider wasmStorageProvider = new TeaVMStorageProvider("wasm");
private final List<String> classPathEntries = new ArrayList<>();
private List<String> directoryClassPathEntries;
private TeaVMStorage storage;
private Map<TeaVMTargetType, TeaVMStorage> storages = new HashMap<>();
private final TeaVMBuilderAssistant assistant;
private final Map<String, File> sourceFileCache = new HashMap<>();
private final Map<File, int[]> fileLineCache = new HashMap<>();
@ -94,9 +96,23 @@ class TeaVMBuild {
}
boolean perform(JpsModule module, ModuleBuildTarget target) throws IOException {
storage = context.getProjectDescriptor().dataManager.getStorage(target, storageProvider);
storages.put(TeaVMTargetType.JAVASCRIPT, context.getProjectDescriptor().dataManager.getStorage(
target, jsStorageProvider));
storages.put(TeaVMTargetType.WEBASSEMBLY, context.getProjectDescriptor().dataManager.getStorage(
target, wasmStorageProvider));
TeaVMJpsConfiguration config = TeaVMJpsConfiguration.get(module);
boolean doneSomething = false;
for (TeaVMJpsConfiguration config : TeaVMJpsConfiguration.getAll(module)) {
if (performForSubsystem(module, target, config)) {
doneSomething = true;
}
}
return doneSomething;
}
private boolean performForSubsystem(JpsModule module, ModuleBuildTarget target, TeaVMJpsConfiguration config)
throws IOException {
if (config == null) {
return false;
}
@ -106,7 +122,7 @@ class TeaVMBuild {
directoryClassPathEntries = classPathEntries.stream().filter(name -> new File(name).isDirectory())
.collect(toList());
if (!hasChanges(target)) {
if (!hasChanges(target, config.getTargetType())) {
return false;
}
@ -137,7 +153,7 @@ class TeaVMBuild {
}
if (!errorOccurred && tool.getProblemProvider().getSevereProblems().isEmpty()) {
updateStorage(tool);
updateStorage(tool, config.getTargetType());
}
CallGraph callGraph = tool.getDependencyInfo().getCallGraph();
@ -377,12 +393,13 @@ class TeaVMBuild {
return lines.getAll();
}
private boolean hasChanges(ModuleBuildTarget target) {
private boolean hasChanges(ModuleBuildTarget target, TeaVMTargetType targetType) {
if (!context.getScope().isBuildIncrementally(target.getTargetType())
|| context.getScope().isBuildForced(target)) {
return true;
}
List<TeaVMStorage.Entry> filesToWatch = storage.getParticipatingFiles();
List<TeaVMStorage.Entry> filesToWatch = storages.get(targetType).getParticipatingFiles();
if (filesToWatch == null) {
return true;
}
@ -396,7 +413,7 @@ class TeaVMBuild {
return false;
}
private void updateStorage(TeaVMTool tool) {
private void updateStorage(TeaVMTool tool, TeaVMTargetType targetType) {
Set<String> resources = Stream.concat(tool.getClasses().stream().map(cls -> cls.replace('.', '/') + ".class"),
tool.getUsedResources().stream())
.sorted()
@ -408,7 +425,8 @@ class TeaVMBuild {
})
.filter(Objects::nonNull)
.collect(toList());
storage.setParticipatingFiles(participatingFiles);
storages.get(targetType).setParticipatingFiles(participatingFiles);
}
private Long getTimestamp(String path) {

View File

@ -74,7 +74,6 @@ public class TeaVMBuilder extends ModuleLevelBuilder {
return doneSomething ? ExitCode.OK : ExitCode.NOTHING_DONE;
}
@NotNull
@Override
public String getPresentableName() {

View File

@ -34,8 +34,8 @@ public class TeaVMStorage implements StorageOwner {
private List<Entry> participatingFiles;
private boolean dirty;
TeaVMStorage(File file) throws IOException {
file = new File(file, "teavm.storage");
TeaVMStorage(File file, String suffix) throws IOException {
file = new File(file, "teavm-" + suffix + ".storage");
this.file = file;
if (file.exists()) {
participatingFiles = new ArrayList<>();
@ -106,10 +106,6 @@ public class TeaVMStorage implements StorageOwner {
}
}
public boolean causesBuild(String file) {
return participatingFiles == null || participatingFiles.contains(file);
}
public static class Entry {
public final String path;
public final long timestamp;

View File

@ -21,9 +21,15 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.jps.builders.storage.StorageProvider;
public class TeaVMStorageProvider extends StorageProvider<TeaVMStorage> {
private String suffix;
public TeaVMStorageProvider(String suffix) {
this.suffix = suffix;
}
@NotNull
@Override
public TeaVMStorage createStorage(File file) throws IOException {
return new TeaVMStorage(file);
return new TeaVMStorage(file, suffix);
}
}