stone-lang 0.1.0

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 (68) hide show
  1. package/README.md +52 -0
  2. package/StoneEngine.js +879 -0
  3. package/StoneEngineService.js +1727 -0
  4. package/adapters/FileSystemAdapter.js +230 -0
  5. package/adapters/OutputAdapter.js +208 -0
  6. package/adapters/index.js +6 -0
  7. package/cli/CLIOutputAdapter.js +196 -0
  8. package/cli/DaemonClient.js +349 -0
  9. package/cli/JSONOutputAdapter.js +135 -0
  10. package/cli/ReplSession.js +567 -0
  11. package/cli/ViewerServer.js +590 -0
  12. package/cli/commands/check.js +84 -0
  13. package/cli/commands/daemon.js +189 -0
  14. package/cli/commands/kill.js +66 -0
  15. package/cli/commands/package.js +713 -0
  16. package/cli/commands/ps.js +65 -0
  17. package/cli/commands/run.js +537 -0
  18. package/cli/entry.js +169 -0
  19. package/cli/index.js +14 -0
  20. package/cli/stonec.js +358 -0
  21. package/cli/test-compiler.js +181 -0
  22. package/cli/viewer/index.html +495 -0
  23. package/daemon/IPCServer.js +455 -0
  24. package/daemon/ProcessManager.js +327 -0
  25. package/daemon/ProcessRunner.js +307 -0
  26. package/daemon/daemon.js +398 -0
  27. package/daemon/index.js +16 -0
  28. package/frontend/analysis/index.js +5 -0
  29. package/frontend/analysis/livenessAnalyzer.js +568 -0
  30. package/frontend/analysis/treeShaker.js +265 -0
  31. package/frontend/index.js +20 -0
  32. package/frontend/parsing/astBuilder.js +2196 -0
  33. package/frontend/parsing/index.js +7 -0
  34. package/frontend/parsing/sonParser.js +592 -0
  35. package/frontend/parsing/stoneAstTypes.js +703 -0
  36. package/frontend/parsing/terminal-registry.js +435 -0
  37. package/frontend/parsing/tokenizer.js +692 -0
  38. package/frontend/type-checker/OverloadedFunctionType.js +43 -0
  39. package/frontend/type-checker/TypeEnvironment.js +165 -0
  40. package/frontend/type-checker/bidirectionalInference.js +149 -0
  41. package/frontend/type-checker/index.js +10 -0
  42. package/frontend/type-checker/moduleAnalysis.js +248 -0
  43. package/frontend/type-checker/operatorMappings.js +35 -0
  44. package/frontend/type-checker/overloadResolution.js +605 -0
  45. package/frontend/type-checker/typeChecker.js +452 -0
  46. package/frontend/type-checker/typeCompatibility.js +389 -0
  47. package/frontend/type-checker/visitors/controlFlow.js +483 -0
  48. package/frontend/type-checker/visitors/functions.js +604 -0
  49. package/frontend/type-checker/visitors/index.js +38 -0
  50. package/frontend/type-checker/visitors/literals.js +341 -0
  51. package/frontend/type-checker/visitors/modules.js +159 -0
  52. package/frontend/type-checker/visitors/operators.js +109 -0
  53. package/frontend/type-checker/visitors/statements.js +768 -0
  54. package/frontend/types/index.js +5 -0
  55. package/frontend/types/operatorMap.js +134 -0
  56. package/frontend/types/types.js +2046 -0
  57. package/frontend/utils/errorCollector.js +244 -0
  58. package/frontend/utils/index.js +5 -0
  59. package/frontend/utils/moduleResolver.js +479 -0
  60. package/package.json +50 -0
  61. package/packages/browserCache.js +359 -0
  62. package/packages/fetcher.js +236 -0
  63. package/packages/index.js +130 -0
  64. package/packages/lockfile.js +271 -0
  65. package/packages/manifest.js +291 -0
  66. package/packages/packageResolver.js +356 -0
  67. package/packages/resolver.js +310 -0
  68. package/packages/semver.js +635 -0
