pinets 0.9.13 → 0.9.15

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.
@@ -132,7 +132,35 @@ export declare class Context {
132
132
  * @param value - The value to set
133
133
  */
134
134
  set(target: any, value: any): void;
135
+ /**
136
+ * Resolve an iterable for `for x in collection` codegen.
137
+ * Handles PineArrayObject (unwrap to inner JS array) and plain JS arrays uniformly.
138
+ * Returns the value itself if it's already iterable (Map, Set, etc.).
139
+ *
140
+ * Centralizing this here means the transpiler can emit a uniform shape regardless of
141
+ * whether the iterable is a built-in returning a plain array (e.g. box.all) or a UDT
142
+ * field holding a PineArrayObject — and future collection types only need to update
143
+ * this helper, not the codegen.
144
+ */
145
+ iter(source: any): any;
146
+ /**
147
+ * Resolve an iterable yielding [index, value] tuples for `for [i, x] in collection`
148
+ * destructuring codegen. PineArrayObject's [Symbol.iterator] yields scalar values, so
149
+ * we must explicitly call `.entries()` on the underlying array.
150
+ */
151
+ entries(source: any): IterableIterator<[number, any]>;
135
152
  private _callStack;
153
+ /**
154
+ * Cumulative call-path stack. Each entry is the full path from the root to
155
+ * the current call, formed by joining the syntactic call-site ids with '|'.
156
+ *
157
+ * Pine semantics is per-call-PATH (not per-syntactic-call-site): a function
158
+ * with internal `var` state, called via two distinct paths through a wrapper,
159
+ * must keep state independent per path. Keying lctx by the path (rather than
160
+ * the immediate site id) makes `$$.var.*` slots and `$$.id + '_taN'` ta
161
+ * callsite ids correctly path-scoped without any transpiler changes.
162
+ */
163
+ private _pathStack;
136
164
  /**
137
165
  * Pushes a call ID onto the stack
138
166
  * @param id - The call ID
@@ -143,7 +171,8 @@ export declare class Context {
143
171
  */
144
172
  popId(): void;
145
173
  /**
146
- * Returns the current call ID from the top of the stack
174
+ * Returns the current call PATH (cumulative ids joined by '|') from the top
175
+ * of the stack. Used as the lctx key for the current function call.
147
176
  */
148
177
  peekId(): string;
149
178
  /**
@@ -1,4 +1,3 @@
1
- import { PineTypeObject } from './PineTypeObject';
2
1
  import type { IndicatorOptions } from '../types/PineTypes';
3
2
  export declare function parseIndicatorOptions(args: any[]): Partial<IndicatorOptions>;
4
3
  /**
@@ -84,8 +83,5 @@ export declare class Core {
84
83
  int(series: any): number;
85
84
  float(series: any): number;
86
85
  string(series: any): any;
87
- Type(definition: Record<string, string | [string, any]>): {
88
- new: (...args: any[]) => PineTypeObject;
89
- copy: (object: PineTypeObject) => PineTypeObject;
90
- };
86
+ Type(definition: Record<string, string | [string, any]>): any;
91
87
  }
@@ -2,7 +2,19 @@ export declare class PineTypeObject {
2
2
  private _definition;
3
3
  context: any;
4
4
  get __def__(): Record<string, string>;
5
- constructor(_definition: Record<string, string>, context: any);
5
+ /**
6
+ * Back-reference to the UDT factory that produced this instance.
7
+ * Used by `request.security_lower_tf`'s pure-builtin fast path to
8
+ * detect UDTs whose field defaults are all bare price builtins
9
+ * (e.g. `type candle { float o = open; float h = high; … }`) — when
10
+ * detected, the secondary's per-LTF-bar values can be synthesised
11
+ * directly from the candle stream without running any user script.
12
+ * Optional and nullable: instances created outside `Type().new` (or
13
+ * for legacy / direct constructions) leave this undefined and the
14
+ * fast path simply doesn't engage.
15
+ */
16
+ _udt?: any;
17
+ constructor(_definition: Record<string, string>, context: any, _udt?: any);
6
18
  copy(): PineTypeObject;
7
19
  toString(): string;
8
20
  }
