From e93a0f1a6efcd459512c2ea238d67ab74606317f Mon Sep 17 00:00:00 2001 From: Alexey Andreev Date: Sun, 6 Nov 2016 22:00:15 +0300 Subject: [PATCH] IDEA: add WebAssembly facet --- .../idea/jps/model/TeaVMJpsConfiguration.java | 14 ++++ .../model/TeaVMModelSerializerService.java | 25 +++++++- .../java/org/teavm/idea/jps/TeaVMBuild.java | 1 + .../main/java/org/teavm/idea/TeaVMFacet.java | 7 +- .../java/org/teavm/idea/TeaVMFacetType.java | 2 +- .../teavm/idea/TeaVMWebAssemblyFacetType.java | 64 +++++++++++++++++++ .../teavm/idea/maven/TeaVMMavenImporter.java | 57 ++++++++++++++--- .../src/main/resources/META-INF/plugin.xml | 1 + 8 files changed, 155 insertions(+), 16 deletions(-) create mode 100644 tools/idea/src/main/java/org/teavm/idea/TeaVMWebAssemblyFacetType.java diff --git a/tools/idea/jps-common/src/main/java/org/teavm/idea/jps/model/TeaVMJpsConfiguration.java b/tools/idea/jps-common/src/main/java/org/teavm/idea/jps/model/TeaVMJpsConfiguration.java index dd0a845c8..901a6706c 100644 --- a/tools/idea/jps-common/src/main/java/org/teavm/idea/jps/model/TeaVMJpsConfiguration.java +++ b/tools/idea/jps-common/src/main/java/org/teavm/idea/jps/model/TeaVMJpsConfiguration.java @@ -15,21 +15,35 @@ */ package org.teavm.idea.jps.model; +import com.intellij.util.xmlb.annotations.Transient; import org.jetbrains.annotations.NotNull; import org.jetbrains.jps.model.JpsElementChildRole; import org.jetbrains.jps.model.ex.JpsElementBase; import org.jetbrains.jps.model.ex.JpsElementChildRoleBase; import org.jetbrains.jps.model.module.JpsModule; +import org.teavm.tooling.TeaVMTargetType; public class TeaVMJpsConfiguration extends JpsElementBase { static final JpsElementChildRole ROLE = JpsElementChildRoleBase.create( "TeaVM configuration"); + + @Transient + private TeaVMTargetType targetType; + private String mainClass; private String targetDirectory; private boolean minifying; private boolean sourceMapsFileGenerated = true; private boolean sourceFilesCopied = true; + public TeaVMTargetType getTargetType() { + return targetType; + } + + public void setTargetType(TeaVMTargetType targetType) { + this.targetType = targetType; + } + public String getMainClass() { return mainClass; } diff --git a/tools/idea/jps-common/src/main/java/org/teavm/idea/jps/model/TeaVMModelSerializerService.java b/tools/idea/jps-common/src/main/java/org/teavm/idea/jps/model/TeaVMModelSerializerService.java index 5bc061e3d..75e66be67 100644 --- a/tools/idea/jps-common/src/main/java/org/teavm/idea/jps/model/TeaVMModelSerializerService.java +++ b/tools/idea/jps-common/src/main/java/org/teavm/idea/jps/model/TeaVMModelSerializerService.java @@ -24,21 +24,40 @@ import org.jetbrains.jps.model.JpsElement; import org.jetbrains.jps.model.module.JpsModule; import org.jetbrains.jps.model.serialization.JpsModelSerializerExtension; import org.jetbrains.jps.model.serialization.facet.JpsFacetConfigurationSerializer; +import org.teavm.tooling.TeaVMTargetType; public class TeaVMModelSerializerService extends JpsModelSerializerExtension { @NotNull @Override public List> getFacetConfigurationSerializers() { - return Arrays.asList(serializer); + return Arrays.asList(jsSerializer, wasmSerializer); } - JpsFacetConfigurationSerializer serializer = + JpsFacetConfigurationSerializer jsSerializer = new JpsFacetConfigurationSerializer(TeaVMJpsConfiguration.ROLE, "teavm-js", "TeaVM (JS)") { @Override protected TeaVMJpsConfiguration loadExtension(@NotNull Element element, String s, JpsElement jpsElement, JpsModule jpsModule) { - return XmlSerializer.deserialize(element, TeaVMJpsConfiguration.class); + TeaVMJpsConfiguration configuration = XmlSerializer.deserialize(element, TeaVMJpsConfiguration.class); + configuration.setTargetType(TeaVMTargetType.JAVASCRIPT); + return configuration; + } + + @Override + protected void saveExtension(TeaVMJpsConfiguration configuration, Element element, JpsModule jpsModule) { + } + }; + + JpsFacetConfigurationSerializer wasmSerializer = + new JpsFacetConfigurationSerializer(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 diff --git a/tools/idea/jps-plugin/src/main/java/org/teavm/idea/jps/TeaVMBuild.java b/tools/idea/jps-plugin/src/main/java/org/teavm/idea/jps/TeaVMBuild.java index 194385adf..a1984e9c8 100644 --- a/tools/idea/jps-plugin/src/main/java/org/teavm/idea/jps/TeaVMBuild.java +++ b/tools/idea/jps-plugin/src/main/java/org/teavm/idea/jps/TeaVMBuild.java @@ -113,6 +113,7 @@ class TeaVMBuild { TeaVMTool tool = new TeaVMTool(); tool.setProgressListener(createProgressListener(context)); tool.setLog(new EmptyTeaVMToolLog()); + tool.setTargetType(config.getTargetType()); tool.setMainClass(config.getMainClass()); tool.setTargetDirectory(new File(config.getTargetDirectory())); tool.setClassLoader(buildClassLoader()); diff --git a/tools/idea/src/main/java/org/teavm/idea/TeaVMFacet.java b/tools/idea/src/main/java/org/teavm/idea/TeaVMFacet.java index d399ef883..ef4278dd4 100644 --- a/tools/idea/src/main/java/org/teavm/idea/TeaVMFacet.java +++ b/tools/idea/src/main/java/org/teavm/idea/TeaVMFacet.java @@ -16,11 +16,14 @@ package org.teavm.idea; import com.intellij.facet.Facet; +import com.intellij.facet.FacetType; import com.intellij.openapi.module.Module; import org.jetbrains.annotations.NotNull; +import org.jetbrains.annotations.Nullable; public class TeaVMFacet extends Facet { - public TeaVMFacet(@NotNull Module module, @NotNull String name, @NotNull TeaVMFacetConfiguration configuration) { - super(TeaVMFacetType.getInstance(), module, name, configuration, null); + public TeaVMFacet(@NotNull FacetType facetType, @NotNull Module module, + @NotNull String name, @NotNull TeaVMFacetConfiguration configuration, @Nullable Facet underlyingFacet) { + super(facetType, module, name, configuration, underlyingFacet); } } diff --git a/tools/idea/src/main/java/org/teavm/idea/TeaVMFacetType.java b/tools/idea/src/main/java/org/teavm/idea/TeaVMFacetType.java index 12e80540f..40c23c719 100644 --- a/tools/idea/src/main/java/org/teavm/idea/TeaVMFacetType.java +++ b/tools/idea/src/main/java/org/teavm/idea/TeaVMFacetType.java @@ -43,7 +43,7 @@ public class TeaVMFacetType extends FacetType { + public static final FacetTypeId TYPE_ID = new FacetTypeId<>("teavm-wasm"); + private static final Icon icon = IconLoader.getIcon("/teavm-16.png"); + + public TeaVMWebAssemblyFacetType() { + super(TYPE_ID, "teavm-wasm", "TeaVM (WebAssembly)"); + } + + @Override + public TeaVMFacetConfiguration createDefaultConfiguration() { + return new TeaVMFacetConfiguration(); + } + + @Override + public TeaVMFacet createFacet(@NotNull Module module, String name, @NotNull TeaVMFacetConfiguration configuration, + @Nullable Facet underlyingFacet) { + return new TeaVMFacet(this, module, name, configuration, underlyingFacet); + } + + @Override + public boolean isSuitableModuleType(ModuleType moduleType) { + return moduleType instanceof JavaModuleType; + } + + @Nullable + @Override + public Icon getIcon() { + return icon; + } + + @NotNull + public static TeaVMWebAssemblyFacetType getInstance() { + return (TeaVMWebAssemblyFacetType) FacetTypeRegistry.getInstance().findFacetType(TYPE_ID); + } +} diff --git a/tools/idea/src/main/java/org/teavm/idea/maven/TeaVMMavenImporter.java b/tools/idea/src/main/java/org/teavm/idea/maven/TeaVMMavenImporter.java index df91e3ad2..ab2f9e769 100644 --- a/tools/idea/src/main/java/org/teavm/idea/maven/TeaVMMavenImporter.java +++ b/tools/idea/src/main/java/org/teavm/idea/maven/TeaVMMavenImporter.java @@ -16,10 +16,13 @@ package org.teavm.idea.maven; import com.intellij.facet.FacetManager; +import com.intellij.facet.FacetType; import com.intellij.openapi.externalSystem.service.project.IdeModifiableModelsProvider; import com.intellij.openapi.module.Module; +import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Set; import org.jdom.Element; import org.jetbrains.idea.maven.importing.MavenImporter; import org.jetbrains.idea.maven.importing.MavenRootModelAdapter; @@ -29,8 +32,11 @@ import org.jetbrains.idea.maven.project.MavenProjectChanges; import org.jetbrains.idea.maven.project.MavenProjectsProcessorTask; import org.jetbrains.idea.maven.project.MavenProjectsTree; import org.teavm.idea.TeaVMFacet; +import org.teavm.idea.TeaVMFacetConfiguration; import org.teavm.idea.TeaVMFacetType; +import org.teavm.idea.TeaVMWebAssemblyFacetType; import org.teavm.idea.jps.model.TeaVMJpsConfiguration; +import org.teavm.tooling.TeaVMTargetType; public class TeaVMMavenImporter extends MavenImporter { public TeaVMMavenImporter() { @@ -49,35 +55,53 @@ public class TeaVMMavenImporter extends MavenImporter { List postTasks) { FacetManager facetManager = FacetManager.getInstance(module); + Set targetTypes = new HashSet<>(); for (MavenPlugin mavenPlugin : mavenProject.getPlugins()) { if (mavenPlugin.getGroupId().equals(myPluginGroupID) && mavenPlugin.getArtifactId().equals(myPluginArtifactID)) { - updateConfiguration(mavenPlugin, facetManager, module); + updateConfiguration(mavenPlugin, facetManager, module, targetTypes); } } } - private void updateConfiguration(MavenPlugin plugin, FacetManager facetManager, Module module) { + private void updateConfiguration(MavenPlugin plugin, FacetManager facetManager, Module module, + Set targetTypes) { if (plugin.getConfigurationElement() != null) { - updateConfiguration(plugin.getConfigurationElement(), facetManager, module); + updateConfiguration(plugin.getConfigurationElement(), facetManager, module, targetTypes); } for (MavenPlugin.Execution execution : plugin.getExecutions()) { if (execution.getGoals().contains("compile")) { if (execution.getConfigurationElement() != null) { - updateConfiguration(execution.getConfigurationElement(), facetManager, module); + updateConfiguration(execution.getConfigurationElement(), facetManager, module, targetTypes); } - break; } } } - private void updateConfiguration(Element source, FacetManager facetManager, Module module) { - TeaVMFacet facet = facetManager.getFacetByType(TeaVMFacetType.TYPE_ID); + private void updateConfiguration(Element source, FacetManager facetManager, Module module, + Set targetTypes) { + FacetType facetType; + switch (getTargetType(source)) { + case JAVASCRIPT: + facetType = TeaVMFacetType.getInstance(); + break; + case WEBASSEMBLY: + facetType = TeaVMWebAssemblyFacetType.getInstance(); + break; + default: + return; + } + + if (!targetTypes.add(facetType.getStringId())) { + return; + } + + TeaVMFacet facet = facetManager.getFacetByType(facetType.getId()); if (facet == null) { - TeaVMFacetType type = TeaVMFacetType.getInstance(); - facet = new TeaVMFacet(module, "TeaVM (JS)", type.createDefaultConfiguration()); - facetManager.addFacet(type, facet.getName(), facet); + facet = new TeaVMFacet(facetType, module, facetType.getDefaultFacetName(), + facetType.createDefaultConfiguration(), null); + facetManager.addFacet(facetType, facet.getName(), facet); } TeaVMJpsConfiguration configuration = facet.getConfiguration().getState(); @@ -104,4 +128,17 @@ public class TeaVMMavenImporter extends MavenImporter { facet.getConfiguration().loadState(configuration); } + + private TeaVMTargetType getTargetType(Element source) { + for (Element child : source.getChildren()) { + if (child.getName().equals("targetType")) { + try { + return TeaVMTargetType.valueOf(child.getTextTrim()); + } catch (IllegalArgumentException e) { + // do nothing, continue iterating + } + } + } + return TeaVMTargetType.JAVASCRIPT; + } } diff --git a/tools/idea/src/main/resources/META-INF/plugin.xml b/tools/idea/src/main/resources/META-INF/plugin.xml index 7c107432e..397541b67 100644 --- a/tools/idea/src/main/resources/META-INF/plugin.xml +++ b/tools/idea/src/main/resources/META-INF/plugin.xml @@ -32,6 +32,7 @@ +