package com.intellij.flex.bc; import com.intellij.flex.FlexCommonUtils; import com.intellij.flex.build.FlexCompilerConfigFileUtilBase; import com.intellij.flex.model.bc.ComponentSet; import com.intellij.flex.model.bc.LinkageType; import com.intellij.flex.model.bc.OutputType; import com.intellij.flex.model.bc.TargetPlatform; import com.intellij.flex.util.FlexTestUtils; import com.intellij.javascript.flex.css.FlexStylesIndexableSetContributor; import com.intellij.lang.javascript.flex.FlexModuleType; import com.intellij.lang.javascript.flex.FlexUtils; import com.intellij.lang.javascript.flex.build.CompilerConfigGenerator; import com.intellij.lang.javascript.flex.flexunit.FlexUnitPrecompileTask; import com.intellij.lang.javascript.flex.projectStructure.model.*; import com.intellij.lang.javascript.flex.projectStructure.model.impl.Factory; import com.intellij.lang.javascript.flex.sdk.FlexSdkType2; import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.command.WriteCommandAction; import com.intellij.openapi.module.Module; import com.intellij.openapi.module.ModuleType; import com.intellij.openapi.projectRoots.*; import com.intellij.openapi.roots.OrderRootType; import com.intellij.openapi.roots.RootProvider; import com.intellij.openapi.roots.impl.RootProviderBaseImpl; import com.intellij.openapi.util.Key; import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.vfs.LocalFileSystem; import com.intellij.openapi.vfs.VfsUtilCore; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.newvfs.impl.VfsRootAccess; import com.intellij.testFramework.PlatformTestCase; import com.intellij.testFramework.PsiTestUtil; import com.intellij.util.PathUtil; import gnu.trove.THashMap; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.jps.model.serialization.PathMacroUtil; import java.io.File; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.Method; import java.util.HashMap; import java.util.Map; import static com.intellij.openapi.vfs.VfsUtilCore.convertFromUrl; import static com.intellij.openapi.vfs.VfsUtilCore.urlToPath; public class FlexCompilerConfigTest extends PlatformTestCase { private static final String[] SDK_3_ROOTS = new String[]{ "/frameworks/libs/player/9/playerglobal.swc", "/frameworks/libs/player/10/playerglobal.swc", "/frameworks/libs/air/airglobal.swc", "/frameworks/libs/air/airframework.swc", "/frameworks/libs/air/applicationupdater.swc", "/frameworks/libs/air/applicationupdater_ui.swc", "/frameworks/libs/air/servicemonitor.swc", "/frameworks/libs/flex.swc", "/frameworks/libs/framework.swc", "/frameworks/libs/rpc.swc", "/frameworks/libs/utilities.swc", }; @Override protected void setUp() throws Exception { VfsRootAccess.allowRootAccess(getTestRootDisposable(), urlToPath(convertFromUrl(FlexStylesIndexableSetContributor.class.getResource("FlexStyles.as")))); super.setUp(); } private static final String[] SDK_40_ROOTS = new String[]{ "/frameworks/libs/player/10.0/playerglobal.swc", "/frameworks/libs/air/airglobal.swc", "/frameworks/libs/air/airframework.swc", "/frameworks/libs/air/airspark.swc", "/frameworks/libs/air/applicationupdater.swc", "/frameworks/libs/air/applicationupdater_ui.swc", "/frameworks/libs/air/servicemonitor.swc", "/frameworks/libs/datavisualization.swc", "/frameworks/libs/flash-integration.swc", "/frameworks/libs/flex.swc", "/frameworks/libs/framework.swc", "/frameworks/libs/osmf.swc", "/frameworks/libs/rpc.swc", "/frameworks/libs/spark.swc", "/frameworks/libs/sparkskins.swc", "/frameworks/libs/textLayout.swc", "/frameworks/libs/utilities.swc", }; private static final String[] SDK_45_ROOTS = new String[]{ "/frameworks/libs/player/10.0/playerglobal.swc", "/frameworks/libs/player/10.1/playerglobal.swc", "/frameworks/libs/player/10.2/playerglobal.swc", "/frameworks/libs/player/10.3/playerglobal.swc", "/frameworks/libs/player/11/playerglobal.swc", "/frameworks/libs/player/11.1/playerglobal.swc", "/frameworks/libs/air/airglobal.swc", "/frameworks/libs/air/aircore.swc", "/frameworks/libs/air/airframework.swc", "/frameworks/libs/air/airspark.swc", "/frameworks/libs/air/applicationupdater.swc", "/frameworks/libs/air/applicationupdater_ui.swc", "/frameworks/libs/air/servicemonitor.swc", "/frameworks/libs/advancedgrids.swc", "/frameworks/libs/authoringsupport.swc", "/frameworks/libs/charts.swc", "/frameworks/libs/core.swc", "/frameworks/libs/flash-integration.swc", "/frameworks/libs/framework.swc", "/frameworks/libs/osmf.swc", "/frameworks/libs/rpc.swc", "/frameworks/libs/spark.swc", "/frameworks/libs/spark_dmv.swc", "/frameworks/libs/sparkskins.swc", "/frameworks/libs/textLayout.swc", "/frameworks/libs/mobile/mobilecomponents.swc", "/frameworks/libs/mx/mx.swc", }; private static final String[] SDK_46_ROOTS = SDK_45_ROOTS; private static final String[] AIR_SDK_ROOTS = new String[]{ "/frameworks/libs/player/11.6/playerglobal.swc", "/frameworks/libs/air/airglobal.swc", "/frameworks/libs/air/aircore.swc", "/frameworks/libs/air/airframework.swc", "/frameworks/libs/air/applicationupdater.swc", "/frameworks/libs/air/applicationupdater_ui.swc", "/frameworks/libs/air/servicemonitor.swc", "/frameworks/libs/asc-support.swc", "/frameworks/libs/core.swc", }; private static final String TEST_FLEX_SDK_NAME = "Test Flex SDK"; private static String getTestDataPath() { return FlexTestUtils.getTestDataPath("compilerConfig") + "/"; } @Override protected ModuleType getModuleType() { return FlexModuleType.getInstance(); } @NotNull @Override protected Module createMainModule() throws IOException { final Module module = super.createMainModule(); new WriteCommandAction.Simple(myProject) { @Override protected void run() throws Throwable { VirtualFile moduleDir = module.getModuleFile().getParent(); VirtualFile src = moduleDir.createChildDirectory(this, "src"); PsiTestUtil.addContentRoot(module, moduleDir); PsiTestUtil.addSourceRoot(module, src); } }.execute(); return module; } private static ModifiableFlexBuildConfiguration createBuildConfiguration(final TargetPlatform targetPlatform, final boolean isPureAS, final OutputType outputType, final String targetPlayer) { final ModifiableFlexBuildConfiguration bc = Factory.createBuildConfiguration(); bc.setTargetPlatform(targetPlatform); bc.setPureAs(isPureAS); bc.setOutputType(outputType); bc.setMainClass("Main"); setOutputPaths(bc); bc.getDependencies().setSdkEntry(Factory.createSdkEntry(TEST_FLEX_SDK_NAME)); bc.getDependencies().setTargetPlayer(targetPlayer); bc.getDependencies().setComponentSet(ComponentSet.SparkAndMx); bc.getDependencies().setFrameworkLinkage(LinkageType.Default); return bc; } private static void setOutputPaths(final ModifiableFlexBuildConfiguration bc) { bc.setOutputFileName(bc.getName() + (bc.getOutputType() == OutputType.Library ? ".swc" : ".swf")); bc.setOutputFolder("output/folder"); } private void doTest(final String sdkVersion, final FlexBuildConfiguration bc) throws Exception { doTest(sdkVersion, bc, Factory.createCompilerOptions(), Factory.createCompilerOptions(), "", null); } private void doTest(final String sdkVersion, final FlexBuildConfiguration bc, final CompilerOptions moduleLevelOptions, final CompilerOptions projectLevelOptions, final String suffix, @Nullable Map<String, String> additionalMacros) throws Exception { WriteCommandAction.runWriteCommandAction(null, () -> { ProjectJdkTable.getInstance().addJdk(createTestSdk(sdkVersion), getTestRootDisposable()); }); final Constructor<CompilerConfigGenerator> constructor = CompilerConfigGenerator.class.getDeclaredConstructor(Module.class, FlexBuildConfiguration.class, CompilerOptions.class, CompilerOptions.class); constructor.setAccessible(true); final CompilerConfigGenerator configGenerator = constructor.newInstance(getModule(), bc, moduleLevelOptions, projectLevelOptions); final Method method = CompilerConfigGenerator.class.getDeclaredMethod("generateConfigFileText"); method.setAccessible(true); String text = (String)method.invoke(configGenerator); if (bc.isTempBCForCompilation()) { text = FlexCompilerConfigFileUtilBase .mergeWithCustomConfigFile(text, bc.getCompilerOptions().getAdditionalConfigFilePath(), true, false); } VirtualFile expectedFile = getVirtualFile(getTestName(false) + suffix + ".xml"); String expectedText = StringUtil.convertLineSeparators(VfsUtilCore.loadText(expectedFile)); assertEquals(expectedFile.getName(), replaceMacros(expectedText, bc.getSdk(), additionalMacros), text); } private Sdk createTestSdk(final String sdkVersion) { return new Sdk() { @Override @NotNull public SdkType getSdkType() { return FlexSdkType2.getInstance(); } @Override @NotNull public String getName() { return TEST_FLEX_SDK_NAME; } @Override public String getVersionString() { return sdkVersion; } @Override public String getHomePath() { return getTestDataPath() + (sdkVersion.startsWith("AIR SDK ") ? "air_sdk" : "flex_sdk_" + sdkVersion.substring(0, "0.0.0".length())); } @Override public VirtualFile getHomeDirectory() { return null; } @Override @NotNull public RootProvider getRootProvider() { return new RootProviderBaseImpl() { @Override @NotNull public String[] getUrls(@NotNull final OrderRootType rootType) { final String[] relPaths = sdkVersion.startsWith("AIR SDK ") ? AIR_SDK_ROOTS : sdkVersion.startsWith("4.6") ? SDK_46_ROOTS : sdkVersion.startsWith("4.5") ? SDK_45_ROOTS : sdkVersion.startsWith("4") ? SDK_40_ROOTS : SDK_3_ROOTS; final String[] urls = new String[relPaths.length]; for (int i = 0; i < relPaths.length; i++) { urls[i] = getHomePath() + relPaths[i]; } return urls; } @Override @NotNull public VirtualFile[] getFiles(@NotNull final OrderRootType rootType) { return VirtualFile.EMPTY_ARRAY; } }; } @Override @NotNull public SdkModificator getSdkModificator() { return null; } @Override public SdkAdditionalData getSdkAdditionalData() { return null; } @Override public <T> T getUserData(@NotNull final Key<T> key) { return null; } @Override public <T> void putUserData(@NotNull final Key<T> key, @Nullable final T value) { } @Override @NotNull public Object clone() throws CloneNotSupportedException { return super.clone(); } }; } private static Map<String, String> createMap(String... keysAndValues) { final Map<String, String> result = new THashMap<>(); for (int i = 0; i < keysAndValues.length; i++) { //noinspection AssignmentToForLoopParameter result.put(keysAndValues[i], keysAndValues[++i]); } return result; } public void testFlexAppSdk45() throws Exception { final ModifiableFlexBuildConfiguration bc = createBuildConfiguration(TargetPlatform.Web, false, OutputType.Application, "11.1"); bc.getCompilerOptions().setAllOptions(createMap("compiler.locale", "ru_RU\nen_US\nfr_FR", "compiler.context-root", "context-root", "compiler.define", "a\tb\nc\td", "compiler.namespaces.namespace", "A\tB")); doTest("4.5.1.21328", bc); } public void testFlexLibSdk45() throws Exception { final ModifiableFlexBuildConfiguration bc = createBuildConfiguration(TargetPlatform.Web, false, OutputType.Library, "11"); bc.getCompilerOptions().setAllOptions(createMap("compiler.theme", "custom", "compiler.namespaces.namespace", "A\tB")); doTest("4.5.0", bc); } public void testASAppSdk45() throws Exception { final ModifiableFlexBuildConfiguration bc = createBuildConfiguration(TargetPlatform.Web, true, OutputType.Application, "10.3"); final ModifiableCompilerOptions moduleLevelOptions = Factory.createCompilerOptions(); final ModifiableCompilerOptions projectLevelOptions = Factory.createCompilerOptions(); bc.getCompilerOptions().setAllOptions(createMap("compiler.debug.swc", "false", "compiler.services", "BC", "compiler.defaults-css-files", "BC", "compiler.defaults-css-url", "BC")); moduleLevelOptions.setAllOptions(createMap("compiler.services", "MODULE", "compiler.context-root", "MODULE", "compiler.defaults-css-files", "MODULE", "compiler.keep-as3-metadata", "MODULE")); projectLevelOptions.setAllOptions(createMap("compiler.services", "PROJECT", "compiler.context-root", "PROJECT", "compiler.defaults-css-url", "PROJECT", "compiler.keep-generated-actionscript", "PROJECT")); doTest("4.5.0", bc, moduleLevelOptions, projectLevelOptions, "", null); } public void testAirAppSdk45() throws Exception { doTest("4.6.0", createBuildConfiguration(TargetPlatform.Desktop, false, OutputType.Application, "10.2")); } public void testMobileAppSdk45() throws Exception { doTest("4.5.0", createBuildConfiguration(TargetPlatform.Mobile, false, OutputType.Application, "10.1")); } public void testFlexAppSdk41() throws Exception { final ModifiableFlexBuildConfiguration bc = createBuildConfiguration(TargetPlatform.Web, false, OutputType.Application, "10.0"); final ModifiableCompilerOptions projectLevelOptions = Factory.createCompilerOptions(); projectLevelOptions.setAllOptions(createMap("compiler.debug.swf", "false")); bc.getCompilerOptions().setAllOptions(createMap("compiler.locale", "", "metadata.creator", "<><>")); doTest("4.1.0.16076", bc, Factory.createCompilerOptions(), projectLevelOptions, "", null); } public void testFlexLibSdk40() throws Exception { final ModifiableFlexBuildConfiguration bc = createBuildConfiguration(TargetPlatform.Web, false, OutputType.Library, "10.0"); bc.getDependencies().setFrameworkLinkage(LinkageType.Merged); bc.getCompilerOptions().setAllOptions(createMap("compiler.debug.swc", "false", "compiler.namespaces.namespace", "A\tB\nC\tD")); doTest("4.0.0.14159", bc); } public void testFlexLibMxOnlySdk40() throws Exception { final ModifiableFlexBuildConfiguration bc = createBuildConfiguration(TargetPlatform.Web, false, OutputType.Library, "10.0"); bc.getDependencies().setFrameworkLinkage(LinkageType.Merged); bc.getDependencies().setComponentSet(ComponentSet.MxOnly); doTest("4.0.0.14159", bc); } public void testFlexAppSparkOnlySdk46() throws Exception { final ModifiableFlexBuildConfiguration bc = createBuildConfiguration(TargetPlatform.Web, false, OutputType.Application, "10.0"); bc.getDependencies().setFrameworkLinkage(LinkageType.Merged); bc.getDependencies().setComponentSet(ComponentSet.SparkOnly); doTest("4.6.0", bc); } public void testFlexAppSdk3() throws Exception { doTest("3.6.0.16995", createBuildConfiguration(TargetPlatform.Web, false, OutputType.Application, "9")); } public void testFlexAppSdk3Rsl() throws Exception { final ModifiableFlexBuildConfiguration bc = createBuildConfiguration(TargetPlatform.Web, false, OutputType.Application, "9"); bc.getDependencies().setFrameworkLinkage(LinkageType.RSL); bc.getCompilerOptions().setAdditionalOptions("-services=some_path"); doTest("3.6.0.16995", bc); } public void testMergeWithAdditionalConfigFile() throws Exception { final String sdkVersion = "4.6.0"; final ModifiableFlexBuildConfiguration bc = createBuildConfiguration(TargetPlatform.Web, false, OutputType.Application, "11.1"); VirtualFile f = getVirtualFile(getTestName(false) + "_config.xml"); ApplicationManager.getApplication().runWriteAction(() -> { VirtualFile additionalConfigFile; try { additionalConfigFile = FlexUtils.addFileWithContent(f.getName(), replaceMacros(VfsUtilCore.loadText(f), createTestSdk(sdkVersion), null), myModule.getModuleFile().getParent()); } catch (IOException e) { throw new RuntimeException(e); } bc.setOutputFileName("SetInBC.swf"); bc.getCompilerOptions().setAdditionalConfigFilePath(additionalConfigFile.getPath()); }); bc.getCompilerOptions().setAllOptions(createMap("compiler.locale", "en_US\nja_JP", "compiler.services", "services")); doTest(sdkVersion, Factory.getTemporaryCopyForCompilation(bc)); } private String replaceMacros(String text, final Sdk sdk, @Nullable Map<String, String> additionalMacros) { text = text.replace("$" + PathMacroUtil.MODULE_DIR_MACRO_NAME + "$", myModule.getModuleFile().getParent().getPath()); text = text.replace("$FLEX_SDK$", sdk.getHomePath()); if (additionalMacros != null) { for (String key : additionalMacros.keySet()) { text = text.replace(key, additionalMacros.get(key)); } } return text; } public void testTestDependencies() throws Exception { final Module module2 = FlexTestUtils.createModule(myProject, "module2", getVirtualFile("m2")); final Module module3 = FlexTestUtils.createModule(myProject, "module3", getVirtualFile("m3")); VirtualFile moduleDir = myModule.getModuleFile().getParent(); FlexTestUtils.addFlexLibrary(false, myModule, "Lib", true, getTestDataPath(), "Lib", null, null, LinkageType.Test, moduleDir); FlexTestUtils.addFlexLibrary(false, myModule, "Lib2", true, getTestDataPath(), "Lib2", null, null, LinkageType.Merged, moduleDir); FlexTestUtils.addFlexLibrary(true, myModule, "Lib3", true, getTestDataPath(), "Lib3", null, null, LinkageType.Test, moduleDir); FlexTestUtils.addFlexLibrary(true, myModule, "Lib4", true, getTestDataPath(), "Lib4", null, null, LinkageType.Merged, moduleDir); FlexTestUtils.modifyConfigs(myProject, editor -> { ModifiableFlexBuildConfiguration bc1 = editor.getConfigurations(myModule)[0]; bc1.getDependencies().setSdkEntry(Factory.createSdkEntry(TEST_FLEX_SDK_NAME)); bc1.setName("bc1"); setOutputPaths(bc1); ModifiableFlexBuildConfiguration bc2 = editor.getConfigurations(module2)[0]; bc2.setOutputType(OutputType.Library); bc2.setName("bc2"); setOutputPaths(bc2); ModifiableFlexBuildConfiguration bc3 = editor.getConfigurations(module3)[0]; bc3.setOutputType(OutputType.Library); bc2.setName("bc3"); setOutputPaths(bc3); ModifiableBuildConfigurationEntry entry1 = editor.createBcEntry(bc1.getDependencies(), bc2, null); entry1.getDependencyType().setLinkageType(LinkageType.Test); bc1.getDependencies().getModifiableEntries().add(entry1); ModifiableBuildConfigurationEntry entry2 = editor.createBcEntry(bc2.getDependencies(), bc3, null); entry2.getDependencyType().setLinkageType(LinkageType.Test); bc2.getDependencies().getModifiableEntries().add(entry2); }); final FlexBuildConfiguration bc = FlexBuildConfigurationManager.getInstance(myModule).getActiveConfiguration(); ModifiableFlexBuildConfiguration tempBc = Factory.getTemporaryCopyForCompilation(bc); doTest("4.5.1.21328", tempBc, Factory.createCompilerOptions(), Factory.createCompilerOptions(), "_1", null); tempBc.setMainClass(FlexCommonUtils.FLEX_UNIT_LAUNCHER); Map<String, String> map = new HashMap<>(); map.put("$FLEX_UNIT_TEMP_FOLDER$", FlexUnitPrecompileTask.getPathToFlexUnitTempDirectory(myProject)); map.put("$FLEX_DIR$", PathUtil.getParentPath(PathUtil.getParentPath(FlexTestUtils.getTestDataPath("")))); String path = FileUtil.toSystemIndependentName(FlexCommonUtils.getPathToBundledJar("")); VfsRootAccess.allowRootAccess(getTestRootDisposable(), path); doTest("4.5.1.21328", tempBc, Factory.createCompilerOptions(), Factory.createCompilerOptions(), "_2", map); } private static VirtualFile getVirtualFile(@NonNls String filePath) { String fullPath = getTestDataPath() + filePath; final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/')); assertNotNull("file " + fullPath + " not found", vFile); return vFile; } public void testAirSdk() throws Exception { doTest("AIR SDK 3.6.0.5990", createBuildConfiguration(TargetPlatform.Web, true, OutputType.Application, "11.6")); } }