overpy 9.6.4 → 9.6.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -602,6 +602,10 @@ If specified, allows redefining a `macro`, `#!define` or `enum` member. Can be u
602
602
 
603
603
  Will generate a summary of the used elements per rule in the output, and add a comment with the number of elements used for each rule/condition/action.
604
604
 
605
+ ## #!writeToOutputFile
606
+
607
+ If specified, the compiled code will not be copied to the clipboard but instead written to a file with the same name as the main file, but with a `.ws.txt` extension (eg `myGamemode.opy` will produce `myGamemode.ws.txt`).
608
+
605
609
  ## Optimizations
606
610
 
607
611
  By default, OverPy automatically optimizes gamemodes for speed. This means useless code is removed, calculations are done when possible, and function patterns are replaced with builtin functions.
package/overpy.d.ts CHANGED
@@ -18,6 +18,7 @@ declare namespace overpy {
18
18
  availableExtensionPoints: number;
19
19
  translationLanguages: string[];
20
20
  translatedStrings: unknown[];
21
+ writeToOutputFile: boolean;
21
22
  }
22
23
 
23
24
  function compile(
package/overpy.js CHANGED
@@ -38582,6 +38582,10 @@ ${scriptText}`, {
38582
38582
  setDisableInspector(true);
38583
38583
  return;
38584
38584
  }
38585
+ if (content2.startsWith("#!writeToOutputFile")) {
38586
+ setWriteToOutputFile(true);
38587
+ return;
38588
+ }
38585
38589
  if (content2.startsWith("#!disableTranslationSourceLines")) {
38586
38590
  setDisableTranslationSourceLines(true);
38587
38591
  return;
@@ -38605,19 +38609,19 @@ ${scriptText}`, {
38605
38609
  return;
38606
38610
  }
38607
38611
  if (content2.startsWith("#!optimizeForSize")) {
38608
- addToken("__enableOptimizeForSize__");
38612
+ currentLine.tokens.push(new Token("__enableOptimizeForSize__", getFileStackCopy()));
38609
38613
  return;
38610
38614
  }
38611
38615
  if (content2.startsWith("#!disableOptimizeForSize")) {
38612
- addToken("__disableOptimizeForSize__");
38616
+ currentLine.tokens.push(new Token("__disableOptimizeForSize__", getFileStackCopy()));
38613
38617
  return;
38614
38618
  }
38615
38619
  if (content2.startsWith("#!optimizeStrict")) {
38616
- addToken("__enableOptimizeStrict__");
38620
+ currentLine.tokens.push(new Token("__enableOptimizeStrict__", getFileStackCopy()));
38617
38621
  return;
38618
38622
  }
38619
38623
  if (content2.startsWith("#!disableOptimizeStrict")) {
38620
- addToken("__disableOptimizeStrict__");
38624
+ currentLine.tokens.push(new Token("__disableOptimizeStrict__", getFileStackCopy()));
38621
38625
  return;
38622
38626
  }
38623
38627
  if (content2.startsWith("#!setupTx") || content2.startsWith("#!setupTags")) {
@@ -38682,10 +38686,10 @@ ${scriptText}`, {
38682
38686
  }
38683
38687
  if (content2.startsWith("#!rulePrefix ")) {
38684
38688
  let prefix = content2.substring("#!rulePrefix ".length).trim();
38685
- addToken("__rulePrefix__");
38686
- addToken("(");
38687
- addToken(prefix);
38688
- addToken(")");
38689
+ currentLine.tokens.push(new Token("__rulePrefix__", getFileStackCopy()));
38690
+ currentLine.tokens.push(new Token("(", getFileStackCopy()));
38691
+ currentLine.tokens.push(new Token(prefix, getFileStackCopy()));
38692
+ currentLine.tokens.push(new Token(")", getFileStackCopy()));
38689
38693
  return;
38690
38694
  }
38691
38695
  if (content2.startsWith("#!rulePrefixTemplate")) {
@@ -39686,6 +39690,10 @@ var Ast2 = class _Ast {
39686
39690
  //Used for translated strings, if set to true then player var won't be used
39687
39691
  forceNotResolvingTranslation;
39688
39692
  //Used for translated strings, if true then the resulting string array won't be indexed and will need to be indexed later on with the _() function
39693
+ isGotoInSameScope;
39694
+ //Used for gotos, if true then the goto doesn't jump to another scope and can be optimized more easily. For now, only set on automatically generated gotos
39695
+ isSwitchIf;
39696
+ //true if it is the "if true" from a switch
39689
39697
  argIndex = 0;
39690
39698
  childIndex = 0;
39691
39699
  wasParsed = false;
@@ -39761,6 +39769,8 @@ var Ast2 = class _Ast {
39761
39769
  clone.numValue = this.numValue;
39762
39770
  clone.stringTokens = structuredClone(this.stringTokens);
39763
39771
  clone.isSpectatorTranslation = this.isSpectatorTranslation;
39772
+ clone.isGotoInSameScope = this.isGotoInSameScope;
39773
+ clone.isSwitchIf = this.isSwitchIf;
39764
39774
  return clone;
39765
39775
  }
39766
39776
  };
@@ -39880,6 +39890,15 @@ function astContainsFunctions(ast, functionNames, errorOnTrue = false) {
39880
39890
  }
39881
39891
  return false;
39882
39892
  }
39893
+ function astIsInLambdaFunction(ast) {
39894
+ if (!ast.parent) {
39895
+ return false;
39896
+ }
39897
+ if (["__filteredArray__", "__mappedArray__"].includes(ast.parent.name) && ast.parent.argIndex === 1) {
39898
+ return true;
39899
+ }
39900
+ return astIsInLambdaFunction(ast.parent);
39901
+ }
39883
39902
  function astIsLiteral(ast) {
39884
39903
  if (typeof ast.type === "string" && !["Hero", "Map", "Gamemode", "Team", "Button", "Color"].includes(ast.type)) {
39885
39904
  if (["IntLiteral", "UnsignedIntLiteral", "SignedIntLiteral", "FloatLiteral", "UnsignedFloatLiteral", "SignedFloatLiteral", "GlobalVariable", "PlayerVariable", "Subroutine", "HeroLiteral", "MapLiteral", "GamemodeLiteral", "TeamLiteral", "ButtonLiteral", "StringLiteral", "LocalizedStringLiteral", "CustomStringLiteral"].concat(Object.keys(constantValues)).includes(ast.type)) {
@@ -44948,6 +44967,9 @@ astParsingFunctions.__equals__ = function(content) {
44948
44967
 
44949
44968
  // src/compiler/functions/__filteredArray__.ts
44950
44969
  astParsingFunctions.__filteredArray__ = function(content) {
44970
+ if (astIsInLambdaFunction(content)) {
44971
+ error("Cannot nest .filter() or .map()");
44972
+ }
44951
44973
  if (enableOptimization) {
44952
44974
  if (!optimizeForSize2) {
44953
44975
  if (!astContainsFunctions(content.args[1], ["__currentArrayElement__", "__currentArrayIndex__"])) {
@@ -45199,7 +45221,9 @@ astParsingFunctions.__if__ = function(content) {
45199
45221
  } else {
45200
45222
  content.args[0] = astParsingFunctions.__not__(new Ast2("__not__", [content.args[0]]));
45201
45223
  }
45202
- return new Ast2("__skipIf__", [content.args[0], new Ast2("__distanceTo__", [new Ast2(label, [], [], "Label")])]);
45224
+ let skip = new Ast2("__skipIf__", [content.args[0], new Ast2("__distanceTo__", [new Ast2(label, [], [], "Label")])]);
45225
+ skip.isGotoInSameScope = true;
45226
+ return skip;
45203
45227
  }
45204
45228
  if (includeEnd) {
45205
45229
  content.parent.children.splice(content.parent.childIndex + 1, 0, getAstForEnd());
@@ -45311,6 +45335,9 @@ astParsingFunctions.__map__ = function(content) {
45311
45335
 
45312
45336
  // src/compiler/functions/__mappedArray__.ts
45313
45337
  astParsingFunctions.__mappedArray__ = function(content) {
45338
+ if (astIsInLambdaFunction(content)) {
45339
+ error("Cannot nest .filter() or .map()");
45340
+ }
45314
45341
  if (enableOptimization) {
45315
45342
  if (content.args[1].name === "__currentArrayElement__") {
45316
45343
  return content.args[0];
@@ -45536,10 +45563,10 @@ astParsingFunctions.__rule__ = function(content) {
45536
45563
  function iterateOnRuleActions(children) {
45537
45564
  for (let i2 = 0; i2 < children.length; i2++) {
45538
45565
  setFileStack(content.fileStack);
45539
- if (children[i2].name === "__skip__" && children[i2].args[0].name !== "__distanceTo__" || children[i2].name === "__skipIf__" && children[i2].args[1].name !== "__distanceTo__") {
45566
+ if ((children[i2].name === "__skip__" && children[i2].args[0].name !== "__distanceTo__" || children[i2].name === "__skipIf__" && children[i2].args[1].name !== "__distanceTo__") && !children[i2].isGotoInSameScope) {
45540
45567
  isRelativeGotoEncountered = true;
45541
45568
  }
45542
- if (children[i2].name === "__skip__" || children[i2].name === "__skipIf__") {
45569
+ if ((children[i2].name === "__skip__" || children[i2].name === "__skipIf__") && !children[i2].isGotoInSameScope) {
45543
45570
  isGotoEncountered = true;
45544
45571
  }
45545
45572
  if (content.type === "Label") {
@@ -45549,7 +45576,7 @@ astParsingFunctions.__rule__ = function(content) {
45549
45576
  declaredLabels.push(content.name);
45550
45577
  }
45551
45578
  iterateOnRuleActions(children[i2].children);
45552
- if (!isRelativeGotoEncountered) {
45579
+ if (!isRelativeGotoEncountered && !children[i2].isSwitchIf) {
45553
45580
  if (children[i2].name === "pass") {
45554
45581
  children.splice(i2, 1);
45555
45582
  i2--;
@@ -45819,7 +45846,10 @@ astParsingFunctions.__switch__ = function(content) {
45819
45846
  error("Parent is undefined in __switch__");
45820
45847
  }
45821
45848
  content.parent.children.splice(content.parent.childIndex + 1, 0, ...casesChildren);
45822
- var result = new Ast2("__if__", [getAstForTrue()], [new Ast2("__skip__", [new Ast2("__valueInArray__", [new Ast2("__array__", caseOffsets), new Ast2("__add__", [getAstFor1(), new Ast2(".index", [new Ast2("__array__", switchCaseArgs), content.args[0]])])])])]);
45849
+ let skip = new Ast2("__skip__", [new Ast2("__valueInArray__", [new Ast2("__array__", caseOffsets), new Ast2("__add__", [getAstFor1(), new Ast2(".index", [new Ast2("__array__", switchCaseArgs), content.args[0]])])])]);
45850
+ skip.isGotoInSameScope = true;
45851
+ var result = new Ast2("__if__", [getAstForTrue()], [skip]);
45852
+ result.isSwitchIf = true;
45823
45853
  result.doNotReparse = true;
45824
45854
  return result;
45825
45855
  };
@@ -65001,7 +65031,7 @@ function astToWs(content) {
65001
65031
  }
65002
65032
  str = str.replaceAll("\uEC51", separator);
65003
65033
  return astToWs(new Ast2(".split", [getAstForCustomString(str), separatorAst]));
65004
- } else if (content.args.length >= 3 && content.args.every((x) => areAstsAlwaysEqual(x, content.args[0]))) {
65034
+ } else if (!astIsInLambdaFunction(content) && content.args.length >= 3 && content.args.every((x) => areAstsAlwaysEqual(x, content.args[0]))) {
65005
65035
  let estimatedElementCount = 1 + (content.args[0].name === "__customString__" ? 4 : content.args[0].args.length);
65006
65036
  if (estimatedElementCount === 1 && content.args.length >= 11 || estimatedElementCount === 2 && content.args.length >= 5 || estimatedElementCount === 3 && content.args.length >= 4 || estimatedElementCount >= 4) {
65007
65037
  return astToWs(new Ast2("__mappedArray__", [
@@ -65068,13 +65098,17 @@ function astToWs(content) {
65068
65098
  content.name = newName;
65069
65099
  } else if (content.name === "__globalVar__") {
65070
65100
  incrementNbElements();
65101
+ content.argIndex = 0;
65071
65102
  return tows("__global__", valueKw) + "." + astToWs(content.args[0]);
65072
65103
  } else if (content.name === "__number__") {
65073
65104
  incrementNbElements(2);
65074
65105
  return trimNb(content.args[0].name);
65075
65106
  } else if (content.name === "__playerVar__") {
65076
65107
  incrementNbElements();
65077
- return "(" + astToWs(content.args[0]) + ")." + astToWs(content.args[1]);
65108
+ content.argIndex = 0;
65109
+ let result2 = "(" + astToWs(content.args[0]) + ").";
65110
+ content.argIndex = 1;
65111
+ return result2 + astToWs(content.args[1]);
65078
65112
  } else if (content.name === "ceil") {
65079
65113
  content.name = "__round__";
65080
65114
  content.args = [content.args[0], new Ast2("__roundUp__", [], [], "__Rounding__")];
@@ -65204,6 +65238,7 @@ function astToWs(content) {
65204
65238
  if (content.args[i].type === "void") {
65205
65239
  error("Expected a value, but got " + functionNameToString(content.args[i]) + " which is an action", content.args[i].fileStack);
65206
65240
  }
65241
+ content.argIndex = i;
65207
65242
  result += astToWs(content.args[i]);
65208
65243
  if (content.type === "void") {
65209
65244
  incrementNbElements(Math.floor(nbHeroesInValue / 2));
@@ -65824,7 +65859,8 @@ rule "Disable inspector":
65824
65859
  spentExtensionPoints,
65825
65860
  availableExtensionPoints,
65826
65861
  translationLanguages: translationLanguages2,
65827
- translatedStrings
65862
+ translatedStrings,
65863
+ writeToOutputFile
65828
65864
  };
65829
65865
  }
65830
65866
  function compileRules(astRules) {
@@ -69776,6 +69812,8 @@ var rulePrefixTemplateFilestack = [];
69776
69812
  var setRulePrefixTemplateFilestack = (filestack) => rulePrefixTemplateFilestack = filestack;
69777
69813
  var useVariableForCompressionAlphabet = false;
69778
69814
  var setUseVariableForCompressionAlphabet = (use) => useVariableForCompressionAlphabet = use;
69815
+ var writeToOutputFile = false;
69816
+ var setWriteToOutputFile = (write) => writeToOutputFile = write;
69779
69817
  var decompilerGotos;
69780
69818
  var resetDecompilerGotos = () => decompilerGotos = [];
69781
69819
  var nbTabs;
@@ -69857,6 +69895,7 @@ function resetGlobalVariables(language) {
69857
69895
  rulePrefixTemplate = "";
69858
69896
  rulePrefixTemplateFilestack = [];
69859
69897
  useVariableForCompressionAlphabet = false;
69898
+ writeToOutputFile = false;
69860
69899
  }
69861
69900
  var operatorPrecedence = {
69862
69901
  "=": 1,
@@ -72341,6 +72380,9 @@ You can also specify \`noTlErr\` to have spectators view the default language wh
72341
72380
  "disableTranslationSourceLines": {
72342
72381
  "description": "If set, the source lines of the translations will not be included in the generated .po files. Use this if you are not actively translating your gamemode, to prevent cluttering git diffs."
72343
72382
  },
72383
+ "writeToOutputFile": {
72384
+ "description": "If specified, the compiled code will not be copied to the clipboard but instead written to a file with the same name as the main file, but with a `.ws.txt` extension (eg `myGamemode.opy` will produce `myGamemode.ws.txt`)."
72385
+ },
72344
72386
  "postCompileHook": {
72345
72387
  "description": `
72346
72388
  Specifies a JavaScript file to be executed after compilation, with the compiled code as a \`content\` variable. The script must return the modified code.
package/package.json CHANGED
@@ -7,7 +7,7 @@
7
7
  "url": "https://github.com/Zezombye/overpy"
8
8
  },
9
9
  "description": "High-level language for the Overwatch Workshop, with decompilation and compilation.",
10
- "version": "9.6.4",
10
+ "version": "9.6.6",
11
11
  "readme": "README.md",
12
12
  "keywords": [
13
13
  "overpy",