@witchcraft/expressit 0.0.2
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 +86 -0
- package/dist/ast/builders/array.d.ts +8 -0
- package/dist/ast/builders/array.d.ts.map +1 -0
- package/dist/ast/builders/array.js +31 -0
- package/dist/ast/builders/condition.d.ts +20 -0
- package/dist/ast/builders/condition.d.ts.map +1 -0
- package/dist/ast/builders/condition.js +28 -0
- package/dist/ast/builders/delim.d.ts +11 -0
- package/dist/ast/builders/delim.d.ts.map +1 -0
- package/dist/ast/builders/delim.js +20 -0
- package/dist/ast/builders/error.d.ts +9 -0
- package/dist/ast/builders/error.d.ts.map +1 -0
- package/dist/ast/builders/error.js +16 -0
- package/dist/ast/builders/expression.d.ts +12 -0
- package/dist/ast/builders/expression.d.ts.map +1 -0
- package/dist/ast/builders/expression.js +31 -0
- package/dist/ast/builders/group.d.ts +20 -0
- package/dist/ast/builders/group.d.ts.map +1 -0
- package/dist/ast/builders/group.js +47 -0
- package/dist/ast/builders/index.d.ts +12 -0
- package/dist/ast/builders/index.d.ts.map +1 -0
- package/dist/ast/builders/index.js +24 -0
- package/dist/ast/builders/isFullPos.d.ts +6 -0
- package/dist/ast/builders/isFullPos.d.ts.map +1 -0
- package/dist/ast/builders/isFullPos.js +6 -0
- package/dist/ast/builders/pos.d.ts +21 -0
- package/dist/ast/builders/pos.d.ts.map +1 -0
- package/dist/ast/builders/pos.js +28 -0
- package/dist/ast/builders/token.d.ts +12 -0
- package/dist/ast/builders/token.d.ts.map +1 -0
- package/dist/ast/builders/token.js +26 -0
- package/dist/ast/builders/type.d.ts +6 -0
- package/dist/ast/builders/type.d.ts.map +1 -0
- package/dist/ast/builders/type.js +37 -0
- package/dist/ast/builders/variable.d.ts +17 -0
- package/dist/ast/builders/variable.d.ts.map +1 -0
- package/dist/ast/builders/variable.js +62 -0
- package/dist/ast/classes/ArrayNode.d.ts +18 -0
- package/dist/ast/classes/ArrayNode.d.ts.map +1 -0
- package/dist/ast/classes/ArrayNode.js +55 -0
- package/dist/ast/classes/Condition.d.ts +13 -0
- package/dist/ast/classes/Condition.d.ts.map +1 -0
- package/dist/ast/classes/Condition.js +21 -0
- package/dist/ast/classes/ConditionNode.d.ts +73 -0
- package/dist/ast/classes/ConditionNode.d.ts.map +1 -0
- package/dist/ast/classes/ConditionNode.js +101 -0
- package/dist/ast/classes/ErrorToken.d.ts +27 -0
- package/dist/ast/classes/ErrorToken.d.ts.map +1 -0
- package/dist/ast/classes/ErrorToken.js +47 -0
- package/dist/ast/classes/Expression.d.ts +13 -0
- package/dist/ast/classes/Expression.d.ts.map +1 -0
- package/dist/ast/classes/Expression.js +19 -0
- package/dist/ast/classes/ExpressionNode.d.ts +21 -0
- package/dist/ast/classes/ExpressionNode.d.ts.map +1 -0
- package/dist/ast/classes/ExpressionNode.js +57 -0
- package/dist/ast/classes/GroupNode.d.ts +64 -0
- package/dist/ast/classes/GroupNode.d.ts.map +1 -0
- package/dist/ast/classes/GroupNode.js +69 -0
- package/dist/ast/classes/Node.d.ts +22 -0
- package/dist/ast/classes/Node.d.ts.map +1 -0
- package/dist/ast/classes/Node.js +28 -0
- package/dist/ast/classes/Token.d.ts +27 -0
- package/dist/ast/classes/Token.d.ts.map +1 -0
- package/dist/ast/classes/Token.js +28 -0
- package/dist/ast/classes/ValidToken.d.ts +26 -0
- package/dist/ast/classes/ValidToken.d.ts.map +1 -0
- package/dist/ast/classes/ValidToken.js +49 -0
- package/dist/ast/classes/VariableNode.d.ts +33 -0
- package/dist/ast/classes/VariableNode.d.ts.map +1 -0
- package/dist/ast/classes/VariableNode.js +58 -0
- package/dist/ast/classes/index.d.ts +12 -0
- package/dist/ast/classes/index.d.ts.map +1 -0
- package/dist/ast/classes/index.js +24 -0
- package/dist/ast/handlers.d.ts +42 -0
- package/dist/ast/handlers.d.ts.map +1 -0
- package/dist/ast/handlers.js +150 -0
- package/dist/ast/index.d.ts +4 -0
- package/dist/ast/index.d.ts.map +1 -0
- package/dist/ast/index.js +8 -0
- package/dist/examples/advancedValueComparer.d.ts +3 -0
- package/dist/examples/advancedValueComparer.d.ts.map +1 -0
- package/dist/examples/advancedValueComparer.js +28 -0
- package/dist/examples/shortcutContextParser.d.ts +22 -0
- package/dist/examples/shortcutContextParser.d.ts.map +1 -0
- package/dist/examples/shortcutContextParser.js +126 -0
- package/dist/global.d.js +1 -0
- package/dist/grammar/ParserBase.d.ts +51 -0
- package/dist/grammar/ParserBase.d.ts.map +1 -0
- package/dist/grammar/ParserBase.js +516 -0
- package/dist/grammar/createTokens.d.ts +56 -0
- package/dist/grammar/createTokens.d.ts.map +1 -0
- package/dist/grammar/createTokens.js +843 -0
- package/dist/grammar/index.d.ts +3 -0
- package/dist/grammar/index.d.ts.map +1 -0
- package/dist/grammar/index.js +6 -0
- package/dist/helpers/errors.d.ts +9 -0
- package/dist/helpers/errors.d.ts.map +1 -0
- package/dist/helpers/errors.js +41 -0
- package/dist/helpers/general/applyBoolean.d.ts +3 -0
- package/dist/helpers/general/applyBoolean.d.ts.map +1 -0
- package/dist/helpers/general/applyBoolean.js +17 -0
- package/dist/helpers/general/applyPrefix.d.ts +4 -0
- package/dist/helpers/general/applyPrefix.d.ts.map +1 -0
- package/dist/helpers/general/applyPrefix.js +9 -0
- package/dist/helpers/general/defaultConditionNormalizer.d.ts +3 -0
- package/dist/helpers/general/defaultConditionNormalizer.d.ts.map +1 -0
- package/dist/helpers/general/defaultConditionNormalizer.js +6 -0
- package/dist/helpers/general/defaultKeyParser.d.ts +3 -0
- package/dist/helpers/general/defaultKeyParser.d.ts.map +1 -0
- package/dist/helpers/general/defaultKeyParser.js +8 -0
- package/dist/helpers/general/defaultPrefixApplier.d.ts +3 -0
- package/dist/helpers/general/defaultPrefixApplier.d.ts.map +1 -0
- package/dist/helpers/general/defaultPrefixApplier.js +6 -0
- package/dist/helpers/general/defaultValueComparer.d.ts +3 -0
- package/dist/helpers/general/defaultValueComparer.d.ts.map +1 -0
- package/dist/helpers/general/defaultValueComparer.js +6 -0
- package/dist/helpers/general/index.d.ts +7 -0
- package/dist/helpers/general/index.d.ts.map +1 -0
- package/dist/helpers/general/index.js +14 -0
- package/dist/helpers/index.d.ts +4 -0
- package/dist/helpers/index.d.ts.map +1 -0
- package/dist/helpers/index.js +8 -0
- package/dist/helpers/parser/assignParents.d.ts +4 -0
- package/dist/helpers/parser/assignParents.d.ts.map +1 -0
- package/dist/helpers/parser/assignParents.js +71 -0
- package/dist/helpers/parser/checkParserOpts.d.ts +3 -0
- package/dist/helpers/parser/checkParserOpts.d.ts.map +1 -0
- package/dist/helpers/parser/checkParserOpts.js +126 -0
- package/dist/helpers/parser/extractPosition.d.ts +9 -0
- package/dist/helpers/parser/extractPosition.d.ts.map +1 -0
- package/dist/helpers/parser/extractPosition.js +9 -0
- package/dist/helpers/parser/getUnclosedRightParenCount.d.ts +5 -0
- package/dist/helpers/parser/getUnclosedRightParenCount.d.ts.map +1 -0
- package/dist/helpers/parser/getUnclosedRightParenCount.js +20 -0
- package/dist/helpers/parser/index.d.ts +9 -0
- package/dist/helpers/parser/index.d.ts.map +1 -0
- package/dist/helpers/parser/index.js +18 -0
- package/dist/helpers/parser/parseParserOptions.d.ts +4 -0
- package/dist/helpers/parser/parseParserOptions.d.ts.map +1 -0
- package/dist/helpers/parser/parseParserOptions.js +45 -0
- package/dist/helpers/parser/seal.d.ts +8 -0
- package/dist/helpers/parser/seal.d.ts.map +1 -0
- package/dist/helpers/parser/seal.js +10 -0
- package/dist/helpers/parser/setParent.d.ts +6 -0
- package/dist/helpers/parser/setParent.d.ts.map +1 -0
- package/dist/helpers/parser/setParent.js +4 -0
- package/dist/helpers/parser/unescape.d.ts +3 -0
- package/dist/helpers/parser/unescape.d.ts.map +1 -0
- package/dist/helpers/parser/unescape.js +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +17 -0
- package/dist/methods/autocomplete.d.ts +18 -0
- package/dist/methods/autocomplete.d.ts.map +1 -0
- package/dist/methods/autocomplete.js +109 -0
- package/dist/methods/autoreplace.d.ts +13 -0
- package/dist/methods/autoreplace.d.ts.map +1 -0
- package/dist/methods/autoreplace.js +36 -0
- package/dist/methods/autosuggest.d.ts +28 -0
- package/dist/methods/autosuggest.d.ts.map +1 -0
- package/dist/methods/autosuggest.js +371 -0
- package/dist/methods/evaluate.d.ts +11 -0
- package/dist/methods/evaluate.d.ts.map +1 -0
- package/dist/methods/evaluate.js +30 -0
- package/dist/methods/getBestIndex.d.ts +19 -0
- package/dist/methods/getBestIndex.d.ts.map +1 -0
- package/dist/methods/getBestIndex.js +53 -0
- package/dist/methods/getIndexes.d.ts +17 -0
- package/dist/methods/getIndexes.d.ts.map +1 -0
- package/dist/methods/getIndexes.js +97 -0
- package/dist/methods/index.d.ts +9 -0
- package/dist/methods/index.d.ts.map +1 -0
- package/dist/methods/index.js +18 -0
- package/dist/methods/normalize.d.ts +12 -0
- package/dist/methods/normalize.d.ts.map +1 -0
- package/dist/methods/normalize.js +99 -0
- package/dist/methods/validate.d.ts +11 -0
- package/dist/methods/validate.d.ts.map +1 -0
- package/dist/methods/validate.js +111 -0
- package/dist/package.js +7 -0
- package/dist/package.json.js +193 -0
- package/dist/parser.d.ts +58 -0
- package/dist/parser.d.ts.map +1 -0
- package/dist/parser.js +136 -0
- package/dist/types/ast.d.ts +70 -0
- package/dist/types/ast.d.ts.map +1 -0
- package/dist/types/ast.js +29 -0
- package/dist/types/autocomplete.d.ts +143 -0
- package/dist/types/autocomplete.d.ts.map +1 -0
- package/dist/types/autocomplete.js +24 -0
- package/dist/types/errors.d.ts +34 -0
- package/dist/types/errors.d.ts.map +1 -0
- package/dist/types/errors.js +10 -0
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +9 -0
- package/dist/types/parser.d.ts +451 -0
- package/dist/types/parser.d.ts.map +1 -0
- package/dist/types/parser.js +1 -0
- package/dist/utils/extractTokens.d.ts +8 -0
- package/dist/utils/extractTokens.d.ts.map +1 -0
- package/dist/utils/extractTokens.js +50 -0
- package/dist/utils/getCursorInfo.d.ts +7 -0
- package/dist/utils/getCursorInfo.d.ts.map +1 -0
- package/dist/utils/getCursorInfo.js +86 -0
- package/dist/utils/getOppositeDelimiter.d.ts +6 -0
- package/dist/utils/getOppositeDelimiter.d.ts.map +1 -0
- package/dist/utils/getOppositeDelimiter.js +35 -0
- package/dist/utils/getSurroundingErrors.d.ts +25 -0
- package/dist/utils/getSurroundingErrors.d.ts.map +1 -0
- package/dist/utils/getSurroundingErrors.js +37 -0
- package/dist/utils/index.d.ts +10 -0
- package/dist/utils/index.d.ts.map +1 -0
- package/dist/utils/index.js +20 -0
- package/dist/utils/isBracket.d.ts +3 -0
- package/dist/utils/isBracket.d.ts.map +1 -0
- package/dist/utils/isBracket.js +7 -0
- package/dist/utils/isDelimiter.d.ts +6 -0
- package/dist/utils/isDelimiter.d.ts.map +1 -0
- package/dist/utils/isDelimiter.js +17 -0
- package/dist/utils/isParen.d.ts +3 -0
- package/dist/utils/isParen.d.ts.map +1 -0
- package/dist/utils/isParen.js +7 -0
- package/dist/utils/isQuote.d.ts +4 -0
- package/dist/utils/isQuote.d.ts.map +1 -0
- package/dist/utils/isQuote.js +7 -0
- package/dist/utils/prettyAst.d.ts +35 -0
- package/dist/utils/prettyAst.d.ts.map +1 -0
- package/dist/utils/prettyAst.js +112 -0
- package/package.json +152 -0
- package/src/ast/builders/array.ts +45 -0
- package/src/ast/builders/condition.ts +56 -0
- package/src/ast/builders/delim.ts +39 -0
- package/src/ast/builders/error.ts +22 -0
- package/src/ast/builders/expression.ts +66 -0
- package/src/ast/builders/group.ts +79 -0
- package/src/ast/builders/index.ts +13 -0
- package/src/ast/builders/isFullPos.ts +10 -0
- package/src/ast/builders/pos.ts +57 -0
- package/src/ast/builders/token.ts +46 -0
- package/src/ast/builders/type.ts +32 -0
- package/src/ast/builders/variable.ts +89 -0
- package/src/ast/classes/ArrayNode.ts +46 -0
- package/src/ast/classes/Condition.ts +22 -0
- package/src/ast/classes/ConditionNode.ts +141 -0
- package/src/ast/classes/ErrorToken.ts +49 -0
- package/src/ast/classes/Expression.ts +26 -0
- package/src/ast/classes/ExpressionNode.ts +62 -0
- package/src/ast/classes/GroupNode.ts +127 -0
- package/src/ast/classes/Node.ts +47 -0
- package/src/ast/classes/Token.ts +59 -0
- package/src/ast/classes/ValidToken.ts +56 -0
- package/src/ast/classes/VariableNode.ts +67 -0
- package/src/ast/classes/index.ts +13 -0
- package/src/ast/handlers.ts +190 -0
- package/src/ast/index.ts +5 -0
- package/src/examples/advancedValueComparer.ts +31 -0
- package/src/examples/shortcutContextParser.ts +140 -0
- package/src/global.d.ts +4 -0
- package/src/grammar/ParserBase.ts +715 -0
- package/src/grammar/createTokens.ts +512 -0
- package/src/grammar/index.ts +4 -0
- package/src/helpers/errors.ts +45 -0
- package/src/helpers/general/applyBoolean.ts +9 -0
- package/src/helpers/general/applyPrefix.ts +7 -0
- package/src/helpers/general/defaultConditionNormalizer.ts +9 -0
- package/src/helpers/general/defaultKeyParser.ts +8 -0
- package/src/helpers/general/defaultPrefixApplier.ts +7 -0
- package/src/helpers/general/defaultValueComparer.ts +7 -0
- package/src/helpers/general/index.ts +8 -0
- package/src/helpers/index.ts +5 -0
- package/src/helpers/parser/assignParents.ts +51 -0
- package/src/helpers/parser/checkParserOpts.ts +143 -0
- package/src/helpers/parser/extractPosition.ts +15 -0
- package/src/helpers/parser/getUnclosedRightParenCount.ts +22 -0
- package/src/helpers/parser/index.ts +10 -0
- package/src/helpers/parser/parseParserOptions.ts +54 -0
- package/src/helpers/parser/seal.ts +14 -0
- package/src/helpers/parser/setParent.ts +5 -0
- package/src/helpers/parser/unescape.ts +4 -0
- package/src/index.ts +7 -0
- package/src/methods/autocomplete.ts +128 -0
- package/src/methods/autoreplace.ts +46 -0
- package/src/methods/autosuggest.ts +543 -0
- package/src/methods/evaluate.ts +37 -0
- package/src/methods/getBestIndex.ts +53 -0
- package/src/methods/getIndexes.ts +99 -0
- package/src/methods/index.ts +10 -0
- package/src/methods/normalize.ts +138 -0
- package/src/methods/validate.ts +141 -0
- package/src/package.js +11 -0
- package/src/parser.ts +183 -0
- package/src/types/ast.ts +148 -0
- package/src/types/autocomplete.ts +152 -0
- package/src/types/errors.ts +40 -0
- package/src/types/index.ts +6 -0
- package/src/types/parser.ts +479 -0
- package/src/utils/extractTokens.ts +67 -0
- package/src/utils/getCursorInfo.ts +106 -0
- package/src/utils/getOppositeDelimiter.ts +36 -0
- package/src/utils/getSurroundingErrors.ts +57 -0
- package/src/utils/index.ts +11 -0
- package/src/utils/isBracket.ts +6 -0
- package/src/utils/isDelimiter.ts +18 -0
- package/src/utils/isParen.ts +6 -0
- package/src/utils/isQuote.ts +6 -0
- package/src/utils/prettyAst.ts +152 -0
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { unreachable } from "@alanscodelog/utils"
|
|
2
|
+
|
|
3
|
+
import { isBracket } from "./isBracket.js"
|
|
4
|
+
import { isDelimiter } from "./isDelimiter.js"
|
|
5
|
+
import { isParen } from "./isParen.js"
|
|
6
|
+
import { isQuote } from "./isQuote.js"
|
|
7
|
+
|
|
8
|
+
import type { ArrayNode, ConditionNode, GroupNode, VariableNode } from "../ast/classes/index.js"
|
|
9
|
+
import { type AnyToken, TOKEN_TYPE, type TokenDelimiterTypes } from "../types/ast.js"
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Given a delimiter token, returns it's opposite pair, or undefined if the type passed was not a delimiter token (so you can pass any type without checking).
|
|
13
|
+
*/
|
|
14
|
+
export function getOppositeDelimiter(token: AnyToken): AnyToken<TokenDelimiterTypes> | undefined {
|
|
15
|
+
if (!isDelimiter(token)) throw new Error("Token is not a delimiter type.")
|
|
16
|
+
if (isParen(token)) {
|
|
17
|
+
const paren = (token.parent as GroupNode).paren
|
|
18
|
+
const opposite = paren.left === token ? "right" : "left"
|
|
19
|
+
return paren[opposite]
|
|
20
|
+
} else if (isBracket(token)) {
|
|
21
|
+
const bracket = (token.parent as ArrayNode).bracket
|
|
22
|
+
const opposite = bracket.left === token ? "right" : "left"
|
|
23
|
+
return bracket[opposite]
|
|
24
|
+
} else if (isQuote(token)) {
|
|
25
|
+
const quotes = (token.parent as VariableNode).quote
|
|
26
|
+
if (quotes === undefined) unreachable()
|
|
27
|
+
const opposite = quotes.left === token ? "right" : "left"
|
|
28
|
+
return quotes[opposite]
|
|
29
|
+
} else if (token.type === TOKEN_TYPE.OP_EXPANDED_SEP) {
|
|
30
|
+
const sep = (token.parent as ConditionNode).sep
|
|
31
|
+
if (sep === undefined) unreachable()
|
|
32
|
+
const opposite = sep.left === token ? "right" : "left"
|
|
33
|
+
return sep[opposite]
|
|
34
|
+
}
|
|
35
|
+
unreachable()
|
|
36
|
+
}
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mostly for internal use by @see autosuggest.
|
|
3
|
+
*
|
|
4
|
+
* Returns all error tokens immediately before/after cursor (since there might be multiple error tokens one after the other).
|
|
5
|
+
*
|
|
6
|
+
* The errors are sorted by closeness to the given cursor (inside @see CursorInfo), with quote errors having priority, then paren errors, then any other errors. They can be sorted by closeness because although two errors might follow each other, their positions might be different because of whitespace, but they can still be fixed from any cursor position between their ends.
|
|
7
|
+
*
|
|
8
|
+
* For example:
|
|
9
|
+
* ```
|
|
10
|
+
* a a"
|
|
11
|
+
* ^ operator missing at 1
|
|
12
|
+
* ^ doublequote missing at 2
|
|
13
|
+
* if the cursor is at 1 (`a| a"`):
|
|
14
|
+
* errors = [operator, doublequote]
|
|
15
|
+
* if the cursor is at 2 (`a |a"`):
|
|
16
|
+
* errors = [doublequote, operator]
|
|
17
|
+
*
|
|
18
|
+
* either insertion would fix the issue for either position would fix the issue, albeit with different results
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
|
|
22
|
+
import { ErrorToken } from "../ast/classes/ErrorToken.js"
|
|
23
|
+
import { type AnyToken, TOKEN_TYPE } from "../types/ast.js"
|
|
24
|
+
import type { CursorInfo } from "../types/autocomplete.js"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
export function getSurroundingErrors(tokens: AnyToken[], token: CursorInfo): ErrorToken[] {
|
|
28
|
+
if (token.at) {return []}
|
|
29
|
+
const i = tokens.indexOf(token.next ?? token.prev as any)
|
|
30
|
+
|
|
31
|
+
let iNext: number = tokens[i] === token.next ? i : i + 1
|
|
32
|
+
let iPrev: number = tokens[i] === token.next ? i - 1 : i
|
|
33
|
+
|
|
34
|
+
const errors = []
|
|
35
|
+
while (tokens[iNext] instanceof ErrorToken) {
|
|
36
|
+
errors.push(tokens[iNext])
|
|
37
|
+
iNext++
|
|
38
|
+
}
|
|
39
|
+
while (tokens[iPrev] instanceof ErrorToken) {
|
|
40
|
+
errors.push(tokens[iPrev])
|
|
41
|
+
iPrev--
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return errors.sort((a, b) => {
|
|
45
|
+
const aIsQuote = [TOKEN_TYPE.DOUBLEQUOTE, TOKEN_TYPE.BACKTICK, TOKEN_TYPE.SINGLEQUOTE].includes(a.expected[0])
|
|
46
|
+
const bIsQuote = [TOKEN_TYPE.DOUBLEQUOTE, TOKEN_TYPE.BACKTICK, TOKEN_TYPE.SINGLEQUOTE].includes(b.expected[0])
|
|
47
|
+
const aIsParen = [TOKEN_TYPE.PARENR, TOKEN_TYPE.PARENL].includes(a.expected[0])
|
|
48
|
+
const bIsParen = [TOKEN_TYPE.PARENR, TOKEN_TYPE.PARENL].includes(b.expected[0])
|
|
49
|
+
const aCloseness = Math.abs(i - tokens.indexOf(a))
|
|
50
|
+
const bCloseness = Math.abs(i - tokens.indexOf(b))
|
|
51
|
+
const closenessComparison = aCloseness - bCloseness
|
|
52
|
+
if (aIsQuote === bIsQuote) {
|
|
53
|
+
if (aIsParen !== bIsParen) {return aIsParen ? -1 : 1}
|
|
54
|
+
}
|
|
55
|
+
return closenessComparison
|
|
56
|
+
}) as ErrorToken[]
|
|
57
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/* Autogenerated Index */
|
|
2
|
+
|
|
3
|
+
export { extractTokens } from "./extractTokens.js"
|
|
4
|
+
export { getCursorInfo } from "./getCursorInfo.js"
|
|
5
|
+
export { getOppositeDelimiter } from "./getOppositeDelimiter.js"
|
|
6
|
+
export { getSurroundingErrors } from "./getSurroundingErrors.js"
|
|
7
|
+
export { isBracket } from "./isBracket.js"
|
|
8
|
+
export { isDelimiter } from "./isDelimiter.js"
|
|
9
|
+
export { isParen } from "./isParen.js"
|
|
10
|
+
export { isQuote } from "./isQuote.js"
|
|
11
|
+
export { prettyAst } from "./prettyAst.js"
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { type AnyToken, TOKEN_TYPE, type TokenDelimiterTypes } from "../types/ast.js"
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Returns whether token is a delimiter type (including if it's an expanded operator separator).
|
|
5
|
+
*/
|
|
6
|
+
export function isDelimiter(token?: AnyToken): token is AnyToken<TokenDelimiterTypes> {
|
|
7
|
+
return ([
|
|
8
|
+
TOKEN_TYPE.BACKTICK,
|
|
9
|
+
TOKEN_TYPE.DOUBLEQUOTE,
|
|
10
|
+
TOKEN_TYPE.SINGLEQUOTE,
|
|
11
|
+
TOKEN_TYPE.PARENL,
|
|
12
|
+
TOKEN_TYPE.PARENR,
|
|
13
|
+
TOKEN_TYPE.BRACKETL,
|
|
14
|
+
TOKEN_TYPE.BRACKETR,
|
|
15
|
+
TOKEN_TYPE.OP_EXPANDED_SEP,
|
|
16
|
+
TOKEN_TYPE.REGEX,
|
|
17
|
+
] as TokenDelimiterTypes[]).includes(token?.type as TokenDelimiterTypes)
|
|
18
|
+
}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type AnyToken, TOKEN_TYPE, type TokenQuoteTypes } from "../types/ast.js"
|
|
2
|
+
|
|
3
|
+
/** Returns if the token is a quote token. This includes regex delimiters. */
|
|
4
|
+
export function isQuote(token?: AnyToken): token is AnyToken<TokenQuoteTypes> {
|
|
5
|
+
return ([TOKEN_TYPE.BACKTICK, TOKEN_TYPE.DOUBLEQUOTE, TOKEN_TYPE.SINGLEQUOTE, TOKEN_TYPE.REGEX] as any[]).includes(token?.type)
|
|
6
|
+
}
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
/* eslint-disable prefer-rest-params */
|
|
2
|
+
import { type AddParameters, colors as color } from "@alanscodelog/utils"
|
|
3
|
+
import { isBlank, unreachable } from "@alanscodelog/utils"
|
|
4
|
+
|
|
5
|
+
import { ArrayNode, ConditionNode, ErrorToken, ExpressionNode, GroupNode, ValidToken, VariableNode } from "../ast/classes/index.js"
|
|
6
|
+
import { type AnyToken, type ParserResults, TOKEN_TYPE } from "../types/ast.js"
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
type Colors = {
|
|
10
|
+
/** Color used to highlight the actual text content of the token nodes. */
|
|
11
|
+
values: string
|
|
12
|
+
/** Color used to highlight the extra information some nodes contain in their headers for a quick overview (e.g. which operator for expression nodes, if a condition/group value is true, how long an array value is etc). */
|
|
13
|
+
info: string
|
|
14
|
+
position: string
|
|
15
|
+
/** Color used to highlight the hints in parens that indicate how the node is being used (e.g. a variable node might be a property, or alone as a variable, etc) */
|
|
16
|
+
hint: string
|
|
17
|
+
error: string
|
|
18
|
+
/** Color used to reset highlights. */
|
|
19
|
+
reset: string
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const defaultColors: Colors = {
|
|
23
|
+
values: color.yellow,
|
|
24
|
+
info: color.cyan,
|
|
25
|
+
position: color.green,
|
|
26
|
+
hint: color.blue,
|
|
27
|
+
error: color.red,
|
|
28
|
+
reset: color.reset,
|
|
29
|
+
}
|
|
30
|
+
const disableColors: Colors = Object.fromEntries(Object.keys(defaultColors).map(key => [key, ""])) as Colors
|
|
31
|
+
|
|
32
|
+
const toRows = (rows: string[], opts: Required<NonNullable<Parameters<typeof prettyAst>[1]>>): string[] => {
|
|
33
|
+
rows = rows.filter(child => child !== "")
|
|
34
|
+
|
|
35
|
+
return [
|
|
36
|
+
...rows.slice(0, rows.length - 1).map(child => `${opts.indent}${opts.children}${child}`),
|
|
37
|
+
`${opts.indent}${opts.last}${rows[rows.length - 1]}`,
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Returns a more compressed, color coded, string representation of the ast for debugging.
|
|
42
|
+
*
|
|
43
|
+
* There are options to change which symbols are used for tree and if the variables are surrounded by quotes (default false).
|
|
44
|
+
*
|
|
45
|
+
* Colors can changed by passing ansi codes (or whatever you want\*) to the third parameter. Or you can pass false instead of an object to disable them. Default colors are:
|
|
46
|
+
* ```ts
|
|
47
|
+
* {
|
|
48
|
+
* values: // yellow,
|
|
49
|
+
* position: // green,
|
|
50
|
+
* info: // cyan,
|
|
51
|
+
* hint: // blue,
|
|
52
|
+
* error: // red,
|
|
53
|
+
* reset: // ansi reset code
|
|
54
|
+
* }
|
|
55
|
+
* ```
|
|
56
|
+
* \* For example, you could pass html tags to show this in the browser instead (this is how the demo works). This is why the reset color is exposed. For example, a color might be `<span class="error">` and reset can be `</span>`.
|
|
57
|
+
*/
|
|
58
|
+
|
|
59
|
+
export function prettyAst(
|
|
60
|
+
ast: ParserResults | AnyToken | VariableNode | ArrayNode | GroupNode,
|
|
61
|
+
{ indent = " ", children = "├╴", last = "└╴", branch = "│", quote = "" }: Partial<Record<"indent" | "children" | "last" | "branch" | "quote", string>> = {},
|
|
62
|
+
colors: Partial<Colors> | false = {},
|
|
63
|
+
): string {
|
|
64
|
+
const opts = { indent, children, last, branch, quote }
|
|
65
|
+
const c: Colors = colors ? { ...defaultColors, ...colors } : disableColors
|
|
66
|
+
const pos = `${c.position}(${ast.start}, ${ast.end})${c.reset}`
|
|
67
|
+
const _ = indent
|
|
68
|
+
// accumulated indent
|
|
69
|
+
const __: string = arguments[3] ?? ""
|
|
70
|
+
let extra: string = arguments[4] ?? ""
|
|
71
|
+
if (!isBlank(extra)) extra = ` ${c.hint}${extra}${c.reset}`
|
|
72
|
+
// indent to add to children items
|
|
73
|
+
const ___ = __ + _ + branch
|
|
74
|
+
// indent to add to last child item
|
|
75
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
76
|
+
const __L = __ + _ + indent[0]
|
|
77
|
+
const prettyAst_ = prettyAst as any as AddParameters<typeof prettyAst, [
|
|
78
|
+
typeof __,
|
|
79
|
+
typeof extra,
|
|
80
|
+
]>
|
|
81
|
+
if (ast instanceof ValidToken) {
|
|
82
|
+
const value = `${ast.value}`
|
|
83
|
+
return `TOKEN ${pos} ${c.values}${quote}${value}${quote}${c.reset}${extra}`
|
|
84
|
+
}
|
|
85
|
+
if (ast instanceof ErrorToken) {
|
|
86
|
+
const value = `[${ast.expected.join(", ")}]`
|
|
87
|
+
return `ERROR ${pos} ${c.error}${value}${c.reset}${extra}`
|
|
88
|
+
}
|
|
89
|
+
if (ast instanceof ConditionNode) {
|
|
90
|
+
const header = `${c.info}${ast.operator === undefined}${c.reset}`
|
|
91
|
+
const not = ast.operator ? prettyAst_(ast.operator, opts, c, ___, `(negation)`) : ""
|
|
92
|
+
const property = ast.property ? prettyAst_(ast.property, opts, c, ___, `(property)`) : ""
|
|
93
|
+
const sepL = ast.sep?.left ? prettyAst_(ast.sep.left, opts, c, ___, `(separator)`) : ""
|
|
94
|
+
const op = ast.propertyOperator ? prettyAst_(ast.propertyOperator, opts, c, ___, `(property operator)`) : ""
|
|
95
|
+
const sepR = ast.sep?.right ? prettyAst_(ast.sep.right, opts, c, ___, `(separator)`) : ""
|
|
96
|
+
const isRegex = ast.value instanceof VariableNode && ast.value.quote?.left.type === TOKEN_TYPE.REGEX
|
|
97
|
+
const isArray = ast.value instanceof ArrayNode
|
|
98
|
+
const variable = prettyAst_(ast.value, opts, c, __L, `(${property ? "value" : "variable/alone"}${isRegex ? " - regex" : isArray ? "- array" : ""})`)
|
|
99
|
+
return [
|
|
100
|
+
`CONDITION ${pos} ${header}${extra}`,
|
|
101
|
+
...toRows([not, property, sepL, op, sepR, variable], opts),
|
|
102
|
+
].join(`\n${__}`)
|
|
103
|
+
}
|
|
104
|
+
if (ast instanceof VariableNode) {
|
|
105
|
+
const prefix = ast.prefix ? prettyAst_(ast.prefix, opts, c, ___, `(value prefix)`) : ""
|
|
106
|
+
const left = ast.quote?.left ? prettyAst_(ast.quote.left, opts, c, ___, "") : ""
|
|
107
|
+
const value = prettyAst_(ast.value, opts, c, !ast.quote ? __L : !ast.quote?.right ? __L : ___, "")
|
|
108
|
+
const right = ast.quote?.right ? prettyAst_(ast.quote.right, opts, c, !ast.quote?.flags ? __L : ___, "") : ""
|
|
109
|
+
const flags = ast.quote?.flags ? prettyAst_(ast.quote.flags, opts, c, __L, "(flags)") : ""
|
|
110
|
+
|
|
111
|
+
return [
|
|
112
|
+
`VARIABLE ${pos}${extra}`,
|
|
113
|
+
...toRows([prefix, left, value, right, flags], opts),
|
|
114
|
+
].join(`\n${__}`)
|
|
115
|
+
}
|
|
116
|
+
if (ast instanceof GroupNode) {
|
|
117
|
+
const header = `${c.info}${ast.prefix === undefined || (ast.prefix as ConditionNode).operator === undefined}${c.reset}`
|
|
118
|
+
const prefix = ast.prefix ? prettyAst_(ast.prefix, opts, c, ___, `(group prefix)`) : ""
|
|
119
|
+
const expression = prettyAst_(ast.expression, opts, c, __L, "")
|
|
120
|
+
return [
|
|
121
|
+
`GROUP ${pos}${!extra.includes("value") ? ` ${header}` : ""}${extra}`,
|
|
122
|
+
...toRows([prefix, expression], opts),
|
|
123
|
+
].join(`\n${__}`)
|
|
124
|
+
}
|
|
125
|
+
if (ast instanceof ArrayNode) {
|
|
126
|
+
const bracketL = ast.bracket.left ? prettyAst_(ast.bracket.left, opts, c, ast.values.length === 0 && !ast.bracket.right ? __L : ___, "") : ""
|
|
127
|
+
const values = ast.values.length > 0
|
|
128
|
+
? ast.values.map((node, i) =>
|
|
129
|
+
prettyAst_(node, opts, c, !ast.bracket.right && i === ast.values.length - 1 ? __L : ___, "")
|
|
130
|
+
)
|
|
131
|
+
: []
|
|
132
|
+
const bracketR = ast.bracket.right ? prettyAst_(ast.bracket.right, opts, c, __L, "") : ""
|
|
133
|
+
return [
|
|
134
|
+
`ARRAY ${pos} ${c.info}[${ast.values.length}]${c.reset}${extra}`,
|
|
135
|
+
...toRows([bracketL, ...values, bracketR], opts),
|
|
136
|
+
].join(`\n${__}`)
|
|
137
|
+
}
|
|
138
|
+
if (ast instanceof ExpressionNode) {
|
|
139
|
+
const left = prettyAst_(ast.left, opts, c, ___, "")
|
|
140
|
+
const operator = prettyAst_(ast.operator, opts, c, ___, `(boolean operator)`)
|
|
141
|
+
const right = prettyAst_(ast.right, opts, c, __L, "")
|
|
142
|
+
|
|
143
|
+
const header = ast.operator instanceof ErrorToken
|
|
144
|
+
? `${c.info}[${ast.operator.expected.join(",")}]${c.reset}`
|
|
145
|
+
: `${c.info}"${ast.operator.value}"${c.reset}`
|
|
146
|
+
return [
|
|
147
|
+
`EXPRESSION ${pos} ${header}${extra}`,
|
|
148
|
+
...toRows([left, operator, right], opts),
|
|
149
|
+
].join(`\n${__}`)
|
|
150
|
+
}
|
|
151
|
+
unreachable()
|
|
152
|
+
}
|