solve-engine 1.0.0-beta.2 → 1.0.0-beta.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{Lexer-D9l4Yrk2.d.ts → Lexer-Cfm79Dak.d.cts} +18 -2
- package/dist/{Lexer-BJdhlnej.d.cts → Lexer-W9MBOP0V.d.ts} +18 -2
- package/dist/{PackageRegistry-DaH4aIKP.d.ts → PackageRegistry-CjDt-Jy_.d.ts} +60 -4
- package/dist/{PackageRegistry-D-Tv_7ca.d.cts → PackageRegistry-pHtKythi.d.cts} +60 -4
- package/dist/{Parselet-CK8cQu2a.d.cts → Parselet-Cu0bLSis.d.cts} +1 -1
- package/dist/{Parselet-ConOIdRO.d.ts → Parselet-DEdF9I7n.d.ts} +1 -1
- package/dist/{Token-0jpvUdPY.d.cts → Token-BzG5G4ja.d.cts} +44 -0
- package/dist/{Token-0jpvUdPY.d.ts → Token-BzG5G4ja.d.ts} +44 -0
- package/dist/TokenNormalizer-DGVa24Q-.d.cts +377 -0
- package/dist/TokenNormalizer-t_GotBxr.d.ts +377 -0
- package/dist/{chunk-HWSZJQCI.js → chunk-2CS6OMZK.js} +37 -15
- package/dist/chunk-2CS6OMZK.js.map +1 -0
- package/dist/{chunk-XJCMXB2E.cjs → chunk-2MV4HBKC.cjs} +187 -61
- package/dist/chunk-2MV4HBKC.cjs.map +1 -0
- package/dist/{chunk-J73SJHR3.cjs → chunk-2NPS5DQ3.cjs} +558 -341
- package/dist/chunk-2NPS5DQ3.cjs.map +1 -0
- package/dist/{chunk-QWY3VEZN.js → chunk-3MNKQZ77.js} +65 -12
- package/dist/chunk-3MNKQZ77.js.map +1 -0
- package/dist/{chunk-RZCWSXTA.cjs → chunk-43G3JT2E.cjs} +1491 -218
- package/dist/chunk-43G3JT2E.cjs.map +1 -0
- package/dist/{chunk-WQTTOGXC.cjs → chunk-4AVD7NZW.cjs} +4 -4
- package/dist/{chunk-WQTTOGXC.cjs.map → chunk-4AVD7NZW.cjs.map} +1 -1
- package/dist/{chunk-HTXVVJRA.cjs → chunk-4CVLFLOB.cjs} +112 -2
- package/dist/chunk-4CVLFLOB.cjs.map +1 -0
- package/dist/{chunk-5YEMOYSE.js → chunk-6GCKCWLB.js} +9 -3
- package/dist/chunk-6GCKCWLB.js.map +1 -0
- package/dist/{chunk-EBSPLUW4.cjs → chunk-AHCLWAM5.cjs} +28 -10
- package/dist/chunk-AHCLWAM5.cjs.map +1 -0
- package/dist/{chunk-KVILKGMS.js → chunk-AJA6LUI7.js} +36 -2
- package/dist/chunk-AJA6LUI7.js.map +1 -0
- package/dist/{chunk-EHAHVROS.cjs → chunk-CLVQBF5C.cjs} +5 -5
- package/dist/{chunk-EHAHVROS.cjs.map → chunk-CLVQBF5C.cjs.map} +1 -1
- package/dist/{chunk-34RRD7PC.js → chunk-CYFK5SY2.js} +111 -3
- package/dist/chunk-CYFK5SY2.js.map +1 -0
- package/dist/{chunk-M5LX5AOO.js → chunk-DDQVZGLO.js} +25 -12
- package/dist/chunk-DDQVZGLO.js.map +1 -0
- package/dist/{chunk-LR7YASZF.cjs → chunk-EAAHVJ4P.cjs} +3 -3
- package/dist/chunk-EAAHVJ4P.cjs.map +1 -0
- package/dist/{chunk-3PPFLFH4.js → chunk-FIFQPKBA.js} +1417 -144
- package/dist/chunk-FIFQPKBA.js.map +1 -0
- package/dist/{chunk-RIN643A3.js → chunk-GPPLSM2Z.js} +61 -2
- package/dist/chunk-GPPLSM2Z.js.map +1 -0
- package/dist/{chunk-4QADQTWS.js → chunk-KHJUSHFU.js} +231 -14
- package/dist/chunk-KHJUSHFU.js.map +1 -0
- package/dist/{chunk-NMD5VRN4.cjs → chunk-M4F66R4O.cjs} +74 -73
- package/dist/chunk-M4F66R4O.cjs.map +1 -0
- package/dist/{chunk-6NTVRDQV.cjs → chunk-M4Q47KHF.cjs} +126 -73
- package/dist/chunk-M4Q47KHF.cjs.map +1 -0
- package/dist/{chunk-LIPPNDBE.js → chunk-M5E34VG5.js} +3 -3
- package/dist/{chunk-LIPPNDBE.js.map → chunk-M5E34VG5.js.map} +1 -1
- package/dist/{chunk-53B6KDDJ.cjs → chunk-MBNQVDVC.cjs} +38 -3
- package/dist/{chunk-53B6KDDJ.cjs.map → chunk-MBNQVDVC.cjs.map} +1 -1
- package/dist/{chunk-SDGRK7EP.js → chunk-MEOHSQEH.js} +6 -5
- package/dist/chunk-MEOHSQEH.js.map +1 -0
- package/dist/{chunk-NMCRQP3Z.cjs → chunk-MTX2KVU7.cjs} +71 -70
- package/dist/chunk-MTX2KVU7.cjs.map +1 -0
- package/dist/{chunk-QNJ4ACRT.cjs → chunk-NJTXJ5AG.cjs} +37 -15
- package/dist/chunk-NJTXJ5AG.cjs.map +1 -0
- package/dist/{chunk-C4XZV6E7.cjs → chunk-NZFKROS7.cjs} +26 -20
- package/dist/chunk-NZFKROS7.cjs.map +1 -0
- package/dist/{chunk-64W6GLLZ.js → chunk-OFXOTECC.js} +24 -6
- package/dist/chunk-OFXOTECC.js.map +1 -0
- package/dist/{chunk-3YNVWKR2.cjs → chunk-OUHT5Z36.cjs} +28 -5
- package/dist/chunk-OUHT5Z36.cjs.map +1 -0
- package/dist/{chunk-EIGTWK5N.js → chunk-OWRHDUJD.js} +3 -3
- package/dist/chunk-OWRHDUJD.js.map +1 -0
- package/dist/{chunk-4MG4XKO2.js → chunk-PCPX42KL.js} +38 -3
- package/dist/{chunk-4MG4XKO2.js.map → chunk-PCPX42KL.js.map} +1 -1
- package/dist/{chunk-GW32KPCU.cjs → chunk-R24DI24X.cjs} +61 -2
- package/dist/chunk-R24DI24X.cjs.map +1 -0
- package/dist/{chunk-XVWCOTR6.js → chunk-SFQWJMKT.js} +7 -6
- package/dist/chunk-SFQWJMKT.js.map +1 -0
- package/dist/{chunk-6BKTCEUP.cjs → chunk-TY3TLZAW.cjs} +36 -2
- package/dist/chunk-TY3TLZAW.cjs.map +1 -0
- package/dist/{chunk-DM3LMRBC.js → chunk-UKPGSAZW.js} +187 -61
- package/dist/chunk-UKPGSAZW.js.map +1 -0
- package/dist/{chunk-NH2O2AUR.js → chunk-WC5FFSHB.js} +26 -4
- package/dist/chunk-WC5FFSHB.js.map +1 -0
- package/dist/{chunk-CLL7RUQV.cjs → chunk-WWOLFXTX.cjs} +40 -18
- package/dist/chunk-WWOLFXTX.cjs.map +1 -0
- package/dist/{chunk-JBSYC7BB.cjs → chunk-X2BWAZAU.cjs} +66 -53
- package/dist/chunk-X2BWAZAU.cjs.map +1 -0
- package/dist/{chunk-GOLDJNMZ.js → chunk-XBTEO4OB.js} +28 -5
- package/dist/chunk-XBTEO4OB.js.map +1 -0
- package/dist/{chunk-EPOXXJBK.js → chunk-YU2CUNFO.js} +3 -3
- package/dist/{chunk-EPOXXJBK.js.map → chunk-YU2CUNFO.js.map} +1 -1
- package/dist/constants.cjs +4 -4
- package/dist/constants.js +1 -1
- package/dist/engine.cjs +29 -30
- package/dist/engine.d.cts +6 -6
- package/dist/engine.d.ts +6 -6
- package/dist/engine.js +19 -20
- package/dist/format.cjs +7 -8
- package/dist/format.cjs.map +1 -1
- package/dist/format.js +2 -3
- package/dist/format.js.map +1 -1
- package/dist/index.cjs +28 -29
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +6 -6
- package/dist/index.d.ts +6 -6
- package/dist/index.js +20 -21
- package/dist/index.js.map +1 -1
- package/dist/language.cjs +74 -12
- package/dist/language.cjs.map +1 -1
- package/dist/language.d.cts +6 -6
- package/dist/language.d.ts +6 -6
- package/dist/language.js +68 -6
- package/dist/language.js.map +1 -1
- package/dist/lexer.cjs +19 -19
- package/dist/lexer.d.cts +3 -3
- package/dist/lexer.d.ts +3 -3
- package/dist/lexer.js +7 -7
- package/dist/normalizer.cjs +12 -12
- package/dist/normalizer.d.cts +4 -210
- package/dist/normalizer.d.ts +4 -210
- package/dist/normalizer.js +6 -6
- package/dist/packages.cjs +36 -37
- package/dist/packages.d.cts +5 -47
- package/dist/packages.d.ts +5 -47
- package/dist/packages.js +13 -14
- package/dist/parser.cjs +12 -12
- package/dist/parser.d.cts +3 -2
- package/dist/parser.d.ts +3 -2
- package/dist/parser.js +4 -4
- package/dist/resolvers.d.cts +1 -1
- package/dist/resolvers.d.ts +1 -1
- package/dist/uom.cjs +14 -14
- package/dist/uom.d.cts +12 -4
- package/dist/uom.d.ts +12 -4
- package/dist/uom.js +4 -4
- package/dist/vm.cjs +17 -17
- package/dist/vm.js +6 -6
- package/package.json +2 -1
- package/dist/NormalizerRule-BrVoVjmP.d.cts +0 -163
- package/dist/NormalizerRule-CEjf1FyD.d.ts +0 -163
- package/dist/chunk-34RRD7PC.js.map +0 -1
- package/dist/chunk-3PPFLFH4.js.map +0 -1
- package/dist/chunk-3YNVWKR2.cjs.map +0 -1
- package/dist/chunk-4QADQTWS.js.map +0 -1
- package/dist/chunk-5YEMOYSE.js.map +0 -1
- package/dist/chunk-64W6GLLZ.js.map +0 -1
- package/dist/chunk-6BKTCEUP.cjs.map +0 -1
- package/dist/chunk-6NTVRDQV.cjs.map +0 -1
- package/dist/chunk-C4XZV6E7.cjs.map +0 -1
- package/dist/chunk-CLL7RUQV.cjs.map +0 -1
- package/dist/chunk-DM3LMRBC.js.map +0 -1
- package/dist/chunk-EBSPLUW4.cjs.map +0 -1
- package/dist/chunk-EIGTWK5N.js.map +0 -1
- package/dist/chunk-GOLDJNMZ.js.map +0 -1
- package/dist/chunk-GW32KPCU.cjs.map +0 -1
- package/dist/chunk-HTXVVJRA.cjs.map +0 -1
- package/dist/chunk-HWSZJQCI.js.map +0 -1
- package/dist/chunk-J73SJHR3.cjs.map +0 -1
- package/dist/chunk-JBSYC7BB.cjs.map +0 -1
- package/dist/chunk-KVILKGMS.js.map +0 -1
- package/dist/chunk-LR7YASZF.cjs.map +0 -1
- package/dist/chunk-M5LX5AOO.js.map +0 -1
- package/dist/chunk-NH2O2AUR.js.map +0 -1
- package/dist/chunk-NMCRQP3Z.cjs.map +0 -1
- package/dist/chunk-NMD5VRN4.cjs.map +0 -1
- package/dist/chunk-OT6OJY7C.cjs +0 -114
- package/dist/chunk-OT6OJY7C.cjs.map +0 -1
- package/dist/chunk-QNJ4ACRT.cjs.map +0 -1
- package/dist/chunk-QWY3VEZN.js.map +0 -1
- package/dist/chunk-RFYD5TJE.js +0 -111
- package/dist/chunk-RFYD5TJE.js.map +0 -1
- package/dist/chunk-RIN643A3.js.map +0 -1
- package/dist/chunk-RZCWSXTA.cjs.map +0 -1
- package/dist/chunk-SDGRK7EP.js.map +0 -1
- package/dist/chunk-XJCMXB2E.cjs.map +0 -1
- package/dist/chunk-XVWCOTR6.js.map +0 -1
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { T as Token } from './Token-
|
|
1
|
+
import { T as Token } from './Token-BzG5G4ja.cjs';
|
|
2
2
|
|
|
3
3
|
/** Trie node for multi-word phrase matching. */
|
|
4
4
|
interface PhraseNode {
|
|
@@ -102,7 +102,11 @@ declare class LexerToken implements Token {
|
|
|
102
102
|
lineBreaks: number;
|
|
103
103
|
line: number;
|
|
104
104
|
col: number;
|
|
105
|
-
|
|
105
|
+
/** See {@link Token.sourceEnd}. Set only on normalizer-fused tokens. */
|
|
106
|
+
sourceEnd?: number | undefined;
|
|
107
|
+
constructor(type: string, typeId: number, value: string, text: string, offset: number, lineBreaks: number, line: number, col: number,
|
|
108
|
+
/** See {@link Token.sourceEnd}. Set only on normalizer-fused tokens. */
|
|
109
|
+
sourceEnd?: number | undefined);
|
|
106
110
|
}
|
|
107
111
|
/**
|
|
108
112
|
* Plugin interface for extending the ExpressionLexer with custom tokens.
|
|
@@ -512,6 +516,18 @@ declare class Lexer {
|
|
|
512
516
|
length: number;
|
|
513
517
|
category: TokenCategory | undefined;
|
|
514
518
|
}[];
|
|
519
|
+
/**
|
|
520
|
+
* The same tokens {@link getHighlightTokens} reduces, before reduction.
|
|
521
|
+
*
|
|
522
|
+
* Exists because normalization operates on tokens, not on the flattened
|
|
523
|
+
* shape, and a consumer that wants phrase-fused highlighting has to run the
|
|
524
|
+
* normalizer between the two. See `LanguageService.getSemanticTokens`.
|
|
525
|
+
*
|
|
526
|
+
* @param lineText - One line of source.
|
|
527
|
+
* @returns Every token on the line that is worth painting, unreduced.
|
|
528
|
+
*/
|
|
529
|
+
getHighlightTokenObjects(lineText: string): Token[];
|
|
530
|
+
private collectTokenObjects;
|
|
515
531
|
private collectHighlightTokens;
|
|
516
532
|
}
|
|
517
533
|
/**
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { T as Token } from './Token-
|
|
1
|
+
import { T as Token } from './Token-BzG5G4ja.js';
|
|
2
2
|
|
|
3
3
|
/** Trie node for multi-word phrase matching. */
|
|
4
4
|
interface PhraseNode {
|
|
@@ -102,7 +102,11 @@ declare class LexerToken implements Token {
|
|
|
102
102
|
lineBreaks: number;
|
|
103
103
|
line: number;
|
|
104
104
|
col: number;
|
|
105
|
-
|
|
105
|
+
/** See {@link Token.sourceEnd}. Set only on normalizer-fused tokens. */
|
|
106
|
+
sourceEnd?: number | undefined;
|
|
107
|
+
constructor(type: string, typeId: number, value: string, text: string, offset: number, lineBreaks: number, line: number, col: number,
|
|
108
|
+
/** See {@link Token.sourceEnd}. Set only on normalizer-fused tokens. */
|
|
109
|
+
sourceEnd?: number | undefined);
|
|
106
110
|
}
|
|
107
111
|
/**
|
|
108
112
|
* Plugin interface for extending the ExpressionLexer with custom tokens.
|
|
@@ -512,6 +516,18 @@ declare class Lexer {
|
|
|
512
516
|
length: number;
|
|
513
517
|
category: TokenCategory | undefined;
|
|
514
518
|
}[];
|
|
519
|
+
/**
|
|
520
|
+
* The same tokens {@link getHighlightTokens} reduces, before reduction.
|
|
521
|
+
*
|
|
522
|
+
* Exists because normalization operates on tokens, not on the flattened
|
|
523
|
+
* shape, and a consumer that wants phrase-fused highlighting has to run the
|
|
524
|
+
* normalizer between the two. See `LanguageService.getSemanticTokens`.
|
|
525
|
+
*
|
|
526
|
+
* @param lineText - One line of source.
|
|
527
|
+
* @returns Every token on the line that is worth painting, unreduced.
|
|
528
|
+
*/
|
|
529
|
+
getHighlightTokenObjects(lineText: string): Token[];
|
|
530
|
+
private collectTokenObjects;
|
|
515
531
|
private collectHighlightTokens;
|
|
516
532
|
}
|
|
517
533
|
/**
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { a as PrecedenceParser, b as PrefixParselet, I as InfixParselet } from './Parselet-
|
|
1
|
+
import { a as PrecedenceParser, b as PrefixParselet, I as InfixParselet } from './Parselet-DEdF9I7n.js';
|
|
2
2
|
import { V as Value } from './Value-KtAQNHur.js';
|
|
3
3
|
import { IVariableSource } from './variables.js';
|
|
4
|
-
import { M as MarkdownLineType, L as Lexer, e as TokenCategory, c as LexerVocabulary } from './Lexer-
|
|
4
|
+
import { M as MarkdownLineType, L as Lexer, e as TokenCategory, c as LexerVocabulary } from './Lexer-W9MBOP0V.js';
|
|
5
5
|
import { IAsyncResolver } from './resolvers.js';
|
|
6
|
-
import { T as TokenFusion,
|
|
6
|
+
import { T as TokenFusion, c as TokenNormalizer, a as NormalizerRule } from './TokenNormalizer-t_GotBxr.js';
|
|
7
7
|
import { D as DependencyGraph, V as VM, a as DagSnapshot, b as EngineContext, S as ScopeManager, L as LineExecutionContext } from './ScopeManager-B5k0nk05.js';
|
|
8
8
|
import { a as BytecodeProgram } from './BytecodeBuilder-3egMyuDi.js';
|
|
9
9
|
import { QueryClient } from '@tanstack/query-core';
|
|
10
10
|
import { E as EngineError } from './EngineError-DvPSnhZi.js';
|
|
11
11
|
import { a as DiagnosticReportJSON, D as DiagnosticPipeline } from './pipeline-CrsRPmsv.js';
|
|
12
|
-
import { T as Token } from './Token-
|
|
12
|
+
import { T as Token } from './Token-BzG5G4ja.js';
|
|
13
13
|
import { D as DEFAULT_CONFIG, E as EngineConfig } from './Configuration-fVpd-HC-.js';
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -1958,6 +1958,17 @@ declare class ExpressionEngine {
|
|
|
1958
1958
|
getContext(): EngineContext;
|
|
1959
1959
|
getScopeManager(): ScopeManager;
|
|
1960
1960
|
getLexer(): Lexer;
|
|
1961
|
+
/**
|
|
1962
|
+
* This engine's token normalizer, with every phrase and rule its packages
|
|
1963
|
+
* registered.
|
|
1964
|
+
*
|
|
1965
|
+
* Exposed for the highlighting path. `LanguageService` classifies tokens
|
|
1966
|
+
* after the lexer but can only see phrase-fused types (a date literal, a
|
|
1967
|
+
* timecode, a package's own fused token) by running the same normalizer
|
|
1968
|
+
* evaluation runs. Sharing this instance rather than building a second one
|
|
1969
|
+
* is what keeps the two from disagreeing.
|
|
1970
|
+
*/
|
|
1971
|
+
getNormalizer(): TokenNormalizer;
|
|
1961
1972
|
/**
|
|
1962
1973
|
* Every completion candidate contributed by currently-registered
|
|
1963
1974
|
* packages (`IEnginePackage.completionItems`), flattened across all of
|
|
@@ -2174,6 +2185,20 @@ interface LanguageServiceOptions {
|
|
|
2174
2185
|
* evaluation engine's DAG snapshot instead.
|
|
2175
2186
|
*/
|
|
2176
2187
|
variableNameSource?: () => Iterable<string>;
|
|
2188
|
+
/**
|
|
2189
|
+
* Run the normalizer on the highlighting path, so phrase-fused tokens are
|
|
2190
|
+
* classified as the thing the parser will actually see.
|
|
2191
|
+
*
|
|
2192
|
+
* Off by default, and the default is a judgement rather than an oversight.
|
|
2193
|
+
* Highlighting runs per keystroke, normalization is real work, and a host
|
|
2194
|
+
* that is happy with lexer-level categories should not start paying for
|
|
2195
|
+
* fusion because a new version shipped. Turn it on and `12/09/2026` is one
|
|
2196
|
+
* `datetime` span instead of five number and operator spans; leave it off
|
|
2197
|
+
* and nothing about this class changes.
|
|
2198
|
+
*
|
|
2199
|
+
* See `benchmarks/languageServiceBenchmarks.spec.ts` for what it costs.
|
|
2200
|
+
*/
|
|
2201
|
+
normalizeForHighlighting?: boolean;
|
|
2177
2202
|
}
|
|
2178
2203
|
/**
|
|
2179
2204
|
* Editor-agnostic "language server" for solve expressions: turns a line of
|
|
@@ -2229,11 +2254,42 @@ interface LanguageServiceOptions {
|
|
|
2229
2254
|
declare class LanguageService {
|
|
2230
2255
|
private engine;
|
|
2231
2256
|
private variableNameSource;
|
|
2257
|
+
private readonly normalizeForHighlighting;
|
|
2232
2258
|
private cache;
|
|
2233
2259
|
private staticCompletionCandidates;
|
|
2234
2260
|
private staticCompletionIndex;
|
|
2235
2261
|
constructor(engine?: ExpressionEngine | null, options?: LanguageServiceOptions);
|
|
2236
2262
|
private defaultVariableNames;
|
|
2263
|
+
/**
|
|
2264
|
+
* Lex a line, normalize it, and place every resulting token back in the
|
|
2265
|
+
* source text.
|
|
2266
|
+
*
|
|
2267
|
+
* ## Why placing them back is the hard part
|
|
2268
|
+
*
|
|
2269
|
+
* Normalization produces three kinds of token and only one of them can be
|
|
2270
|
+
* highlighted the obvious way.
|
|
2271
|
+
*
|
|
2272
|
+
* A token the normalizer left alone still describes its own text, so its
|
|
2273
|
+
* span is `offset` to `offset + value.length`, exactly as before.
|
|
2274
|
+
*
|
|
2275
|
+
* A FUSED token does not. `10 frames` becomes a FRAME_COUNT whose value is
|
|
2276
|
+
* `10`, and a timecode becomes a token whose value is a comma-separated
|
|
2277
|
+
* tuple appearing nowhere on the line. Those carry `sourceEnd`, set by
|
|
2278
|
+
* `createFusedToken`, which is the only place that knows where the fusion
|
|
2279
|
+
* ended.
|
|
2280
|
+
*
|
|
2281
|
+
* An INSERTED token has no text at all. Implicit multiplication puts a STAR
|
|
2282
|
+
* at the following token's offset, so `5(3)` gains a `*` sitting exactly
|
|
2283
|
+
* where the `(` is. Painting it would colour a character the reader never
|
|
2284
|
+
* typed as an operator, and would overlap the token that really is there.
|
|
2285
|
+
* These are dropped, detected by the one test that needs no cooperation
|
|
2286
|
+
* from any rule: a token with no recorded fusion span must match the text
|
|
2287
|
+
* at its own offset, and an inserted one does not.
|
|
2288
|
+
*
|
|
2289
|
+
* @param lineText - The raw line.
|
|
2290
|
+
* @returns Spans in the same shape `Lexer.getHighlightTokens` returns.
|
|
2291
|
+
*/
|
|
2292
|
+
private classifyNormalized;
|
|
2237
2293
|
/**
|
|
2238
2294
|
* Classify every recognized token on one line.
|
|
2239
2295
|
*
|
|
@@ -1,15 +1,15 @@
|
|
|
1
|
-
import { a as PrecedenceParser, b as PrefixParselet, I as InfixParselet } from './Parselet-
|
|
1
|
+
import { a as PrecedenceParser, b as PrefixParselet, I as InfixParselet } from './Parselet-Cu0bLSis.cjs';
|
|
2
2
|
import { V as Value } from './Value-KtAQNHur.cjs';
|
|
3
3
|
import { IVariableSource } from './variables.cjs';
|
|
4
|
-
import { M as MarkdownLineType, L as Lexer, e as TokenCategory, c as LexerVocabulary } from './Lexer-
|
|
4
|
+
import { M as MarkdownLineType, L as Lexer, e as TokenCategory, c as LexerVocabulary } from './Lexer-Cfm79Dak.cjs';
|
|
5
5
|
import { IAsyncResolver } from './resolvers.cjs';
|
|
6
|
-
import { T as TokenFusion,
|
|
6
|
+
import { T as TokenFusion, c as TokenNormalizer, a as NormalizerRule } from './TokenNormalizer-DGVa24Q-.cjs';
|
|
7
7
|
import { D as DependencyGraph, V as VM, a as DagSnapshot, b as EngineContext, S as ScopeManager, L as LineExecutionContext } from './ScopeManager-CKfQtl7l.cjs';
|
|
8
8
|
import { a as BytecodeProgram } from './BytecodeBuilder-3egMyuDi.cjs';
|
|
9
9
|
import { QueryClient } from '@tanstack/query-core';
|
|
10
10
|
import { E as EngineError } from './EngineError-DvPSnhZi.cjs';
|
|
11
11
|
import { a as DiagnosticReportJSON, D as DiagnosticPipeline } from './pipeline-DPUQt7yL.cjs';
|
|
12
|
-
import { T as Token } from './Token-
|
|
12
|
+
import { T as Token } from './Token-BzG5G4ja.cjs';
|
|
13
13
|
import { D as DEFAULT_CONFIG, E as EngineConfig } from './Configuration-fVpd-HC-.cjs';
|
|
14
14
|
|
|
15
15
|
/**
|
|
@@ -1958,6 +1958,17 @@ declare class ExpressionEngine {
|
|
|
1958
1958
|
getContext(): EngineContext;
|
|
1959
1959
|
getScopeManager(): ScopeManager;
|
|
1960
1960
|
getLexer(): Lexer;
|
|
1961
|
+
/**
|
|
1962
|
+
* This engine's token normalizer, with every phrase and rule its packages
|
|
1963
|
+
* registered.
|
|
1964
|
+
*
|
|
1965
|
+
* Exposed for the highlighting path. `LanguageService` classifies tokens
|
|
1966
|
+
* after the lexer but can only see phrase-fused types (a date literal, a
|
|
1967
|
+
* timecode, a package's own fused token) by running the same normalizer
|
|
1968
|
+
* evaluation runs. Sharing this instance rather than building a second one
|
|
1969
|
+
* is what keeps the two from disagreeing.
|
|
1970
|
+
*/
|
|
1971
|
+
getNormalizer(): TokenNormalizer;
|
|
1961
1972
|
/**
|
|
1962
1973
|
* Every completion candidate contributed by currently-registered
|
|
1963
1974
|
* packages (`IEnginePackage.completionItems`), flattened across all of
|
|
@@ -2174,6 +2185,20 @@ interface LanguageServiceOptions {
|
|
|
2174
2185
|
* evaluation engine's DAG snapshot instead.
|
|
2175
2186
|
*/
|
|
2176
2187
|
variableNameSource?: () => Iterable<string>;
|
|
2188
|
+
/**
|
|
2189
|
+
* Run the normalizer on the highlighting path, so phrase-fused tokens are
|
|
2190
|
+
* classified as the thing the parser will actually see.
|
|
2191
|
+
*
|
|
2192
|
+
* Off by default, and the default is a judgement rather than an oversight.
|
|
2193
|
+
* Highlighting runs per keystroke, normalization is real work, and a host
|
|
2194
|
+
* that is happy with lexer-level categories should not start paying for
|
|
2195
|
+
* fusion because a new version shipped. Turn it on and `12/09/2026` is one
|
|
2196
|
+
* `datetime` span instead of five number and operator spans; leave it off
|
|
2197
|
+
* and nothing about this class changes.
|
|
2198
|
+
*
|
|
2199
|
+
* See `benchmarks/languageServiceBenchmarks.spec.ts` for what it costs.
|
|
2200
|
+
*/
|
|
2201
|
+
normalizeForHighlighting?: boolean;
|
|
2177
2202
|
}
|
|
2178
2203
|
/**
|
|
2179
2204
|
* Editor-agnostic "language server" for solve expressions: turns a line of
|
|
@@ -2229,11 +2254,42 @@ interface LanguageServiceOptions {
|
|
|
2229
2254
|
declare class LanguageService {
|
|
2230
2255
|
private engine;
|
|
2231
2256
|
private variableNameSource;
|
|
2257
|
+
private readonly normalizeForHighlighting;
|
|
2232
2258
|
private cache;
|
|
2233
2259
|
private staticCompletionCandidates;
|
|
2234
2260
|
private staticCompletionIndex;
|
|
2235
2261
|
constructor(engine?: ExpressionEngine | null, options?: LanguageServiceOptions);
|
|
2236
2262
|
private defaultVariableNames;
|
|
2263
|
+
/**
|
|
2264
|
+
* Lex a line, normalize it, and place every resulting token back in the
|
|
2265
|
+
* source text.
|
|
2266
|
+
*
|
|
2267
|
+
* ## Why placing them back is the hard part
|
|
2268
|
+
*
|
|
2269
|
+
* Normalization produces three kinds of token and only one of them can be
|
|
2270
|
+
* highlighted the obvious way.
|
|
2271
|
+
*
|
|
2272
|
+
* A token the normalizer left alone still describes its own text, so its
|
|
2273
|
+
* span is `offset` to `offset + value.length`, exactly as before.
|
|
2274
|
+
*
|
|
2275
|
+
* A FUSED token does not. `10 frames` becomes a FRAME_COUNT whose value is
|
|
2276
|
+
* `10`, and a timecode becomes a token whose value is a comma-separated
|
|
2277
|
+
* tuple appearing nowhere on the line. Those carry `sourceEnd`, set by
|
|
2278
|
+
* `createFusedToken`, which is the only place that knows where the fusion
|
|
2279
|
+
* ended.
|
|
2280
|
+
*
|
|
2281
|
+
* An INSERTED token has no text at all. Implicit multiplication puts a STAR
|
|
2282
|
+
* at the following token's offset, so `5(3)` gains a `*` sitting exactly
|
|
2283
|
+
* where the `(` is. Painting it would colour a character the reader never
|
|
2284
|
+
* typed as an operator, and would overlap the token that really is there.
|
|
2285
|
+
* These are dropped, detected by the one test that needs no cooperation
|
|
2286
|
+
* from any rule: a token with no recorded fusion span must match the text
|
|
2287
|
+
* at its own offset, and an inserted one does not.
|
|
2288
|
+
*
|
|
2289
|
+
* @param lineText - The raw line.
|
|
2290
|
+
* @returns Spans in the same shape `Lexer.getHighlightTokens` returns.
|
|
2291
|
+
*/
|
|
2292
|
+
private classifyNormalized;
|
|
2237
2293
|
/**
|
|
2238
2294
|
* Classify every recognized token on one line.
|
|
2239
2295
|
*
|
|
@@ -19,6 +19,20 @@ interface Token {
|
|
|
19
19
|
lineBreaks: number;
|
|
20
20
|
line: number;
|
|
21
21
|
col: number;
|
|
22
|
+
/**
|
|
23
|
+
* End offset of the source text this token was fused from, exclusive.
|
|
24
|
+
*
|
|
25
|
+
* Only set on tokens the normalizer built by fusing several lexer tokens
|
|
26
|
+
* into one, and only there because those are the tokens whose `value` no
|
|
27
|
+
* longer describes the text they came from. `10 frames` fuses into a
|
|
28
|
+
* FRAME_COUNT whose value is `10`, so `offset + value.length` would cover
|
|
29
|
+
* two characters of a nine-character phrase.
|
|
30
|
+
*
|
|
31
|
+
* Evaluation never reads this. It exists so that a consumer painting a line
|
|
32
|
+
* (see `LanguageService.getSemanticTokens`) can highlight a fused phrase as
|
|
33
|
+
* the one thing the parser will see rather than as its parts.
|
|
34
|
+
*/
|
|
35
|
+
sourceEnd?: number;
|
|
22
36
|
}
|
|
23
37
|
/**
|
|
24
38
|
* Canonical token type name constants.
|
|
@@ -73,6 +87,7 @@ declare const TokenTypes: {
|
|
|
73
87
|
readonly PI: "PI";
|
|
74
88
|
readonly E: "E";
|
|
75
89
|
readonly MOD: "MOD";
|
|
90
|
+
readonly AND_CONJ: "AND_CONJ";
|
|
76
91
|
readonly OF: "OF";
|
|
77
92
|
readonly INCREASE_BY: "INCREASE_BY";
|
|
78
93
|
readonly DECREASE_BY: "DECREASE_BY";
|
|
@@ -124,6 +139,9 @@ declare const TokenTypes: {
|
|
|
124
139
|
readonly ELSE: "ELSE";
|
|
125
140
|
readonly AS: "AS";
|
|
126
141
|
readonly CONVERTER_NAME: "CONVERTER_NAME";
|
|
142
|
+
readonly ROUNDED: "ROUNDED";
|
|
143
|
+
readonly TO_NEAREST: "TO_NEAREST";
|
|
144
|
+
readonly DECIMAL_PLACES: "DECIMAL_PLACES";
|
|
127
145
|
readonly AVERAGE_OF: "AVERAGE_OF";
|
|
128
146
|
readonly MEDIAN_OF: "MEDIAN_OF";
|
|
129
147
|
readonly TOTAL_OF: "TOTAL_OF";
|
|
@@ -132,8 +150,22 @@ declare const TokenTypes: {
|
|
|
132
150
|
readonly SMALLER_OF: "SMALLER_OF";
|
|
133
151
|
readonly HALF_OF: "HALF_OF";
|
|
134
152
|
readonly MIDPOINT_BETWEEN: "MIDPOINT_BETWEEN";
|
|
153
|
+
readonly REMAINDER_OF: "REMAINDER_OF";
|
|
154
|
+
readonly NTH_ROOT: "NTH_ROOT";
|
|
155
|
+
readonly LOG_PHRASE: "LOG_PHRASE";
|
|
156
|
+
readonly LOG_BASE: "LOG_BASE";
|
|
157
|
+
readonly GCD_OF: "GCD_OF";
|
|
158
|
+
readonly LCM_OF: "LCM_OF";
|
|
159
|
+
readonly SQUARE_ROOT_OF: "SQUARE_ROOT_OF";
|
|
160
|
+
readonly CUBE_ROOT_OF: "CUBE_ROOT_OF";
|
|
135
161
|
readonly RANDOM_NUMBER: "RANDOM_NUMBER";
|
|
136
162
|
readonly IS_TO: "IS_TO";
|
|
163
|
+
readonly IS: "IS";
|
|
164
|
+
readonly PCT_ON: "PCT_ON";
|
|
165
|
+
readonly PCT_OFF: "PCT_OFF";
|
|
166
|
+
readonly OF_WHAT: "OF_WHAT";
|
|
167
|
+
readonly OFF_WHAT: "OFF_WHAT";
|
|
168
|
+
readonly ON_WHAT: "ON_WHAT";
|
|
137
169
|
readonly CLAMP: "CLAMP";
|
|
138
170
|
readonly MAP: "MAP";
|
|
139
171
|
readonly REDUCE: "REDUCE";
|
|
@@ -167,6 +199,13 @@ declare const TokenTypes: {
|
|
|
167
199
|
readonly GLOBAL: "GLOBAL";
|
|
168
200
|
readonly OVER: "OVER";
|
|
169
201
|
readonly RATE_AT: "RATE_AT";
|
|
202
|
+
readonly AFTER: "AFTER";
|
|
203
|
+
readonly PRESENT_VALUE_OF: "PRESENT_VALUE_OF";
|
|
204
|
+
readonly ANNUAL_RETURN_ON: "ANNUAL_RETURN_ON";
|
|
205
|
+
readonly FOR_DURATION: "FOR_DURATION";
|
|
206
|
+
readonly COMPOUNDING: "COMPOUNDING";
|
|
207
|
+
readonly INVESTED: "INVESTED";
|
|
208
|
+
readonly RETURNED: "RETURNED";
|
|
170
209
|
readonly COMPOUND_INTEREST_ON: "COMPOUND_INTEREST_ON";
|
|
171
210
|
readonly INTEREST_ON: "INTEREST_ON";
|
|
172
211
|
readonly DAILY_REPAYMENT_ON: "DAILY_REPAYMENT_ON";
|
|
@@ -179,6 +218,7 @@ declare const TokenTypes: {
|
|
|
179
218
|
readonly TOTAL_LOAN_INTEREST_ON: "TOTAL_LOAN_INTEREST_ON";
|
|
180
219
|
readonly TAX_ON: "TAX_ON";
|
|
181
220
|
readonly TAX_OFF: "TAX_OFF";
|
|
221
|
+
readonly TAX_IN_PHRASE: "TAX_IN_PHRASE";
|
|
182
222
|
readonly WHAT_IS: "WHAT_IS";
|
|
183
223
|
readonly WHAT_WAS: "WHAT_WAS";
|
|
184
224
|
readonly VALUE_OF: "VALUE_OF";
|
|
@@ -195,6 +235,10 @@ declare const TokenTypes: {
|
|
|
195
235
|
readonly MONTH_ON: "MONTH_ON";
|
|
196
236
|
readonly MONTH_IN: "MONTH_IN";
|
|
197
237
|
readonly WEEK_ON: "WEEK_ON";
|
|
238
|
+
readonly DAYS_IN_PERIOD: "DAYS_IN_PERIOD";
|
|
239
|
+
readonly IN_TWO_UNITS: "IN_TWO_UNITS";
|
|
240
|
+
readonly PER_UNIT: "PER_UNIT";
|
|
241
|
+
readonly AT_RATE: "AT_RATE";
|
|
198
242
|
readonly WEEK_IN: "WEEK_IN";
|
|
199
243
|
readonly BETWEEN_UNIT: "BETWEEN_UNIT";
|
|
200
244
|
readonly IS_WEEKEND: "IS_WEEKEND";
|
|
@@ -19,6 +19,20 @@ interface Token {
|
|
|
19
19
|
lineBreaks: number;
|
|
20
20
|
line: number;
|
|
21
21
|
col: number;
|
|
22
|
+
/**
|
|
23
|
+
* End offset of the source text this token was fused from, exclusive.
|
|
24
|
+
*
|
|
25
|
+
* Only set on tokens the normalizer built by fusing several lexer tokens
|
|
26
|
+
* into one, and only there because those are the tokens whose `value` no
|
|
27
|
+
* longer describes the text they came from. `10 frames` fuses into a
|
|
28
|
+
* FRAME_COUNT whose value is `10`, so `offset + value.length` would cover
|
|
29
|
+
* two characters of a nine-character phrase.
|
|
30
|
+
*
|
|
31
|
+
* Evaluation never reads this. It exists so that a consumer painting a line
|
|
32
|
+
* (see `LanguageService.getSemanticTokens`) can highlight a fused phrase as
|
|
33
|
+
* the one thing the parser will see rather than as its parts.
|
|
34
|
+
*/
|
|
35
|
+
sourceEnd?: number;
|
|
22
36
|
}
|
|
23
37
|
/**
|
|
24
38
|
* Canonical token type name constants.
|
|
@@ -73,6 +87,7 @@ declare const TokenTypes: {
|
|
|
73
87
|
readonly PI: "PI";
|
|
74
88
|
readonly E: "E";
|
|
75
89
|
readonly MOD: "MOD";
|
|
90
|
+
readonly AND_CONJ: "AND_CONJ";
|
|
76
91
|
readonly OF: "OF";
|
|
77
92
|
readonly INCREASE_BY: "INCREASE_BY";
|
|
78
93
|
readonly DECREASE_BY: "DECREASE_BY";
|
|
@@ -124,6 +139,9 @@ declare const TokenTypes: {
|
|
|
124
139
|
readonly ELSE: "ELSE";
|
|
125
140
|
readonly AS: "AS";
|
|
126
141
|
readonly CONVERTER_NAME: "CONVERTER_NAME";
|
|
142
|
+
readonly ROUNDED: "ROUNDED";
|
|
143
|
+
readonly TO_NEAREST: "TO_NEAREST";
|
|
144
|
+
readonly DECIMAL_PLACES: "DECIMAL_PLACES";
|
|
127
145
|
readonly AVERAGE_OF: "AVERAGE_OF";
|
|
128
146
|
readonly MEDIAN_OF: "MEDIAN_OF";
|
|
129
147
|
readonly TOTAL_OF: "TOTAL_OF";
|
|
@@ -132,8 +150,22 @@ declare const TokenTypes: {
|
|
|
132
150
|
readonly SMALLER_OF: "SMALLER_OF";
|
|
133
151
|
readonly HALF_OF: "HALF_OF";
|
|
134
152
|
readonly MIDPOINT_BETWEEN: "MIDPOINT_BETWEEN";
|
|
153
|
+
readonly REMAINDER_OF: "REMAINDER_OF";
|
|
154
|
+
readonly NTH_ROOT: "NTH_ROOT";
|
|
155
|
+
readonly LOG_PHRASE: "LOG_PHRASE";
|
|
156
|
+
readonly LOG_BASE: "LOG_BASE";
|
|
157
|
+
readonly GCD_OF: "GCD_OF";
|
|
158
|
+
readonly LCM_OF: "LCM_OF";
|
|
159
|
+
readonly SQUARE_ROOT_OF: "SQUARE_ROOT_OF";
|
|
160
|
+
readonly CUBE_ROOT_OF: "CUBE_ROOT_OF";
|
|
135
161
|
readonly RANDOM_NUMBER: "RANDOM_NUMBER";
|
|
136
162
|
readonly IS_TO: "IS_TO";
|
|
163
|
+
readonly IS: "IS";
|
|
164
|
+
readonly PCT_ON: "PCT_ON";
|
|
165
|
+
readonly PCT_OFF: "PCT_OFF";
|
|
166
|
+
readonly OF_WHAT: "OF_WHAT";
|
|
167
|
+
readonly OFF_WHAT: "OFF_WHAT";
|
|
168
|
+
readonly ON_WHAT: "ON_WHAT";
|
|
137
169
|
readonly CLAMP: "CLAMP";
|
|
138
170
|
readonly MAP: "MAP";
|
|
139
171
|
readonly REDUCE: "REDUCE";
|
|
@@ -167,6 +199,13 @@ declare const TokenTypes: {
|
|
|
167
199
|
readonly GLOBAL: "GLOBAL";
|
|
168
200
|
readonly OVER: "OVER";
|
|
169
201
|
readonly RATE_AT: "RATE_AT";
|
|
202
|
+
readonly AFTER: "AFTER";
|
|
203
|
+
readonly PRESENT_VALUE_OF: "PRESENT_VALUE_OF";
|
|
204
|
+
readonly ANNUAL_RETURN_ON: "ANNUAL_RETURN_ON";
|
|
205
|
+
readonly FOR_DURATION: "FOR_DURATION";
|
|
206
|
+
readonly COMPOUNDING: "COMPOUNDING";
|
|
207
|
+
readonly INVESTED: "INVESTED";
|
|
208
|
+
readonly RETURNED: "RETURNED";
|
|
170
209
|
readonly COMPOUND_INTEREST_ON: "COMPOUND_INTEREST_ON";
|
|
171
210
|
readonly INTEREST_ON: "INTEREST_ON";
|
|
172
211
|
readonly DAILY_REPAYMENT_ON: "DAILY_REPAYMENT_ON";
|
|
@@ -179,6 +218,7 @@ declare const TokenTypes: {
|
|
|
179
218
|
readonly TOTAL_LOAN_INTEREST_ON: "TOTAL_LOAN_INTEREST_ON";
|
|
180
219
|
readonly TAX_ON: "TAX_ON";
|
|
181
220
|
readonly TAX_OFF: "TAX_OFF";
|
|
221
|
+
readonly TAX_IN_PHRASE: "TAX_IN_PHRASE";
|
|
182
222
|
readonly WHAT_IS: "WHAT_IS";
|
|
183
223
|
readonly WHAT_WAS: "WHAT_WAS";
|
|
184
224
|
readonly VALUE_OF: "VALUE_OF";
|
|
@@ -195,6 +235,10 @@ declare const TokenTypes: {
|
|
|
195
235
|
readonly MONTH_ON: "MONTH_ON";
|
|
196
236
|
readonly MONTH_IN: "MONTH_IN";
|
|
197
237
|
readonly WEEK_ON: "WEEK_ON";
|
|
238
|
+
readonly DAYS_IN_PERIOD: "DAYS_IN_PERIOD";
|
|
239
|
+
readonly IN_TWO_UNITS: "IN_TWO_UNITS";
|
|
240
|
+
readonly PER_UNIT: "PER_UNIT";
|
|
241
|
+
readonly AT_RATE: "AT_RATE";
|
|
198
242
|
readonly WEEK_IN: "WEEK_IN";
|
|
199
243
|
readonly BETWEEN_UNIT: "BETWEEN_UNIT";
|
|
200
244
|
readonly IS_WEEKEND: "IS_WEEKEND";
|