@aster-cloud/aster-lang-ts 1.2.1 → 1.2.3

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 (86) hide show
  1. package/CHANGELOG.md +43 -0
  2. package/dist/src/config/config-service.d.ts +4 -2
  3. package/dist/src/config/config-service.d.ts.map +1 -1
  4. package/dist/src/config/config-service.js +9 -6
  5. package/dist/src/config/config-service.js.map +1 -1
  6. package/dist/src/core/interpreter.d.ts.map +1 -1
  7. package/dist/src/core/interpreter.js +62 -9
  8. package/dist/src/core/interpreter.js.map +1 -1
  9. package/dist/src/frontend/resolution-choice.d.ts +2 -0
  10. package/dist/src/frontend/resolution-choice.d.ts.map +1 -1
  11. package/dist/src/frontend/resolution-choice.js +33 -2
  12. package/dist/src/frontend/resolution-choice.js.map +1 -1
  13. package/dist/src/frontend/resolve-declarations.js +2 -2
  14. package/dist/src/frontend/resolve-declarations.js.map +1 -1
  15. package/dist/src/lsp/completion.d.ts +7 -2
  16. package/dist/src/lsp/completion.d.ts.map +1 -1
  17. package/dist/src/lsp/completion.js +11 -4
  18. package/dist/src/lsp/completion.js.map +1 -1
  19. package/dist/src/lsp/diagnostics.d.ts.map +1 -1
  20. package/dist/src/lsp/diagnostics.js +6 -6
  21. package/dist/src/lsp/diagnostics.js.map +1 -1
  22. package/dist/src/lsp/log-sink.d.ts +21 -0
  23. package/dist/src/lsp/log-sink.d.ts.map +1 -0
  24. package/dist/src/lsp/log-sink.js +37 -0
  25. package/dist/src/lsp/log-sink.js.map +1 -0
  26. package/dist/src/lsp/member-completion.d.ts +38 -3
  27. package/dist/src/lsp/member-completion.d.ts.map +1 -1
  28. package/dist/src/lsp/member-completion.js +102 -19
  29. package/dist/src/lsp/member-completion.js.map +1 -1
  30. package/dist/src/lsp/server.js +7 -1
  31. package/dist/src/lsp/server.js.map +1 -1
  32. package/dist/src/typecheck/context.d.ts.map +1 -1
  33. package/dist/src/typecheck/context.js +29 -2
  34. package/dist/src/typecheck/context.js.map +1 -1
  35. package/dist/src/typecheck/expression.d.ts.map +1 -1
  36. package/dist/src/typecheck/expression.js +20 -2
  37. package/dist/src/typecheck/expression.js.map +1 -1
  38. package/dist/src/typecheck/pattern.js +2 -2
  39. package/dist/src/typecheck/pattern.js.map +1 -1
  40. package/dist/src/typecheck/statement.js +1 -1
  41. package/dist/src/typecheck/statement.js.map +1 -1
  42. package/dist/src/typecheck/symbol_table.d.ts +7 -1
  43. package/dist/src/typecheck/symbol_table.d.ts.map +1 -1
  44. package/dist/src/typecheck/symbol_table.js +14 -0
  45. package/dist/src/typecheck/symbol_table.js.map +1 -1
  46. package/dist/src/utils/logger.d.ts +11 -0
  47. package/dist/src/utils/logger.d.ts.map +1 -1
  48. package/dist/src/utils/logger.js +16 -2
  49. package/dist/src/utils/logger.js.map +1 -1
  50. package/dist/test/integration/lsp/lsp-member-completion.test.js +43 -4
  51. package/dist/test/integration/lsp/lsp-member-completion.test.js.map +1 -1
  52. package/dist/test/integration/lsp/package-exports.test.d.ts +2 -0
  53. package/dist/test/integration/lsp/package-exports.test.d.ts.map +1 -0
  54. package/dist/test/integration/lsp/package-exports.test.js +30 -0
  55. package/dist/test/integration/lsp/package-exports.test.js.map +1 -0
  56. package/dist/test/unit/canonicalizer/possessive-anchor.test.js +25 -28
  57. package/dist/test/unit/canonicalizer/possessive-anchor.test.js.map +1 -1
  58. package/dist/test/unit/config/config-service.test.js +13 -0
  59. package/dist/test/unit/config/config-service.test.js.map +1 -1
  60. package/dist/test/unit/formatter-corpus-roundtrip.test.js +42 -3
  61. package/dist/test/unit/formatter-corpus-roundtrip.test.js.map +1 -1
  62. package/dist/test/unit/frontend/resolution-choice.test.d.ts +2 -0
  63. package/dist/test/unit/frontend/resolution-choice.test.d.ts.map +1 -0
  64. package/dist/test/unit/frontend/resolution-choice.test.js +90 -0
  65. package/dist/test/unit/frontend/resolution-choice.test.js.map +1 -0
  66. package/dist/test/unit/interpreter/scope-writeback.test.d.ts +2 -0
  67. package/dist/test/unit/interpreter/scope-writeback.test.d.ts.map +1 -0
  68. package/dist/test/unit/interpreter/scope-writeback.test.js +154 -0
  69. package/dist/test/unit/interpreter/scope-writeback.test.js.map +1 -0
  70. package/dist/test/unit/lsp/log-levels.test.d.ts +2 -0
  71. package/dist/test/unit/lsp/log-levels.test.d.ts.map +1 -0
  72. package/dist/test/unit/lsp/log-levels.test.js +152 -0
  73. package/dist/test/unit/lsp/log-levels.test.js.map +1 -0
  74. package/dist/test/unit/lsp/member-completion.test.d.ts +2 -0
  75. package/dist/test/unit/lsp/member-completion.test.d.ts.map +1 -0
  76. package/dist/test/unit/lsp/member-completion.test.js +142 -0
  77. package/dist/test/unit/lsp/member-completion.test.js.map +1 -0
  78. package/dist/test/unit/rule-function-values.test.d.ts +2 -0
  79. package/dist/test/unit/rule-function-values.test.d.ts.map +1 -0
  80. package/dist/test/unit/rule-function-values.test.js +89 -0
  81. package/dist/test/unit/rule-function-values.test.js.map +1 -0
  82. package/dist/test/unit/typecheck/assign-mutability.test.d.ts +2 -0
  83. package/dist/test/unit/typecheck/assign-mutability.test.d.ts.map +1 -0
  84. package/dist/test/unit/typecheck/assign-mutability.test.js +144 -0
  85. package/dist/test/unit/typecheck/assign-mutability.test.js.map +1 -0
  86. package/package.json +5 -1
