lua-obfuscator 1.0.0 → 1.0.2

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.
Files changed (98) hide show
  1. package/.github/workflows/release.yml +40 -0
  2. package/dist/index.d.ts +1 -1
  3. package/dist/index.js +32 -18
  4. package/dist/prometheus/LICENSE +661 -661
  5. package/dist/prometheus/build.bat +9 -9
  6. package/dist/prometheus/doc/README.md +11 -11
  7. package/dist/prometheus/doc/SUMMARY.md +27 -27
  8. package/dist/prometheus/doc/advanced/using-prometheus-in-your-lua-application.md +31 -31
  9. package/dist/prometheus/doc/getting-started/command-line-options.md +13 -13
  10. package/dist/prometheus/doc/getting-started/installation.md +11 -11
  11. package/dist/prometheus/doc/getting-started/obfuscating-your-first-script.md +50 -50
  12. package/dist/prometheus/doc/getting-started/presets.md +10 -10
  13. package/dist/prometheus/doc/getting-started/the-config-object.md +58 -58
  14. package/dist/prometheus/doc/getting-started/writing-a-custom-config-file.md +56 -56
  15. package/dist/prometheus/doc/steps/anti-tamper.md +11 -11
  16. package/dist/prometheus/doc/steps/constantarray.md +71 -71
  17. package/dist/prometheus/doc/steps/encryptstrings.md +86 -86
  18. package/dist/prometheus/doc/steps/proxifylocals.md +47 -47
  19. package/dist/prometheus/doc/steps/splitstrings.md +40 -40
  20. package/dist/prometheus/doc/steps/vmify.md +9 -9
  21. package/dist/prometheus/doc/steps/wrapinfunction.md +29 -29
  22. package/dist/prometheus/readme.md +57 -57
  23. package/dist/prometheus/readme.txt +4 -4
  24. package/package.json +5 -1
  25. package/src/index.ts +93 -75
  26. package/tsconfig.json +12 -12
  27. package/src/prometheus/.editorconfig +0 -4
  28. package/src/prometheus/.gitattributes +0 -2
  29. package/src/prometheus/.gitbook.yaml +0 -1
  30. package/src/prometheus/.github/ISSUE_TEMPLATE/bug_report.md +0 -25
  31. package/src/prometheus/.github/workflows/Build.yml +0 -49
  32. package/src/prometheus/.github/workflows/Test.yml +0 -19
  33. package/src/prometheus/LICENSE +0 -661
  34. package/src/prometheus/benchmark.lua +0 -34
  35. package/src/prometheus/build.bat +0 -10
  36. package/src/prometheus/cli.lua +0 -12
  37. package/src/prometheus/doc/README.md +0 -11
  38. package/src/prometheus/doc/SUMMARY.md +0 -27
  39. package/src/prometheus/doc/advanced/using-prometheus-in-your-lua-application.md +0 -31
  40. package/src/prometheus/doc/getting-started/command-line-options.md +0 -13
  41. package/src/prometheus/doc/getting-started/installation.md +0 -11
  42. package/src/prometheus/doc/getting-started/obfuscating-your-first-script.md +0 -50
  43. package/src/prometheus/doc/getting-started/presets.md +0 -10
  44. package/src/prometheus/doc/getting-started/the-config-object.md +0 -58
  45. package/src/prometheus/doc/getting-started/writing-a-custom-config-file.md +0 -56
  46. package/src/prometheus/doc/steps/anti-tamper.md +0 -11
  47. package/src/prometheus/doc/steps/constantarray.md +0 -71
  48. package/src/prometheus/doc/steps/encryptstrings.md +0 -86
  49. package/src/prometheus/doc/steps/proxifylocals.md +0 -47
  50. package/src/prometheus/doc/steps/splitstrings.md +0 -40
  51. package/src/prometheus/doc/steps/vmify.md +0 -9
  52. package/src/prometheus/doc/steps/wrapinfunction.md +0 -29
  53. package/src/prometheus/prometheus-main.lua +0 -1
  54. package/src/prometheus/readme.md +0 -57
  55. package/src/prometheus/readme.txt +0 -5
  56. package/src/prometheus/src/cli.lua +0 -154
  57. package/src/prometheus/src/colors.lua +0 -61
  58. package/src/prometheus/src/highlightlua.lua +0 -61
  59. package/src/prometheus/src/logger.lua +0 -62
  60. package/src/prometheus/src/presets.lua +0 -174
  61. package/src/prometheus/src/prometheus/ast.lua +0 -792
  62. package/src/prometheus/src/prometheus/bit.lua +0 -521
  63. package/src/prometheus/src/prometheus/compiler/compiler.lua +0 -2365
  64. package/src/prometheus/src/prometheus/enums.lua +0 -106
  65. package/src/prometheus/src/prometheus/namegenerators/Il.lua +0 -41
  66. package/src/prometheus/src/prometheus/namegenerators/confuse.lua +0 -169
  67. package/src/prometheus/src/prometheus/namegenerators/mangled.lua +0 -26
  68. package/src/prometheus/src/prometheus/namegenerators/mangled_shuffled.lua +0 -35
  69. package/src/prometheus/src/prometheus/namegenerators/number.lua +0 -11
  70. package/src/prometheus/src/prometheus/namegenerators.lua +0 -7
  71. package/src/prometheus/src/prometheus/parser.lua +0 -969
  72. package/src/prometheus/src/prometheus/pipeline.lua +0 -250
  73. package/src/prometheus/src/prometheus/randomLiterals.lua +0 -41
  74. package/src/prometheus/src/prometheus/randomStrings.lua +0 -24
  75. package/src/prometheus/src/prometheus/scope.lua +0 -332
  76. package/src/prometheus/src/prometheus/step.lua +0 -79
  77. package/src/prometheus/src/prometheus/steps/AddVararg.lua +0 -33
  78. package/src/prometheus/src/prometheus/steps/AntiTamper.lua +0 -194
  79. package/src/prometheus/src/prometheus/steps/ConstantArray.lua +0 -521
  80. package/src/prometheus/src/prometheus/steps/EncryptStrings.lua +0 -239
  81. package/src/prometheus/src/prometheus/steps/NumbersToExpressions.lua +0 -82
  82. package/src/prometheus/src/prometheus/steps/ProxifyLocals.lua +0 -313
  83. package/src/prometheus/src/prometheus/steps/SplitStrings.lua +0 -338
  84. package/src/prometheus/src/prometheus/steps/Vmify.lua +0 -30
  85. package/src/prometheus/src/prometheus/steps/Watermark.lua +0 -61
  86. package/src/prometheus/src/prometheus/steps/WatermarkCheck.lua +0 -50
  87. package/src/prometheus/src/prometheus/steps/WrapInFunction.lua +0 -45
  88. package/src/prometheus/src/prometheus/steps.lua +0 -12
  89. package/src/prometheus/src/prometheus/tokenizer.lua +0 -546
  90. package/src/prometheus/src/prometheus/unparser.lua +0 -866
  91. package/src/prometheus/src/prometheus/util.lua +0 -297
  92. package/src/prometheus/src/prometheus/visitast.lua +0 -245
  93. package/src/prometheus/src/prometheus.lua +0 -71
  94. package/src/prometheus/tests/closures.lua +0 -12
  95. package/src/prometheus/tests/fibonacci.lua +0 -10
  96. package/src/prometheus/tests/loops.lua +0 -8
  97. package/src/prometheus/tests/primes.lua +0 -18
  98. package/src/prometheus/tests.lua +0 -149
