@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.
Files changed (143) hide show
  1. package/README.md +716 -238
  2. package/dist/index.d.ts +225 -119
  3. package/dist/index.js +10911 -5600
  4. package/dist/index.js.map +1 -1
  5. package/package.json +9 -4
  6. package/src/analyzer/augmentor.ts +242 -0
  7. package/src/analyzer/cursor-services.ts +75 -0
  8. package/src/analyzer/scope-manager.ts +57 -0
  9. package/src/analyzer/trivia-indexer.ts +58 -0
  10. package/src/analyzer/type-compat.ts +157 -0
  11. package/src/analyzer/utils.ts +132 -0
  12. package/src/analyzer.ts +921 -1208
  13. package/src/completion-provider.ts +209 -191
  14. package/src/{quantity-value.ts → complex-types/quantity-value.ts} +112 -22
  15. package/src/complex-types/temporal.ts +1737 -0
  16. package/src/errors.ts +25 -3
  17. package/src/index.ts +17 -104
  18. package/src/inspect.ts +4 -4
  19. package/src/{boxing.ts → interpreter/boxing.ts} +1 -1
  20. package/src/interpreter/navigator.ts +94 -0
  21. package/src/interpreter/runtime-context.ts +273 -0
  22. package/src/interpreter.ts +435 -469
  23. package/src/lexer.ts +188 -210
  24. package/src/model-provider.ts +71 -43
  25. package/src/operations/abs-function.ts +1 -1
  26. package/src/operations/aggregate-function.ts +84 -5
  27. package/src/operations/all-function.ts +4 -3
  28. package/src/operations/allFalse-function.ts +2 -1
  29. package/src/operations/allTrue-function.ts +2 -1
  30. package/src/operations/and-operator.ts +2 -1
  31. package/src/operations/anyFalse-function.ts +2 -1
  32. package/src/operations/anyTrue-function.ts +2 -1
  33. package/src/operations/as-function.ts +58 -0
  34. package/src/operations/as-operator.ts +57 -19
  35. package/src/operations/ceiling-function.ts +1 -1
  36. package/src/operations/children-function.ts +14 -5
  37. package/src/operations/combine-function.ts +6 -3
  38. package/src/operations/combine-operator.ts +6 -7
  39. package/src/operations/comparison.ts +692 -0
  40. package/src/operations/contains-function.ts +1 -1
  41. package/src/operations/contains-operator.ts +2 -1
  42. package/src/operations/convertsToBoolean-function.ts +78 -0
  43. package/src/operations/convertsToDecimal-function.ts +82 -0
  44. package/src/operations/convertsToInteger-function.ts +71 -0
  45. package/src/operations/convertsToLong-function.ts +89 -0
  46. package/src/operations/convertsToQuantity-function.ts +116 -0
  47. package/src/operations/convertsToString-function.ts +88 -0
  48. package/src/operations/count-function.ts +2 -1
  49. package/src/operations/dateOf-function.ts +69 -0
  50. package/src/operations/dayOf-function.ts +66 -0
  51. package/src/operations/decimal-boundaries.ts +133 -0
  52. package/src/operations/defineVariable-function.ts +130 -17
  53. package/src/operations/distinct-function.ts +1 -1
  54. package/src/operations/div-operator.ts +1 -1
  55. package/src/operations/divide-operator.ts +12 -7
  56. package/src/operations/dot-operator.ts +1 -1
  57. package/src/operations/empty-function.ts +30 -21
  58. package/src/operations/endsWith-function.ts +6 -1
  59. package/src/operations/equal-operator.ts +23 -32
  60. package/src/operations/equivalent-operator.ts +13 -53
  61. package/src/operations/exclude-function.ts +2 -1
  62. package/src/operations/exists-function.ts +4 -3
  63. package/src/operations/first-function.ts +1 -1
  64. package/src/operations/floor-function.ts +1 -1
  65. package/src/operations/greater-operator.ts +20 -3
  66. package/src/operations/greater-or-equal-operator.ts +20 -3
  67. package/src/operations/highBoundary-function.ts +120 -0
  68. package/src/operations/hourOf-function.ts +66 -0
  69. package/src/operations/iif-function.ts +186 -7
  70. package/src/operations/implies-operator.ts +1 -1
  71. package/src/operations/in-operator.ts +2 -1
  72. package/src/operations/index.ts +41 -0
  73. package/src/operations/indexOf-function.ts +1 -1
  74. package/src/operations/intersect-function.ts +1 -1
  75. package/src/operations/is-function.ts +59 -0
  76. package/src/operations/is-operator.ts +20 -9
  77. package/src/operations/isDistinct-function.ts +2 -1
  78. package/src/operations/join-function.ts +1 -1
  79. package/src/operations/last-function.ts +1 -1
  80. package/src/operations/lastIndexOf-function.ts +85 -0
  81. package/src/operations/length-function.ts +1 -1
  82. package/src/operations/less-operator.ts +20 -3
  83. package/src/operations/less-or-equal-operator.ts +20 -3
  84. package/src/operations/less-than.ts +2 -2
  85. package/src/operations/lowBoundary-function.ts +120 -0
  86. package/src/operations/lower-function.ts +1 -1
  87. package/src/operations/matches-function.ts +86 -0
  88. package/src/operations/matchesFull-function.ts +96 -0
  89. package/src/operations/millisecondOf-function.ts +66 -0
  90. package/src/operations/minus-operator.ts +69 -4
  91. package/src/operations/minuteOf-function.ts +66 -0
  92. package/src/operations/mod-operator.ts +1 -1
  93. package/src/operations/monthOf-function.ts +66 -0
  94. package/src/operations/multiply-operator.ts +27 -3
  95. package/src/operations/not-equal-operator.ts +24 -30
  96. package/src/operations/not-equivalent-operator.ts +13 -53
  97. package/src/operations/not-function.ts +1 -1
  98. package/src/operations/ofType-function.ts +8 -12
  99. package/src/operations/or-operator.ts +2 -1
  100. package/src/operations/plus-operator.ts +71 -7
  101. package/src/operations/power-function.ts +35 -10
  102. package/src/operations/repeat-function.ts +169 -0
  103. package/src/operations/replace-function.ts +1 -1
  104. package/src/operations/replaceMatches-function.ts +120 -0
  105. package/src/operations/round-function.ts +1 -1
  106. package/src/operations/secondOf-function.ts +66 -0
  107. package/src/operations/select-function.ts +66 -5
  108. package/src/operations/single-function.ts +1 -1
  109. package/src/operations/skip-function.ts +1 -1
  110. package/src/operations/split-function.ts +1 -1
  111. package/src/operations/sqrt-function.ts +15 -8
  112. package/src/operations/startsWith-function.ts +1 -1
  113. package/src/operations/subsetOf-function.ts +6 -2
  114. package/src/operations/substring-function.ts +1 -1
  115. package/src/operations/supersetOf-function.ts +6 -2
  116. package/src/operations/tail-function.ts +1 -1
  117. package/src/operations/take-function.ts +1 -1
  118. package/src/operations/temporal-functions.ts +555 -0
  119. package/src/operations/timeOf-function.ts +67 -0
  120. package/src/operations/timezoneOffsetOf-function.ts +69 -0
  121. package/src/operations/toBoolean-function.ts +27 -8
  122. package/src/operations/toChars-function.ts +56 -0
  123. package/src/operations/toDecimal-function.ts +27 -8
  124. package/src/operations/toInteger-function.ts +15 -3
  125. package/src/operations/toLong-function.ts +98 -0
  126. package/src/operations/toQuantity-function.ts +181 -0
  127. package/src/operations/toString-function.ts +45 -3
  128. package/src/operations/trace-function.ts +1 -1
  129. package/src/operations/trim-function.ts +1 -1
  130. package/src/operations/truncate-function.ts +1 -1
  131. package/src/operations/unary-minus-operator.ts +2 -2
  132. package/src/operations/unary-plus-operator.ts +1 -1
  133. package/src/operations/union-function.ts +1 -1
  134. package/src/operations/union-operator.ts +16 -26
  135. package/src/operations/upper-function.ts +1 -1
  136. package/src/operations/where-function.ts +3 -3
  137. package/src/operations/xor-operator.ts +1 -1
  138. package/src/operations/yearOf-function.ts +66 -0
  139. package/src/{cursor-nodes.ts → parser/cursor-nodes.ts} +10 -7
  140. package/src/parser.ts +248 -501
  141. package/src/registry.ts +53 -42
  142. package/src/types.ts +128 -16
  143. 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 | TypeOrIdentifierNode | LiteralNode | BinaryNode | UnaryNode | FunctionNode | VariableNode | IndexNode | MembershipTestNode | TypeCastNode | CollectionNode | TypeReferenceNode | QuantityNode | ErrorNode;
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[], startToken: Token): FunctionNode;
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, isCalendarUnit: boolean, startToken: Token, endToken: Token): QuantityNode;
462
- protected handleError(message: string, token?: Token): never;
463
- private enrichNodeForLSP;
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): FunctionDefinition[];
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
- isFunctionApplicableToType(functionName: string, typeName: TypeName | string): boolean;
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
- * Infer the expected type at a cursor position based on context
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 inferExpectedTypeForCursor;
673
+ private analyzeNode;
640
674
  /**
641
- * Annotate AST with type information
675
+ * Analyzes binary operators with special handling for union and dot.
642
676
  */
643
- private annotateAST;
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 = "FP3002",
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 order */
972
+ /** Sort text for ordering (if different from label) */
867
973
  sortText?: string;
868
974
  }
869
975
  /**