@atomic-ehr/fhirpath 0.0.2 → 0.0.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.
- package/README.md +716 -238
- package/dist/index.d.ts +225 -119
- package/dist/index.js +10911 -5600
- package/dist/index.js.map +1 -1
- package/package.json +9 -4
- package/src/analyzer/augmentor.ts +242 -0
- package/src/analyzer/cursor-services.ts +75 -0
- package/src/analyzer/scope-manager.ts +57 -0
- package/src/analyzer/trivia-indexer.ts +58 -0
- package/src/analyzer/type-compat.ts +157 -0
- package/src/analyzer/utils.ts +132 -0
- package/src/analyzer.ts +921 -1208
- package/src/completion-provider.ts +209 -191
- package/src/{quantity-value.ts → complex-types/quantity-value.ts} +112 -22
- package/src/complex-types/temporal.ts +1737 -0
- package/src/errors.ts +25 -3
- package/src/index.ts +17 -104
- package/src/inspect.ts +4 -4
- package/src/{boxing.ts → interpreter/boxing.ts} +1 -1
- package/src/interpreter/navigator.ts +94 -0
- package/src/interpreter/runtime-context.ts +273 -0
- package/src/interpreter.ts +435 -469
- package/src/lexer.ts +188 -210
- package/src/model-provider.ts +71 -43
- package/src/operations/abs-function.ts +1 -1
- package/src/operations/aggregate-function.ts +84 -5
- package/src/operations/all-function.ts +4 -3
- package/src/operations/allFalse-function.ts +2 -1
- package/src/operations/allTrue-function.ts +2 -1
- package/src/operations/and-operator.ts +2 -1
- package/src/operations/anyFalse-function.ts +2 -1
- package/src/operations/anyTrue-function.ts +2 -1
- package/src/operations/as-function.ts +58 -0
- package/src/operations/as-operator.ts +57 -19
- package/src/operations/ceiling-function.ts +1 -1
- package/src/operations/children-function.ts +14 -5
- package/src/operations/combine-function.ts +6 -3
- package/src/operations/combine-operator.ts +6 -7
- package/src/operations/comparison.ts +692 -0
- package/src/operations/contains-function.ts +1 -1
- package/src/operations/contains-operator.ts +2 -1
- package/src/operations/convertsToBoolean-function.ts +78 -0
- package/src/operations/convertsToDecimal-function.ts +82 -0
- package/src/operations/convertsToInteger-function.ts +71 -0
- package/src/operations/convertsToLong-function.ts +89 -0
- package/src/operations/convertsToQuantity-function.ts +116 -0
- package/src/operations/convertsToString-function.ts +88 -0
- package/src/operations/count-function.ts +2 -1
- package/src/operations/dateOf-function.ts +69 -0
- package/src/operations/dayOf-function.ts +66 -0
- package/src/operations/decimal-boundaries.ts +133 -0
- package/src/operations/defineVariable-function.ts +130 -17
- package/src/operations/distinct-function.ts +1 -1
- package/src/operations/div-operator.ts +1 -1
- package/src/operations/divide-operator.ts +12 -7
- package/src/operations/dot-operator.ts +1 -1
- package/src/operations/empty-function.ts +30 -21
- package/src/operations/endsWith-function.ts +6 -1
- package/src/operations/equal-operator.ts +23 -32
- package/src/operations/equivalent-operator.ts +13 -53
- package/src/operations/exclude-function.ts +2 -1
- package/src/operations/exists-function.ts +4 -3
- package/src/operations/first-function.ts +1 -1
- package/src/operations/floor-function.ts +1 -1
- package/src/operations/greater-operator.ts +20 -3
- package/src/operations/greater-or-equal-operator.ts +20 -3
- package/src/operations/highBoundary-function.ts +120 -0
- package/src/operations/hourOf-function.ts +66 -0
- package/src/operations/iif-function.ts +186 -7
- package/src/operations/implies-operator.ts +1 -1
- package/src/operations/in-operator.ts +2 -1
- package/src/operations/index.ts +41 -0
- package/src/operations/indexOf-function.ts +1 -1
- package/src/operations/intersect-function.ts +1 -1
- package/src/operations/is-function.ts +59 -0
- package/src/operations/is-operator.ts +20 -9
- package/src/operations/isDistinct-function.ts +2 -1
- package/src/operations/join-function.ts +1 -1
- package/src/operations/last-function.ts +1 -1
- package/src/operations/lastIndexOf-function.ts +85 -0
- package/src/operations/length-function.ts +1 -1
- package/src/operations/less-operator.ts +20 -3
- package/src/operations/less-or-equal-operator.ts +20 -3
- package/src/operations/less-than.ts +2 -2
- package/src/operations/lowBoundary-function.ts +120 -0
- package/src/operations/lower-function.ts +1 -1
- package/src/operations/matches-function.ts +86 -0
- package/src/operations/matchesFull-function.ts +96 -0
- package/src/operations/millisecondOf-function.ts +66 -0
- package/src/operations/minus-operator.ts +69 -4
- package/src/operations/minuteOf-function.ts +66 -0
- package/src/operations/mod-operator.ts +1 -1
- package/src/operations/monthOf-function.ts +66 -0
- package/src/operations/multiply-operator.ts +27 -3
- package/src/operations/not-equal-operator.ts +24 -30
- package/src/operations/not-equivalent-operator.ts +13 -53
- package/src/operations/not-function.ts +1 -1
- package/src/operations/ofType-function.ts +8 -12
- package/src/operations/or-operator.ts +2 -1
- package/src/operations/plus-operator.ts +71 -7
- package/src/operations/power-function.ts +35 -10
- package/src/operations/repeat-function.ts +169 -0
- package/src/operations/replace-function.ts +1 -1
- package/src/operations/replaceMatches-function.ts +120 -0
- package/src/operations/round-function.ts +1 -1
- package/src/operations/secondOf-function.ts +66 -0
- package/src/operations/select-function.ts +66 -5
- package/src/operations/single-function.ts +1 -1
- package/src/operations/skip-function.ts +1 -1
- package/src/operations/split-function.ts +1 -1
- package/src/operations/sqrt-function.ts +15 -8
- package/src/operations/startsWith-function.ts +1 -1
- package/src/operations/subsetOf-function.ts +6 -2
- package/src/operations/substring-function.ts +1 -1
- package/src/operations/supersetOf-function.ts +6 -2
- package/src/operations/tail-function.ts +1 -1
- package/src/operations/take-function.ts +1 -1
- package/src/operations/temporal-functions.ts +555 -0
- package/src/operations/timeOf-function.ts +67 -0
- package/src/operations/timezoneOffsetOf-function.ts +69 -0
- package/src/operations/toBoolean-function.ts +27 -8
- package/src/operations/toChars-function.ts +56 -0
- package/src/operations/toDecimal-function.ts +27 -8
- package/src/operations/toInteger-function.ts +15 -3
- package/src/operations/toLong-function.ts +98 -0
- package/src/operations/toQuantity-function.ts +181 -0
- package/src/operations/toString-function.ts +45 -3
- package/src/operations/trace-function.ts +1 -1
- package/src/operations/trim-function.ts +1 -1
- package/src/operations/truncate-function.ts +1 -1
- package/src/operations/unary-minus-operator.ts +2 -2
- package/src/operations/unary-plus-operator.ts +1 -1
- package/src/operations/union-function.ts +1 -1
- package/src/operations/union-operator.ts +16 -26
- package/src/operations/upper-function.ts +1 -1
- package/src/operations/where-function.ts +3 -3
- package/src/operations/xor-operator.ts +1 -1
- package/src/operations/yearOf-function.ts +66 -0
- package/src/{cursor-nodes.ts → parser/cursor-nodes.ts} +10 -7
- package/src/parser.ts +248 -501
- package/src/registry.ts +53 -42
- package/src/types.ts +128 -16
- package/src/utils/pprint.ts +151 -0
package/dist/index.d.ts
CHANGED
|
@@ -53,6 +53,7 @@ declare enum TokenType {
|
|
|
53
53
|
DATETIME = 4,
|
|
54
54
|
TIME = 5,
|
|
55
55
|
QUANTITY = 6,// Quantity literals like 5 'mg'
|
|
56
|
+
DATE = 7,// Date literals like @2020-01-01
|
|
56
57
|
OPERATOR = 10,// +, -, *, /, <, >, <=, >=, =, !=, ~, !~, |, &
|
|
57
58
|
DOT = 50,// .
|
|
58
59
|
COMMA = 51,// ,
|
|
@@ -93,8 +94,6 @@ declare class Lexer {
|
|
|
93
94
|
private position;
|
|
94
95
|
private line;
|
|
95
96
|
private column;
|
|
96
|
-
private lspLine;
|
|
97
|
-
private lspCharacter;
|
|
98
97
|
private options;
|
|
99
98
|
private lineOffsets;
|
|
100
99
|
constructor(input: string, options?: LexerOptions);
|
|
@@ -115,6 +114,10 @@ declare class Lexer {
|
|
|
115
114
|
private readTime;
|
|
116
115
|
private readTimeFormat;
|
|
117
116
|
private readTimezone;
|
|
117
|
+
private static readonly OPERATORS;
|
|
118
|
+
private isOperatorStarter;
|
|
119
|
+
private readOperator;
|
|
120
|
+
private scanQuoted;
|
|
118
121
|
private skipWhitespace;
|
|
119
122
|
private skipLineComment;
|
|
120
123
|
private skipBlockComment;
|
|
@@ -123,6 +126,9 @@ declare class Lexer {
|
|
|
123
126
|
private peek;
|
|
124
127
|
private isDigit;
|
|
125
128
|
private isWhitespace;
|
|
129
|
+
private isIdentifierHead;
|
|
130
|
+
private isIdentifierPart;
|
|
131
|
+
private scanIdentifierBody;
|
|
126
132
|
/**
|
|
127
133
|
* Convert absolute offset to LSP Position
|
|
128
134
|
*/
|
|
@@ -143,6 +149,41 @@ declare class Lexer {
|
|
|
143
149
|
static couldBeKeywordOperator(token: Token): boolean;
|
|
144
150
|
}
|
|
145
151
|
|
|
152
|
+
declare enum CursorContext {
|
|
153
|
+
Operator = "operator",
|
|
154
|
+
Identifier = "identifier",
|
|
155
|
+
Argument = "argument",
|
|
156
|
+
Index = "index",
|
|
157
|
+
Type = "type"
|
|
158
|
+
}
|
|
159
|
+
interface CursorNode extends BaseASTNode {
|
|
160
|
+
type: 'CursorNode';
|
|
161
|
+
context: CursorContext;
|
|
162
|
+
position: number;
|
|
163
|
+
}
|
|
164
|
+
interface CursorOperatorNode extends CursorNode {
|
|
165
|
+
context: CursorContext.Operator;
|
|
166
|
+
}
|
|
167
|
+
interface CursorIdentifierNode extends CursorNode {
|
|
168
|
+
context: CursorContext.Identifier;
|
|
169
|
+
partialText?: string;
|
|
170
|
+
}
|
|
171
|
+
interface CursorArgumentNode extends CursorNode {
|
|
172
|
+
context: CursorContext.Argument;
|
|
173
|
+
functionName: string;
|
|
174
|
+
argumentIndex: number;
|
|
175
|
+
}
|
|
176
|
+
interface CursorIndexNode extends CursorNode {
|
|
177
|
+
context: CursorContext.Index;
|
|
178
|
+
}
|
|
179
|
+
interface CursorTypeNode extends CursorNode {
|
|
180
|
+
context: CursorContext.Type;
|
|
181
|
+
typeOperator: 'is' | 'as' | 'ofType';
|
|
182
|
+
partialText?: string;
|
|
183
|
+
}
|
|
184
|
+
type AnyCursorNode = CursorOperatorNode | CursorIdentifierNode | CursorArgumentNode | CursorIndexNode | CursorTypeNode;
|
|
185
|
+
declare function isCursorNode(node: any): node is CursorNode;
|
|
186
|
+
|
|
146
187
|
declare enum PRECEDENCE {
|
|
147
188
|
IMPLIES = 10,
|
|
148
189
|
OR = 20,
|
|
@@ -163,6 +204,7 @@ type TypeName = 'Any' | 'Boolean' | 'String' | 'Integer' | 'Long' | 'Decimal' |
|
|
|
163
204
|
interface TypeInfo<TypeContext = unknown> {
|
|
164
205
|
type: TypeName;
|
|
165
206
|
singleton?: boolean;
|
|
207
|
+
isEmpty?: boolean;
|
|
166
208
|
namespace?: string;
|
|
167
209
|
name?: string;
|
|
168
210
|
modelContext?: TypeContext;
|
|
@@ -191,6 +233,7 @@ interface OperatorSignature {
|
|
|
191
233
|
interface OperatorDefinition {
|
|
192
234
|
symbol: string;
|
|
193
235
|
name: string;
|
|
236
|
+
doesNotPropagateEmpty?: boolean;
|
|
194
237
|
category: string[];
|
|
195
238
|
precedence: PRECEDENCE;
|
|
196
239
|
associativity: 'left' | 'right';
|
|
@@ -207,6 +250,7 @@ interface FunctionSignature {
|
|
|
207
250
|
optional?: boolean;
|
|
208
251
|
type: TypeInfo;
|
|
209
252
|
expression?: boolean;
|
|
253
|
+
typeReference?: boolean;
|
|
210
254
|
}>;
|
|
211
255
|
result: TypeInfo | 'inputType' | 'inputTypeSingleton' | 'parameterType';
|
|
212
256
|
}
|
|
@@ -217,14 +261,17 @@ interface FunctionDefinition {
|
|
|
217
261
|
examples: string[];
|
|
218
262
|
signatures: FunctionSignature[];
|
|
219
263
|
evaluate: FunctionEvaluator;
|
|
264
|
+
inferResultType?: (analyzer: any, node: any, inputType?: TypeInfo) => Promise<TypeInfo>;
|
|
265
|
+
analyze?: (context: AnalysisContext, args: ASTNode[]) => Promise<InternalAnalysisResult> | InternalAnalysisResult;
|
|
266
|
+
doesNotPropagateEmpty?: boolean;
|
|
220
267
|
}
|
|
221
268
|
declare enum NodeType {
|
|
222
269
|
EOF = "EOF",
|
|
223
270
|
Binary = "Binary",
|
|
224
271
|
Unary = "Unary",
|
|
225
|
-
TypeOrIdentifier = "TypeOrIdentifier",
|
|
226
272
|
Identifier = "Identifier",
|
|
227
273
|
Literal = "Literal",
|
|
274
|
+
TemporalLiteral = "TemporalLiteral",
|
|
228
275
|
Function = "Function",
|
|
229
276
|
Variable = "Variable",
|
|
230
277
|
Index = "Index",
|
|
@@ -256,7 +303,7 @@ interface TriviaInfo {
|
|
|
256
303
|
range: Range;
|
|
257
304
|
}
|
|
258
305
|
interface BaseASTNode {
|
|
259
|
-
type: NodeType | 'Error';
|
|
306
|
+
type: NodeType | 'Error' | 'CursorNode';
|
|
260
307
|
range: Range;
|
|
261
308
|
parent?: ASTNode;
|
|
262
309
|
children?: ASTNode[];
|
|
@@ -280,15 +327,17 @@ interface IdentifierNode extends BaseASTNode {
|
|
|
280
327
|
name: string;
|
|
281
328
|
symbolKind?: SymbolKind.Variable | SymbolKind.Function | SymbolKind.Property;
|
|
282
329
|
}
|
|
283
|
-
interface TypeOrIdentifierNode extends BaseASTNode {
|
|
284
|
-
type: NodeType.TypeOrIdentifier;
|
|
285
|
-
name: string;
|
|
286
|
-
}
|
|
287
330
|
interface LiteralNode extends BaseASTNode {
|
|
288
331
|
type: NodeType.Literal;
|
|
289
332
|
value: any;
|
|
290
333
|
valueType: 'string' | 'number' | 'boolean' | 'date' | 'time' | 'datetime' | 'null';
|
|
291
334
|
}
|
|
335
|
+
interface TemporalLiteralNode extends BaseASTNode {
|
|
336
|
+
type: NodeType.TemporalLiteral;
|
|
337
|
+
value: any;
|
|
338
|
+
valueType: 'date' | 'time' | 'datetime';
|
|
339
|
+
rawValue: string;
|
|
340
|
+
}
|
|
292
341
|
interface BinaryNode extends BaseASTNode {
|
|
293
342
|
type: NodeType.Binary;
|
|
294
343
|
operator: string;
|
|
@@ -338,9 +387,8 @@ interface QuantityNode extends BaseASTNode {
|
|
|
338
387
|
type: NodeType.Quantity;
|
|
339
388
|
value: number;
|
|
340
389
|
unit: string;
|
|
341
|
-
isCalendarUnit?: boolean;
|
|
342
390
|
}
|
|
343
|
-
type ASTNode = IdentifierNode |
|
|
391
|
+
type ASTNode = IdentifierNode | LiteralNode | TemporalLiteralNode | BinaryNode | UnaryNode | FunctionNode | VariableNode | IndexNode | MembershipTestNode | TypeCastNode | CollectionNode | TypeReferenceNode | QuantityNode | ErrorNode | AnyCursorNode;
|
|
344
392
|
interface RuntimeContext {
|
|
345
393
|
input: any[];
|
|
346
394
|
focus: any[];
|
|
@@ -371,6 +419,8 @@ interface Diagnostic {
|
|
|
371
419
|
interface AnalysisResult {
|
|
372
420
|
diagnostics: Diagnostic[];
|
|
373
421
|
ast: ASTNode;
|
|
422
|
+
type?: TypeInfo;
|
|
423
|
+
userVariables?: Map<string, TypeInfo>;
|
|
374
424
|
}
|
|
375
425
|
interface ParseError {
|
|
376
426
|
message: string;
|
|
@@ -383,7 +433,7 @@ interface ParseResult {
|
|
|
383
433
|
errors: ParseError[];
|
|
384
434
|
indexes?: {
|
|
385
435
|
nodeById: Map<string, ASTNode>;
|
|
386
|
-
nodesByType: Map<NodeType | 'Error', ASTNode[]>;
|
|
436
|
+
nodesByType: Map<NodeType | 'Error' | 'CursorNode', ASTNode[]>;
|
|
387
437
|
identifiers: Map<string, ASTNode[]>;
|
|
388
438
|
};
|
|
389
439
|
cursorContext?: {
|
|
@@ -394,6 +444,34 @@ interface ParseResult {
|
|
|
394
444
|
}
|
|
395
445
|
type OperationEvaluator = (input: FHIRPathValue[], context: RuntimeContext, ...args: any[]) => Promise<EvaluationResult>;
|
|
396
446
|
type FunctionEvaluator = (input: FHIRPathValue[], context: RuntimeContext, args: ASTNode[], evaluator: (node: ASTNode, input: FHIRPathValue[], context: RuntimeContext) => Promise<EvaluationResult>) => Promise<EvaluationResult>;
|
|
447
|
+
/**
|
|
448
|
+
* Result of analyzing a single AST node in the context-flow architecture.
|
|
449
|
+
*/
|
|
450
|
+
interface InternalAnalysisResult {
|
|
451
|
+
type: TypeInfo;
|
|
452
|
+
diagnostics: Diagnostic[];
|
|
453
|
+
context?: AnalysisContext;
|
|
454
|
+
}
|
|
455
|
+
/**
|
|
456
|
+
* Immutable context that flows through the analysis tree.
|
|
457
|
+
* Carries variable scopes and input types through the AST.
|
|
458
|
+
*/
|
|
459
|
+
declare class AnalysisContext {
|
|
460
|
+
readonly inputType: TypeInfo;
|
|
461
|
+
readonly systemVariables: ReadonlyMap<string, TypeInfo>;
|
|
462
|
+
readonly userVariables: ReadonlyMap<string, TypeInfo>;
|
|
463
|
+
private readonly analyzeNodeCallback;
|
|
464
|
+
readonly modelProvider?: ModelProvider | undefined;
|
|
465
|
+
readonly hasDynamicVariables: boolean;
|
|
466
|
+
readonly _chainHead: boolean;
|
|
467
|
+
constructor(inputType: TypeInfo, systemVariables: ReadonlyMap<string, TypeInfo>, userVariables: ReadonlyMap<string, TypeInfo>, analyzeNodeCallback: (node: ASTNode, ctx: AnalysisContext) => Promise<InternalAnalysisResult>, modelProvider?: ModelProvider | undefined, hasDynamicVariables?: boolean, _chainHead?: boolean);
|
|
468
|
+
withUserVariable(name: string, type: TypeInfo): AnalysisContext;
|
|
469
|
+
withSystemVariable(name: string, type: TypeInfo): AnalysisContext;
|
|
470
|
+
withInputType(type: TypeInfo): AnalysisContext;
|
|
471
|
+
withDynamicVariables(): AnalysisContext;
|
|
472
|
+
fork(): AnalysisContext;
|
|
473
|
+
analyzeNode(node: ASTNode): Promise<InternalAnalysisResult>;
|
|
474
|
+
}
|
|
397
475
|
|
|
398
476
|
interface ParserOptions {
|
|
399
477
|
mode?: 'simple' | 'lsp';
|
|
@@ -411,16 +489,15 @@ declare class Parser {
|
|
|
411
489
|
protected current: number;
|
|
412
490
|
private mode;
|
|
413
491
|
private options;
|
|
492
|
+
private preserveTriviaEffective;
|
|
414
493
|
private errors?;
|
|
415
|
-
private nodeIdCounter?;
|
|
416
|
-
private nodeIndex?;
|
|
417
|
-
private nodesByType?;
|
|
418
|
-
private identifierIndex?;
|
|
419
|
-
private currentParent?;
|
|
420
494
|
private input;
|
|
495
|
+
private leadingTriviaByTokenStart?;
|
|
496
|
+
private trailingTriviaByTokenEnd?;
|
|
497
|
+
private tokenByStart?;
|
|
498
|
+
private tokenByEnd?;
|
|
421
499
|
private readonly synchronizationTokens;
|
|
422
500
|
constructor(input: string, options?: ParserOptions);
|
|
423
|
-
private checkCursor;
|
|
424
501
|
private injectCursorToken;
|
|
425
502
|
private getRangeFromToken;
|
|
426
503
|
private getRangeFromTokens;
|
|
@@ -432,15 +509,13 @@ declare class Parser {
|
|
|
432
509
|
protected parseExpressionWithPrecedence(minPrecedence: number): ASTNode;
|
|
433
510
|
protected parsePrimary(): ASTNode;
|
|
434
511
|
protected parseInvocation(): ASTNode;
|
|
435
|
-
protected parseArgumentList(): ASTNode[];
|
|
512
|
+
protected parseArgumentList(functionName?: string): ASTNode[];
|
|
513
|
+
protected parseFunctionCall(nameNode: ASTNode): ASTNode;
|
|
436
514
|
protected parseCollectionElements(): ASTNode[];
|
|
437
515
|
protected parseTypeName(): string;
|
|
438
516
|
protected parseStringValue(raw: string): string;
|
|
439
517
|
protected parseIdentifierValue(raw: string): string;
|
|
440
518
|
protected isFunctionCall(node: ASTNode): boolean;
|
|
441
|
-
protected isBinaryOperatorToken(token: Token): boolean;
|
|
442
|
-
protected isKeywordAllowedAsMember(token: Token): boolean;
|
|
443
|
-
protected isKeywordAllowedAsIdentifier(token: Token): boolean;
|
|
444
519
|
protected peek(): Token;
|
|
445
520
|
protected previous(): Token;
|
|
446
521
|
protected isAtEnd(): boolean;
|
|
@@ -450,24 +525,22 @@ declare class Parser {
|
|
|
450
525
|
protected consume(type: TokenType, message: string): Token;
|
|
451
526
|
protected createIdentifierNode(name: string, token: Token): ASTNode;
|
|
452
527
|
protected createLiteralNode(value: any, valueType: LiteralNode['valueType'], token: Token): LiteralNode;
|
|
528
|
+
protected createTemporalLiteralNode(rawValue: string, valueType: TemporalLiteralNode['valueType'], token: Token): TemporalLiteralNode;
|
|
453
529
|
protected createBinaryNode(token: Token, left: ASTNode, right: ASTNode): BinaryNode;
|
|
454
530
|
protected createUnaryNode(token: Token, operand: ASTNode): UnaryNode;
|
|
455
|
-
protected createFunctionNode(name: ASTNode, args: ASTNode[]
|
|
531
|
+
protected createFunctionNode(name: ASTNode, args: ASTNode[]): FunctionNode;
|
|
456
532
|
protected createVariableNode(name: string, token: Token): VariableNode;
|
|
457
533
|
protected createIndexNode(expression: ASTNode, index: ASTNode, startToken: Token): IndexNode;
|
|
458
534
|
protected createMembershipTestNode(expression: ASTNode, targetType: string, startToken: Token): MembershipTestNode;
|
|
459
535
|
protected createTypeCastNode(expression: ASTNode, targetType: string, startToken: Token): TypeCastNode;
|
|
460
536
|
protected createCollectionNode(elements: ASTNode[], startToken: Token): CollectionNode;
|
|
461
|
-
protected createQuantityNode(value: number, unit: string,
|
|
462
|
-
protected
|
|
463
|
-
private
|
|
537
|
+
protected createQuantityNode(value: number, unit: string, startToken: Token, endToken: Token): QuantityNode;
|
|
538
|
+
protected handleAstError(message: string, token?: Token): ErrorNode;
|
|
539
|
+
private reportError;
|
|
540
|
+
private throwSyntax;
|
|
464
541
|
private createErrorNode;
|
|
465
542
|
private addError;
|
|
466
543
|
private synchronize;
|
|
467
|
-
private findNodeAtPosition;
|
|
468
|
-
private getExpectedTokens;
|
|
469
|
-
private getExpectedTokensForError;
|
|
470
|
-
private getCompletions;
|
|
471
544
|
}
|
|
472
545
|
declare function parse(input: string, options?: ParserOptions): ParseResult;
|
|
473
546
|
|
|
@@ -497,7 +570,7 @@ declare class Registry {
|
|
|
497
570
|
/**
|
|
498
571
|
* Get functions applicable to a specific type
|
|
499
572
|
*/
|
|
500
|
-
getFunctionsForType(typeName: TypeName | string)
|
|
573
|
+
getFunctionsForType: (typeName: TypeName | string) => FunctionDefinition[];
|
|
501
574
|
/**
|
|
502
575
|
* Get operators applicable to a specific type
|
|
503
576
|
*/
|
|
@@ -505,7 +578,9 @@ declare class Registry {
|
|
|
505
578
|
/**
|
|
506
579
|
* Check if a function is applicable to a type
|
|
507
580
|
*/
|
|
508
|
-
|
|
581
|
+
private getTypeInfoFromString;
|
|
582
|
+
isTypeCompatible(inputType: TypeInfo, requiredType: TypeInfo): boolean;
|
|
583
|
+
isFunctionApplicableToType(functionName: string, type: string): boolean;
|
|
509
584
|
/**
|
|
510
585
|
* Check if an operator is applicable to a type
|
|
511
586
|
*/
|
|
@@ -513,6 +588,10 @@ declare class Registry {
|
|
|
513
588
|
}
|
|
514
589
|
declare const registry: Registry;
|
|
515
590
|
|
|
591
|
+
/**
|
|
592
|
+
* Runtime context manager that provides efficient prototype-based context operations
|
|
593
|
+
* for both interpreter and compiler.
|
|
594
|
+
*/
|
|
516
595
|
declare class Interpreter {
|
|
517
596
|
private registry;
|
|
518
597
|
private nodeEvaluators;
|
|
@@ -523,9 +602,27 @@ declare class Interpreter {
|
|
|
523
602
|
private registerOperationEvaluators;
|
|
524
603
|
evaluate(node: ASTNode, input?: any[], context?: RuntimeContext): Promise<EvaluationResult>;
|
|
525
604
|
private createInitialContext;
|
|
605
|
+
/**
|
|
606
|
+
* Parse, analyze and evaluate a FHIRPath expression with optional
|
|
607
|
+
* model provider, variables and input type. Returns unboxed values
|
|
608
|
+
* with temporal values formatted as FHIRPath literals.
|
|
609
|
+
*/
|
|
610
|
+
evaluateExpression(expression: string, options?: {
|
|
611
|
+
input?: unknown;
|
|
612
|
+
variables?: Record<string, unknown>;
|
|
613
|
+
inputType?: TypeInfo;
|
|
614
|
+
modelProvider?: ModelProvider;
|
|
615
|
+
now?: Date;
|
|
616
|
+
}): Promise<any[]>;
|
|
617
|
+
private getBooleanKind;
|
|
618
|
+
private boxBoolean;
|
|
619
|
+
private evaluateTemporalLiteral;
|
|
526
620
|
private evaluateLiteral;
|
|
621
|
+
private handleExtension;
|
|
622
|
+
private handleChoiceTypes;
|
|
623
|
+
private handleUnionChoices;
|
|
624
|
+
private handleStandardProperty;
|
|
527
625
|
private evaluateIdentifier;
|
|
528
|
-
private evaluateTypeOrIdentifier;
|
|
529
626
|
private evaluateBinary;
|
|
530
627
|
private evaluateUnary;
|
|
531
628
|
private evaluateVariable;
|
|
@@ -537,51 +634,6 @@ declare class Interpreter {
|
|
|
537
634
|
private evaluateQuantity;
|
|
538
635
|
}
|
|
539
636
|
|
|
540
|
-
declare enum CursorContext {
|
|
541
|
-
Operator = "operator",
|
|
542
|
-
Identifier = "identifier",
|
|
543
|
-
Argument = "argument",
|
|
544
|
-
Index = "index",
|
|
545
|
-
Type = "type"
|
|
546
|
-
}
|
|
547
|
-
interface CursorNode {
|
|
548
|
-
type: 'CursorNode';
|
|
549
|
-
context: CursorContext;
|
|
550
|
-
position: number;
|
|
551
|
-
range: {
|
|
552
|
-
start: {
|
|
553
|
-
line: number;
|
|
554
|
-
character: number;
|
|
555
|
-
offset: number;
|
|
556
|
-
};
|
|
557
|
-
end: {
|
|
558
|
-
line: number;
|
|
559
|
-
character: number;
|
|
560
|
-
offset: number;
|
|
561
|
-
};
|
|
562
|
-
};
|
|
563
|
-
}
|
|
564
|
-
interface CursorOperatorNode extends CursorNode {
|
|
565
|
-
context: CursorContext.Operator;
|
|
566
|
-
}
|
|
567
|
-
interface CursorIdentifierNode extends CursorNode {
|
|
568
|
-
context: CursorContext.Identifier;
|
|
569
|
-
}
|
|
570
|
-
interface CursorArgumentNode extends CursorNode {
|
|
571
|
-
context: CursorContext.Argument;
|
|
572
|
-
functionName: string;
|
|
573
|
-
argumentIndex: number;
|
|
574
|
-
}
|
|
575
|
-
interface CursorIndexNode extends CursorNode {
|
|
576
|
-
context: CursorContext.Index;
|
|
577
|
-
}
|
|
578
|
-
interface CursorTypeNode extends CursorNode {
|
|
579
|
-
context: CursorContext.Type;
|
|
580
|
-
typeOperator: 'is' | 'as' | 'ofType';
|
|
581
|
-
}
|
|
582
|
-
type AnyCursorNode = CursorOperatorNode | CursorIdentifierNode | CursorArgumentNode | CursorIndexNode | CursorTypeNode;
|
|
583
|
-
declare function isCursorNode(node: any): node is CursorNode;
|
|
584
|
-
|
|
585
637
|
interface AnalyzerOptions {
|
|
586
638
|
cursorMode?: boolean;
|
|
587
639
|
}
|
|
@@ -591,56 +643,104 @@ interface AnalysisResultWithCursor extends AnalysisResult {
|
|
|
591
643
|
typeBeforeCursor?: TypeInfo;
|
|
592
644
|
expectedType?: TypeInfo;
|
|
593
645
|
cursorNode?: AnyCursorNode;
|
|
646
|
+
functionCall?: {
|
|
647
|
+
definition: FunctionDefinition;
|
|
648
|
+
argumentIndex: number;
|
|
649
|
+
};
|
|
594
650
|
};
|
|
595
651
|
}
|
|
596
652
|
declare class Analyzer {
|
|
597
|
-
private diagnostics;
|
|
598
|
-
private variables;
|
|
599
653
|
private modelProvider?;
|
|
600
|
-
private userVariableTypes;
|
|
601
|
-
private systemVariableTypes;
|
|
602
654
|
private cursorMode;
|
|
603
655
|
private stoppedAtCursor;
|
|
604
656
|
private cursorContext?;
|
|
605
657
|
constructor(modelProvider?: ModelProvider);
|
|
606
|
-
analyze(ast: ASTNode, userVariables?: Record<string, any>, inputType?: TypeInfo, options?: AnalyzerOptions): Promise<AnalysisResultWithCursor>;
|
|
607
|
-
private visitNode;
|
|
608
|
-
private visitBinaryOperator;
|
|
609
|
-
private visitIdentifier;
|
|
610
|
-
private visitFunctionCall;
|
|
611
|
-
private visitMembershipTest;
|
|
612
|
-
private visitTypeCast;
|
|
613
|
-
private validateVariable;
|
|
614
|
-
private collectDefinedVariables;
|
|
615
|
-
private collectDefinedVariablesWithTypes;
|
|
616
|
-
private inferType;
|
|
617
|
-
private inferErrorNodeType;
|
|
618
|
-
private inferLiteralType;
|
|
619
|
-
private inferBinaryType;
|
|
620
|
-
private inferNavigationType;
|
|
621
|
-
private inferUnaryType;
|
|
622
|
-
private inferFunctionType;
|
|
623
|
-
private inferIdentifierType;
|
|
624
|
-
private inferTypeOrIdentifierType;
|
|
625
|
-
private inferVariableType;
|
|
626
|
-
private inferCollectionType;
|
|
627
|
-
private inferTypeCastType;
|
|
628
|
-
private isTypeCompatible;
|
|
629
|
-
private isSubtypeOf;
|
|
630
|
-
private isNumericType;
|
|
631
|
-
private inferValueType;
|
|
632
|
-
private resolveResultType;
|
|
633
|
-
private checkBinaryOperatorTypes;
|
|
634
|
-
private checkFunctionArgumentTypes;
|
|
635
|
-
private typeToString;
|
|
636
658
|
/**
|
|
637
|
-
*
|
|
659
|
+
* Parse and analyze a FHIRPath expression end-to-end, returning an AnalysisResult
|
|
660
|
+
* and structured diagnostics. Supports optional error recovery (LSP mode).
|
|
661
|
+
*/
|
|
662
|
+
static analyzeExpression(expression: string, options?: {
|
|
663
|
+
variables?: Record<string, unknown>;
|
|
664
|
+
modelProvider?: ModelProvider;
|
|
665
|
+
inputType?: TypeInfo;
|
|
666
|
+
errorRecovery?: boolean;
|
|
667
|
+
parserOptions?: ParserOptions;
|
|
668
|
+
}): Promise<AnalysisResultWithCursor>;
|
|
669
|
+
/**
|
|
670
|
+
* Main entry point for context-flow analysis.
|
|
671
|
+
* Analyzes a node with the given context.
|
|
638
672
|
*/
|
|
639
|
-
private
|
|
673
|
+
private analyzeNode;
|
|
640
674
|
/**
|
|
641
|
-
*
|
|
675
|
+
* Analyzes binary operators with special handling for union and dot.
|
|
642
676
|
*/
|
|
643
|
-
private
|
|
677
|
+
private analyzeBinary;
|
|
678
|
+
/**
|
|
679
|
+
* Analyzes function calls, delegating to function's analyze method if available.
|
|
680
|
+
*/
|
|
681
|
+
private analyzeFunction;
|
|
682
|
+
private getFunctionName;
|
|
683
|
+
private validateArity;
|
|
684
|
+
private validateUnionTypeFilters;
|
|
685
|
+
private analyzeArguments;
|
|
686
|
+
private matchAndDiagnoseSignature;
|
|
687
|
+
private propagatesEmpty;
|
|
688
|
+
private inferFunctionResultType;
|
|
689
|
+
/**
|
|
690
|
+
* Analyzes variable references, checking against context.
|
|
691
|
+
*/
|
|
692
|
+
private analyzeVariable;
|
|
693
|
+
/**
|
|
694
|
+
* Analyzes identifier nodes (property access).
|
|
695
|
+
*/
|
|
696
|
+
private analyzeIdentifier;
|
|
697
|
+
/**
|
|
698
|
+
* Analyzes literal values.
|
|
699
|
+
*/
|
|
700
|
+
private analyzeLiteral;
|
|
701
|
+
private analyzeTemporalLiteral;
|
|
702
|
+
/**
|
|
703
|
+
* Analyzes unary operators.
|
|
704
|
+
*/
|
|
705
|
+
private analyzeUnary;
|
|
706
|
+
/**
|
|
707
|
+
* Analyzes index operations.
|
|
708
|
+
*/
|
|
709
|
+
private analyzeIndex;
|
|
710
|
+
/**
|
|
711
|
+
* Analyzes quantity literals.
|
|
712
|
+
*/
|
|
713
|
+
private analyzeQuantity;
|
|
714
|
+
/**
|
|
715
|
+
* Analyzes collection literals.
|
|
716
|
+
*/
|
|
717
|
+
private analyzeCollection;
|
|
718
|
+
/**
|
|
719
|
+
* Analyzes membership test (is operator).
|
|
720
|
+
*/
|
|
721
|
+
private analyzeMembershipTest;
|
|
722
|
+
/**
|
|
723
|
+
* Analyzes type cast (as operator).
|
|
724
|
+
*/
|
|
725
|
+
private analyzeTypeCast;
|
|
726
|
+
/**
|
|
727
|
+
* Analyzes error nodes.
|
|
728
|
+
*/
|
|
729
|
+
private analyzeError;
|
|
730
|
+
/**
|
|
731
|
+
* Analyzes cursor nodes for completion.
|
|
732
|
+
*/
|
|
733
|
+
private analyzeCursorNode;
|
|
734
|
+
/**
|
|
735
|
+
* Helper to create diagnostic errors.
|
|
736
|
+
*/
|
|
737
|
+
private createError;
|
|
738
|
+
private createWarning;
|
|
739
|
+
/**
|
|
740
|
+
* Helper method to infer TypeInfo from runtime values (used for user variables).
|
|
741
|
+
*/
|
|
742
|
+
private inferValueType;
|
|
743
|
+
analyze(ast: ASTNode, userVariables?: Record<string, any>, inputType?: TypeInfo, options?: AnalyzerOptions): Promise<AnalysisResultWithCursor>;
|
|
644
744
|
}
|
|
645
745
|
|
|
646
746
|
interface FHIRModelContext {
|
|
@@ -707,7 +807,6 @@ declare class FHIRModelProvider implements ModelProvider<FHIRModelContext> {
|
|
|
707
807
|
getResourceTypes(): Promise<string[]>;
|
|
708
808
|
getComplexTypes(): Promise<string[]>;
|
|
709
809
|
getPrimitiveTypes(): Promise<string[]>;
|
|
710
|
-
getTypeFromCache(typeName: string): TypeInfo<FHIRModelContext> | undefined;
|
|
711
810
|
}
|
|
712
811
|
|
|
713
812
|
interface ASTMetadata {
|
|
@@ -769,6 +868,7 @@ declare const Errors: {
|
|
|
769
868
|
unknownNodeType(nodeType: string, location?: Range): FHIRPathError;
|
|
770
869
|
noEvaluatorFound(evaluatorType: string, name: string, location?: Range): FHIRPathError;
|
|
771
870
|
variableNotDefined(name: string, location?: Range): FHIRPathError;
|
|
871
|
+
variableAlreadyDefined(name: string, location?: Range): FHIRPathError;
|
|
772
872
|
wrongArgumentCount(funcName: string, expected: number, actual: number, location?: Range): FHIRPathError;
|
|
773
873
|
wrongArgumentCountRange(funcName: string, min: number, max: number, actual: number, location?: Range): FHIRPathError;
|
|
774
874
|
singletonRequired(funcName: string, actualCount: number, location?: Range): FHIRPathError;
|
|
@@ -798,6 +898,8 @@ declare const Errors: {
|
|
|
798
898
|
invalidPrecision(operation: string, location?: Range): FHIRPathError;
|
|
799
899
|
invalidStringOperation(operation: string, paramName: string, location?: Range): FHIRPathError;
|
|
800
900
|
invalidNumericOperation(operation: string, paramName: string, expectedType: string, location?: Range): FHIRPathError;
|
|
901
|
+
invalidTemporalUnit(temporalType: string, unit: string, location?: Range): FHIRPathError;
|
|
902
|
+
unsupportedTemporalUnitForType(temporalType: string, unit: string, location?: Range): FHIRPathError;
|
|
801
903
|
};
|
|
802
904
|
declare enum ErrorCodes {
|
|
803
905
|
UNKNOWN_OPERATOR = "FP1001",
|
|
@@ -813,7 +915,7 @@ declare enum ErrorCodes {
|
|
|
813
915
|
SINGLETON_REQUIRED = "FP2003",
|
|
814
916
|
EMPTY_NOT_ALLOWED = "FP2004",
|
|
815
917
|
ARGUMENT_REQUIRED = "FP2005",
|
|
816
|
-
OPERATOR_TYPE_MISMATCH = "
|
|
918
|
+
OPERATOR_TYPE_MISMATCH = "FP3006",
|
|
817
919
|
ARGUMENT_TYPE_MISMATCH = "FP3003",
|
|
818
920
|
CONVERSION_FAILED = "FP3004",
|
|
819
921
|
INVALID_VALUE_TYPE = "FP3005",
|
|
@@ -834,7 +936,11 @@ declare enum ErrorCodes {
|
|
|
834
936
|
INVALID_OPERATION = "FP6005",
|
|
835
937
|
INVALID_PRECISION = "FP6006",
|
|
836
938
|
INVALID_STRING_OPERATION = "FP6007",
|
|
837
|
-
INVALID_NUMERIC_OPERATION = "FP6008"
|
|
939
|
+
INVALID_NUMERIC_OPERATION = "FP6008",
|
|
940
|
+
VARIABLE_ALREADY_DEFINED = "FP6009",
|
|
941
|
+
INVALID_TEMPORAL_UNIT = "FP6010",
|
|
942
|
+
UNSUPPORTED_TEMPORAL_UNIT_FOR_TYPE = "FP6011",
|
|
943
|
+
UNREACHABLE_CODE = "FP7001"
|
|
838
944
|
}
|
|
839
945
|
|
|
840
946
|
/**
|
|
@@ -863,7 +969,7 @@ interface CompletionItem {
|
|
|
863
969
|
documentation?: string;
|
|
864
970
|
/** Text to insert (if different from label) */
|
|
865
971
|
insertText?: string;
|
|
866
|
-
/** Sort
|
|
972
|
+
/** Sort text for ordering (if different from label) */
|
|
867
973
|
sortText?: string;
|
|
868
974
|
}
|
|
869
975
|
/**
|