diff --git a/asconfigc/src/main/java/com/as3mxml/asconfigc/ASConfigCOptions.java b/asconfigc/src/main/java/com/as3mxml/asconfigc/ASConfigCOptions.java index 0c89d4194..e618a1a67 100644 --- a/asconfigc/src/main/java/com/as3mxml/asconfigc/ASConfigCOptions.java +++ b/asconfigc/src/main/java/com/as3mxml/asconfigc/ASConfigCOptions.java @@ -54,6 +54,7 @@ public class ASConfigCOptions { public boolean verbose = false; public List jvmargs = null; public boolean printConfig = false; + public List tokens = null; public ASConfigCOptions(String project, String sdk, Boolean debug, String air, String storepass, Boolean unpackageANEs, IASConfigCCompiler compiler) { @@ -131,6 +132,11 @@ public ASConfigCOptions(CommandLine line) { String printConfigString = line.getOptionValue(OPTION_PRINT_CONFIG, Boolean.FALSE.toString()); printConfig = printConfigString.equals(Boolean.TRUE.toString()); } - compiler = new DefaultCompiler(verbose, jvmargs); + if (line.getArgList().size() != 0) { + tokens = line.getArgList().stream().filter((v) -> { + return v.startsWith("+"); + }).collect(Collectors.toList()); + } + compiler = new DefaultCompiler(verbose, jvmargs, tokens); } -} \ No newline at end of file +} diff --git a/asconfigc/src/main/java/com/as3mxml/asconfigc/compiler/DefaultCompiler.java b/asconfigc/src/main/java/com/as3mxml/asconfigc/compiler/DefaultCompiler.java index 7c26c0be1..b01ba21d5 100644 --- a/asconfigc/src/main/java/com/as3mxml/asconfigc/compiler/DefaultCompiler.java +++ b/asconfigc/src/main/java/com/as3mxml/asconfigc/compiler/DefaultCompiler.java @@ -27,16 +27,18 @@ public class DefaultCompiler implements IASConfigCCompiler { public DefaultCompiler() { - this(false, null); + this(false, null, null); } - public DefaultCompiler(boolean verbose, List jvmargs) { + public DefaultCompiler(boolean verbose, List jvmargs, List tokens) { this.verbose = verbose; this.jvmargs = jvmargs; + this.tokens = tokens; } private boolean verbose = false; private List jvmargs = null; + private List tokens = null; public void compile(String projectType, List compilerOptions, Path workspaceRoot, Path sdkPath) throws ASConfigCException { @@ -48,6 +50,11 @@ public void compile(String projectType, List compilerOptions, Path works System.out.println("Compiling application..."); } } + + if (tokens != null) { + compilerOptions.addAll(0, tokens); + } + boolean sdkIsRoyale = ApacheRoyaleUtils.isValidSDK(sdkPath) != null; Path jarPath = ProjectUtils.findCompilerJarPath(projectType, sdkPath.toString(), !sdkIsRoyale); if (jarPath == null) { @@ -99,4 +106,4 @@ public void compile(String projectType, List compilerOptions, Path works throw new ASConfigCException("Failed to execute compiler: " + e.getMessage()); } } -} \ No newline at end of file +} diff --git a/language-server/src/main/java/com/as3mxml/vscode/ActionScriptServices.java b/language-server/src/main/java/com/as3mxml/vscode/ActionScriptServices.java index beed9eea4..122ad7af5 100644 --- a/language-server/src/main/java/com/as3mxml/vscode/ActionScriptServices.java +++ b/language-server/src/main/java/com/as3mxml/vscode/ActionScriptServices.java @@ -227,6 +227,7 @@ public class ActionScriptServices implements TextDocumentService, WorkspaceServi private SimpleProjectConfigStrategy fallbackConfig; private CompilerShell compilerShell; private String jvmargs; + private List tokens; public ActionScriptServices(IProjectConfigStrategyFactory factory) { compilerWorkspace = new Workspace(); @@ -1246,6 +1247,7 @@ public void didChangeConfiguration(DidChangeConfigurationParams params) { this.updateRealTimeProblems(settings); this.updateSourcePathWarning(settings); this.updateJVMArgs(settings); + this.updateTokens(settings); this.updateConcurrentRequests(settings); this.updateCodeGenerationGetterSettersForcePublicFunctions(settings); this.updateCodeGenerationGetterSettersForcePrivateVariable(settings); @@ -2356,6 +2358,42 @@ private void updateJVMArgs(JsonObject settings) { } } + private void updateTokens(JsonObject settings) { + if (!settings.has("as3mxml")) { + return; + } + JsonObject as3mxml = settings.get("as3mxml").getAsJsonObject(); + if (!as3mxml.has("asconfigc")) { + return; + } + JsonObject asconfigc = as3mxml.get("asconfigc").getAsJsonObject(); + if (!asconfigc.has("additionalTokens")) { + return; + } + JsonObject additionalTokens = asconfigc.get("additionalTokens").getAsJsonObject(); + + List newTokens = null; + if (additionalTokens.size() > 0) { + newTokens = additionalTokens.entrySet().stream().filter( + entry -> entry.getValue().isJsonPrimitive() && entry.getValue().getAsJsonPrimitive().isString()) + .map(entry -> "+" + entry.getKey() + "=" + entry.getValue().getAsString()) + .collect(Collectors.toList()); + } + + if ((tokens == null && newTokens == null) || (newTokens != null && newTokens.equals(tokens))) { + return; + } + + tokens = newTokens; + if (compilerShell != null) { + compilerShell.dispose(); + compilerShell = null; + } + + this.actionScriptProjectManager.getAllProjectData().stream().forEach(d -> d.config.setTokens(tokens)); + checkForProblemsNow(true); + } + private void updateConcurrentRequests(JsonObject settings) { if (!settings.has("as3mxml")) { return; @@ -2846,7 +2884,7 @@ private CompletableFuture executeQuickCompileCommand(ExecuteCommandParam String[] argsArray = jvmargs.split(" "); argsList = Arrays.stream(argsArray).collect(Collectors.toList()); } - compilerShell = new CompilerShell(languageClient, argsList); + compilerShell = new CompilerShell(languageClient, argsList, tokens); } String frameworkLib = System.getProperty(PROPERTY_FRAMEWORK_LIB); Path frameworkSDKHome = Paths.get(frameworkLib, ".."); diff --git a/language-server/src/main/java/com/as3mxml/vscode/compiler/CompilerShell.java b/language-server/src/main/java/com/as3mxml/vscode/compiler/CompilerShell.java index 34f50018a..850a97287 100644 --- a/language-server/src/main/java/com/as3mxml/vscode/compiler/CompilerShell.java +++ b/language-server/src/main/java/com/as3mxml/vscode/compiler/CompilerShell.java @@ -65,11 +65,14 @@ public class CompilerShell implements IASConfigCCompiler { private boolean isRoyale = false; private boolean isAIR = false; private List jvmargs = null; + private List tokens = null; private boolean active = false; - public CompilerShell(ActionScriptLanguageClient languageClient, List jvmargs) throws URISyntaxException { + public CompilerShell(ActionScriptLanguageClient languageClient, List jvmargs, List tokens) + throws URISyntaxException { this.languageClient = languageClient; this.jvmargs = jvmargs; + this.tokens = tokens; URI uri = getClass().getProtectionDomain().getCodeSource().getLocation().toURI(); Path binPath = Paths.get(uri).getParent().normalize(); rcshPath = binPath.resolve(FILE_NAME_RCSH); @@ -367,11 +370,18 @@ private String getNewCommand(String projectType, List compilerOptions) { } else { command.append(EXECUTABLE_MXMLC); } + + for (String token : tokens) { + command.append(token); + command.append(" "); + } + command.append(" "); for (String option : compilerOptions) { command.append(option); command.append(" "); } + command.append("\n"); return command.toString(); } @@ -393,4 +403,4 @@ private String getCompileCommand() { builder.append("\n"); return builder.toString(); } -} \ No newline at end of file +} diff --git a/language-server/src/main/java/com/as3mxml/vscode/project/ASConfigProjectConfigStrategy.java b/language-server/src/main/java/com/as3mxml/vscode/project/ASConfigProjectConfigStrategy.java index c71b62bf7..6a50511c5 100644 --- a/language-server/src/main/java/com/as3mxml/vscode/project/ASConfigProjectConfigStrategy.java +++ b/language-server/src/main/java/com/as3mxml/vscode/project/ASConfigProjectConfigStrategy.java @@ -58,6 +58,7 @@ public class ASConfigProjectConfigStrategy implements IProjectConfigStrategy { private Path projectPath; private Path asconfigPath; private boolean changed = true; + private List tokens = null; public ASConfigProjectConfigStrategy(Path projectPath, WorkspaceFolder workspaceFolder) { this.projectPath = projectPath; @@ -245,6 +246,11 @@ public ProjectOptions getOptions() { options.compilerOptions = compilerOptions; options.additionalOptions = additionalOptions; options.targets = targets; + options.additionalTokens = tokens; return options; } + + public void setTokens(List tokens) { + this.tokens = tokens; + } } diff --git a/language-server/src/main/java/com/as3mxml/vscode/project/IProjectConfigStrategy.java b/language-server/src/main/java/com/as3mxml/vscode/project/IProjectConfigStrategy.java index 449d1ea92..36981641c 100644 --- a/language-server/src/main/java/com/as3mxml/vscode/project/IProjectConfigStrategy.java +++ b/language-server/src/main/java/com/as3mxml/vscode/project/IProjectConfigStrategy.java @@ -16,11 +16,12 @@ package com.as3mxml.vscode.project; import java.nio.file.Path; +import java.util.List; import org.eclipse.lsp4j.WorkspaceFolder; /** - * Loads the configuration for a project. + * Loads the configuration for a project. */ public interface IProjectConfigStrategy { /** @@ -58,4 +59,9 @@ public interface IProjectConfigStrategy { * Returns the project configuration options. */ ProjectOptions getOptions(); + + /** + * Sets extra tokens that get added to ProjectOptions + */ + void setTokens(List tokens); } diff --git a/language-server/src/main/java/com/as3mxml/vscode/project/ProjectOptions.java b/language-server/src/main/java/com/as3mxml/vscode/project/ProjectOptions.java index 61a08d5d8..16bb670a8 100644 --- a/language-server/src/main/java/com/as3mxml/vscode/project/ProjectOptions.java +++ b/language-server/src/main/java/com/as3mxml/vscode/project/ProjectOptions.java @@ -34,6 +34,7 @@ public class ProjectOptions { public String[] files; public List compilerOptions; public List additionalOptions; + public List additionalTokens; // while the following values are also included in the compiler options, // we need them available for other things in the language server @@ -42,6 +43,6 @@ public class ProjectOptions { public boolean equals(ProjectOptions other) { return other.type.equals(type) && other.config.equals(config) && Arrays.equals(other.files, files) && other.compilerOptions.equals(compilerOptions) && other.additionalOptions.equals(additionalOptions) - && other.targets.equals(targets); + && other.targets.equals(targets) && other.additionalTokens.equals(additionalTokens); } -} \ No newline at end of file +} diff --git a/language-server/src/main/java/com/as3mxml/vscode/project/SimpleProjectConfigStrategy.java b/language-server/src/main/java/com/as3mxml/vscode/project/SimpleProjectConfigStrategy.java index d4f6fb69c..3b683e900 100644 --- a/language-server/src/main/java/com/as3mxml/vscode/project/SimpleProjectConfigStrategy.java +++ b/language-server/src/main/java/com/as3mxml/vscode/project/SimpleProjectConfigStrategy.java @@ -36,6 +36,7 @@ public class SimpleProjectConfigStrategy implements IProjectConfigStrategy { private Path projectPath; private WorkspaceFolder workspaceFolder; private boolean changed = true; + private List tokens = null; public SimpleProjectConfigStrategy(Path projectPath, WorkspaceFolder workspaceFolder) { this.projectPath = projectPath; @@ -115,6 +116,11 @@ public ProjectOptions getOptions() { options.compilerOptions = compilerOptions; options.additionalOptions = null; options.targets = targets; + options.additionalTokens = tokens; return options; } + + public void setTokens(List tokens) { + this.tokens = tokens; + } } diff --git a/language-server/src/main/java/com/as3mxml/vscode/utils/CompilerProjectUtils.java b/language-server/src/main/java/com/as3mxml/vscode/utils/CompilerProjectUtils.java index c3b14eb05..692533d8f 100644 --- a/language-server/src/main/java/com/as3mxml/vscode/utils/CompilerProjectUtils.java +++ b/language-server/src/main/java/com/as3mxml/vscode/utils/CompilerProjectUtils.java @@ -21,6 +21,7 @@ import java.util.ArrayList; import java.util.Arrays; import java.util.List; +import java.util.stream.Collectors; import com.as3mxml.asconfigc.compiler.ProjectType; import com.as3mxml.vscode.project.ILspProject; @@ -150,7 +151,8 @@ public static RoyaleProjectConfigurator createConfigurator(ILspProject project, boolean frameworkSDKContainsSparkTheme = sparkPath.toFile().exists(); List compilerOptions = projectOptions.compilerOptions; - RoyaleProjectConfigurator configurator = null; + List extraTokens = projectOptions.additionalTokens; + final RoyaleProjectConfigurator configurator; if (project instanceof RoyaleJSProject || frameworkSDKIsRoyale) { configurator = new VSCodeProjectConfigurator(JSGoogConfiguration.class); } else // swf only @@ -168,6 +170,15 @@ public static RoyaleProjectConfigurator createConfigurator(ILspProject project, String[] files = projectOptions.files; List additionalOptions = projectOptions.additionalOptions; ArrayList combinedOptions = new ArrayList<>(); + if (extraTokens != null) { + // ["+a=b", "+c=d"] -> (a,b), (c,d) + extraTokens.stream().forEach(token -> { + String[] parts = token.split("="); + String name = parts[0].substring(1); + String value = Arrays.stream(parts).skip(1).collect(Collectors.joining()); + configurator.setToken(name, value); + }); + } if (compilerOptions != null) { combinedOptions.addAll(compilerOptions); } @@ -234,4 +245,4 @@ public static ICompilationUnit findCompilationUnit(Path pathToFind, ICompilerPro } return null; } -} \ No newline at end of file +} diff --git a/vscode-extension/package.json b/vscode-extension/package.json index be2e6913b..60ae2b86d 100644 --- a/vscode-extension/package.json +++ b/vscode-extension/package.json @@ -417,6 +417,18 @@ "default": false, "description": "(Advanced) Specifies whether asconfigc will display verbose output during builds." }, + "as3mxml.asconfigc.additionalTokens": { + "type":"object", + "default": {}, + "description": "Adds extra tokens to the compiler that can be used for paths", + "patternProperties": { + "^[a-zA-Z0-9]+$": { + "type": "string", + "description": "value of the token by the name of this key" + } + }, + "additionalProperties": false + }, "as3mxml.quickCompile.enabled": { "type": "boolean", "default": true, diff --git a/vscode-extension/src/main/ts/utils/ActionScriptTaskProvider.ts b/vscode-extension/src/main/ts/utils/ActionScriptTaskProvider.ts index fe0e5bdb9..56faa03bc 100644 --- a/vscode-extension/src/main/ts/utils/ActionScriptTaskProvider.ts +++ b/vscode-extension/src/main/ts/utils/ActionScriptTaskProvider.ts @@ -5,7 +5,7 @@ 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 + 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, @@ -18,6 +18,7 @@ import * as vscode from "vscode"; import getFrameworkSDKPathWithFallbacks from "./getFrameworkSDKPathWithFallbacks"; import BaseAsconfigTaskProvider from "./BaseAsconfigTaskProvider"; import validateRoyale from "./validateRoyale"; +import getExtraCompilerTokens from "./getExtraCompilerTokens"; const ASCONFIG_JSON = "asconfig.json"; const FIELD_AIR_OPTIONS = "airOptions"; @@ -78,8 +79,7 @@ interface ActionScriptTaskDefinition extends vscode.TaskDefinition { export default class ActionScriptTaskProvider extends BaseAsconfigTaskProvider - implements vscode.TaskProvider -{ + implements vscode.TaskProvider { protected provideTasksForASConfigJSON( jsonURI: vscode.Uri, workspaceFolder: vscode.WorkspaceFolder, @@ -559,6 +559,10 @@ export default class ActionScriptTaskProvider if (command.length > 1) { options.unshift(...command.slice(1)); } + let tokens = getExtraCompilerTokens(); + if (tokens && tokens.length != 0) { + options = options.concat(tokens); + } let source = airPlatform === null ? TASK_SOURCE_ACTIONSCRIPT : TASK_SOURCE_AIR; let execution = new vscode.ProcessExecution(command[0], options); @@ -617,6 +621,10 @@ export default class ActionScriptTaskProvider if (command.length > 1) { options.unshift(...command.slice(1)); } + let tokens = getExtraCompilerTokens(); + if (tokens && tokens.length != 0) { + options = options.concat(tokens); + } let execution = new vscode.ProcessExecution(command[0], options); let task = new vscode.Task( definition, diff --git a/vscode-extension/src/main/ts/utils/AnimateTaskProvider.ts b/vscode-extension/src/main/ts/utils/AnimateTaskProvider.ts index a2159d707..85435da48 100644 --- a/vscode-extension/src/main/ts/utils/AnimateTaskProvider.ts +++ b/vscode-extension/src/main/ts/utils/AnimateTaskProvider.ts @@ -19,6 +19,7 @@ import * as vscode from "vscode"; import getFrameworkSDKPathWithFallbacks from "./getFrameworkSDKPathWithFallbacks"; import findAnimate from "./findAnimate"; import BaseAsconfigTaskProvider from "./BaseAsconfigTaskProvider"; +import getExtraCompilerTokens from "./getExtraCompilerTokens"; const FIELD_ANIMATE_OPTIONS = "animateOptions"; const FIELD_FILE = "file"; @@ -175,6 +176,11 @@ export default class ActionScriptTaskProvider if (command.length > 1) { options.unshift(...command.slice(1)); } + let tokens = getExtraCompilerTokens(); + if (tokens && tokens.length != 0) + { + options = options.concat(tokens); + } let execution = new vscode.ProcessExecution(command[0], options); let task = new vscode.Task( definition, diff --git a/vscode-extension/src/main/ts/utils/getExtraCompilerTokens.ts b/vscode-extension/src/main/ts/utils/getExtraCompilerTokens.ts new file mode 100644 index 000000000..3f866a519 --- /dev/null +++ b/vscode-extension/src/main/ts/utils/getExtraCompilerTokens.ts @@ -0,0 +1,34 @@ +/* +Copyright 2016-2021 Bowler Hat LLC + +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. +*/ +import * as vscode from "vscode" + +export default function getExtraCompilerTokens(): string[] +{ + let tokens : object = vscode.workspace.getConfiguration("as3mxml").get("asconfigc.additionalTokens"); + if (!tokens) + { + return []; + } + + let k : keyof typeof tokens; + let ret : string[] = []; + for (const k in tokens) + { + ret.push("+" + k + "=" + (tokens[k])); + } + + return ret; +}