@witchcraft/expressit 0.2.2 → 0.3.0
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 +1 -2
- package/dist/Lexer.d.ts +99 -94
- package/dist/Lexer.d.ts.map +1 -1
- package/dist/Lexer.js +211 -559
- package/dist/Parser.d.ts +26 -26
- package/dist/Parser.d.ts.map +1 -1
- package/dist/Parser.js +2 -1
- package/dist/ast/builders/condition.d.ts +1 -1
- package/dist/ast/builders/condition.d.ts.map +1 -1
- package/dist/ast/builders/condition.js +1 -0
- package/dist/ast/builders/delim.d.ts +2 -2
- package/dist/ast/builders/delim.d.ts.map +1 -1
- package/dist/ast/builders/error.d.ts +2 -2
- package/dist/ast/builders/error.d.ts.map +1 -1
- package/dist/ast/builders/expression.d.ts +2 -2
- package/dist/ast/builders/expression.d.ts.map +1 -1
- package/dist/ast/builders/expression.js +2 -6
- package/dist/ast/builders/group.d.ts +1 -1
- package/dist/ast/builders/group.d.ts.map +1 -1
- package/dist/ast/builders/group.js +1 -3
- package/dist/ast/builders/pos.d.ts +2 -2
- package/dist/ast/builders/pos.d.ts.map +1 -1
- package/dist/ast/builders/token.d.ts +2 -2
- package/dist/ast/builders/token.d.ts.map +1 -1
- package/dist/ast/builders/type.d.ts +2 -2
- package/dist/ast/builders/type.d.ts.map +1 -1
- package/dist/ast/builders/variable.d.ts +3 -3
- package/dist/ast/builders/variable.d.ts.map +1 -1
- package/dist/ast/createConditionNode.d.ts +1 -1
- package/dist/ast/createConditionNode.d.ts.map +1 -1
- package/dist/ast/createGroupNode.d.ts +1 -1
- package/dist/ast/createGroupNode.d.ts.map +1 -1
- package/dist/ast/createToken.d.ts +2 -2
- package/dist/ast/createToken.d.ts.map +1 -1
- package/dist/ast/createToken.js +2 -2
- package/dist/ast/error.d.ts +2 -2
- package/dist/ast/error.d.ts.map +1 -1
- package/dist/ast/error.js +1 -0
- package/dist/ast/handlers.d.ts +23 -23
- package/dist/ast/handlers.d.ts.map +1 -1
- package/dist/ast/handlers.js +1 -1
- package/dist/examples/ParserWithSqlSupport.d.ts +5 -5
- package/dist/examples/ParserWithSqlSupport.d.ts.map +1 -1
- package/dist/examples/ParserWithSqlSupport.js +2 -0
- package/dist/index.js +2 -2
- package/dist/internal/ExpressitError.d.ts +2 -2
- package/dist/internal/ExpressitError.d.ts.map +1 -1
- package/dist/internal/checkParserOpts.js +11 -11
- package/dist/package.json.js +2 -60
- package/dist/types/ast.d.ts +60 -58
- package/dist/types/ast.d.ts.map +1 -1
- package/dist/types/ast.js +26 -27
- package/dist/types/autocomplete.d.ts +23 -21
- package/dist/types/autocomplete.d.ts.map +1 -1
- package/dist/types/autocomplete.js +24 -21
- package/dist/types/errors.d.ts +12 -10
- package/dist/types/errors.d.ts.map +1 -1
- package/dist/types/errors.js +8 -7
- package/dist/types/index.js +2 -2
- package/dist/types/parser.d.ts +3 -3
- package/dist/types/parser.d.ts.map +1 -1
- package/dist/utils/getCursorInfo.js +2 -0
- package/dist/utils/getOppositeDelimiter.d.ts +2 -2
- package/dist/utils/getOppositeDelimiter.d.ts.map +1 -1
- package/dist/utils/isDelimiter.d.ts +2 -2
- package/dist/utils/isDelimiter.d.ts.map +1 -1
- package/dist/utils/isParen.d.ts +2 -2
- package/dist/utils/isParen.d.ts.map +1 -1
- package/dist/utils/isQuote.d.ts +2 -2
- package/dist/utils/isQuote.d.ts.map +1 -1
- package/package.json +13 -13
- package/src/Lexer.ts +98 -88
- package/src/Parser.ts +61 -61
- package/src/ast/builders/condition.ts +3 -3
- package/src/ast/builders/delim.ts +4 -4
- package/src/ast/builders/error.ts +3 -3
- package/src/ast/builders/expression.ts +4 -8
- package/src/ast/builders/group.ts +2 -4
- package/src/ast/builders/pos.ts +3 -3
- package/src/ast/builders/token.ts +2 -2
- package/src/ast/builders/type.ts +2 -2
- package/src/ast/builders/variable.ts +5 -5
- package/src/ast/createConditionNode.ts +2 -2
- package/src/ast/createGroupNode.ts +4 -4
- package/src/ast/createToken.ts +6 -6
- package/src/ast/error.ts +2 -2
- package/src/ast/handlers.ts +20 -20
- package/src/examples/ParserWithSqlSupport.ts +11 -5
- package/src/internal/ExpressitError.ts +3 -3
- package/src/internal/checkParserOpts.ts +11 -11
- package/src/types/ast.ts +101 -96
- package/src/types/autocomplete.ts +26 -22
- package/src/types/errors.ts +18 -13
- package/src/types/parser.ts +3 -3
- package/src/utils/getOppositeDelimiter.ts +2 -2
- package/src/utils/getSurroundingErrors.ts +4 -4
- package/src/utils/isDelimiter.ts +3 -3
- package/src/utils/isParen.ts +2 -2
- package/src/utils/isQuote.ts +2 -2
package/src/Parser.ts
CHANGED
|
@@ -19,9 +19,9 @@ import { extractPosition } from "./internal/extractPosition.js"
|
|
|
19
19
|
import { getUnclosedRightParenCount } from "./internal/getUnclosedRightParenCount.js"
|
|
20
20
|
import { parseParserOptions } from "./internal/parseParserOptions.js"
|
|
21
21
|
import { unescape } from "./internal/unescape.js"
|
|
22
|
-
import { $C, $T, Lexer,type
|
|
23
|
-
import type { ArrayNode, ConditionNode, GroupNode, NormalizedCondition, NormalizedExpression, ParserResults,
|
|
24
|
-
import { type AnyToken, AST_TYPE,type Completion, type Position, type Suggestion,SUGGESTION_TYPE, TOKEN_TYPE } from "./types/index.js"
|
|
22
|
+
import { $C, type $CType, $T, type $TType, Lexer, type LexerCategoryToken, type LexerRealToken, type LexerToken,type Token } from "./Lexer.js"
|
|
23
|
+
import type { ArrayNode, ConditionNode, GroupNode, NormalizedCondition, NormalizedExpression, ParserResults, TokenBoolean, TokenType, ValidToken, VariableNode } from "./types/ast.js"
|
|
24
|
+
import { type AnyToken, AST_TYPE, type Completion, type Position, type Suggestion, SUGGESTION_TYPE, type SuggestionType,TOKEN_TYPE } from "./types/index.js"
|
|
25
25
|
import type { FullParserOptions, KeywordEntry, ParserOptions, ValidationQuery, ValueQuery } from "./types/parser.js"
|
|
26
26
|
import { extractTokens } from "./utils/extractTokens.js"
|
|
27
27
|
import { generateParentsMap } from "./utils/generateParentsMap.js"
|
|
@@ -52,7 +52,7 @@ const defaultNodeDirs = {
|
|
|
52
52
|
const createDefaultRequires = (partial: DeepPartial<Suggestion["requires"]> = {}): Suggestion["requires"] => ({
|
|
53
53
|
whitespace: {
|
|
54
54
|
...defaultNodeDirs,
|
|
55
|
-
...(partial.whitespace
|
|
55
|
+
...(partial.whitespace ?? {}),
|
|
56
56
|
},
|
|
57
57
|
group: partial.group ?? false,
|
|
58
58
|
prefix: partial.prefix ?? false,
|
|
@@ -62,7 +62,7 @@ const createDefaultRequires = (partial: DeepPartial<Suggestion["requires"]> = {}
|
|
|
62
62
|
const tokenRequiresWhitespace = (valid: ValidToken | undefined, whitespace: boolean, wordOps: KeywordEntry[]): boolean => {
|
|
63
63
|
if (whitespace || valid === undefined) return false
|
|
64
64
|
return valid.type === TOKEN_TYPE.VALUE ||
|
|
65
|
-
([TOKEN_TYPE.AND, TOKEN_TYPE.OR, TOKEN_TYPE.NOT].includes(valid.type) &&
|
|
65
|
+
(([TOKEN_TYPE.AND, TOKEN_TYPE.OR, TOKEN_TYPE.NOT] as string[]).includes(valid.type) &&
|
|
66
66
|
wordOps.find(_ => _.value === valid.value) !== undefined)
|
|
67
67
|
}
|
|
68
68
|
const tokenVariable = [TOKEN_TYPE.BACKTICK, TOKEN_TYPE.DOUBLEQUOTE, TOKEN_TYPE.SINGLEQUOTE, TOKEN_TYPE.VALUE, TOKEN_TYPE.REGEX]
|
|
@@ -96,9 +96,9 @@ export class Parser<T = any> {
|
|
|
96
96
|
|
|
97
97
|
private readonly lexer: Lexer
|
|
98
98
|
|
|
99
|
-
private readonly $: Record<$
|
|
99
|
+
private readonly $: Record<$TType, LexerRealToken<$TType>>
|
|
100
100
|
|
|
101
|
-
private readonly $categories: Partial<Record<$
|
|
101
|
+
private readonly $categories: Partial<Record<$CType, LexerCategoryToken<$CType>>>
|
|
102
102
|
|
|
103
103
|
private readonly info: Pick<ReturnType<Lexer["calculateSymbolInfo"]>, "expandedSepAlsoCustom" | "customOpAlsoNegation">
|
|
104
104
|
|
|
@@ -117,7 +117,7 @@ export class Parser<T = any> {
|
|
|
117
117
|
|
|
118
118
|
state: {
|
|
119
119
|
rawInput: string
|
|
120
|
-
lexedTokens: Token<$
|
|
120
|
+
lexedTokens: Token<$TType>[]
|
|
121
121
|
index: number
|
|
122
122
|
shift: number
|
|
123
123
|
} = {
|
|
@@ -131,7 +131,7 @@ export class Parser<T = any> {
|
|
|
131
131
|
* This is exposed mainly for debugging purposes. Use parse directly instead.
|
|
132
132
|
*/
|
|
133
133
|
lex(input: string): {
|
|
134
|
-
tokens: Token<$
|
|
134
|
+
tokens: Token<$TType> []
|
|
135
135
|
shift: number
|
|
136
136
|
rawInput: string
|
|
137
137
|
} {
|
|
@@ -168,7 +168,7 @@ export class Parser<T = any> {
|
|
|
168
168
|
parse(
|
|
169
169
|
input: string
|
|
170
170
|
| {
|
|
171
|
-
tokens: Token<$
|
|
171
|
+
tokens: Token<$TType> []
|
|
172
172
|
shift: number
|
|
173
173
|
rawInput: string
|
|
174
174
|
},
|
|
@@ -206,9 +206,9 @@ export class Parser<T = any> {
|
|
|
206
206
|
}
|
|
207
207
|
|
|
208
208
|
|
|
209
|
-
transformCategoryToken<TC extends $
|
|
209
|
+
transformCategoryToken<TC extends $CType>(
|
|
210
210
|
token: Token,
|
|
211
|
-
categoryToken:
|
|
211
|
+
categoryToken: LexerCategoryToken<TC>,
|
|
212
212
|
): Token<TC> {
|
|
213
213
|
return {
|
|
214
214
|
...token,
|
|
@@ -216,37 +216,37 @@ export class Parser<T = any> {
|
|
|
216
216
|
}
|
|
217
217
|
}
|
|
218
218
|
|
|
219
|
-
getCategoryTokens<TType extends $
|
|
219
|
+
getCategoryTokens<TType extends $CType>(
|
|
220
220
|
type: TType,
|
|
221
|
-
):
|
|
222
|
-
return this.$categories[type as $
|
|
221
|
+
): LexerCategoryToken<TType>["entries"] | undefined {
|
|
222
|
+
return this.$categories[type as $CType]?.entries as any
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
-
getTokenType(type: $
|
|
226
|
-
return this.$[type as any as $
|
|
225
|
+
getTokenType(type: $TType | $CType): LexerToken<$TType> | undefined {
|
|
226
|
+
return this.$[type as any as $TType] as any
|
|
227
227
|
}
|
|
228
228
|
|
|
229
|
-
isExactType<TType extends $
|
|
229
|
+
isExactType<TType extends $TType>(token: Token, type: TType): token is Token<TType> {
|
|
230
230
|
if (this.$[type]) {
|
|
231
231
|
return this.isType(token, type)
|
|
232
232
|
}
|
|
233
233
|
return false
|
|
234
234
|
}
|
|
235
235
|
|
|
236
|
-
isType(token: Token | undefined, type: $
|
|
236
|
+
isType(token: Token | undefined, type: $TType | $CType): boolean {
|
|
237
237
|
if (token === undefined) return false
|
|
238
238
|
if (token.type === type) return true
|
|
239
239
|
const tokenType = this.getTokenType(token.type)
|
|
240
240
|
|
|
241
241
|
if (tokenType?.type === type) return true
|
|
242
|
-
const category = this.$categories[type as $
|
|
243
|
-
if (category?.entries[token.type as $
|
|
242
|
+
const category = this.$categories[type as $CType]
|
|
243
|
+
if (category?.entries[token.type as $TType] !== undefined) {
|
|
244
244
|
return true
|
|
245
245
|
}
|
|
246
246
|
return false
|
|
247
247
|
}
|
|
248
248
|
|
|
249
|
-
createErrorToken(type: $
|
|
249
|
+
createErrorToken(type: $TType, index?: number): Token {
|
|
250
250
|
return {
|
|
251
251
|
type,
|
|
252
252
|
value: "",
|
|
@@ -265,7 +265,7 @@ export class Parser<T = any> {
|
|
|
265
265
|
}
|
|
266
266
|
|
|
267
267
|
|
|
268
|
-
peek(n = 1): Token<$
|
|
268
|
+
peek(n = 1): Token<$TType> | undefined {
|
|
269
269
|
return this.state.lexedTokens[this.state.index + n]
|
|
270
270
|
}
|
|
271
271
|
|
|
@@ -273,12 +273,12 @@ export class Parser<T = any> {
|
|
|
273
273
|
return this.peek(1) === undefined
|
|
274
274
|
}
|
|
275
275
|
|
|
276
|
-
consumeAny(): Token<$
|
|
276
|
+
consumeAny(): Token<$TType> {
|
|
277
277
|
return this.consume(this.peek(1)?.type)
|
|
278
278
|
}
|
|
279
279
|
|
|
280
280
|
consume<
|
|
281
|
-
TType extends $
|
|
281
|
+
TType extends $TType | $CType,
|
|
282
282
|
>(
|
|
283
283
|
type: TType | undefined,
|
|
284
284
|
): Token<TType> {
|
|
@@ -289,9 +289,9 @@ export class Parser<T = any> {
|
|
|
289
289
|
if (nextToken === undefined) {
|
|
290
290
|
throw new Error(`Reached end of input without consuming a token of type ${type}`)
|
|
291
291
|
}
|
|
292
|
-
if (this.$categories[type as $
|
|
293
|
-
const categoryToken = this.$categories[type as $
|
|
294
|
-
const tokenType = categoryToken?.entries[nextToken.type as $
|
|
292
|
+
if (this.$categories[type as $CType] !== undefined) {
|
|
293
|
+
const categoryToken = this.$categories[type as $CType]
|
|
294
|
+
const tokenType = categoryToken?.entries[nextToken.type as $TType]
|
|
295
295
|
if (categoryToken && tokenType) {
|
|
296
296
|
this.state.index++
|
|
297
297
|
return this.transformCategoryToken(nextToken, categoryToken) as Token<TType>
|
|
@@ -299,7 +299,7 @@ export class Parser<T = any> {
|
|
|
299
299
|
throw new Error("here")
|
|
300
300
|
}
|
|
301
301
|
} else {
|
|
302
|
-
const tokenType = this.getTokenType(type as $
|
|
302
|
+
const tokenType = this.getTokenType(type as $TType)
|
|
303
303
|
if (tokenType !== undefined) {
|
|
304
304
|
if (nextToken?.type === tokenType.type) {
|
|
305
305
|
this.state.index++
|
|
@@ -554,9 +554,9 @@ export class Parser<T = any> {
|
|
|
554
554
|
{ onlyValues = false, convertRegexValues = false, convertArrayValues = false }:
|
|
555
555
|
{ onlyValues?: boolean, convertRegexValues?: boolean, convertArrayValues?: boolean } = {},
|
|
556
556
|
): [
|
|
557
|
-
ValidToken<TOKEN_TYPE.PARENL> | undefined,
|
|
557
|
+
ValidToken<typeof TOKEN_TYPE.PARENL> | undefined,
|
|
558
558
|
GroupNode["expression"],
|
|
559
|
-
ValidToken<TOKEN_TYPE.PARENR> | undefined,
|
|
559
|
+
ValidToken<typeof TOKEN_TYPE.PARENR> | undefined,
|
|
560
560
|
] {
|
|
561
561
|
const parenL = this.ruleParenL()
|
|
562
562
|
let parenLeftCount = 0
|
|
@@ -709,7 +709,7 @@ export class Parser<T = any> {
|
|
|
709
709
|
rest = {
|
|
710
710
|
sepL: undefined,
|
|
711
711
|
sepR,
|
|
712
|
-
propertyOperator: sepL as any as AnyToken<TOKEN_TYPE.OP_CUSTOM>,
|
|
712
|
+
propertyOperator: sepL as any as AnyToken<typeof TOKEN_TYPE.OP_CUSTOM>,
|
|
713
713
|
}
|
|
714
714
|
} else {
|
|
715
715
|
rest = { sepL, sepR, propertyOperator: op }
|
|
@@ -756,7 +756,7 @@ export class Parser<T = any> {
|
|
|
756
756
|
}
|
|
757
757
|
if (this.isType(next, $C.REGEX_ANY)) {
|
|
758
758
|
// this is safe since the start can never match flags
|
|
759
|
-
const quoteL = this.ruleRegexAny() as ValidToken<TOKEN_TYPE.REGEX>
|
|
759
|
+
const quoteL = this.ruleRegexAny() as ValidToken<typeof TOKEN_TYPE.REGEX>
|
|
760
760
|
// unlike other values, regexes will swallow all input if incorrect
|
|
761
761
|
const maybeValue = this.peek(1)
|
|
762
762
|
// note the inversion (todo inverse map)
|
|
@@ -774,7 +774,7 @@ export class Parser<T = any> {
|
|
|
774
774
|
return handle.variable(undefined, undefined, value, quoteR)
|
|
775
775
|
}
|
|
776
776
|
if (this.isType(next, $C.QUOTE_ANY)) {
|
|
777
|
-
const quoteToken = next as Token
|
|
777
|
+
const quoteToken = next as Token<typeof $T.QUOTE_BACKTICK | typeof $T.QUOTE_DOUBLE | typeof $T.QUOTE_SINGLE>
|
|
778
778
|
const quoteL = this.ruleValueDelimAny()
|
|
779
779
|
const maybeValue = this.peek(1)
|
|
780
780
|
const value = !quoteL && this.isType(maybeValue, $T.VALUE_UNQUOTED)
|
|
@@ -792,7 +792,7 @@ export class Parser<T = any> {
|
|
|
792
792
|
return undefined
|
|
793
793
|
}
|
|
794
794
|
|
|
795
|
-
ruleValueDelimAny(): ValidToken<TOKEN_TYPE.SINGLEQUOTE | TOKEN_TYPE.DOUBLEQUOTE | TOKEN_TYPE.BACKTICK | TOKEN_TYPE.REGEX> | undefined {
|
|
795
|
+
ruleValueDelimAny(): ValidToken<typeof TOKEN_TYPE.SINGLEQUOTE | typeof TOKEN_TYPE.DOUBLEQUOTE | typeof TOKEN_TYPE.BACKTICK | typeof TOKEN_TYPE.REGEX> | undefined {
|
|
796
796
|
const next = this.peek(1)!
|
|
797
797
|
|
|
798
798
|
if (this.isType(next, $C.QUOTE_ANY)) {
|
|
@@ -802,7 +802,7 @@ export class Parser<T = any> {
|
|
|
802
802
|
return undefined
|
|
803
803
|
}
|
|
804
804
|
|
|
805
|
-
ruleRegexAny(): ValidToken<TOKEN_TYPE.REGEX> | [ValidToken<TOKEN_TYPE.REGEX>, AnyToken<TOKEN_TYPE.VALUE>] {
|
|
805
|
+
ruleRegexAny(): ValidToken<typeof TOKEN_TYPE.REGEX> | [ValidToken<typeof TOKEN_TYPE.REGEX>, AnyToken<typeof TOKEN_TYPE.VALUE>] {
|
|
806
806
|
const value = this.consume($C.REGEX_ANY)
|
|
807
807
|
if (value.value.length > 1) {
|
|
808
808
|
// cheat a bit to extract the flags
|
|
@@ -826,11 +826,11 @@ export class Parser<T = any> {
|
|
|
826
826
|
}
|
|
827
827
|
|
|
828
828
|
ruleValueNot<
|
|
829
|
-
TType extends $T.QUOTE_SINGLE | $T.QUOTE_DOUBLE | $T.QUOTE_BACKTICK | $C.REGEX_ANY,
|
|
829
|
+
TType extends typeof $T.QUOTE_SINGLE | typeof $T.QUOTE_DOUBLE | typeof $T.QUOTE_BACKTICK | typeof $C.REGEX_ANY,
|
|
830
830
|
>(
|
|
831
831
|
type: TType,
|
|
832
832
|
): ValidToken<
|
|
833
|
-
TOKEN_TYPE.VALUE
|
|
833
|
+
typeof TOKEN_TYPE.VALUE
|
|
834
834
|
> {
|
|
835
835
|
const realType = {
|
|
836
836
|
[$T.QUOTE_SINGLE]: $C.VALUE_FOR_SINGLE,
|
|
@@ -848,15 +848,15 @@ export class Parser<T = any> {
|
|
|
848
848
|
return handle.token.value(...this.processToken(value)) as any
|
|
849
849
|
}
|
|
850
850
|
|
|
851
|
-
ruleQuote<TType extends $T.QUOTE_SINGLE | $T.QUOTE_DOUBLE | $T.QUOTE_BACKTICK >(
|
|
851
|
+
ruleQuote<TType extends typeof $T.QUOTE_SINGLE | typeof $T.QUOTE_DOUBLE | typeof $T.QUOTE_BACKTICK >(
|
|
852
852
|
type: TType,
|
|
853
853
|
): ValidToken<
|
|
854
|
-
TType extends $T.QUOTE_SINGLE
|
|
855
|
-
? TOKEN_TYPE.SINGLEQUOTE
|
|
856
|
-
: TType extends $T.QUOTE_DOUBLE
|
|
857
|
-
? TOKEN_TYPE.DOUBLEQUOTE
|
|
858
|
-
: TType extends $T.QUOTE_BACKTICK
|
|
859
|
-
? TOKEN_TYPE.BACKTICK
|
|
854
|
+
TType extends typeof $T.QUOTE_SINGLE
|
|
855
|
+
? typeof TOKEN_TYPE.SINGLEQUOTE
|
|
856
|
+
: TType extends typeof $T.QUOTE_DOUBLE
|
|
857
|
+
? typeof TOKEN_TYPE.DOUBLEQUOTE
|
|
858
|
+
: TType extends typeof $T.QUOTE_BACKTICK
|
|
859
|
+
? typeof TOKEN_TYPE.BACKTICK
|
|
860
860
|
: never
|
|
861
861
|
> {
|
|
862
862
|
const quote = this.peek(1)
|
|
@@ -891,7 +891,7 @@ export class Parser<T = any> {
|
|
|
891
891
|
onlyToken?: TOnlyToken
|
|
892
892
|
unprefixed?: boolean
|
|
893
893
|
} = {},
|
|
894
|
-
): TOnlyToken extends true ? Token
|
|
894
|
+
): TOnlyToken extends true ? Token<typeof $T.VALUE_UNQUOTED> | undefined : AnyToken<typeof TOKEN_TYPE.VALUE> | undefined {
|
|
895
895
|
const next = this.peek(1)
|
|
896
896
|
const next2 = this.peek(2)
|
|
897
897
|
const next4 = this.peek(4)
|
|
@@ -912,13 +912,13 @@ export class Parser<T = any> {
|
|
|
912
912
|
}: {
|
|
913
913
|
onlyToken?: TOnlyToken
|
|
914
914
|
} = {},
|
|
915
|
-
): TOnlyToken extends true ? Token
|
|
915
|
+
): TOnlyToken extends true ? Token<typeof $T.VALUE_UNQUOTED> : AnyToken<typeof TOKEN_TYPE.VALUE> {
|
|
916
916
|
const t = this.consume($T.VALUE_UNQUOTED)
|
|
917
917
|
const res = onlyToken ? t : handle.token.value(...this.processToken(t))
|
|
918
918
|
return (res) as any
|
|
919
919
|
}
|
|
920
920
|
|
|
921
|
-
ruleParenL(): ValidToken<TOKEN_TYPE.PARENL> | undefined {
|
|
921
|
+
ruleParenL(): ValidToken<typeof TOKEN_TYPE.PARENL> | undefined {
|
|
922
922
|
const next = this.peek(1)
|
|
923
923
|
const value = next?.type === $T.PAREN_L
|
|
924
924
|
? this.consume($T.PAREN_L)
|
|
@@ -929,12 +929,12 @@ export class Parser<T = any> {
|
|
|
929
929
|
: undefined
|
|
930
930
|
}
|
|
931
931
|
|
|
932
|
-
ruleParenR(): ValidToken<TOKEN_TYPE.PARENR> | undefined {
|
|
932
|
+
ruleParenR(): ValidToken<typeof TOKEN_TYPE.PARENR> | undefined {
|
|
933
933
|
const value = this.consume($T.PAREN_R)
|
|
934
934
|
return handle.delimiter.parenR(...this.processToken(value))
|
|
935
935
|
}
|
|
936
936
|
|
|
937
|
-
ruleBracketL(): ValidToken<TOKEN_TYPE.BRACKETL> | undefined {
|
|
937
|
+
ruleBracketL(): ValidToken<typeof TOKEN_TYPE.BRACKETL> | undefined {
|
|
938
938
|
const next = this.peek(1)
|
|
939
939
|
const value = next?.type === $T.BRACKET_L
|
|
940
940
|
? this.consume($T.BRACKET_L)
|
|
@@ -945,12 +945,12 @@ export class Parser<T = any> {
|
|
|
945
945
|
: undefined
|
|
946
946
|
}
|
|
947
947
|
|
|
948
|
-
ruleBracketR(): ValidToken<TOKEN_TYPE.BRACKETR> | undefined {
|
|
948
|
+
ruleBracketR(): ValidToken<typeof TOKEN_TYPE.BRACKETR> | undefined {
|
|
949
949
|
const value = this.consume($T.BRACKET_R)
|
|
950
950
|
return handle.delimiter.bracketR(...this.processToken(value))
|
|
951
951
|
}
|
|
952
952
|
|
|
953
|
-
ruleNot(): ValidToken<TOKEN_TYPE.NOT> | undefined {
|
|
953
|
+
ruleNot(): ValidToken<typeof TOKEN_TYPE.NOT> | undefined {
|
|
954
954
|
if (this.isType(this.peek(1), $C.OPERATOR_NOT)) {
|
|
955
955
|
const op = this.consume($C.OPERATOR_NOT)
|
|
956
956
|
return handle.operator.not(...this.processToken<true>(op))
|
|
@@ -1129,13 +1129,13 @@ export class Parser<T = any> {
|
|
|
1129
1129
|
const wordOps = [...opts.keywords.and, ...opts.keywords.or, ...opts.keywords.not].filter(op => !op.isSymbol)
|
|
1130
1130
|
|
|
1131
1131
|
const canSuggestOpAfterPrev = (
|
|
1132
|
-
token.valid.prev && tokenVariable.includes(token.valid.prev?.type) &&
|
|
1132
|
+
token.valid.prev && (tokenVariable as string[]).includes(token.valid.prev?.type) &&
|
|
1133
1133
|
(token.whitespace.prev || token.valid.prev.type === TOKEN_TYPE.PARENR) &&
|
|
1134
1134
|
!token.at && token.valid.next === undefined
|
|
1135
1135
|
)
|
|
1136
1136
|
const canSuggestOpBeforeNext =
|
|
1137
1137
|
(
|
|
1138
|
-
token.valid.next && tokenVariable.includes(token.valid.next?.type) &&
|
|
1138
|
+
token.valid.next && (tokenVariable as string[]).includes(token.valid.next?.type) &&
|
|
1139
1139
|
token.whitespace.next && // no parenL allowed since check since there will already be prefix suggestions
|
|
1140
1140
|
!token.at && token.valid.prev === undefined
|
|
1141
1141
|
)
|
|
@@ -1169,7 +1169,7 @@ export class Parser<T = any> {
|
|
|
1169
1169
|
} else {
|
|
1170
1170
|
const surroundingErrors = getSurroundingErrors(tokens, token)
|
|
1171
1171
|
|
|
1172
|
-
const errorTypesHandled:
|
|
1172
|
+
const errorTypesHandled: TokenType[] = []
|
|
1173
1173
|
const errorSuggestion = {
|
|
1174
1174
|
isError: true,
|
|
1175
1175
|
cursorInfo: token,
|
|
@@ -1192,7 +1192,7 @@ export class Parser<T = any> {
|
|
|
1192
1192
|
const isRight = (errorParent as VariableNode).quote!.right === error
|
|
1193
1193
|
suggestions.push({
|
|
1194
1194
|
...errorSuggestion,
|
|
1195
|
-
type: type as any as
|
|
1195
|
+
type: type as any as SuggestionType,
|
|
1196
1196
|
requires: createDefaultRequires({
|
|
1197
1197
|
whitespace: {
|
|
1198
1198
|
before: isRight ? false : requiresWhitespacePrev,
|
|
@@ -1229,7 +1229,7 @@ export class Parser<T = any> {
|
|
|
1229
1229
|
case TOKEN_TYPE.PARENR:
|
|
1230
1230
|
suggestions.push({
|
|
1231
1231
|
...errorSuggestion,
|
|
1232
|
-
type: type as any as
|
|
1232
|
+
type: type as any as SuggestionType,
|
|
1233
1233
|
requires: createDefaultRequires(),
|
|
1234
1234
|
range: pos({ start: index }, { fill: true }),
|
|
1235
1235
|
})
|
|
@@ -1880,7 +1880,7 @@ export class Parser<T = any> {
|
|
|
1880
1880
|
|
|
1881
1881
|
// apply De Morgan's laws if group prefix was negative
|
|
1882
1882
|
// the values are already flipped, we just have to flip the operator
|
|
1883
|
-
const type:
|
|
1883
|
+
const type: TokenBoolean = (groupValue === false ? OPPOSITE[ast.operator!.type!] : ast.operator.type)!
|
|
1884
1884
|
return createExpression<TType, TValue>({ operator: type, left: left as any, right: right as any })
|
|
1885
1885
|
}
|
|
1886
1886
|
return unreachable()
|
|
@@ -1910,7 +1910,7 @@ export class Parser<T = any> {
|
|
|
1910
1910
|
// eslint-disable-next-line prefer-rest-params
|
|
1911
1911
|
const prefixes: VariableNode[] = arguments[5] ?? []
|
|
1912
1912
|
// eslint-disable-next-line prefer-rest-params
|
|
1913
|
-
let operator: ValidToken<TOKEN_TYPE.VALUE | TOKEN_TYPE.OP_CUSTOM> | undefined = arguments[6]
|
|
1913
|
+
let operator: ValidToken<typeof TOKEN_TYPE.VALUE | typeof TOKEN_TYPE.OP_CUSTOM> | undefined = arguments[6]
|
|
1914
1914
|
|
|
1915
1915
|
const self_ = this as any as Parser & { validate: AddParameters<Parser["validate"], [typeof prefix, typeof groupValue, typeof results, typeof prefixes, typeof operator]> }
|
|
1916
1916
|
|
|
@@ -1952,7 +1952,7 @@ export class Parser<T = any> {
|
|
|
1952
1952
|
const valuePrefix = ast.value.type === AST_TYPE.VARIABLE && ast.value.prefix
|
|
1953
1953
|
? ast.value.prefix
|
|
1954
1954
|
: undefined
|
|
1955
|
-
operator ??= ast.propertyOperator as ValidToken<TOKEN_TYPE.VALUE | TOKEN_TYPE.OP_CUSTOM>
|
|
1955
|
+
operator ??= ast.propertyOperator as ValidToken<typeof TOKEN_TYPE.VALUE | typeof TOKEN_TYPE.OP_CUSTOM>
|
|
1956
1956
|
const isRegex = (ast.value as VariableNode)?.quote?.left.type === TOKEN_TYPE.REGEX
|
|
1957
1957
|
const isQuoted = (ast.value as VariableNode)?.quote !== undefined
|
|
1958
1958
|
const isExpanded = ast.sep !== undefined
|
|
@@ -1985,7 +1985,7 @@ export class Parser<T = any> {
|
|
|
1985
1985
|
|
|
1986
1986
|
if (ast.property) prefixes.push((ast.property as any))
|
|
1987
1987
|
// eslint-disable-next-line @typescript-eslint/no-shadow
|
|
1988
|
-
const operator = ast.propertyOperator as ValidToken<TOKEN_TYPE.VALUE | TOKEN_TYPE.OP_CUSTOM>
|
|
1988
|
+
const operator = ast.propertyOperator as ValidToken<typeof TOKEN_TYPE.VALUE | typeof TOKEN_TYPE.OP_CUSTOM>
|
|
1989
1989
|
self_.validate(ast.value, context, name, boolValue, results, prefixes, operator)
|
|
1990
1990
|
}
|
|
1991
1991
|
}
|
|
@@ -21,10 +21,10 @@ export function condition(
|
|
|
21
21
|
| GroupNode
|
|
22
22
|
| ArrayNode
|
|
23
23
|
| ErrorToken,
|
|
24
|
-
not: true | ValidToken<TOKEN_TYPE.NOT> = true,
|
|
24
|
+
not: true | ValidToken<typeof TOKEN_TYPE.NOT> = true,
|
|
25
25
|
property?: VariableNode | ErrorToken,
|
|
26
|
-
propertyOperator?: AnyToken<TOKEN_TYPE.OP_CUSTOM | TOKEN_TYPE.VALUE>,
|
|
27
|
-
{ right, left }: Partial<Record<"right" | "left", ValidToken<TOKEN_TYPE.OP_EXPANDED_SEP>>> = { },
|
|
26
|
+
propertyOperator?: AnyToken<typeof TOKEN_TYPE.OP_CUSTOM | typeof TOKEN_TYPE.VALUE>,
|
|
27
|
+
{ right, left }: Partial<Record<"right" | "left", ValidToken<typeof TOKEN_TYPE.OP_EXPANDED_SEP>>> = { },
|
|
28
28
|
): ConditionNode {
|
|
29
29
|
const position = pos(value satisfies Position)
|
|
30
30
|
const notStart = not === true ? undefined : not.start
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type } from "./type.js"
|
|
2
2
|
|
|
3
|
-
import { type
|
|
3
|
+
import { type ExtractToken, TOKEN_TYPE } from "../../types/ast.js"
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Faster way, more intuitive way to generate the options for matching delimiters (e.g. quotes and parens) for functions like {@link variable} and {@link group} .
|
|
@@ -10,9 +10,9 @@ export function delim<
|
|
|
10
10
|
TLeft extends boolean | string,
|
|
11
11
|
TRight extends boolean | string,
|
|
12
12
|
TType extends TLeft extends string
|
|
13
|
-
?
|
|
13
|
+
? ExtractToken<TLeft>
|
|
14
14
|
: TRight extends string
|
|
15
|
-
?
|
|
15
|
+
? ExtractToken<TRight>
|
|
16
16
|
: undefined,
|
|
17
17
|
>(
|
|
18
18
|
left: TLeft = false as TLeft,
|
|
@@ -31,7 +31,7 @@ export function delim<
|
|
|
31
31
|
right: right === true || (typeof right === "string" && right !== undefined),
|
|
32
32
|
}
|
|
33
33
|
if (quoteType !== undefined &&
|
|
34
|
-
![TOKEN_TYPE.PARENL, TOKEN_TYPE.PARENR].includes(quoteType)
|
|
34
|
+
!([TOKEN_TYPE.PARENL, TOKEN_TYPE.PARENR] as string[]).includes(quoteType)
|
|
35
35
|
) {
|
|
36
36
|
opts.type = quoteType
|
|
37
37
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { type } from "./type.js"
|
|
2
2
|
|
|
3
|
-
import { type ErrorToken,TOKEN_TYPE } from "../../types/ast.js"
|
|
3
|
+
import { type ErrorToken,TOKEN_TYPE, type TokenType } from "../../types/ast.js"
|
|
4
4
|
import { createToken } from "../createToken.js"
|
|
5
5
|
|
|
6
6
|
|
|
@@ -9,8 +9,8 @@ import { createToken } from "../createToken.js"
|
|
|
9
9
|
*
|
|
10
10
|
* @param expected Can be passed an array of {@link ValidToken_TYPE} or strings, in which case it will use {@link type} internally. So instead of `[TOKEN_TYPE.VALUE]` we can do `[""]` and instead of `[TOKEN_TYPE.PARENR]` we can do `[")"]`.
|
|
11
11
|
*/
|
|
12
|
-
export function error<T extends
|
|
13
|
-
export function error<T extends
|
|
12
|
+
export function error<T extends TokenType>(pos: number, expected: T[]): ErrorToken
|
|
13
|
+
export function error<T extends TokenType>(pos: number, expected_: T[]): ErrorToken {
|
|
14
14
|
const expected = expected_.map(item => {
|
|
15
15
|
if (TOKEN_TYPE[item as keyof typeof TOKEN_TYPE] === undefined) {
|
|
16
16
|
return type(item)
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { pos } from "./pos.js"
|
|
2
2
|
import { token } from "./token.js"
|
|
3
3
|
|
|
4
|
-
import { type AnyToken, type ConditionNode, type ErrorToken, type ExpressionNode,type GroupNode, type Position, TOKEN_TYPE, type
|
|
4
|
+
import { type AnyToken, type ConditionNode, type ErrorToken, type ExpressionNode,type GroupNode, type Position, TOKEN_TYPE, type TokenBoolean } from "../../types/ast.js"
|
|
5
5
|
import { createExpressionNode } from "../createExpressionNode.js"
|
|
6
6
|
|
|
7
7
|
|
|
@@ -18,7 +18,7 @@ export function expression(
|
|
|
18
18
|
ErrorToken |
|
|
19
19
|
undefined,
|
|
20
20
|
operator:
|
|
21
|
-
AnyToken<
|
|
21
|
+
AnyToken<TokenBoolean> |
|
|
22
22
|
undefined,
|
|
23
23
|
right:
|
|
24
24
|
ConditionNode |
|
|
@@ -39,17 +39,13 @@ export function expression(
|
|
|
39
39
|
|
|
40
40
|
const position = pos({ start, end } as Position)
|
|
41
41
|
|
|
42
|
-
|
|
43
|
-
left = token(TOKEN_TYPE.VALUE, undefined, { start: position.start })
|
|
44
|
-
}
|
|
42
|
+
left ??= token(TOKEN_TYPE.VALUE, undefined, { start: position.start })
|
|
45
43
|
let op!: ExpressionNode["operator"]
|
|
46
44
|
if (operator === undefined) {
|
|
47
45
|
operator = token([TOKEN_TYPE.AND, TOKEN_TYPE.OR], undefined, { start: left.end })
|
|
48
46
|
} else op = operator
|
|
49
47
|
|
|
50
|
-
|
|
51
|
-
right = token(TOKEN_TYPE.VALUE, undefined, { start: op.end })
|
|
52
|
-
}
|
|
48
|
+
right ??= token(TOKEN_TYPE.VALUE, undefined, { start: op.end })
|
|
53
49
|
|
|
54
50
|
return createExpressionNode({
|
|
55
51
|
left,
|
|
@@ -16,7 +16,7 @@ import { createGroupNode } from "../createGroupNode.js"
|
|
|
16
16
|
export function group(
|
|
17
17
|
prefix:
|
|
18
18
|
| ConditionNode
|
|
19
|
-
| ValidToken<TOKEN_TYPE.NOT>
|
|
19
|
+
| ValidToken<typeof TOKEN_TYPE.NOT>
|
|
20
20
|
| undefined,
|
|
21
21
|
|
|
22
22
|
expression:
|
|
@@ -30,9 +30,7 @@ export function group(
|
|
|
30
30
|
parenLeftPos?: Position,
|
|
31
31
|
parenRightPos?: Position,
|
|
32
32
|
): GroupNode {
|
|
33
|
-
|
|
34
|
-
expression = token(TOKEN_TYPE.VALUE, undefined, prefix?.end !== undefined ? { start: prefix.end } : undefined)
|
|
35
|
-
}
|
|
33
|
+
expression ??= token(TOKEN_TYPE.VALUE, undefined, prefix?.end !== undefined ? { start: prefix.end } : undefined)
|
|
36
34
|
|
|
37
35
|
const node: Partial<FirstParam<typeof createGroupNode>> = {
|
|
38
36
|
prefix: undefined,
|
package/src/ast/builders/pos.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isFullPos } from "./isFullPos.js"
|
|
2
2
|
|
|
3
|
-
import type { AnyToken,
|
|
3
|
+
import type { AnyToken, AstType, EmptyObj, Node, Position, TokenType } from "../../types/ast.js"
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Can either:
|
|
@@ -22,9 +22,9 @@ export function pos<TItem extends Position | Partial<Position> | EmptyObj>(
|
|
|
22
22
|
// not sure why this needs the AnyToken check
|
|
23
23
|
TItem extends Position
|
|
24
24
|
? Position
|
|
25
|
-
: TItem extends AnyToken<
|
|
25
|
+
: TItem extends AnyToken<TokenType> | Position | EmptyObj
|
|
26
26
|
? Position | EmptyObj
|
|
27
|
-
: TItem extends Node<
|
|
27
|
+
: TItem extends Node<AstType> | Position | EmptyObj
|
|
28
28
|
? Position | EmptyObj
|
|
29
29
|
: EmptyObj
|
|
30
30
|
export function pos(start: number, end: number): Position
|
|
@@ -2,7 +2,7 @@ import { isArray } from "@alanscodelog/utils/isArray.js"
|
|
|
2
2
|
|
|
3
3
|
import { pos } from "./pos.js"
|
|
4
4
|
|
|
5
|
-
import type { AnyToken, EmptyObj, ErrorToken, Position,
|
|
5
|
+
import type { AnyToken, EmptyObj, ErrorToken, Position, TokenType, ValidToken } from "../../types/ast.js"
|
|
6
6
|
import { createToken } from "../createToken.js"
|
|
7
7
|
|
|
8
8
|
|
|
@@ -16,7 +16,7 @@ import { createToken } from "../createToken.js"
|
|
|
16
16
|
|
|
17
17
|
export function token<
|
|
18
18
|
TValue extends string | undefined,
|
|
19
|
-
TType extends
|
|
19
|
+
TType extends TokenType = TokenType,
|
|
20
20
|
>(
|
|
21
21
|
type: TValue extends undefined ? TType | TType[] : TType,
|
|
22
22
|
value: TValue,
|
package/src/ast/builders/type.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { type
|
|
1
|
+
import { type ExtractToken, TOKEN_TYPE } from "../../types/ast.js"
|
|
2
2
|
/**
|
|
3
3
|
* Given a the string value of an operator or single delimiter token, returns the corresponding {@link ValidToken_TYPE} .
|
|
4
4
|
*/
|
|
5
5
|
export function type<T extends string>(
|
|
6
6
|
operatorSymbol: T,
|
|
7
|
-
):
|
|
7
|
+
): ExtractToken<T> {
|
|
8
8
|
switch (operatorSymbol) {
|
|
9
9
|
case "`": return TOKEN_TYPE.BACKTICK as any
|
|
10
10
|
case `'`: return TOKEN_TYPE.SINGLEQUOTE as any
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { pos } from "./pos.js"
|
|
2
2
|
import { token } from "./token.js"
|
|
3
3
|
|
|
4
|
-
import { type AnyToken, type EmptyObj,type FirstParam, type Position, TOKEN_TYPE, type
|
|
4
|
+
import { type AnyToken, type EmptyObj,type FirstParam, type Position, TOKEN_TYPE, type TokenQuote, type ValidToken, type VariableNode } from "../../types/ast.js"
|
|
5
5
|
import { createVariableNode } from "../createVariableNode.js"
|
|
6
6
|
|
|
7
7
|
|
|
@@ -14,9 +14,9 @@ import { createVariableNode } from "../createVariableNode.js"
|
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
16
|
export function variable(
|
|
17
|
-
prefix: ValidToken<TOKEN_TYPE.VALUE> | undefined,
|
|
18
|
-
value: string | AnyToken<TOKEN_TYPE.VALUE>,
|
|
19
|
-
quote?: { type:
|
|
17
|
+
prefix: ValidToken<typeof TOKEN_TYPE.VALUE> | undefined,
|
|
18
|
+
value: string | AnyToken<typeof TOKEN_TYPE.VALUE>,
|
|
19
|
+
quote?: { type: TokenQuote, left?: boolean, right?: boolean, flags?: string },
|
|
20
20
|
position?: Position | EmptyObj,
|
|
21
21
|
): VariableNode {
|
|
22
22
|
if (typeof value === "string") {
|
|
@@ -76,7 +76,7 @@ export function variable(
|
|
|
76
76
|
return createVariableNode(node as any)
|
|
77
77
|
}
|
|
78
78
|
|
|
79
|
-
function quoteFromType(type:
|
|
79
|
+
function quoteFromType(type: TokenQuote | undefined): string {
|
|
80
80
|
switch (type) {
|
|
81
81
|
case TOKEN_TYPE.BACKTICK: return "`"
|
|
82
82
|
case TOKEN_TYPE.DOUBLEQUOTE: return "\""
|
|
@@ -5,8 +5,8 @@ import { isNode } from "../utils/isNode.js"
|
|
|
5
5
|
export function createConditionNode<
|
|
6
6
|
TValid extends boolean = boolean,
|
|
7
7
|
TOperator extends
|
|
8
|
-
ValidToken<TOKEN_TYPE.NOT> | undefined =
|
|
9
|
-
ValidToken<TOKEN_TYPE.NOT> | undefined,
|
|
8
|
+
ValidToken<typeof TOKEN_TYPE.NOT> | undefined =
|
|
9
|
+
ValidToken<typeof TOKEN_TYPE.NOT> | undefined,
|
|
10
10
|
>(raw: {
|
|
11
11
|
operator?: TOperator
|
|
12
12
|
property?: ConditionNode<TValid>["property"]
|
|
@@ -9,15 +9,15 @@ export function createGroupNode<
|
|
|
9
9
|
TPrefix extends
|
|
10
10
|
TPrefixable extends true
|
|
11
11
|
? ConditionNode<TValid> |
|
|
12
|
-
ValidToken<TOKEN_TYPE.NOT> |
|
|
12
|
+
ValidToken<typeof TOKEN_TYPE.NOT> |
|
|
13
13
|
undefined
|
|
14
|
-
: ValidToken<TOKEN_TYPE.NOT> |
|
|
14
|
+
: ValidToken<typeof TOKEN_TYPE.NOT> |
|
|
15
15
|
undefined =
|
|
16
16
|
TPrefixable extends true
|
|
17
17
|
? ConditionNode<TValid> |
|
|
18
|
-
ValidToken<TOKEN_TYPE.NOT> |
|
|
18
|
+
ValidToken<typeof TOKEN_TYPE.NOT> |
|
|
19
19
|
undefined
|
|
20
|
-
: ValidToken<TOKEN_TYPE.NOT>,
|
|
20
|
+
: ValidToken<typeof TOKEN_TYPE.NOT>,
|
|
21
21
|
>(raw: {
|
|
22
22
|
prefix: TPrefix
|
|
23
23
|
} & RawNode<GroupNode<TValid>>): GroupNode<TValid, TPrefixable, TPrefix> {
|
package/src/ast/createToken.ts
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
import { ExpressitError } from "../internal/ExpressitError.js"
|
|
2
|
-
import type { ErrorToken, RawToken,
|
|
3
|
-
import {
|
|
2
|
+
import type { ErrorToken, RawToken, TokenType, ValidToken } from "../types/ast.js"
|
|
3
|
+
import { PARSER_ERROR } from "../types/errors.js"
|
|
4
4
|
|
|
5
5
|
export function createToken<
|
|
6
|
-
TType extends
|
|
6
|
+
TType extends TokenType,
|
|
7
7
|
>(raw: { type: TType } & RawToken<ValidToken>): ValidToken<TType>
|
|
8
8
|
export function createToken(raw: RawToken<ErrorToken>): ErrorToken
|
|
9
9
|
export function createToken<
|
|
10
10
|
TValid extends boolean = boolean,
|
|
11
11
|
TType extends
|
|
12
|
-
TValid extends true ?
|
|
13
|
-
TValid extends true ?
|
|
12
|
+
TValid extends true ? TokenType : never =
|
|
13
|
+
TValid extends true ? TokenType : never
|
|
14
14
|
>(raw: RawToken<ValidToken> | RawToken<ErrorToken>): TValid extends true
|
|
15
15
|
? ValidToken<TType>
|
|
16
16
|
: ErrorToken {
|
|
17
17
|
if (raw.start === undefined || raw.end === undefined) {
|
|
18
|
-
throw new ExpressitError(
|
|
18
|
+
throw new ExpressitError(PARSER_ERROR.POSITION_ERROR, raw)
|
|
19
19
|
}
|
|
20
20
|
return {
|
|
21
21
|
...raw,
|