@@ -0,0 +1,265 @@
1
+ /**
2
+ * Stone Module Tree Shaker
3
+ *
4
+ * Analyzes imports to determine which exports are actually used from each module,
5
+ * enabling optimization of module loading and reducing memory usage.
6
+ *
7
+ * Features:
8
+ * - Analyzes import statements to track which exports are used
9
+ * - Filters module exports to only include used names
10
+ * - Detects unused imports for warnings
11
+ * - Supports selective imports, namespace imports, and re-exports
12
+ *
13
+ * Usage:
14
+ * const analyzer = new ImportAnalyzer();
15
+ * const usedExports = analyzer.analyze(ast);
16
+ * // usedExports is Map<modulePath, Set<exportName>>
17
+ *
18
+ * const shaker = new TreeShaker();
19
+ * const filteredExports = shaker.filterExports(moduleExports, usedExports.get(modulePath));
20
+ */
21
+
22
+ /**
23
+ * Analyzes an AST to determine which exports are used from each imported module
24
+ */
25
+ export class ImportAnalyzer {
26
+ constructor() {
27
+ // Map from module path to Set of imported names
28
+ this.usedExports = new Map();
29
+ // Map from local name to { modulePath, importedName }
30
+ this.importedBindings = new Map();
31
+ // Set of local names that are actually referenced in code
32
+ this.referencedNames = new Set();
33
+ // Track namespace imports: localName -> modulePath
34
+ this.namespaceImports = new Map();
35
+ }
36
+
37
+ /**
38
+ * Analyze an AST and return a map of used exports per module
39
+ * @param {Object} ast - The parsed AST
40
+ * @returns {Map<string, Set<string>>} Map from module path to set of used export names
41
+ */
42
+ analyze(ast) {
43
+ this.usedExports.clear();
44
+ this.importedBindings.clear();
45
+ this.referencedNames.clear();
46
+ this.namespaceImports.clear();
47
+
48
+ // First pass: collect all imports
49
+ this._collectImports(ast);
50
+
51
+ // Second pass: collect all identifier references
52
+ this._collectReferences(ast);
53
+
54
+ // Third pass: determine which imports are actually used
55
+ return this._computeUsedExports();
56
+ }
57
+
58
+ /**
59
+ * Collect all import statements from the AST
60
+ */
61
+ _collectImports(ast) {
62
+ if (!ast || !ast.imports) return;
63
+
64
+ for (const importNode of ast.imports) {
65
+ if (importNode.type === 'ImportStatement') {
66
+ const modulePath = importNode.modulePath;
67
+
68
+ if (!this.usedExports.has(modulePath)) {
69
+ this.usedExports.set(modulePath, new Set());
70
+ }
71
+
72
+ for (const spec of importNode.specifiers) {
73
+ const importedName = spec.importedName || spec.localName;
74
+ const localName = spec.localName;
75
+
76
+ // Track the binding
77
+ this.importedBindings.set(localName, {
78
+ modulePath,
79
+ importedName,
80
+ });
81
+ }
82
+ } else if (importNode.type === 'NamespaceImportStatement') {
83
+ const modulePath = importNode.modulePath;
84
+ const localName = importNode.alias || this._getModuleLastSegment(modulePath);
85
+
86
+ // Namespace imports use all exports (marked with '*')
87
+ if (!this.usedExports.has(modulePath)) {
88
+ this.usedExports.set(modulePath, new Set());
89
+ }
90
+ this.usedExports.get(modulePath).add('*');
91
+ this.namespaceImports.set(localName, modulePath);
92
+ }
93
+ }
94
+ }
95
+
96
+ /**
97
+ * Collect all identifier references in the AST
98
+ */
99
+ _collectReferences(ast) {
100
+ this._walkAST(ast, (node) => {
101
+ // Identifier nodes (variable references like `x` in `y = x + 1`)
102
+ if (node.type === 'Identifier') {
103
+ this.referencedNames.add(node.name);
104
+ }
105
+
106
+ // FunctionCall nodes have funcName as a string (not an Identifier)
107
+ if (node.type === 'FunctionCall' && node.funcName) {
108
+ this.referencedNames.add(node.funcName);
109
+ }
110
+
111
+ // Handle member access on namespace imports: ns.foo
112
+ if (node.type === 'MemberAccess' && node.object?.type === 'Identifier') {
113
+ const objName = node.object.name;
114
+ if (this.namespaceImports.has(objName) && node.property?.name) {
115
+ // Track the specific property accessed
116
+ const modulePath = this.namespaceImports.get(objName);
117
+ if (this.usedExports.has(modulePath)) {
118
+ this.usedExports.get(modulePath).add(node.property.name);
119
+ }
120
+ }
121
+ }
122
+ });
123
+ }
124
+
125
+ /**
126
+ * Compute which exports are actually used based on references
127
+ */
128
+ _computeUsedExports() {
129
+ // For each imported binding that's referenced, mark its export as used
130
+ for (const [localName, bindingInfo] of this.importedBindings) {
131
+ if (this.referencedNames.has(localName)) {
132
+ const { modulePath, importedName } = bindingInfo;
133
+ if (this.usedExports.has(modulePath)) {
134
+ this.usedExports.get(modulePath).add(importedName);
135
+ }
136
+ }
137
+ }
138
+
139
+ return this.usedExports;
140
+ }
141
+
142
+ /**
143
+ * Get unused imports (imports that are never referenced)
144
+ * @returns {Array<{localName, modulePath, importedName}>}
145
+ */
146
+ getUnusedImports() {
147
+ const unused = [];
148
+ for (const [localName, bindingInfo] of this.importedBindings) {
149
+ if (!this.referencedNames.has(localName)) {
150
+ unused.push({
151
+ localName,
152
+ modulePath: bindingInfo.modulePath,
153
+ importedName: bindingInfo.importedName,
154
+ });
155
+ }
156
+ }
157
+ return unused;
158
+ }
159
+
160
+ /**
161
+ * Walk the AST and call callback for each node
162
+ */
163
+ _walkAST(node, callback) {
164
+ if (!node || typeof node !== 'object') return;
165
+
166
+ callback(node);
167
+
168
+ // Skip certain node types that don't contain code references
169
+ if (node.type === 'ImportStatement' || node.type === 'NamespaceImportStatement') {
170
+ return;
171
+ }
172
+
173
+ // Recursively walk all properties
174
+ for (const key of Object.keys(node)) {
175
+ const value = node[key];
176
+ if (Array.isArray(value)) {
177
+ for (const item of value) {
178
+ this._walkAST(item, callback);
179
+ }
180
+ } else if (value && typeof value === 'object' && value.type) {
181
+ this._walkAST(value, callback);
182
+ }
183
+ }
184
+ }
185
+
186
+ /**
187
+ * Get the last segment of a module path
188
+ */
189
+ _getModuleLastSegment(modulePath) {
190
+ const segments = modulePath.split('/');
191
+ return segments[segments.length - 1];
192
+ }
193
+ }
194
+
195
+ /**
196
+ * Filters module exports based on what's actually used
197
+ */
198
+ export class TreeShaker {
199
+ /**
200
+ * Filter a module's exports to only include used names
201
+ * @param {Object} moduleExports - The full exports object from a module
202
+ * @param {Set<string>} usedNames - Set of export names that are actually used
203
+ * @returns {Object} Filtered exports object
204
+ */
205
+ filterExports(moduleExports, usedNames) {
206
+ if (!moduleExports || !usedNames) {
207
+ return moduleExports;
208
+ }
209
+
210
+ // If '*' is in usedNames, return all exports (namespace import)
211
+ if (usedNames.has('*')) {
212
+ return moduleExports;
213
+ }
214
+
215
+ // Filter to only include used exports
216
+ const filtered = {};
217
+ for (const name of usedNames) {
218
+ if (name in moduleExports) {
219
+ filtered[name] = moduleExports[name];
220
+ }
221
+ }
222
+
223
+ return filtered;
224
+ }
225
+
226
+ /**
227
+ * Analyze an AST and return tree-shaking metadata
228
+ * @param {Object} ast - The parsed AST
229
+ * @returns {Object} Tree-shaking metadata
230
+ */
231
+ analyzeAndShake(ast) {
232
+ const analyzer = new ImportAnalyzer();
233
+ const usedExports = analyzer.analyze(ast);
234
+ const unusedImports = analyzer.getUnusedImports();
235
+
236
+ return {
237
+ usedExports,
238
+ unusedImports,
239
+ hasUnusedImports: unusedImports.length > 0,
240
+ };
241
+ }
242
+ }
243
+
244
+ /**
245
+ * Create a tree shaker with import analysis
246
+ * @param {Object} ast - The parsed AST
247
+ * @returns {Object} Object with { usedExports, filterExports, unusedImports }
248
+ */
249
+ export function createTreeShaker(ast) {
250
+ const analyzer = new ImportAnalyzer();
251
+ const usedExports = analyzer.analyze(ast);
252
+ const unusedImports = analyzer.getUnusedImports();
253
+ const shaker = new TreeShaker();
254
+
255
+ return {
256
+ usedExports,
257
+ unusedImports,
258
+ filterExports: (moduleExports, modulePath) => {
259
+ const used = usedExports.get(modulePath);
260
+ return shaker.filterExports(moduleExports, used);
261
+ },
262
+ };
263
+ }
264
+
265
+ export default TreeShaker;
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Stone Frontend - Barrel exports
3
+ *
4
+ * Re-exports all frontend modules: parsing, types, type-checker, analysis, utils
5
+ */
6
+
7
+ // Parsing
8
+ export * from './parsing/index.js';
9
+
10
+ // Types
11
+ export * from './types/index.js';
12
+
13
+ // Type Checker
14
+ export * from './type-checker/index.js';
15
+
16
+ // Analysis
17
+ export * from './analysis/index.js';
18
+
19
+ // Utils
20
+ export * from './utils/index.js';