@@ -1,250 +0,0 @@
1
- -- This Script is Part of the Prometheus Obfuscator by Levno_710
2
- --
3
- -- pipeline.lua
4
- --
5
- -- This Script Provides a Configurable Obfuscation Pipeline that can obfuscate code using different Modules
6
- -- These Modules can simply be added to the pipeline
7
-
8
- local config = require("config");
9
- local Ast = require("prometheus.ast");
10
- local Enums = require("prometheus.enums");
11
- local util = require("prometheus.util");
12
- local Parser = require("prometheus.parser");
13
- local Unparser = require("prometheus.unparser");
14
- local logger = require("logger");
15
-
16
- local NameGenerators = require("prometheus.namegenerators");
17
-
18
- local Steps = require("prometheus.steps");
19
-
20
- local lookupify = util.lookupify;
21
- local LuaVersion = Enums.LuaVersion;
22
- local AstKind = Ast.AstKind;
23
-
24
- -- On Windows os.clock can be used. On other Systems os.time must be used for benchmarking
25
- local isWindows = package and package.config and type(package.config) == "string" and package.config:sub(1,1) == "\\";
26
- local function gettime()
27
- if isWindows then
28
- return os.clock();
29
- else
30
- return os.time();
31
- end
32
- end
33
-
34
- local Pipeline = {
35
- NameGenerators = NameGenerators;
36
- Steps = Steps;
37
- DefaultSettings = {
38
- LuaVersion = LuaVersion.LuaU; -- The Lua Version to use for the Tokenizer, Parser and Unparser
39
- PrettyPrint = false; -- Note that Pretty Print is currently not producing Pretty results
40
- Seed = 0; -- The Seed. 0 or below uses the current time as a seed
41
- VarNamePrefix = ""; -- The Prefix that every variable will start with
42
- }
43
- }
44
-
45
-
46
- function Pipeline:new(settings)
47
- local luaVersion = settings.luaVersion or settings.LuaVersion or Pipeline.DefaultSettings.LuaVersion;
48
- local conventions = Enums.Conventions[luaVersion];
49
- if(not conventions) then
50
- logger:error("The Lua Version \"" .. luaVersion
51
- .. "\" is not recognised by the Tokenizer! Please use one of the following: \"" .. table.concat(util.keys(Enums.Conventions), "\",\"") .. "\"");
52
- end
53
-
54
- local prettyPrint = settings.PrettyPrint or Pipeline.DefaultSettings.PrettyPrint;
55
- local prefix = settings.VarNamePrefix or Pipeline.DefaultSettings.VarNamePrefix;
56
- local seed = settings.Seed or 0;
57
-
58
- local pipeline = {
59
- LuaVersion = luaVersion;
60
- PrettyPrint = prettyPrint;
61
- VarNamePrefix = prefix;
62
- Seed = seed;
63
- parser = Parser:new({
64
- LuaVersion = luaVersion;
65
- });
66
- unparser = Unparser:new({
67
- LuaVersion = luaVersion;
68
- PrettyPrint = prettyPrint;
69
- Highlight = settings.Highlight;
70
- });
71
- namegenerator = Pipeline.NameGenerators.MangledShuffled;
72
- conventions = conventions;
73
- steps = {};
74
- }
75
-
76
- setmetatable(pipeline, self);
77
- self.__index = self;
78
-
79
- return pipeline;
80
- end
81
-
82
- function Pipeline:fromConfig(config)
83
- config = config or {};
84
- local pipeline = Pipeline:new({
85
- LuaVersion = config.LuaVersion or LuaVersion.Lua51;
86
- PrettyPrint = config.PrettyPrint or false;
87
- VarNamePrefix = config.VarNamePrefix or "";
88
- Seed = config.Seed or 0;
89
- });
90
-
91
- pipeline:setNameGenerator(config.NameGenerator or "MangledShuffled")
92
-
93
- -- Add all Steps defined in Config
94
- local steps = config.Steps or {};
95
- for i, step in ipairs(steps) do
96
- if type(step.Name) ~= "string" then
97
- logger:error("Step.Name must be a String");
98
- end
99
- local constructor = pipeline.Steps[step.Name];
100
- if not constructor then
101
- logger:error(string.format("The Step \"%s\" was not found!", step.Name));
102
- end
103
- pipeline:addStep(constructor:new(step.Settings or {}));
104
- end
105
-
106
- return pipeline;
107
- end
108
-
109
- function Pipeline:addStep(step)
110
- table.insert(self.steps, step);
111
- end
112
-
113
- function Pipeline:resetSteps(step)
114
- self.steps = {};
115
- end
116
-
117
- function Pipeline:getSteps()
118
- return self.steps;
119
- end
120
-
121
- function Pipeline:setOption(name, value)
122
- assert(false, "TODO");
123
- if(Pipeline.DefaultSettings[name] ~= nil) then
124
-
125
- else
126
- logger:error(string.format("\"%s\" is not a valid setting"));
127
- end
128
- end
129
-
130
- function Pipeline:setLuaVersion(luaVersion)
131
- local conventions = Enums.Conventions[luaVersion];
132
- if(not conventions) then
133
- logger:error("The Lua Version \"" .. luaVersion
134
- .. "\" is not recognised by the Tokenizer! Please use one of the following: \"" .. table.concat(util.keys(Enums.Conventions), "\",\"") .. "\"");
135
- end
136
-
137
- self.parser = Parser:new({
138
- luaVersion = luaVersion;
139
- });
140
- self.unparser = Unparser:new({
141
- luaVersion = luaVersion;
142
- });
143
- self.conventions = conventions;
144
- end
145
-
146
- function Pipeline:getLuaVersion()
147
- return self.luaVersion;
148
- end
149
-
150
- function Pipeline:setNameGenerator(nameGenerator)
151
- if(type(nameGenerator) == "string") then
152
- nameGenerator = Pipeline.NameGenerators[nameGenerator];
153
- end
154
-
155
- if(type(nameGenerator) == "function" or type(nameGenerator) == "table") then
156
- self.namegenerator = nameGenerator;
157
- return;
158
- else
159
- logger:error("The Argument to Pipeline:setNameGenerator must be a valid NameGenerator function or function name e.g: \"mangled\"")
160
- end
161
- end
162
-
163
- function Pipeline:apply(code, filename)
164
- local startTime = gettime();
165
- filename = filename or "Anonymus Script";
166
- logger:info(string.format("Applying Obfuscation Pipeline to %s ...", filename));
167
- -- Seed the Random Generator
168
- if(self.Seed > 0) then
169
- math.randomseed(self.Seed);
170
- else
171
- math.randomseed(os.time())
172
- end
173
-
174
- logger:info("Parsing ...");
175
- local parserStartTime = gettime();
176
-
177
- local sourceLen = string.len(code);
178
- local ast = self.parser:parse(code);
179
-
180
- local parserTimeDiff = gettime() - parserStartTime;
181
- logger:info(string.format("Parsing Done in %.2f seconds", parserTimeDiff));
182
-
183
- -- User Defined Steps
184
- for i, step in ipairs(self.steps) do
185
- local stepStartTime = gettime();
186
- logger:info(string.format("Applying Step \"%s\" ...", step.Name or "Unnamed"));
187
- local newAst = step:apply(ast, self);
188
- if type(newAst) == "table" then
189
- ast = newAst;
190
- end
191
- logger:info(string.format("Step \"%s\" Done in %.2f seconds", step.Name or "Unnamed", gettime() - stepStartTime));
192
- end
193
-
194
- -- Rename Variables Step
195
- self:renameVariables(ast);
196
-
197
- code = self:unparse(ast);
198
-
199
- local timeDiff = gettime() - startTime;
200
- logger:info(string.format("Obfuscation Done in %.2f seconds", timeDiff));
201
-
202
- logger:info(string.format("Generated Code size is %.2f%% of the Source Code size", (string.len(code) / sourceLen)*100))
203
-
204
- return code;
205
- end
206
-
207
- function Pipeline:unparse(ast)
208
- local startTime = gettime();
209
- logger:info("Generating Code ...");
210
-
211
- local unparsed = self.unparser:unparse(ast);
212
-
213
- local timeDiff = gettime() - startTime;
214
- logger:info(string.format("Code Generation Done in %.2f seconds", timeDiff));
215
-
216
- return unparsed;
217
- end
218
-
219
- function Pipeline:renameVariables(ast)
220
- local startTime = gettime();
221
- logger:info("Renaming Variables ...");
222
-
223
-
224
- local generatorFunction = self.namegenerator or Pipeline.NameGenerators.mangled;
225
- if(type(generatorFunction) == "table") then
226
- if (type(generatorFunction.prepare) == "function") then
227
- generatorFunction.prepare(ast);
228
- end
229
- generatorFunction = generatorFunction.generateName;
230
- end
231
-
232
- if not self.unparser:isValidIdentifier(self.VarNamePrefix) and #self.VarNamePrefix ~= 0 then
233
- logger:error(string.format("The Prefix \"%s\" is not a valid Identifier in %s", self.VarNamePrefix, self.LuaVersion));
234
- end
235
-
236
- local globalScope = ast.globalScope;
237
- globalScope:renameVariables({
238
- Keywords = self.conventions.Keywords;
239
- generateName = generatorFunction;
240
- prefix = self.VarNamePrefix;
241
- });
242
-
243
- local timeDiff = gettime() - startTime;
244
- logger:info(string.format("Renaming Done in %.2f seconds", timeDiff));
245
- end
246
-
247
-
248
-
249
-
250
- return Pipeline;
@@ -1,41 +0,0 @@
1
- -- This Script is Part of the Prometheus Obfuscator by Levno_710
2
- --
3
- -- Library for Creating Random Literals
4
-
5
- local Ast = require("prometheus.ast");
6
- local RandomStrings = require("prometheus.randomStrings");
7
-
8
- local RandomLiterals = {};
9
-
10
- local function callNameGenerator(generatorFunction, ...)
11
- if(type(generatorFunction) == "table") then
12
- generatorFunction = generatorFunction.generateName;
13
- end
14
- return generatorFunction(...);
15
- end
16
-
17
- function RandomLiterals.String(pipeline)
18
- return Ast.StringExpression(callNameGenerator(pipeline.namegenerator, math.random(1, 4096)));
19
- end
20
-
21
- function RandomLiterals.Dictionary()
22
- return RandomStrings.randomStringNode(true);
23
- end
24
-
25
- function RandomLiterals.Number()
26
- return Ast.NumberExpression(math.random(-8388608, 8388607));
27
- end
28
-
29
- function RandomLiterals.Any(pipeline)
30
- local type = math.random(1, 3);
31
- if type == 1 then
32
- return RandomLiterals.String(pipeline);
33
- elseif type == 2 then
34
- return RandomLiterals.Number();
35
- elseif type == 3 then
36
- return RandomLiterals.Dictionary();
37
- end
38
- end
39
-
40
-
41
- return RandomLiterals;
@@ -1,24 +0,0 @@
1
- local Ast, utils = require("prometheus.ast"), require("prometheus.util");
2
- local charset = utils.chararray("qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM1234567890")
3
-
4
- local function randomString(wordsOrLen)
5
- if type(wordsOrLen) == "table" then
6
- return wordsOrLen[math.random(1, #wordsOrLen)];
7
- end
8
-
9
- wordsOrLen = wordsOrLen or math.random(2, 15);
10
- if wordsOrLen > 0 then
11
- return randomString(wordsOrLen - 1) .. charset[math.random(1, #charset)]
12
- else
13
- return ""
14
- end
15
- end
16
-
17
- local function randomStringNode(wordsOrLen)
18
- return Ast.StringExpression(randomString(wordsOrLen))
19
- end
20
-
21
- return {
22
- randomString = randomString,
23
- randomStringNode = randomStringNode,
24
- }
@@ -1,332 +0,0 @@
1
- -- This Script is Part of the Prometheus Obfuscator by Levno_710
2
- --
3
- -- scope.lua
4
-
5
- local logger = require("logger");
6
- local config = require("config");
7
-
8
- local Scope = {};
9
-
10
- local scopeI = 0;
11
- local function nextName()
12
- scopeI = scopeI + 1;
13
- return "local_scope_" .. tostring(scopeI);
14
- end
15
-
16
- local function generateWarning(token, message)
17
- return "Warning at Position " .. tostring(token.line) .. ":" .. tostring(token.linePos) .. ", " .. message;
18
- end
19
-
20
- -- Create a new Local Scope
21
- function Scope:new(parentScope, name)
22
- local scope = {
23
- isGlobal = false,
24
- parentScope = parentScope,
25
- variables = {},
26
- referenceCounts = {};
27
- variablesLookup = {},
28
- variablesFromHigherScopes = {},
29
- skipIdLookup = {};
30
- name = name or nextName(),
31
- children = {},
32
- level = parentScope.level and (parentScope.level + 1) or 1;
33
- }
34
-
35
- setmetatable(scope, self);
36
- self.__index = self;
37
- parentScope:addChild(scope);
38
- return scope;
39
- end
40
-
41
- -- Create a new Global Scope
42
- function Scope:newGlobal()
43
- local scope = {
44
- isGlobal = true,
45
- parentScope = nil,
46
- variables = {},
47
- variablesLookup = {};
48
- referenceCounts = {};
49
- skipIdLookup = {};
50
- name = "global_scope",
51
- children = {},
52
- level = 0,
53
- };
54
-
55
- setmetatable(scope, self);
56
- self.__index = self;
57
-
58
- return scope;
59
- end
60
-
61
- -- Returns the Parent Scope
62
- function Scope:getParent(parentScope)
63
- return self.parentScope;
64
- end
65
-
66
- function Scope:setParent(parentScope)
67
- self.parentScope:removeChild(self);
68
- parentScope:addChild(self);
69
- self.parentScope = parentScope;
70
- self.level = parentScope.level + 1;
71
- end
72
-
73
- local next_name_i = 1;
74
- -- Adds a Variable to the scope and returns the variable id, if no name is passed then a name is generated
75
- function Scope:addVariable(name, token)
76
- if (not name) then
77
- name = string.format("%s%i", config.IdentPrefix, next_name_i);
78
- next_name_i = next_name_i + 1;
79
- end
80
-
81
- if self.variablesLookup[name] ~= nil then
82
- if(token) then
83
- logger:warn(generateWarning(token, "the variable \"" .. name .. "\" is already defined in that scope"));
84
- else
85
- logger:error(string.format("A variable with the name \"%s\" was already defined, you should have no variables starting with \"%s\"", name, config.IdentPrefix));
86
- end
87
-
88
- --return self.variablesLookup[name];
89
- end
90
-
91
- table.insert(self.variables, name);
92
- local id = #self.variables;
93
- self.variablesLookup[name] = id;
94
- return id;
95
- end
96
-
97
- function Scope:enableVariable(id)
98
- local name = self.variables[id];
99
- self.variablesLookup[name] = id;
100
- end
101
-
102
- function Scope:addDisabledVariable(name, token)
103
- if (not name) then
104
- name = string.format("%s%i", config.IdentPrefix, next_name_i);
105
- next_name_i = next_name_i + 1;
106
- end
107
-
108
- if self.variablesLookup[name] ~= nil then
109
- if(token) then
110
- logger:warn(generateWarning(token, "the variable \"" .. name .. "\" is already defined in that scope"));
111
- else
112
- logger:warn(string.format("a variable with the name \"%s\" was already defined", name));
113
- end
114
-
115
- --return self.variablesLookup[name];
116
- end
117
-
118
- table.insert(self.variables, name);
119
- local id = #self.variables;
120
- return id;
121
- end
122
-
123
- function Scope:addIfNotExists(id)
124
- if(not self.variables[id]) then
125
- local name = string.format("%s%i", config.IdentPrefix, next_name_i);
126
- next_name_i = next_name_i + 1;
127
- self.variables[id] = name;
128
- self.variablesLookup[name] = id;
129
- end
130
- return id;
131
- end
132
-
133
- -- Returns wether the variable is defined in this Scope
134
- function Scope:hasVariable(name)
135
- if(self.isGlobal) then
136
- if self.variablesLookup[name] == nil then
137
- self:addVariable(name);
138
- end
139
- return true;
140
- end
141
- return self.variablesLookup[name] ~= nil;
142
- end
143
-
144
- -- Get List of all Variables defined in this Scope
145
- function Scope:getVariables()
146
- return self.variables;
147
- end
148
-
149
- function Scope:resetReferences(id)
150
- self.referenceCounts[id] = 0;
151
- end
152
-
153
- function Scope:getReferences(id)
154
- return self.referenceCounts[id] or 0;
155
- end
156
-
157
- function Scope:removeReference(id)
158
- self.referenceCounts[id] = (self.referenceCounts[id] or 0) - 1;
159
- end
160
-
161
- function Scope:addReference(id)
162
- self.referenceCounts[id] = (self.referenceCounts[id] or 0) + 1;
163
- end
164
-
165
- -- Resolve the scope of a variable by name
166
- function Scope:resolve(name)
167
- if(self:hasVariable(name)) then
168
- return self, self.variablesLookup[name];
169
- end
170
- assert(self.parentScope, "No Global Variable Scope was Created! This should not be Possible!");
171
- local scope, id = self.parentScope:resolve(name);
172
- self:addReferenceToHigherScope(scope, id, nil, true);
173
- return scope, id;
174
- end
175
-
176
- function Scope:resolveGlobal(name)
177
- if(self.isGlobal and self:hasVariable(name)) then
178
- return self, self.variablesLookup[name];
179
- end
180
- assert(self.parentScope, "No Global Variable Scope was Created! This should not be Possible!");
181
- local scope, id = self.parentScope:resolveGlobal(name);
182
- self:addReferenceToHigherScope(scope, id, nil, true);
183
- return scope, id;
184
- end
185
-
186
- -- Returns the name of an Variable by id - this is used for unparsing
187
- function Scope:getVariableName(id)
188
- return self.variables[id];
189
- end
190
-
191
- -- Remove A Variable from this Scope
192
- function Scope:removeVariable(id)
193
- local name = self.variables[id];
194
- self.variables[id] = nil;
195
- self.variablesLookup[name] = nil;
196
- self.skipIdLookup[id] = true;
197
- end
198
-
199
- -- Add a Children Scope
200
- function Scope:addChild(scope)
201
- -- This will add all References from that Scope to higher Scopes. Note that the higher scopes may only be global
202
- for scope, ids in pairs(scope.variablesFromHigherScopes) do
203
- for id, count in pairs(ids) do
204
- if count and count > 0 then
205
- self:addReferenceToHigherScope(scope, id, count);
206
- end
207
- end
208
- end
209
- table.insert(self.children, scope);
210
- end
211
-
212
- function Scope:clearReferences()
213
- self.referenceCounts = {};
214
- self.variablesFromHigherScopes = {};
215
- end
216
-
217
- function Scope:removeChild(child)
218
- for i, v in ipairs(self.children) do
219
- if(v == child) then
220
- -- This will add all References from that Scope to higher Scopes. Note that the higher scopes may only be global
221
- for scope, ids in pairs(v.variablesFromHigherScopes) do
222
- for id, count in pairs(ids) do
223
- if count and count > 0 then
224
- self:removeReferenceToHigherScope(scope, id, count);
225
- end
226
- end
227
- end
228
- return table.remove(self.children, i);
229
- end
230
- end
231
- end
232
-
233
- function Scope:getMaxId()
234
- return #self.variables;
235
- end
236
-
237
- function Scope:addReferenceToHigherScope(scope, id, n, b)
238
- n = n or 1;
239
- if self.isGlobal then
240
- if not scope.isGlobal then
241
- logger:error(string.format("Could not resolve Scope \"%s\"", scope.name))
242
- end
243
- return
244
- end
245
- if scope == self then
246
- self.referenceCounts[id] = (self.referenceCounts[id] or 0) + n;
247
- return
248
- end
249
- if not self.variablesFromHigherScopes[scope] then
250
- self.variablesFromHigherScopes[scope] = {};
251
- end
252
- local scopeReferences = self.variablesFromHigherScopes[scope];
253
- if scopeReferences[id] then
254
- scopeReferences[id] = scopeReferences[id] + n;
255
- else
256
- scopeReferences[id] = n;
257
- end
258
- if not b then
259
- self.parentScope:addReferenceToHigherScope(scope, id, n);
260
- end
261
- end
262
-
263
- function Scope:removeReferenceToHigherScope(scope, id, n, b)
264
- n = n or 1;
265
- if self.isGlobal then
266
- return
267
- end
268
- if scope == self then
269
- self.referenceCounts[id] = (self.referenceCounts[id] or 0) - n;
270
- return
271
- end
272
- if not self.variablesFromHigherScopes[scope] then
273
- self.variablesFromHigherScopes[scope] = {};
274
- end
275
- local scopeReferences = self.variablesFromHigherScopes[scope];
276
- if scopeReferences[id] then
277
- scopeReferences[id] = scopeReferences[id] - n;
278
- else
279
- scopeReferences[id] = 0;
280
- end
281
- if not b then
282
- self.parentScope:removeReferenceToHigherScope(scope, id, n);
283
- end
284
- end
285
-
286
- -- Rename Variables from that scope downwards
287
- -- this function needs a settings object with the following properties
288
- -- Keywords => forbidden Variable Names
289
- -- generateName(id, scope, originalName) => function to generate unique variable name based on the id and scope
290
- function Scope:renameVariables(settings)
291
- if(not self.isGlobal) then
292
- local prefix = settings.prefix or "";
293
- local forbiddenNamesLookup = {};
294
- for _, keyword in pairs(settings.Keywords) do
295
- forbiddenNamesLookup[keyword] = true;
296
- end
297
-
298
- for scope, ids in pairs(self.variablesFromHigherScopes) do
299
- for id, count in pairs(ids) do
300
- if count and count > 0 then
301
- local name = scope:getVariableName(id);
302
- forbiddenNamesLookup[name] = true;
303
- end
304
- end
305
- end
306
-
307
- self.variablesLookup = {};
308
-
309
- local i = 0;
310
- for id, originalName in pairs(self.variables) do
311
- if(not self.skipIdLookup[id] and (self.referenceCounts[id] or 0) >= 0) then
312
- local name;
313
- repeat
314
- name = prefix .. settings.generateName(i, self, originalName);
315
- if name == nil then
316
- name = originalName;
317
- end
318
- i = i + 1;
319
- until not forbiddenNamesLookup[name];
320
-
321
- self.variables[id] = name;
322
- self.variablesLookup[name] = id;
323
- end
324
- end
325
- end
326
-
327
- for _, scope in pairs(self.children) do
328
- scope:renameVariables(settings);
329
- end
330
- end
331
-
332
- return Scope;