@@ -0,0 +1,152 @@
1
+ /**
2
+ * LSP 日志级别:Logger 按真实级别映射到 window/logMessage 类型,
3
+ * 默认(WARN)不把 INFO / DEBUG 与 [TypecheckCache] 诊断日志推给客户端。
4
+ */
5
+ import { describe, it, afterEach } from 'node:test';
6
+ import assert from 'node:assert/strict';
7
+ import { LogLevel, Logger, installLogSink } from '../../../src/utils/logger.js';
8
+ import { createLspLogSink, installLspLogSink, LSP_DEFAULT_LOG_LEVEL } from '../../../src/lsp/log-sink.js';
9
+ import { computeDiagnostics, invalidateDiagnosticCache } from '../../../src/lsp/diagnostics.js';
10
+ import { ConfigService } from '../../../src/config/config-service.js';
11
+ import { ZH_CN } from '../../../src/config/lexicons/zh-CN.js';
12
+ import { DECLS, docOf, getOrParseWith } from './resolution-fixture.js';
13
+ /** 记录 logMessage 类型:1=Error 2=Warning 3=Info 4=Log */
14
+ function recordingConsole() {
15
+ const messages = [];
16
+ const push = (type) => (text) => void messages.push({ type, text });
17
+ return { console: { error: push(1), warn: push(2), info: push(3), log: push(4) }, messages };
18
+ }
19
+ const restores = [];
20
+ const envBackup = { ASTER_LOG_LEVEL: process.env.ASTER_LOG_LEVEL, LOG_LEVEL: process.env.LOG_LEVEL };
21
+ function install(sinkFactory) {
22
+ restores.push(sinkFactory());
23
+ }
24
+ afterEach(() => {
25
+ while (restores.length)
26
+ restores.pop()();
27
+ for (const [k, v] of Object.entries(envBackup)) {
28
+ if (v === undefined)
29
+ delete process.env[k];
30
+ else
31
+ process.env[k] = v;
32
+ }
33
+ ConfigService.resetForTesting();
34
+ });
35
+ function withEnv(key, value) {
36
+ if (value === undefined)
37
+ delete process.env[key];
38
+ else
39
+ process.env[key] = value;
40
+ ConfigService.resetForTesting();
41
+ }
42
+ describe('LSP 日志级别映射', () => {
43
+ it('默认 WARN:INFO / DEBUG 不产生 logMessage', () => {
44
+ withEnv('ASTER_LOG_LEVEL', undefined);
45
+ withEnv('LOG_LEVEL', undefined);
46
+ const { console, messages } = recordingConsole();
47
+ install(() => installLspLogSink(console));
48
+ const logger = new Logger('typecheck', LogLevel.DEBUG);
49
+ logger.debug('d');
50
+ logger.info('i');
51
+ assert.deepEqual(messages, []);
52
+ assert.equal(LSP_DEFAULT_LOG_LEVEL, LogLevel.WARN);
53
+ });
54
+ it('WARN 产生 type 2,ERROR 产生 type 1,且内容为 JSON 行', () => {
55
+ withEnv('ASTER_LOG_LEVEL', undefined);
56
+ withEnv('LOG_LEVEL', undefined);
57
+ const { console, messages } = recordingConsole();
58
+ install(() => installLspLogSink(console));
59
+ const logger = new Logger('typecheck');
60
+ logger.warn('w');
61
+ logger.error('e', new Error('boom'));
62
+ assert.deepEqual(messages.map((m) => m.type), [2, 1]);
63
+ assert.equal(JSON.parse(messages[0].text).level, 'WARN');
64
+ assert.equal(JSON.parse(messages[1].text).error, 'boom');
65
+ });
66
+ it('ASTER_LOG_LEVEL 可调高:INFO→3,DEBUG→4', () => {
67
+ withEnv('ASTER_LOG_LEVEL', 'debug');
68
+ const { console, messages } = recordingConsole();
69
+ install(() => installLspLogSink(console));
70
+ const logger = new Logger('typecheck');
71
+ logger.info('i');
72
+ logger.debug('d');
73
+ assert.deepEqual(messages.map((m) => m.type), [3, 4]);
74
+ });
75
+ it('ASTER_LOG_LEVEL=error 压低到只发 ERROR', () => {
76
+ withEnv('ASTER_LOG_LEVEL', 'error');
77
+ const { console, messages } = recordingConsole();
78
+ install(() => installLspLogSink(console));
79
+ const logger = new Logger('x');
80
+ logger.warn('w');
81
+ logger.error('e');
82
+ assert.deepEqual(messages.map((m) => m.type), [1]);
83
+ });
84
+ it('落点恢复后回到 stderr 行为', () => {
85
+ const { console, messages } = recordingConsole();
86
+ const restore = installLogSink(createLspLogSink(console, LogLevel.DEBUG));
87
+ restore();
88
+ const original = globalThis.console.error;
89
+ const seen = [];
90
+ globalThis.console.error = (line) => void seen.push(line);
91
+ try {
92
+ new Logger('x', LogLevel.INFO).info('cli');
93
+ }
94
+ finally {
95
+ globalThis.console.error = original;
96
+ }
97
+ assert.equal(messages.length, 0);
98
+ assert.equal(seen.length, 1);
99
+ });
100
+ it('CLI 默认不安装落点:INFO 仍写 stderr', () => {
101
+ const original = globalThis.console.error;
102
+ const seen = [];
103
+ globalThis.console.error = (line) => void seen.push(String(line));
104
+ try {
105
+ new Logger('cli', LogLevel.INFO).info('hello');
106
+ new Logger('cli', LogLevel.INFO).debug('hidden');
107
+ }
108
+ finally {
109
+ globalThis.console.error = original;
110
+ }
111
+ assert.equal(seen.length, 1);
112
+ assert.equal(JSON.parse(seen[0]).level, 'INFO');
113
+ });
114
+ });
115
+ describe('[TypecheckCache] 诊断日志', () => {
116
+ const GOOD = ['规则 检查 给定 x 作为 司机,产出 整数:', ' 返回 x.alter。', ''];
117
+ async function runTwice() {
118
+ const doc = docOf([...DECLS, ...GOOD]);
119
+ const getOrParse = getOrParseWith(ZH_CN);
120
+ await computeDiagnostics(doc.document, getOrParse, ZH_CN);
121
+ invalidateDiagnosticCache(doc.document.uri);
122
+ await computeDiagnostics(doc.document, getOrParse, ZH_CN);
123
+ }
124
+ it('默认级别下不输出,也不写 stderr', async () => {
125
+ withEnv('ASTER_LOG_LEVEL', undefined);
126
+ withEnv('LOG_LEVEL', undefined);
127
+ const { console, messages } = recordingConsole();
128
+ install(() => installLspLogSink(console));
129
+ const original = globalThis.console.error;
130
+ const stderr = [];
131
+ globalThis.console.error = (...a) => void stderr.push(a);
132
+ try {
133
+ await runTwice();
134
+ }
135
+ finally {
136
+ globalThis.console.error = original;
137
+ }
138
+ assert.deepEqual(messages.filter((m) => m.text.includes('TypecheckCache')), []);
139
+ assert.deepEqual(stderr.filter((a) => String(a).includes('TypecheckCache')), []);
140
+ });
141
+ it('调到 DEBUG 后以 type 4 输出(缓存写入与命中)', async () => {
142
+ withEnv('ASTER_LOG_LEVEL', 'debug');
143
+ const { console, messages } = recordingConsole();
144
+ install(() => installLspLogSink(console));
145
+ await runTwice();
146
+ const cache = messages.filter((m) => m.text.includes('[TypecheckCache]'));
147
+ assert.ok(cache.length >= 1, '应至少有一条 TypecheckCache 日志');
148
+ assert.ok(cache.every((m) => m.type === 4));
149
+ assert.ok(cache.some((m) => m.text.includes('Cached')));
150
+ });
151
+ });
152
+ //# sourceMappingURL=log-levels.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log-levels.test.js","sourceRoot":"","sources":["../../../../test/unit/lsp/log-levels.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=member-completion.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"member-completion.test.d.ts","sourceRoot":"","sources":["../../../../test/unit/lsp/member-completion.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,142 @@
1
+ /**
2
+ * 成员补全(member-completion.ts)的函数级测试:
3
+ * - 光标在已有成员名中间(`d.ag|e`)时,替换范围须覆盖名字后半截(#259);
4
+ * - 修补文本推断有缓存、有规模上限(#258):同一修补文本不重复解析,输入前缀时复用,
5
+ * 修补推断有累计耗时预算,超出后放弃其余修补;大文档未写完的行照常补全。
6
+ */
7
+ import { describe, it, beforeEach } from 'node:test';
8
+ import assert from 'node:assert/strict';
9
+ import { EN_US } from '../../../src/config/lexicons/en-US.js';
10
+ import { ZH_CN } from '../../../src/config/lexicons/zh-CN.js';
11
+ import { clearMemberRepairCache, memberCompletions, } from '../../../src/lsp/member-completion.js';
12
+ import { parseDocumentText, parseDocumentWith } from '../../../src/lsp/parse-document.js';
13
+ const HEAD = ['Module demo.p.', '', 'Define Driver has name as Text, age as Int.', '', 'Rule f given d as Driver, produce Int:'];
14
+ function docOf(lines) {
15
+ const text = lines.join('\n');
16
+ return { text, ...parseDocumentText(text, EN_US, undefined, undefined) };
17
+ }
18
+ /** 统计修补文本解析次数的 parse */
19
+ function countingParse() {
20
+ let n = 0;
21
+ return {
22
+ parse: (text, lexicon, vocabulary) => {
23
+ n += 1;
24
+ return parseDocumentWith(text, lexicon, vocabulary);
25
+ },
26
+ count: () => n,
27
+ };
28
+ }
29
+ const labels = (items) => (items ?? []).map((i) => i.label).sort();
30
+ beforeEach(() => clearMemberRepairCache());
31
+ describe('#259 光标在成员名中间', () => {
32
+ const body = ' Return d.age.';
33
+ const dot = ' Return d.'.length;
34
+ const cursor = { line: 5, character: dot + 2 }; // d.ag|e
35
+ it('客户端支持 InsertReplaceEdit:insert = 点号后到光标,replace = 点号后到名字末尾', () => {
36
+ const items = memberCompletions(docOf([...HEAD, body, '']), cursor, EN_US, { insertReplace: true });
37
+ assert.deepEqual(labels(items), ['age', 'name']);
38
+ for (const i of items) {
39
+ assert.deepEqual(i.textEdit, {
40
+ insert: { start: { line: 5, character: dot }, end: cursor },
41
+ replace: { start: { line: 5, character: dot }, end: { line: 5, character: dot + 3 } },
42
+ newText: i.label,
43
+ });
44
+ }
45
+ });
46
+ it('客户端不支持 InsertReplaceEdit:TextEdit 覆盖整个名字(选 age 得到 age,而非 agee)', () => {
47
+ const items = memberCompletions(docOf([...HEAD, body, '']), cursor, EN_US);
48
+ for (const i of items) {
49
+ assert.deepEqual(i.textEdit, { range: { start: { line: 5, character: dot }, end: { line: 5, character: dot + 3 } }, newText: i.label });
50
+ }
51
+ });
52
+ it('光标在名字末尾:仍是普通 TextEdit(insert 与 replace 相同,无需 InsertReplaceEdit)', () => {
53
+ const at = { line: 5, character: dot + 3 };
54
+ const items = memberCompletions(docOf([...HEAD, body, '']), at, EN_US, { insertReplace: true });
55
+ for (const i of items) {
56
+ assert.deepEqual(i.textEdit, { range: { start: { line: 5, character: dot }, end: at }, newText: i.label });
57
+ }
58
+ });
59
+ });
60
+ describe('#258 修补推断的缓存与规模上限', () => {
61
+ // `If d.` 让当前行与所在声明语法不完整:原文推断失败,须走修补文本
62
+ const broken = (prefix) => [...HEAD, ` If d.${prefix} plus 1`, ' Return 1.', ''];
63
+ const at = (prefix) => ({ line: 5, character: ` If d.${prefix}`.length });
64
+ it('同一文档版本再次请求:不重复解析修补文本', () => {
65
+ const doc = docOf(broken(''));
66
+ const first = countingParse();
67
+ assert.deepEqual(labels(memberCompletions(doc, at(''), EN_US, { parse: first.parse })), ['age', 'name']);
68
+ assert.ok(first.count() > 0, '首次请求应解析修补文本');
69
+ const again = countingParse();
70
+ assert.deepEqual(labels(memberCompletions(doc, at(''), EN_US, { parse: again.parse })), ['age', 'name']);
71
+ assert.equal(again.count(), 0);
72
+ });
73
+ it('继续输入成员前缀(新版本 d.a → d.ag):修补文本相同,复用缓存', () => {
74
+ memberCompletions(docOf(broken('')), at(''), EN_US);
75
+ for (const prefix of ['a', 'ag']) {
76
+ const probe = countingParse();
77
+ assert.deepEqual(labels(memberCompletions(docOf(broken(prefix)), at(prefix), EN_US, { parse: probe.parse })), ['age', 'name'], prefix);
78
+ assert.equal(probe.count(), 0, prefix);
79
+ }
80
+ });
81
+ it('文档其它位置改变后缓存不误用:重新解析', () => {
82
+ memberCompletions(docOf(broken('')), at(''), EN_US);
83
+ const changed = [...HEAD.slice(0, 2), 'Define Driver has name as Text, age as Int, level as Int.', ...HEAD.slice(3), ' If d. plus 1', ' Return 1.', ''];
84
+ const probe = countingParse();
85
+ assert.deepEqual(labels(memberCompletions(docOf(changed), at(''), EN_US, { parse: probe.parse })), ['age', 'level', 'name']);
86
+ assert.ok(probe.count() > 0);
87
+ });
88
+ /** 返回一个每次调用前进 step 毫秒的假时钟 */
89
+ const ticking = (step) => {
90
+ let t = 0;
91
+ return () => (t += step);
92
+ };
93
+ it('★大文档(约 5000 行)当前行未写完:照常给字段(不再按行数放弃)', () => {
94
+ const rules = Array.from({ length: 600 }, (_, i) => [`Rule g${i} given d as Driver, produce Int:`, ' Return d.age plus 1.', '']).flat();
95
+ const filler = Array.from({ length: 3000 }, () => '');
96
+ const lines = [...HEAD.slice(0, 4), ...rules, ...filler, HEAD[4], ' If d. plus 1', ' Return 1.', ''];
97
+ assert.ok(lines.length > 4800);
98
+ const probe = countingParse();
99
+ const items = memberCompletions(docOf(lines), { line: lines.length - 3, character: ' If d.'.length }, EN_US, { parse: probe.parse });
100
+ assert.deepEqual(labels(items), ['age', 'name']);
101
+ assert.ok(probe.count() >= 1 && probe.count() <= 3, `修补解析 ${probe.count()} 次`);
102
+ });
103
+ // zh 行尾 `如果 司机.`:前两份修补(删 `.前缀` / 删前缀)仍不完整,第三份(换成 `返回 司机.`)才定出类型
104
+ const ZH_LINES = ['模块 demo.p。', '', '定义 驾驶员 包含 年龄 作为 整数,姓名 作为 文本。', '', '规则 f 给定 司机 作为 驾驶员,产出 整数:', ' 如果 司机.', ''];
105
+ const zhDoc = () => {
106
+ const text = ZH_LINES.join('\n');
107
+ return { text, ...parseDocumentText(text, ZH_CN, undefined, undefined) };
108
+ };
109
+ const ZH_AT = { line: 5, character: ' 如果 司机.'.length };
110
+ it('★累计耗时超过预算后放弃其余修补:第一份修补失败即返回 null', () => {
111
+ const probe = countingParse();
112
+ const items = memberCompletions(zhDoc(), ZH_AT, ZH_CN, { parse: probe.parse, now: ticking(1000), repairBudgetMs: 150, repairBudgetFromLines: 0 });
113
+ assert.equal(items, null);
114
+ assert.equal(probe.count(), 1, '第一份修补总会尝试,之后超预算即停止');
115
+ });
116
+ it('小文档(不足 MEMBER_REPAIR_BUDGET_FROM_LINES 行)不受预算约束:冷启动或高负载下也依次尝试到成功', () => {
117
+ const probe = countingParse();
118
+ const items = memberCompletions(zhDoc(), ZH_AT, ZH_CN, { parse: probe.parse, now: ticking(1000), repairBudgetMs: 150 });
119
+ assert.deepEqual(labels(items), ['姓名', '年龄'].sort());
120
+ assert.equal(probe.count(), 3);
121
+ });
122
+ it('预算未超出时依次尝试,直到某份修补成功', () => {
123
+ const probe = countingParse();
124
+ const items = memberCompletions(zhDoc(), ZH_AT, ZH_CN, { parse: probe.parse, now: ticking(0), repairBudgetMs: 150, repairBudgetFromLines: 0 });
125
+ assert.deepEqual(labels(items), ['姓名', '年龄'].sort());
126
+ assert.equal(probe.count(), 3);
127
+ });
128
+ it('命中缓存的修补不计耗时:预算耗尽时继续输入前缀仍能补全', () => {
129
+ memberCompletions(docOf(broken('')), at(''), EN_US);
130
+ const probe = countingParse();
131
+ const items = memberCompletions(docOf(broken('a')), at('a'), EN_US, { parse: probe.parse, now: ticking(1000), repairBudgetMs: 0, repairBudgetFromLines: 0 });
132
+ assert.deepEqual(labels(items), ['age', 'name']);
133
+ assert.equal(probe.count(), 0);
134
+ });
135
+ it('原文可推断(`Return d.` 本身是完整语句):不做修补解析', () => {
136
+ const probe = countingParse();
137
+ const items = memberCompletions(docOf([...HEAD, ' Return d.', '']), { line: 5, character: ' Return d.'.length }, EN_US, { parse: probe.parse });
138
+ assert.deepEqual(labels(items), ['age', 'name']);
139
+ assert.equal(probe.count(), 0);
140
+ });
141
+ });
142
+ //# sourceMappingURL=member-completion.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"member-completion.test.js","sourceRoot":"","sources":["../../../../test/unit/lsp/member-completion.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=rule-function-values.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule-function-values.test.d.ts","sourceRoot":"","sources":["../../../test/unit/rule-function-values.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,89 @@
1
+ /**
2
+ * 规则引用作为函数值(#256):`twice(inc, n)` 把模块规则 inc 当作函数值传给高阶规则。
3
+ *
4
+ * 语言语义早已允许(ADR 0024:具名规则可作 List.map 的 fn 参数;ADR 0051 §4 名称位置表把
5
+ * 「函数值引用」列为 FUNC_REF),Java 引擎也已支持:
6
+ * - typecheck:TypeChecker.defineFunctionSignature 把全部函数签名以 FuncType 登记进模块作用域,
7
+ * 值位置的 Name 照常查到;
8
+ * - 运行期:truffle Loader 把每个函数以 LambdaValue 放进 env,Name 回退到 env 即得到可调用值。
9
+ * TS 只在 List.* 等 stdlib 回调里特判了函数名,typecheck 报 E101、解释器报 Undefined variable。
10
+ */
11
+ import { describe, it } from 'node:test';
12
+ import assert from 'node:assert/strict';
13
+ import { compileAndTypecheck, evaluate, EN_US } from '../../src/browser.js';
14
+ import { typecheckBrowser } from '../../src/typecheck/browser.js';
15
+ const INC = 'Rule inc given x as Int, produce Int:\n Return x plus 1.\n\n';
16
+ const TWICE = 'Rule twice given f as (Int) -> Int, n as Int, produce Int:\n Return f(f(n)).\n\n';
17
+ function compileClean(body) {
18
+ const r = compileAndTypecheck(`Module demo.\n\n${body}`, { lexicon: EN_US });
19
+ const errors = [...(r.parseErrors ?? []), ...(r.resolutionDiagnostics ?? []), ...(r.typeErrors ?? [])]
20
+ .filter((d) => d.severity === 'error');
21
+ assert.deepEqual(errors, []);
22
+ assert.equal(r.success, true);
23
+ return r.core;
24
+ }
25
+ function run(core, func, input) {
26
+ const r = evaluate(core, func, input);
27
+ assert.equal(r.success, true, r.error);
28
+ return r.value;
29
+ }
30
+ describe('规则引用作为函数值', () => {
31
+ it('★twice(inc, n):无 E101,求值得 n + 2', () => {
32
+ const core = compileClean(INC + TWICE + 'Rule main given n as Int, produce Int:\n Return twice(inc, n).\n');
33
+ assert.equal(run(core, 'main', { n: 1 }), 3);
34
+ });
35
+ it('规则声明在使用之后(前向引用)同样可用', () => {
36
+ const core = compileClean(TWICE + 'Rule main given n as Int, produce Int:\n Return twice(inc, n).\n\n' + INC);
37
+ assert.equal(run(core, 'main', { n: 5 }), 7);
38
+ });
39
+ it('Let g be inc:绑定后按局部名调用', () => {
40
+ const core = compileClean(INC + 'Rule main given n as Int, produce Int:\n Let g be inc.\n Return g(n).\n');
41
+ assert.equal(run(core, 'main', { n: 41 }), 42);
42
+ });
43
+ it('函数值的静态类型为规则签名的 FuncType:经局部名调用的结果类型为返回类型(返回类型不符照常报错)', () => {
44
+ const r = compileAndTypecheck(`Module demo.\n\n${INC}Rule main given n as Int, produce Text:\n Let g be inc.\n Return g(n).\n`, { lexicon: EN_US });
45
+ const codes = (r.typeErrors ?? []).filter((d) => d.severity === 'error').map((d) => d.code);
46
+ assert.ok(codes.length > 0, '返回 Int 却声明 Text,应报类型错误');
47
+ assert.ok(!codes.includes('E101'), `不应报 E101:${codes}`);
48
+ });
49
+ it('局部名遮蔽同名规则:参数 inc 优先于模块规则 inc', () => {
50
+ const core = compileClean(INC + TWICE +
51
+ 'Rule dec given x as Int, produce Int:\n Return x minus 1.\n\n' +
52
+ 'Rule viaParam given inc as (Int) -> Int, n as Int, produce Int:\n Return twice(inc, n).\n\n' +
53
+ 'Rule main given n as Int, produce Int:\n Return viaParam(dec, n).\n');
54
+ assert.equal(run(core, 'main', { n: 10 }), 8);
55
+ });
56
+ it('局部函数值遮蔽同名规则时,调用个数按局部值而非规则签名校验', () => {
57
+ compileClean('Rule pair given a as Int, b as Int, produce Int:\n Return a plus b.\n\n' +
58
+ 'Rule main given pair as (Int) -> Int, n as Int, produce Int:\n Return pair(n).\n');
59
+ });
60
+ it('★经函数值局部名调用时校验参数个数:`Let g be inc. Return g(n, n).` 报 E032(Java 报 TYPE_MISMATCH 拒绝)', () => {
61
+ const r = compileAndTypecheck(`Module demo.\n\n${INC}Rule main given n as Int, produce Int:\n Let g be inc.\n Return g(n, n).\n`, { lexicon: EN_US });
62
+ const arity = (r.typeErrors ?? []).filter((d) => d.code === 'E032');
63
+ assert.equal(arity.length, 1, JSON.stringify(r.typeErrors));
64
+ assert.deepEqual(arity[0].data, { func: 'g', expected: 1, actual: 2 });
65
+ });
66
+ it('函数类型参数调用个数不符同样报 E032', () => {
67
+ const r = compileAndTypecheck(`Module demo.\n\nRule apply given f as (Int) -> Int, n as Int, produce Int:\n Return f().\n`, { lexicon: EN_US });
68
+ assert.deepEqual((r.typeErrors ?? []).filter((d) => d.code === 'E032').map((d) => d.data), [{ func: 'f', expected: 1, actual: 0 }]);
69
+ });
70
+ it('未声明的名字仍被拒绝(名称解析报 E802,不产出 IR)', () => {
71
+ const r = compileAndTypecheck(`Module demo.\n\n${TWICE}Rule main given n as Int, produce Int:\n Return twice(nope, n).\n`, { lexicon: EN_US });
72
+ assert.equal(r.success, false);
73
+ assert.deepEqual((r.resolutionDiagnostics ?? []).map((d) => d.code), ['E802']);
74
+ });
75
+ it('typecheck 层:Core 中未定义的值名仍报 E101(函数签名回退不吞掉未定义名)', () => {
76
+ const core = compileClean(INC + 'Rule main given n as Int, produce Int:\n Return inc(n).\n');
77
+ const main = core.decls.find((d) => d.kind === 'Func' && d.name === 'main');
78
+ const ret = main.body.statements[0];
79
+ const call = ret.expr;
80
+ const broken = { ...core, decls: core.decls.map((d) => (d === main ? { ...main, body: { ...main.body, statements: [{ ...ret, expr: { ...call, args: [{ ...call.args[0], name: 'nope' }] } }] } } : d)) };
81
+ const diags = typecheckBrowser(broken);
82
+ assert.ok(diags.some((d) => d.code === 'E101' && d.message.includes('nope')), JSON.stringify(diags));
83
+ });
84
+ it('List.map(xs, inc) 的既有行为不变', () => {
85
+ const core = compileClean(INC + 'Rule main given xs as List of Int, produce List of Int:\n Return List.map(xs, inc).\n');
86
+ assert.deepEqual(run(core, 'main', { xs: [1, 2] }), [2, 3]);
87
+ });
88
+ });
89
+ //# sourceMappingURL=rule-function-values.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rule-function-values.test.js","sourceRoot":"","sources":["../../../test/unit/rule-function-values.test.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=assign-mutability.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assign-mutability.test.d.ts","sourceRoot":"","sources":["../../../../test/unit/typecheck/assign-mutability.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Set 的可赋值目标(ADR 0052,aster-cloud/aster-lang-truffle#151)。
3
+ *
4
+ * 只有 Let 绑定可被 `Set` 赋值,且可跨 case 体 / If 分支写回外层;形参、lambda 形参、模式绑定不可变,
5
+ * 与 Java BaseTypeChecker 同报 E001(TYPE_MISMATCH)。
6
+ */
7
+ import { describe, it } from 'node:test';
8
+ import assert from 'node:assert/strict';
9
+ import { compileAndTypecheck } from '../../../src/browser.js';
10
+ function errors(lines) {
11
+ const result = compileAndTypecheck(['Module m.', '', ...lines, ''].join('\n'));
12
+ assert.deepEqual(result.parseErrors ?? [], [], JSON.stringify(result.parseErrors));
13
+ return result.typeErrors
14
+ .filter((d) => d.severity === 'error')
15
+ .map((d) => ({ code: d.code, line: d.span?.start.line ?? -1, message: d.message }));
16
+ }
17
+ describe('Set 赋值目标的可变性', () => {
18
+ it('case 体内 Set 外层 Let:无错误', () => {
19
+ assert.deepEqual(errors([
20
+ 'Rule r given n as Int, produce Int:',
21
+ ' Let total be 0.',
22
+ ' Match n:',
23
+ ' When 1,',
24
+ ' Set total to 10.',
25
+ ' When other,',
26
+ ' Set total to total plus other.',
27
+ ' Return total.',
28
+ ]), []);
29
+ });
30
+ it('If / Otherwise 分支内 Set 外层 Let:无错误', () => {
31
+ assert.deepEqual(errors([
32
+ 'Rule r given n as Int, produce Int:',
33
+ ' Let sign be 0.',
34
+ ' If n greater than 0',
35
+ ' Set sign to 1.',
36
+ ' Otherwise',
37
+ ' Set sign to 2.',
38
+ ' Return sign.',
39
+ ]), []);
40
+ });
41
+ it('Set 形参:报 E001 且指明是形参', () => {
42
+ const errs = errors([
43
+ 'Rule r given n as Int, produce Int:',
44
+ ' Set n to 1.',
45
+ ' Return n.',
46
+ ]);
47
+ assert.deepEqual(errs.map((e) => [e.code, e.line]), [["E001" /* ErrorCode.TYPE_MISMATCH */, 4]]);
48
+ assert.match(errs[0].message, /parameter 'n'/);
49
+ });
50
+ it('case 体内 Set 形参:同样拒绝', () => {
51
+ const errs = errors([
52
+ 'Rule r given n as Int, produce Int:',
53
+ ' Match n:',
54
+ ' When 1,',
55
+ ' Set n to 2.',
56
+ ' Return n.',
57
+ ]);
58
+ assert.deepEqual(errs.map((e) => [e.code, e.line]), [["E001" /* ErrorCode.TYPE_MISMATCH */, 6]]);
59
+ });
60
+ it('Set 模式绑定:报 E001 且指明是模式绑定', () => {
61
+ const errs = errors([
62
+ 'Rule r given n as Int, produce Int:',
63
+ ' Let total be 0.',
64
+ ' Match n:',
65
+ ' When other,',
66
+ ' Set other to 1.',
67
+ ' Set total to other.',
68
+ ' Return total.',
69
+ ]);
70
+ assert.deepEqual(errs.map((e) => [e.code, e.line]), [["E001" /* ErrorCode.TYPE_MISMATCH */, 7]]);
71
+ assert.match(errs[0].message, /pattern binding 'other'/);
72
+ });
73
+ it('lambda 体内 Set lambda 形参:同样拒绝', () => {
74
+ const errs = errors([
75
+ 'Rule r given n as Int, produce Int:',
76
+ ' Let f be function with k as Int, produce Int:',
77
+ ' Set k to 1.',
78
+ ' Return k.',
79
+ ' Return f(n).',
80
+ ]);
81
+ assert.deepEqual(errs.map((e) => [e.code, e.line]), [["E001" /* ErrorCode.TYPE_MISMATCH */, 5]]);
82
+ assert.match(errs[0].message, /parameter 'k'/);
83
+ });
84
+ it('lambda 体内 Set 捕获的外层 Let:报 E001(按值捕获,语义未定义,一律拒绝)', () => {
85
+ const errs = errors([
86
+ 'Rule r given n as Int, produce Int:',
87
+ ' Let acc be 0.',
88
+ ' Let f be function with k as Int, produce Int:',
89
+ ' Set acc to acc plus k.',
90
+ ' Return acc.',
91
+ ' Return f(n).',
92
+ ]);
93
+ assert.deepEqual(errs.map((e) => [e.code, e.line]), [["E001" /* ErrorCode.TYPE_MISMATCH */, 6]]);
94
+ assert.match(errs[0].message, /captured variable 'acc'/);
95
+ });
96
+ it('lambda 体内 Set 自己的 Let:无错误', () => {
97
+ assert.deepEqual(errors([
98
+ 'Rule r given n as Int, produce Int:',
99
+ ' Let f be function with k as Int, produce Int:',
100
+ ' Let local be k.',
101
+ ' Set local to local plus 1.',
102
+ ' Return local.',
103
+ ' Return f(n).',
104
+ ]), []);
105
+ });
106
+ it('Set 函数名:报 E101(与 Java 一致)', () => {
107
+ const errs = errors([
108
+ 'Rule g given n as Int, produce Int:',
109
+ ' Return n.',
110
+ '',
111
+ 'Rule r given n as Int, produce Int:',
112
+ ' Set g to 1.',
113
+ ' Return n.',
114
+ ]);
115
+ assert.deepEqual(errs.map((e) => [e.code, e.line]), [["E101" /* ErrorCode.UNDEFINED_VARIABLE */, 7]]);
116
+ });
117
+ it('小写 set 同样是 Set 语句', () => {
118
+ assert.deepEqual(errors([
119
+ 'Rule r given n as Int, produce Int:',
120
+ ' Let total be 0.',
121
+ ' set total to n.',
122
+ ' Return total.',
123
+ ]), []);
124
+ });
125
+ // 有意的破坏性变更(ADR 0052 §6):Set 只能赋值给已有的 Let 绑定,首次声明用 Set 报 E101。
126
+ it('Set 未定义的名字:报 E101', () => {
127
+ const errs = errors([
128
+ 'Rule r given n as Int, produce Int:',
129
+ ' Set missing to 1.',
130
+ ' Return n.',
131
+ ]);
132
+ assert.deepEqual(errs.map((e) => [e.code, e.line]), [["E101" /* ErrorCode.UNDEFINED_VARIABLE */, 4]]);
133
+ });
134
+ it('Set 外层 Let 类型不符:报 E002', () => {
135
+ const errs = errors([
136
+ 'Rule r given n as Int, produce Int:',
137
+ ' Let total be 0.',
138
+ ' Set total to "x".',
139
+ ' Return total.',
140
+ ]);
141
+ assert.ok(errs.some((e) => e.code === "E002" /* ErrorCode.TYPE_MISMATCH_ASSIGN */), JSON.stringify(errs));
142
+ });
143
+ });
144
+ //# sourceMappingURL=assign-mutability.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"assign-mutability.test.js","sourceRoot":"","sources":["../../../../test/unit/typecheck/assign-mutability.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aster-cloud/aster-lang-ts",
3
- "version": "1.2.1",
3
+ "version": "1.2.3",
4
4
  "description": "Aster CNL (Controlled Natural Language) TypeScript Compiler - Lexer, Parser, AST, Core IR, Type Checker",
5
5
  "type": "module",
6
6
  "main": "./dist/src/index.js",
@@ -78,6 +78,10 @@
78
78
  "types": "./dist/src/lsp/diagnostics.d.ts",
79
79
  "import": "./dist/src/lsp/diagnostics.js"
80
80
  },
81
+ "./lsp/completion": {
82
+ "types": "./dist/src/lsp/completion.d.ts",
83
+ "import": "./dist/src/lsp/completion.js"
84
+ },
81
85
  "./browser": {
82
86
  "types": "./dist/src/browser.d.ts",
83
87
  "import": "./dist/src/browser.js"