@@ -20,5 +20,11 @@ export declare class Str {
20
20
  match(source: string, pattern: string): RegExpMatchArray;
21
21
  split(source: string, separator: string): PineArrayObject;
22
22
  substring(source: string, begin_pos: number, end_pos: number): string;
23
+ /**
24
+ * Format a UNIX millisecond timestamp using Java SimpleDateFormat-style tokens
25
+ * (yyyy, MM, dd, HH, mm, ss, EEE, EEEE, MMM, MMMM, a, h, S, Z, etc.).
26
+ * Text inside single quotes is treated as a literal; '' produces a literal '.
27
+ */
28
+ format_time(time: any, format?: string, timezone?: string): string;
23
29
  format(message: string, ...args: any[]): string;
24
30
  }
@@ -10,9 +10,11 @@ export declare class BoxHelper {
10
10
  private _resolvePoint;
11
11
  private _resolve;
12
12
  /**
13
- * Resolve a color value, preserving NaN (na) so renderers can detect "no color".
14
- * The regular `_resolve(val) || fallback` pattern treats NaN as falsy and replaces
15
- * it with the default, losing the explicit `border_color = na` intent.
13
+ * Resolve a color value, preserving na markers so renderers can detect "no color".
14
+ * Pine emits na either as NaN (from `bgcolor = na`) or as null (from
15
+ * `bgcolor = color(na)` `color(na)` returns null per PineColor.any). Both
16
+ * must survive — replacing them with a default would force renderers to paint
17
+ * a visible color where the script asked for none.
16
18
  */
17
19
  private _resolveColor;
18
20
  private _createBox;
@@ -22,7 +24,7 @@ export declare class BoxHelper {
22
24
  */
23
25
  private _enforceMaxCount;
24
26
  new(...args: any[]): BoxObject;
25
- any(...args: any[]): BoxObject;
27
+ any(...args: any[]): BoxObject | null;
26
28
  set_left(id: BoxObject, left: number): void;
27
29
  set_right(id: BoxObject, right: number): void;
28
30
  set_top(id: BoxObject, top: number): void;
@@ -17,7 +17,7 @@ export declare class LabelHelper {
17
17
  private _createLabel;
18
18
  private _enforceMaxCount;
19
19
  new(...args: any[]): LabelObject;
20
- any(...args: any[]): LabelObject;
20
+ any(...args: any[]): LabelObject | null;
21
21
  set_x(id: LabelObject, x: number): void;
22
22
  set_y(id: LabelObject, y: number): void;
23
23
  set_xy(id: LabelObject, x: number, y: number): void;
@@ -18,7 +18,7 @@ export declare class LineHelper {
18
18
  private _createLine;
19
19
  private _enforceMaxCount;
20
20
  new(...args: any[]): LineObject;
21
- any(...args: any[]): LineObject;
21
+ any(...args: any[]): LineObject | null;
22
22
  set_x1(id: LineObject, x: number): void;
23
23
  set_y1(id: LineObject, y: number): void;
24
24
  set_x2(id: LineObject, x: number): void;
@@ -12,7 +12,7 @@ export declare class LinefillHelper {
12
12
  */
13
13
  private _resolve;
14
14
  new(line1: LineObject, line2: LineObject, color: any): LinefillObject;
15
- any(...args: any[]): LinefillObject;
15
+ any(...args: any[]): LinefillObject | null;
16
16
  set_color(id: LinefillObject, color: any): void;
17
17
  get_line1(id: LinefillObject): LineObject | undefined;
18
18
  get_line2(id: LinefillObject): LineObject | undefined;
@@ -11,8 +11,9 @@ export declare class PolylineHelper {
11
11
  */
12
12
  private _resolve;
13
13
  /**
14
- * Resolve a color value, preserving NaN (na = no color) instead of
15
- * letting it fall through to a default via the || operator.
14
+ * Resolve a color value, preserving na markers (NaN from `na`, null from
15
+ * `color(na)`) so renderers can detect "no color" instead of forcing a
16
+ * default via the `||` operator.
16
17
  */
17
18
  private _resolveColor;
18
19
  /**
@@ -21,7 +22,7 @@ export declare class PolylineHelper {
21
22
  private _extractPoints;
22
23
  new(...args: any[]): PolylineObject;
23
24
  private _enforceMaxCount;
24
- any(...args: any[]): PolylineObject;
25
+ any(...args: any[]): PolylineObject | null;
25
26
  delete(id: PolylineObject): void;
26
27
  get all(): PolylineObject[];
27
28
  /**
@@ -1 +1 @@
1
- export declare function security(context: any): (symbol: any, timeframe: any, expression: any, gaps?: boolean | any[], lookahead?: boolean | any[], ignore_invalid_symbol?: boolean, currency?: any, calc_bars_count?: any) => Promise<any>;
1
+ export declare function security(context: any): (...rawArgs: any[]) => Promise<any>;
@@ -7,4 +7,4 @@ import { PineArrayObject } from '../../array/PineArrayObject';
7
7
  * @param context
8
8
  * @returns
9
9
  */
10
- export declare function security_lower_tf(context: any): (symbol: any, timeframe: any, expression: any, ignore_invalid_symbol?: boolean | any[], currency?: any, ignore_invalid_timeframe?: boolean | any[], calc_bars_count?: number | any[]) => Promise<number | PineArrayObject | any[][]>;
10
+ export declare function security_lower_tf(context: any): (...rawArgs: any[]) => Promise<number | PineArrayObject | any[][]>;
@@ -0,0 +1,31 @@
1
+ /**
2
+ * `@silentInSecondary` — method decorator.
3
+ *
4
+ * Marks a helper method as a no-op when invoked on a secondary context
5
+ * (i.e. the auxiliary PineTS instance that `request.security` /
6
+ * `request.security_lower_tf` spawns to compute the captured expression
7
+ * at another symbol/timeframe).
8
+ *
9
+ * Drawings, plots, alerts and similar side-effect-only operations are
10
+ * never observable from a secondary context — its sole job is to populate
11
+ * `secContext.params[expression_name]` with the value of the captured
12
+ * expression bar-by-bar. Silencing those operations on secondaries cuts
13
+ * the per-bar work substantially without changing the captured value
14
+ * (the only output that callers ever read).
15
+ *
16
+ * Constructor-style methods (e.g. `label.new`, `line.new`, `box.new`)
17
+ * return `null`; setters / mutators / deletes return `undefined`. The
18
+ * existing helper code is null-safe end-to-end:
19
+ * - `get_*` methods already return `NaN`/`""` when the receiver is null.
20
+ * - The transpiler emits method calls on UDT-typed receivers as
21
+ * `obj?.method?.(...)`, so `null?.set_x1?.(...)` short-circuits.
22
+ * - Built-in setters like `LineHelper.set_x1(id, x)` already guard
23
+ * `if (id && !id._deleted) ...` and no-op on null.
24
+ *
25
+ * Pre-condition: target classes use the conventional
26
+ * `constructor(private context: any) {}`
27
+ * shape, so `this.context.isSecondaryContext` is uniformly accessible.
28
+ * (`Core.ts` `AlertHelper`, `Plots.ts` `PlotHelper`/`HlineHelper`/
29
+ * `FillHelper`, and the drawing helpers all conform.)
30
+ */
31
+ export declare function silentInSecondary(_target: any, _propertyKey: string, descriptor: PropertyDescriptor): PropertyDescriptor;
@@ -8,7 +8,7 @@ export declare class TableHelper {
8
8
  syncToPlot(): void;
9
9
  private _resolve;
10
10
  new(...args: any[]): TableObject;
11
- any(...args: any[]): TableObject;
11
+ any(...args: any[]): TableObject | null;
12
12
  cell(...args: any[]): void;
13
13
  delete(id: TableObject): void;
14
14
  clear(...args: any[]): void;
@@ -1,5 +1,23 @@
1
1
  import ScopeManager from './ScopeManager';
2
2
  export declare function transformNestedArrowFunctions(ast: any): void;
3
+ /**
4
+ * Pre-walk the AST to populate the UDT registry on the ScopeManager.
5
+ *
6
+ * Two registries are populated:
7
+ * 1. UDT type names — collected from `const X = Type({field: ['type', default], ...})`
8
+ * which pine2js emits from Pine `type X` declarations. The field-type metadata
9
+ * is stored alongside (V2 data model) for future use-site type-aware rewrites.
10
+ *
11
+ * 2. UDT instance variables — variables initialized via `<X>.new(...)` or
12
+ * `<X>.copy(...)` where X ∈ udtTypeNames. Each instance is tagged with its
13
+ * UDT type name (V2 shape).
14
+ *
15
+ * The instance check intentionally consults `isUdtTypeName(X)` rather than just
16
+ * "X is an Identifier", so built-in factory calls like `array.from(...)`,
17
+ * `polyline.new(...)`, `chart.point.from_index(...)` are excluded — those are
18
+ * handled by their own runtime layers and must NOT be treated as UDT instances.
19
+ */
20
+ export declare function preProcessUdtRegistry(ast: any, scopeManager: ScopeManager): void;
3
21
  export declare function preProcessContextBoundVars(ast: any, scopeManager: ScopeManager): void;
4
22
  export declare function transformArrowFunctionParams(node: any, scopeManager: ScopeManager, isRootFunction?: boolean): void;
5
23
  export declare function runAnalysisPass(ast: any, scopeManager: ScopeManager): string | undefined;
@@ -22,6 +22,72 @@ export declare class ScopeManager {
22
22
  private reservedNames;
23
23
  private userFunctions;
24
24
  private userMethods;
25
+ /**
26
+ * Regular user-declared functions (i.e. NOT methods). Tracked separately
27
+ * from `userFunctions` so a UFCS-style direct call to a method-only
28
+ * declaration (`foo(receiver, args)` where `foo` was declared as
29
+ * `method foo(...)`) can be retargeted to the prefixed JS name.
30
+ *
31
+ * If a Pine name has both a regular function and a method form, the
32
+ * regular function takes precedence for direct `name(args)` calls and
33
+ * the method is reachable via dot-syntax `obj.name(args)`.
34
+ */
35
+ private regularUserFunctions;
36
+ /**
37
+ * Registry of user-defined UDT type names → their field map (fieldName → fieldType).
38
+ * Populated from `const X = Type({fieldA: ['type', default], ...})` declarations
39
+ * (which pine2js emits from Pine `type X` declarations).
40
+ *
41
+ * V2 data model: stores field-type metadata. V1 logic only consults
42
+ * `isUdtTypeName` for now; field metadata is ready for future use-site
43
+ * type-aware rewrites (nested UDT chains, mixed scalar/array fields, etc.).
44
+ */
45
+ private udtTypeNames;
46
+ /**
47
+ * Registry of user variables that hold UDT instances → the UDT type name.
48
+ * Populated from `let bar = X.new(...)` / `bar = X.copy(...)` where
49
+ * `X ∈ udtTypeNames`. Stores the type name (V2 shape) so future passes
50
+ * can do typed-field lookups via `getUdtTypeFields(typeName)` without
51
+ * a refactor. V1 logic only consults `isUdtInstance`.
52
+ */
53
+ private udtInstances;
54
+ /**
55
+ * Registry of user-defined function names → UDT type they return.
56
+ * Populated by inspecting each FunctionDeclaration's return paths during
57
+ * the UDT pre-pass. A function is registered only when ALL return paths
58
+ * unambiguously produce the SAME UDT type.
59
+ *
60
+ * Used by the instance populator so that `bar = makeBar()` registers
61
+ * `bar` as a UDT instance when `makeBar` is known to return one.
62
+ */
63
+ private functionReturnTypes;
64
+ /**
65
+ * Registry of user-defined function names → tuple of UDT type names they
66
+ * return. Each slot holds either the UDT type name at that position, or
67
+ * `undefined` when that position is not (unambiguously) a UDT instance.
68
+ *
69
+ * Populated when ALL return paths of a function are ArrayExpressions of
70
+ * the SAME length and each position resolves to the SAME UDT (or to
71
+ * something non-UDT, which becomes `undefined`).
72
+ *
73
+ * Used by the instance populator so that `[a, b] = makeBars()` registers
74
+ * `a` and `b` as UDT instances at their respective tuple positions.
75
+ */
76
+ private functionReturnTupleTypes;
77
+ /**
78
+ * Registry of user-defined function names → map of {paramName → UDT type}.
79
+ * Populated from `<funcName>.__pineParamTypes__ = {...}` markers emitted
80
+ * by pine2js codegen for parameters that carried a Pine type annotation
81
+ * (e.g. `readField(BAR b)`). Filtered to UDT-known types so non-UDT
82
+ * annotations like `int` / `float` / `string` never enter the map.
83
+ *
84
+ * Consumed by `transformFunctionDeclaration`: when entering a function's
85
+ * body, each typed param is temporarily registered as a UDT instance
86
+ * (`markVariableAsUdtInstance`) so the use-site rewrite for `b.field[N]`
87
+ * fires inside the body. The registration is removed when leaving the
88
+ * function scope, keeping the global registry clean.
89
+ */
90
+ private functionParamUdtTypes;
25
91
  get nextParamIdArg(): any;
26
92
  get nextCacheIdArg(): any;
27
93
  getNextTACallId(): any;
@@ -33,10 +99,53 @@ export declare class ScopeManager {
33
99
  pushScope(type: string): void;
34
100
  popScope(): void;
35
101
  getCurrentScopeType(): string;
102
+ /**
103
+ * True when any active scope on the stack is a function scope.
104
+ * Different from `getCurrentScopeType() === 'fn'`, which only matches
105
+ * the immediate scope — code inside a nested `if`/`for`/`while` inside
106
+ * a function body still needs the function-scope context (e.g. for
107
+ * call-path-keyed param/ta-callsite ids).
108
+ */
109
+ isInsideFunctionScope(): boolean;
36
110
  getCurrentScopeCount(): number;
37
111
  addLocalSeriesVar(name: string): void;
38
112
  removeLocalSeriesVar(name: string): void;
39
113
  isLocalSeriesVar(name: string): boolean;
114
+ addUdtTypeName(typeName: string, fields?: Record<string, string>): void;
115
+ isUdtTypeName(name: string): boolean;
116
+ getUdtTypeFields(typeName: string): Record<string, string> | undefined;
117
+ markVariableAsUdtInstance(varName: string, typeName: string): void;
118
+ getVariableUdtType(varName: string): string | undefined;
119
+ isUdtInstance(varName: string): boolean;
120
+ /**
121
+ * Record a user-defined function as returning a specific UDT type.
122
+ * Idempotent — re-registering with the same type is a no-op; conflicting
123
+ * registrations (different type) drop back to "unknown" by removing the
124
+ * entry, so an ambiguous function never falsely promotes a caller.
125
+ */
126
+ setFunctionReturnType(funcName: string, typeName: string): void;
127
+ getFunctionReturnType(funcName: string): string | undefined;
128
+ /**
129
+ * Record a user-defined function as returning a tuple whose positions
130
+ * carry specific UDT types (or `undefined` for non-UDT positions).
131
+ * Idempotent — re-registering with the same shape is a no-op; conflicting
132
+ * registrations (different length OR different type at any position) drop
133
+ * the entry, so an ambiguous function never falsely promotes a caller.
134
+ */
135
+ setFunctionReturnTupleType(funcName: string, tupleTypes: (string | undefined)[]): void;
136
+ getFunctionReturnTupleType(funcName: string): (string | undefined)[] | undefined;
137
+ /**
138
+ * Record a user-defined function's UDT-typed parameters. The argument
139
+ * is a `paramName → UDT type` map filtered down to UDT-known types only.
140
+ */
141
+ setFunctionParamUdtTypes(funcName: string, paramTypes: Record<string, string>): void;
142
+ getFunctionParamUdtTypes(funcName: string): Record<string, string> | undefined;
143
+ /**
144
+ * Remove a previously-registered UDT instance entry. Used to roll back
145
+ * scope-local registrations (e.g. UDT-typed function parameters) when
146
+ * leaving the function body, so the global registry stays clean.
147
+ */
148
+ unmarkVariableAsUdtInstance(varName: string): void;
40
149
  addContextBoundVar(name: string, isRootParam?: boolean): void;
41
150
  removeContextBoundVar(name: any): void;
42
151
  addArrayPatternElement(name: string): void;
@@ -52,6 +161,8 @@ export declare class ScopeManager {
52
161
  isUserFunction(name: string): boolean;
53
162
  addUserMethod(name: string): void;
54
163
  isUserMethod(name: string): boolean;
164
+ addRegularUserFunction(name: string): void;
165
+ isRegularUserFunction(name: string): boolean;
55
166
  addVariable(name: string, kind: string): string;
56
167
  getVariable(name: string): [string, string];
57
168
  /**
@@ -16,27 +16,45 @@ export declare class CodeGenerator {
16
16
  generate(ast: any): string;
17
17
  private preProcessAST;
18
18
  /**
19
- * Scan the program body for variable declarations and assignments whose
20
- * names collide with Pine namespace/built-in names (e.g., `fill`, `size`,
21
- * `color`, `line`). Rename them with a `_$N` suffix so they don't shadow
22
- * the namespace destructured from `$.pine`.
19
+ * Scan the program body for declarations whose names would collide with
20
+ * either Pine namespaces or JavaScript reserved keywords. Rename them
21
+ * with a `_$N` suffix.
23
22
  *
24
- * Only renames **user variables** function parameters are handled
25
- * separately in generateFunctionDeclaration().
23
+ * Two collision classes, one rename pass:
26
24
  *
27
- * Renaming rules:
28
- * - Variable declaration target (let fill = ...) → renamed
29
- * - Assignment target (fill := ...) renamed
30
- * - Bare identifier read (return fill) renamed
31
- * - Call callee (fill(...)) → NOT renamed (namespace call)
32
- * - MemberExpression object (size.tiny) NOT renamed (namespace access)
33
- * - MemberExpression property (array.size) NOT renamed (method name)
34
- * - Object property key ({size: ...}) → NOT renamed (named arg key)
25
+ * 1. Pine namespace collisions (NAMESPACE_COLLISION_NAMES — e.g. `fill`,
26
+ * `size`, `color`, `line`): user variable would shadow the namespace
27
+ * destructured from `$.pine`. The CALL SITE `fill(...)` is the
28
+ * namespace, NOT the renamed variable, so callees are NOT renamed.
29
+ *
30
+ * 2. JS reserved keyword collisions (JS_RESERVED_WORDS e.g. `delete`,
31
+ * `super`, `static`): the generated JS would fail to parse
32
+ * (`function delete()`"Unexpected keyword 'delete'"). The CALL SITE
33
+ * `delete(arg)` IS the user function, so callees MUST be renamed.
34
+ *
35
+ * The walker checks the original name's source list at each call site to
36
+ * pick the right behavior.
37
+ *
38
+ * Renaming rules (common):
39
+ * - Variable declaration target (let fill = ...) → renamed
40
+ * - Function declaration name (function delete()) → renamed (class 2 only)
41
+ * - Assignment target (fill := ...) → renamed
42
+ * - Bare identifier read (return fill) → renamed
43
+ * - MemberExpression object (size.tiny) → NOT renamed
44
+ * - MemberExpression property (obj.delete) → NOT renamed
45
+ * - Object property key ({size: ...}) → NOT renamed
35
46
  */
36
47
  private renameConflictingVariables;
37
48
  /**
38
- * Walk the AST and collect variable declarations / assignment targets
39
- * whose names conflict with CONFLICTING_NAMES.
49
+ * True if `name` requires renaming either a Pine namespace collision
50
+ * or a JS reserved keyword (which would make the generated JS invalid).
51
+ */
52
+ private isReservedName;
53
+ /**
54
+ * Walk the AST and collect declarations whose names conflict with either
55
+ * Pine namespaces (NAMESPACE_COLLISION_NAMES) or JS reserved keywords
56
+ * (JS_RESERVED_WORDS). Both collision classes are renamed with the same
57
+ * `_$N` suffix scheme.
40
58
  */
41
59
  private collectConflictingVarNames;
42
60
  /**
@@ -58,6 +76,7 @@ export declare class CodeGenerator {
58
76
  generateStatement(node: any): void;
59
77
  generateTypeDefinition(node: any): void;
60
78
  private renameIdentifiersInAST;
79
+ private renameParamRefsInBody;
61
80
  generateFunctionDeclaration(node: any): void;
62
81
  generateVariableDeclaration(node: any): void;
63
82
  generateExpressionStatement(node: any): void;
@@ -14,6 +14,14 @@ export declare class Lexer {
14
14
  tokenize(): Token[];
15
15
  handleNewline(): void;
16
16
  handleIndentation(): void;
17
+ /**
18
+ * True when the most recently emitted token (skipping NEWLINE / COMMENT
19
+ * — those are layout, not content) is a token that requires a right-
20
+ * hand-side and therefore implies the next non-blank line is a
21
+ * continuation, not a new block. Mirrors the set the parser's
22
+ * `peekOperatorEx` already crosses NEWLINE for.
23
+ */
24
+ private isContinuationFromPrevToken;
17
25
  readComment(): void;
18
26
  readString(): void;
19
27
  readColorLiteral(): void;
@@ -4,12 +4,21 @@ export declare class Parser {
4
4
  private tokens;
5
5
  private pos;
6
6
  private functionNames;
7
+ private paramScopes;
7
8
  private noLineContinuation;
8
9
  constructor(tokens: Token[]);
9
10
  peek(offset?: number): Token;
11
+ private isCurrentFunctionParam;
10
12
  advance(): Token;
11
13
  match(type: any, value?: any): boolean;
12
14
  expect(type: any, value?: any): Token;
15
+ private static readonly CONTEXTUAL_KEYWORDS;
16
+ /**
17
+ * Consume an identifier OR a contextual keyword used as an identifier.
18
+ * Used in positions where Pine permits soft keywords as names — most notably
19
+ * UDT field names like `int type = 0`.
20
+ */
21
+ expectIdentifierOrContextual(): Token;
13
22
  matchEx(type: any, value?: any, allowLineContinuation?: boolean): boolean;
14
23
  peekOperatorEx(validOps: string[]): any;
15
24
  skipNewlines(allowIndent?: boolean): void;
@@ -3,6 +3,7 @@ export declare const NAMESPACES_LIKE: string[];
3
3
  export declare const ASYNC_METHODS: string[];
4
4
  export declare const FACTORY_METHODS: string[];
5
5
  export declare const NAMESPACE_COLLISION_NAMES: Set<string>;
6
+ export declare const JS_RESERVED_WORDS: Set<string>;
6
7
  export declare const CONTEXT_DATA_VARS: string[];
7
8
  export declare const CONTEXT_PINE_VARS: string[];
8
9
  export declare const CONTEXT_CORE_VARS: string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pinets",
3
- "version": "0.9.13",
3
+ "version": "0.9.15",
4
4
  "description": "Run Pine Script anywhere. PineTS is an open-source transpiler and runtime that brings Pine Script logic to Node.js and the browser with 1:1 syntax compatibility. Reliably write, port, and run indicators or strategies on your own infrastructure.",
5
5
  "keywords": [
6
6
  "Pine Script",