@mirascript/monaco 0.1.83 → 0.1.85

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.
@@ -35,29 +35,35 @@ function tokenScope(scopes: string[]): string {
35
35
  /** Shared instance of highlighter. */
36
36
  class HighlighterManager implements IDisposable {
37
37
  private highlighterPromise: Promise<HighlighterCore> | null = null;
38
-
38
+ private INITIAL!: StateStack;
39
39
  /**
40
- * Get the shared highlighter instance.
40
+ * Load the shared highlighter instance.
41
41
  */
42
- private async getHighlighter(): Promise<HighlighterCore> {
43
- if (this.highlighterPromise) return this.highlighterPromise;
44
-
42
+ private async loadHighlighter(): Promise<HighlighterCore> {
45
43
  const [
46
44
  { createHighlighterCore },
47
- { createOnigurumaEngine },
48
- wasm,
45
+ { createJavaScriptRegexEngine },
46
+ { INITIAL },
49
47
  { mirascript, mirascriptDoc, mirascriptTemplate },
50
48
  ] = await Promise.all([
51
49
  import('@shikijs/core'),
52
- import('@shikijs/engine-oniguruma'),
53
- import('@shikijs/engine-oniguruma/wasm-inlined'),
50
+ import('@shikijs/engine-javascript'),
51
+ import('@shikijs/vscode-textmate'),
54
52
  import('@mirascript/textmate'),
55
53
  ]);
56
- this.highlighterPromise = createHighlighterCore({
54
+ this.INITIAL = INITIAL;
55
+ return await createHighlighterCore({
57
56
  langs: [mirascript, mirascriptDoc, mirascriptTemplate],
58
57
  themes: [],
59
- engine: createOnigurumaEngine(wasm),
58
+ engine: createJavaScriptRegexEngine(),
60
59
  });
60
+ }
61
+
62
+ /**
63
+ * Get the shared highlighter instance.
64
+ */
65
+ private async getHighlighter(): Promise<HighlighterCore> {
66
+ this.highlighterPromise ??= this.loadHighlighter();
61
67
  return this.highlighterPromise;
62
68
  }
63
69
 
@@ -66,9 +72,8 @@ class HighlighterManager implements IDisposable {
66
72
  return {
67
73
  create: async () => {
68
74
  const highlighter = await this.getHighlighter();
69
- const { INITIAL } = await import('@shikijs/vscode-textmate');
70
75
  const grammar = highlighter.getLanguage(languageId);
71
- return new TokensProvider(grammar, INITIAL);
76
+ return new TokensProvider(grammar, this.INITIAL);
72
77
  },
73
78
  };
74
79
  }
@@ -91,11 +96,11 @@ class HighlighterManager implements IDisposable {
91
96
  class TokensProvider implements languages.TokensProvider {
92
97
  constructor(
93
98
  private readonly grammar: Grammar,
94
- private readonly initialState: StateStack,
99
+ private readonly INITIAL: StateStack,
95
100
  ) {}
96
101
  /** @inheritdoc */
97
102
  getInitialState(): StateStack {
98
- return this.initialState;
103
+ return this.INITIAL;
99
104
  }
100
105
  /** @inheritdoc */
101
106
  tokenize(line: string, state: StateStack): languages.ILineTokens {
@@ -2,7 +2,7 @@ import type { Writable } from 'type-fest';
2
2
  import { type editor, Range, type IRange, type IPosition, Position } from '../monaco-api.js';
3
3
  import { strictContainsPosition } from './monaco-utils.js';
4
4
  import { REG_IDENTIFIER_FULL, REG_ORDINAL_FULL } from '../constants.js';
5
- import type { CacheKey, MonacoResult } from './worker.js';
5
+ import type { CacheKey, MonacoResult } from './worker-core.js';
6
6
  import {
7
7
  parseDiagnostics,
8
8
  DiagnosticCode,
@@ -5,6 +5,15 @@ import { DiagnosticCode } from '@mirascript/constants';
5
5
  const REG_COLOR_STR = /^(@*)(['"`])(#(?:[0-9a-f]{6}|[0-9a-f]{3}|[0-9a-f]{8}|[0-9a-f]{4}))\2\1$/iu;
6
6
  const { parseInt } = Number;
7
7
 
8
+ /** 解析颜色 */
9
+ function parseColorPart(text: string): number {
10
+ if (text.length === 1) {
11
+ // 处理单字符的情况,例如 #f00 -> #ff0000
12
+ text = text + text;
13
+ }
14
+ return parseInt(text, 16) / 255;
15
+ }
16
+
8
17
  /** 解析颜色 */
9
18
  function parseColorString(text: string):
10
19
  | {
@@ -25,36 +34,21 @@ function parseColorString(text: string):
25
34
  if (colorString.startsWith('#')) {
26
35
  const colorCode = colorString.slice(1);
27
36
 
28
- if (colorCode.length === 3) {
29
- // 处理 #RGB 格式
30
- color = {
31
- red: parseInt(colorCode[0]! + colorCode[0]!, 16) / 255,
32
- green: parseInt(colorCode[1]! + colorCode[1]!, 16) / 255,
33
- blue: parseInt(colorCode[2]! + colorCode[2]!, 16) / 255,
34
- alpha: 1,
35
- };
36
- } else if (colorCode.length === 6) {
37
- color = {
38
- red: parseInt(colorCode.slice(0, 2), 16) / 255,
39
- green: parseInt(colorCode.slice(2, 4), 16) / 255,
40
- blue: parseInt(colorCode.slice(4, 6), 16) / 255,
41
- alpha: 1, // 假设不透明
42
- };
43
- } else if (colorCode.length === 8) {
44
- // 处理 #RRGGBBAA 格式
37
+ if (colorCode.length === 3 || colorCode.length === 4) {
38
+ // 处理短格式的颜色代码,例如 #f00 或 #f00f
45
39
  color = {
46
- red: parseInt(colorCode.slice(0, 2), 16) / 255,
47
- green: parseInt(colorCode.slice(2, 4), 16) / 255,
48
- blue: parseInt(colorCode.slice(4, 6), 16) / 255,
49
- alpha: parseInt(colorCode.slice(6, 8), 16) / 255,
40
+ red: parseColorPart(colorCode[0]!),
41
+ green: parseColorPart(colorCode[1]!),
42
+ blue: parseColorPart(colorCode[2]!),
43
+ alpha: colorCode[3] ? parseColorPart(colorCode[3]) : 1, // 如果没有 alpha,则假设不透明
50
44
  };
51
- } else if (colorCode.length === 4) {
52
- // 处理 #RGBA 格式
45
+ } else if (colorCode.length === 6 || colorCode.length === 8) {
46
+ // 处理长格式的颜色代码,例如 #ff0000 或 #ff0000ff
53
47
  color = {
54
- red: parseInt(colorCode[0]! + colorCode[0]!, 16) / 255,
55
- green: parseInt(colorCode[1]! + colorCode[1]!, 16) / 255,
56
- blue: parseInt(colorCode[2]! + colorCode[2]!, 16) / 255,
57
- alpha: parseInt(colorCode[3]! + colorCode[3]!, 16) / 255,
48
+ red: parseColorPart(colorCode.slice(0, 2)),
49
+ green: parseColorPart(colorCode.slice(2, 4)),
50
+ blue: parseColorPart(colorCode.slice(4, 6)),
51
+ alpha: colorCode.length === 8 ? parseColorPart(colorCode.slice(6, 8)) : 1, // 如果没有 alpha,则假设不透明
58
52
  };
59
53
  } else {
60
54
  return undefined; // 不支持的颜色格式
@@ -71,6 +65,26 @@ function parseColorString(text: string):
71
65
  };
72
66
  }
73
67
 
68
+ /** 生成颜色 */
69
+ function serializeColorPart(part: number): string {
70
+ const intPart = Math.round(part * 255);
71
+ const hex = intPart.toString(16).padStart(2, '0');
72
+ return hex;
73
+ }
74
+
75
+ /** 生成颜色 */
76
+ function serializeColor(color: languages.IColor): string {
77
+ const r = serializeColorPart(color.red);
78
+ const g = serializeColorPart(color.green);
79
+ const b = serializeColorPart(color.blue);
80
+ if (color.alpha >= 1) {
81
+ return `#${r}${g}${b}`;
82
+ } else {
83
+ const a = serializeColorPart(color.alpha);
84
+ return `#${r}${g}${b}${a}`;
85
+ }
86
+ }
87
+
74
88
  /** @inheritdoc */
75
89
  export class ColorProvider extends Provider implements languages.DocumentColorProvider {
76
90
  /** @inheritdoc */
@@ -109,22 +123,6 @@ export class ColorProvider extends Provider implements languages.DocumentColorPr
109
123
  token: CancellationToken,
110
124
  ): languages.ProviderResult<languages.IColorPresentation[]> {
111
125
  const { color } = colorInfo;
112
- return [
113
- {
114
- label: `#${Math.round(color.red * 255)
115
- .toString(16)
116
- .padStart(2, '0')}${Math.round(color.green * 255)
117
- .toString(16)
118
- .padStart(2, '0')}${Math.round(color.blue * 255)
119
- .toString(16)
120
- .padStart(2, '0')}${
121
- color.alpha >= 1
122
- ? ''
123
- : Math.round(color.alpha * 255)
124
- .toString(16)
125
- .padStart(2, '0')
126
- }`,
127
- },
128
- ];
126
+ return [{ label: serializeColor(color) }];
129
127
  }
130
128
  }
@@ -6,7 +6,7 @@ import type { editor, CancellationToken, IMarkdownString, IRange, languages, Pos
6
6
  import { codeblock, getDeep, valueDoc, paramsList, serializeNumber, serializeInteger } from '../utils.js';
7
7
  import { tokenAt } from '../monaco-private.js';
8
8
  import { rangeAt } from '../monaco-utils.js';
9
- import type { FieldsAccessAt, VariableAccessAt } from '../compile-result.js';
9
+ import type { FieldsAccessAt, LocalDefinition, VariableAccessAt } from '../compile-result.js';
10
10
  import { Provider } from './base.js';
11
11
 
12
12
  const OPERATOR_TOKENS_DESC = Object.keys(HELP_OPERATORS).sort((a, b) => b.length - a.length);
@@ -44,6 +44,25 @@ function operatorAt(lineContent: string, column: number): { token: string; range
44
44
  return undefined;
45
45
  }
46
46
 
47
+ const LOCAL_HOVER = {
48
+ [DiagnosticCode.ParameterSubPatternImmutable]: '(parameter pattern) ',
49
+ [DiagnosticCode.ParameterSubPatternMutable]: '(parameter pattern) mut ',
50
+ [DiagnosticCode.ParameterImmutable]: '(parameter) ',
51
+ [DiagnosticCode.ParameterMutable]: '(parameter) mut ',
52
+ [DiagnosticCode.ParameterIt]: '(parameter) it',
53
+ [DiagnosticCode.ParameterImmutableRest]: '(parameter) ..',
54
+ [DiagnosticCode.ParameterMutableRest]: '(parameter) ..mut ',
55
+ [DiagnosticCode.LocalModule]: 'mod ',
56
+ [DiagnosticCode.LocalImmutable]: 'let ',
57
+ [DiagnosticCode.LocalConst]: 'const ',
58
+ [DiagnosticCode.LocalMutable]: 'let mut ',
59
+ [DiagnosticCode.LocalFunction]: (text: string, model: editor.ITextModel, def: LocalDefinition): string => {
60
+ return `fn ${text}${paramsList(model, def.fn)}`;
61
+ },
62
+ } satisfies Partial<
63
+ Record<DiagnosticCode, string | ((text: string, model: editor.ITextModel, def: LocalDefinition) => string)>
64
+ >;
65
+
47
66
  /** @inheritdoc */
48
67
  export class HoverProvider extends Provider implements languages.HoverProvider {
49
68
  /** 变量提示 */
@@ -65,69 +84,18 @@ export class HoverProvider extends Provider implements languages.HoverProvider {
65
84
  } else {
66
85
  let content: IMarkdownString | undefined;
67
86
  const tag = def.definition;
68
- switch (tag.code) {
69
- case DiagnosticCode.ParameterSubPatternImmutable:
70
- content = {
71
- value: codeblock(`\0(parameter pattern) ${model.getValueInRange(tag.range)}`),
72
- };
73
- break;
74
- case DiagnosticCode.ParameterSubPatternMutable:
75
- content = {
76
- value: codeblock(`\0(parameter pattern) mut ${model.getValueInRange(tag.range)}`),
77
- };
78
- break;
79
- case DiagnosticCode.ParameterImmutable:
80
- content = {
81
- value: codeblock(`\0(parameter) ${model.getValueInRange(tag.range)}`),
82
- };
83
- break;
84
- case DiagnosticCode.ParameterMutable:
85
- content = {
86
- value: codeblock(`\0(parameter) mut ${model.getValueInRange(tag.range)}`),
87
- };
88
- break;
89
- case DiagnosticCode.ParameterIt:
90
- content = {
91
- value: codeblock(`\0(parameter) it`),
92
- };
93
- break;
94
- case DiagnosticCode.ParameterImmutableRest:
87
+ if (tag.code in LOCAL_HOVER) {
88
+ const hover = LOCAL_HOVER[tag.code];
89
+ const text = model.getValueInRange(tag.range);
90
+ if (typeof hover == 'string') {
95
91
  content = {
96
- value: codeblock(`\0(parameter) ..${model.getValueInRange(tag.range)}`),
92
+ value: codeblock(`\0${hover}${text}`),
97
93
  };
98
- break;
99
- case DiagnosticCode.ParameterMutableRest:
100
- content = {
101
- value: codeblock(`\0(parameter) ..mut ${model.getValueInRange(tag.range)}`),
102
- };
103
- break;
104
- case DiagnosticCode.LocalFunction: {
105
- const params = paramsList(model, def.fn);
94
+ } else {
106
95
  content = {
107
- value: codeblock(`\0fn ${model.getValueInRange(tag.range)}${params}`),
96
+ value: codeblock(`\0${hover(text, model, def)}`),
108
97
  };
109
- break;
110
98
  }
111
- case DiagnosticCode.LocalModule:
112
- content = {
113
- value: codeblock(`\0mod ${model.getValueInRange(tag.range)}`),
114
- };
115
- break;
116
- case DiagnosticCode.LocalImmutable:
117
- content = {
118
- value: codeblock(`\0let ${model.getValueInRange(tag.range)}`),
119
- };
120
- break;
121
- case DiagnosticCode.LocalConst:
122
- content = {
123
- value: codeblock(`\0const ${model.getValueInRange(tag.range)}`),
124
- };
125
- break;
126
- case DiagnosticCode.LocalMutable:
127
- content = {
128
- value: codeblock(`\0let mut ${model.getValueInRange(tag.range)}`),
129
- };
130
- break;
131
99
  }
132
100
  if (ref == null) {
133
101
  range = tag.range;
@@ -1,7 +1,96 @@
1
1
  import { languages, Range, type CancellationToken, type editor, type IEvent } from '../../monaco-api.js';
2
+ import type { SourceDiagnostic } from '../compile-result.js';
2
3
  import { Provider } from './base.js';
3
4
  import { DiagnosticCode } from '@mirascript/constants';
4
5
 
6
+ /** 生成 hint */
7
+ function provideInlayHint(tag: SourceDiagnostic, model: editor.ITextModel): languages.InlayHint | null {
8
+ let lineNumber = 0;
9
+ let column = 0;
10
+ let label = '';
11
+ const kind = languages.InlayHintKind.Parameter;
12
+ let paddingLeft = true;
13
+ let paddingRight = false;
14
+ const edits: languages.TextEdit[] = [];
15
+ // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
16
+ switch (tag.code) {
17
+ case DiagnosticCode.ParameterIt: {
18
+ if (!tag.references.length) {
19
+ // 没有引用,隐藏该隐式参数
20
+ return null;
21
+ }
22
+ lineNumber = tag.range.endLineNumber;
23
+ column = tag.range.endColumn;
24
+ label = '(it)';
25
+ paddingLeft = /\bfn$/u.test(model.getValueInRange(new Range(lineNumber, column - 3, lineNumber, column)));
26
+ paddingRight = model.getValueInRange(new Range(lineNumber, column, lineNumber, column + 1)) === '{';
27
+ edits.push({
28
+ range: new Range(lineNumber, column, lineNumber, column),
29
+ text: `${paddingLeft ? ' ' : ''}${label}${paddingRight ? ' ' : ''}`,
30
+ });
31
+ break;
32
+ }
33
+ case DiagnosticCode.UnnamedRecordField0:
34
+ case DiagnosticCode.UnnamedRecordField1:
35
+ case DiagnosticCode.UnnamedRecordField2:
36
+ case DiagnosticCode.UnnamedRecordField3:
37
+ case DiagnosticCode.UnnamedRecordField4:
38
+ case DiagnosticCode.UnnamedRecordField5:
39
+ case DiagnosticCode.UnnamedRecordField6:
40
+ case DiagnosticCode.UnnamedRecordField7:
41
+ case DiagnosticCode.UnnamedRecordField8:
42
+ case DiagnosticCode.UnnamedRecordField9:
43
+ case DiagnosticCode.UnnamedRecordFieldN: {
44
+ const index = tag.code - DiagnosticCode.UnnamedRecordField0;
45
+ if (index > 9) break;
46
+ lineNumber = tag.range.startLineNumber;
47
+ column = tag.range.startColumn;
48
+ label = `${index}:`;
49
+ paddingLeft = /[^\s(]/u.test(model.getValueInRange(new Range(lineNumber, column - 1, lineNumber, column)));
50
+ paddingRight = true;
51
+ break;
52
+ }
53
+ case DiagnosticCode.OmitNamedRecordField: {
54
+ const ref = tag.references[0];
55
+ if (ref?.code !== DiagnosticCode.OmitNamedRecordFieldName) {
56
+ return null;
57
+ }
58
+ lineNumber = tag.range.startLineNumber;
59
+ column = tag.range.startColumn;
60
+ label = model.getValueInRange(ref.range);
61
+ paddingLeft = /[^\s(]/u.test(model.getValueInRange(new Range(lineNumber, column - 1, lineNumber, column)));
62
+ paddingRight = false;
63
+
64
+ const insertRight = !/\s/u.test(
65
+ model.getValueInRange(
66
+ new Range(
67
+ tag.range.endLineNumber,
68
+ tag.range.endColumn,
69
+ tag.range.endLineNumber,
70
+ tag.range.endColumn + 1,
71
+ ),
72
+ ),
73
+ );
74
+ edits.push({
75
+ range: tag.range,
76
+ text: `${paddingLeft ? ' ' : ''}${label}${model.getValueInRange(tag.range)}${insertRight ? ' ' : ''}`,
77
+ });
78
+ break;
79
+ }
80
+ }
81
+ if (!label) {
82
+ return null;
83
+ }
84
+ return {
85
+ position: { lineNumber, column },
86
+ label,
87
+ kind,
88
+ paddingLeft,
89
+ paddingRight,
90
+ textEdits: edits,
91
+ };
92
+ }
93
+
5
94
  /** @inheritdoc */
6
95
  export class InlayHintsProvider extends Provider implements languages.InlayHintsProvider {
7
96
  /** @inheritdoc */
@@ -23,99 +112,14 @@ export class InlayHintsProvider extends Provider implements languages.InlayHints
23
112
  if (!range.containsRange(tag.range)) {
24
113
  continue;
25
114
  }
26
- let lineNumber = 0;
27
- let column = 0;
28
- let label = '';
29
- const kind = languages.InlayHintKind.Parameter;
30
- let paddingLeft = true;
31
- let paddingRight = false;
32
- const edits: languages.TextEdit[] = [];
33
- // eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
34
- switch (tag.code) {
35
- case DiagnosticCode.ParameterIt: {
36
- if (!tag.references.length) {
37
- // 没有引用,隐藏该隐式参数
38
- continue;
39
- }
40
- lineNumber = tag.range.endLineNumber;
41
- column = tag.range.endColumn;
42
- label = '(it)';
43
- paddingLeft = /\bfn$/u.test(
44
- model.getValueInRange(new Range(lineNumber, column - 3, lineNumber, column)),
45
- );
46
- paddingRight = model.getValueInRange(new Range(lineNumber, column, lineNumber, column + 1)) === '{';
47
- edits.push({
48
- range: new Range(lineNumber, column, lineNumber, column),
49
- text: `${paddingLeft ? ' ' : ''}${label}${paddingRight ? ' ' : ''}`,
50
- });
51
- break;
52
- }
53
- case DiagnosticCode.UnnamedRecordField0:
54
- case DiagnosticCode.UnnamedRecordField1:
55
- case DiagnosticCode.UnnamedRecordField2:
56
- case DiagnosticCode.UnnamedRecordField3:
57
- case DiagnosticCode.UnnamedRecordField4:
58
- case DiagnosticCode.UnnamedRecordField5:
59
- case DiagnosticCode.UnnamedRecordField6:
60
- case DiagnosticCode.UnnamedRecordField7:
61
- case DiagnosticCode.UnnamedRecordField8:
62
- case DiagnosticCode.UnnamedRecordField9:
63
- case DiagnosticCode.UnnamedRecordFieldN: {
64
- const index = tag.code - DiagnosticCode.UnnamedRecordField0;
65
- if (index > 9) break;
66
- lineNumber = tag.range.startLineNumber;
67
- column = tag.range.startColumn;
68
- label = `${index}:`;
69
- paddingLeft = /[^\s(]/u.test(
70
- model.getValueInRange(new Range(lineNumber, column - 1, lineNumber, column)),
71
- );
72
- paddingRight = true;
73
- break;
74
- }
75
- case DiagnosticCode.OmitNamedRecordField: {
76
- const ref = tag.references[0];
77
- if (ref?.code !== DiagnosticCode.OmitNamedRecordFieldName) continue;
78
- lineNumber = tag.range.startLineNumber;
79
- column = tag.range.startColumn;
80
- label = model.getValueInRange(ref.range);
81
- paddingLeft = /[^\s(]/u.test(
82
- model.getValueInRange(new Range(lineNumber, column - 1, lineNumber, column)),
83
- );
84
- paddingRight = false;
85
-
86
- const insertRight = !/\s/u.test(
87
- model.getValueInRange(
88
- new Range(
89
- tag.range.endLineNumber,
90
- tag.range.endColumn,
91
- tag.range.endLineNumber,
92
- tag.range.endColumn + 1,
93
- ),
94
- ),
95
- );
96
- edits.push({
97
- range: tag.range,
98
- text: `${paddingLeft ? ' ' : ''}${label}${model.getValueInRange(tag.range)}${insertRight ? ' ' : ''}`,
99
- });
100
- break;
101
- }
115
+ const hint = provideInlayHint(tag, model);
116
+ if (hint) {
117
+ hints.push(hint);
102
118
  }
103
- if (!label) continue;
104
- const hint: languages.InlayHint = {
105
- position: { lineNumber, column },
106
- label,
107
- kind,
108
- paddingLeft,
109
- paddingRight,
110
- textEdits: edits,
111
- };
112
- hints.push(hint);
113
119
  }
114
120
  return {
115
121
  hints,
116
- dispose: () => {
117
- // Cleanup if necessary
118
- },
122
+ dispose: () => undefined,
119
123
  };
120
124
  }
121
125
  }
package/src/lsp/utils.ts CHANGED
@@ -400,10 +400,8 @@ export function valueDoc(
400
400
  prefix = `let ${name} = `;
401
401
  }
402
402
  suffix = ';';
403
- } else if (/^\d/.test(name)) {
404
- prefix = `[${name}]: `;
405
403
  } else {
406
- prefix = `${name}: `;
404
+ prefix = `${serializeRecordKey(name)}: `;
407
405
  }
408
406
  if (isVmModule(value)) {
409
407
  let script;
@@ -0,0 +1,68 @@
1
+ import type { InputMode } from '@mirascript/mirascript';
2
+ import type { BcModule } from '@mirascript/bindings/wasm';
3
+ import type { Tagged } from 'type-fest';
4
+
5
+ const { loadModule } = await import('@mirascript/bindings/wasm');
6
+ const mod = await loadModule();
7
+ const { wasm, createConfig } = mod;
8
+
9
+ /** Monaco 编译结果 */
10
+ export interface MonacoResult extends BcModule.CompileResult {
11
+ /** 格式化结果 */
12
+ formatted?: string;
13
+ }
14
+
15
+ /** 缓存 Key (model id) */
16
+ export type CacheKey = Tagged<string, 'modelId'>;
17
+ /** 请求参数 */
18
+ export type Req = [key: CacheKey, version: number, script: string, mode: InputMode];
19
+ /** 编译结果 */
20
+ export type ResOk = [key: CacheKey, version: number, result: MonacoResult];
21
+ /** 编译结果 */
22
+ export type ResErr = [key: CacheKey, version: number, error: Error];
23
+ /** 编译结果 */
24
+ export type Res = ResOk | ResErr;
25
+ /** Ready */
26
+ export type Ready = 'mirascript lsp ready';
27
+
28
+ const configTemplate = createConfig({
29
+ diagnostic_position_encoding: 'Utf16',
30
+ diagnostic_tag: true,
31
+ diagnostic_sourcemap: true,
32
+ trivia: true,
33
+ input_mode: 'Template',
34
+ });
35
+ const configScript = createConfig({
36
+ diagnostic_position_encoding: 'Utf16',
37
+ diagnostic_tag: true,
38
+ diagnostic_sourcemap: true,
39
+ trivia: true,
40
+ input_mode: 'Script',
41
+ });
42
+
43
+ /** 编译 */
44
+ export function compile(script: string, mode: InputMode): MonacoResult {
45
+ const config = mode === 'Script' ? configScript : configTemplate;
46
+ const compiler = new wasm.MonacoCompiler(script, config);
47
+ try {
48
+ const parseOk = compiler.parse();
49
+ if (!parseOk) {
50
+ return { diagnostics: compiler.diagnostics(), chunk: undefined };
51
+ }
52
+ const chunk = compiler.emit();
53
+ const formatted = compiler.format();
54
+ return {
55
+ diagnostics: compiler.diagnostics(),
56
+ chunk,
57
+ formatted,
58
+ };
59
+ } finally {
60
+ try {
61
+ compiler.free();
62
+ } catch (ex) {
63
+ /* 忽略错误 */
64
+ // eslint-disable-next-line no-console
65
+ console.error(ex);
66
+ }
67
+ }
68
+ }
@@ -1,6 +1,6 @@
1
1
  import type { InputMode } from '@mirascript/constants';
2
2
  import { editor } from '../monaco-api.js';
3
- import type { Ready, CacheKey, Req, Res, ResOk } from './worker.js';
3
+ import type { Ready, CacheKey, Req, Res, ResOk } from './worker-core.js';
4
4
  import { CompileResult } from './compile-result.js';
5
5
  import { makeModelMarkers } from './diagnostics.js';
6
6
 
@@ -89,12 +89,12 @@ async function compileWorker(req: Req): Promise<CompileResult> {
89
89
  return new CompileResult(key, version, source, result);
90
90
  }
91
91
 
92
- let compileImpl: typeof import('./worker.js').compile;
92
+ let compileImpl: typeof import('./worker-core.js').compile;
93
93
  /** 使用当前线程编译 */
94
94
  async function compileSync(req: Req): Promise<CompileResult> {
95
95
  const [key, version, script, mode] = req;
96
96
  if (compileImpl == null) {
97
- const mod = await import('./worker.js');
97
+ const mod = await import('./worker-core.js');
98
98
  compileImpl = mod.compile;
99
99
  }
100
100
  const result = compileImpl(script, mode);