@herb-tools/core 0.1.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/CHANGELOG.md +3 -0
- package/README.md +9 -0
- package/dist/herb-core.browser.js +2704 -0
- package/dist/herb-core.browser.js.map +1 -0
- package/dist/herb-core.cjs +2759 -0
- package/dist/herb-core.cjs.map +1 -0
- package/dist/herb-core.esm.js +2704 -0
- package/dist/herb-core.esm.js.map +1 -0
- package/dist/herb-core.umd.js +2765 -0
- package/dist/herb-core.umd.js.map +1 -0
- package/dist/types/ast.d.ts +4 -0
- package/dist/types/backend.d.ts +24 -0
- package/dist/types/error.d.ts +16 -0
- package/dist/types/errors.d.ts +222 -0
- package/dist/types/herb-backend.d.ts +87 -0
- package/dist/types/index.d.ts +15 -0
- package/dist/types/lex-result.d.ts +50 -0
- package/dist/types/location.d.ts +18 -0
- package/dist/types/node.d.ts +27 -0
- package/dist/types/nodes.d.ts +682 -0
- package/dist/types/parse-result.d.ts +62 -0
- package/dist/types/position.d.ts +15 -0
- package/dist/types/range.d.ts +12 -0
- package/dist/types/result.d.ts +10 -0
- package/dist/types/token-list.d.ts +16 -0
- package/dist/types/token.d.ts +22 -0
- package/dist/types/util.d.ts +2 -0
- package/dist/types/visitor.d.ts +11 -0
- package/dist/types/warning.d.ts +11 -0
- package/package.json +49 -0
- package/src/ast.ts +7 -0
- package/src/backend.ts +85 -0
- package/src/error.ts +38 -0
- package/src/errors.ts +820 -0
- package/src/herb-backend.ts +152 -0
- package/src/index.ts +15 -0
- package/src/lex-result.ts +78 -0
- package/src/location.ts +51 -0
- package/src/node.ts +106 -0
- package/src/nodes.ts +2294 -0
- package/src/parse-result.ts +101 -0
- package/src/position.ts +38 -0
- package/src/range.ts +35 -0
- package/src/result.ts +26 -0
- package/src/token-list.ts +57 -0
- package/src/token.ts +63 -0
- package/src/util.ts +19 -0
- package/src/visitor.ts +14 -0
- package/src/warning.ts +20 -0
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { Result } from "./result.js";
|
|
2
|
+
import { DocumentNode } from "./nodes.js";
|
|
3
|
+
import { HerbError } from "./error.js";
|
|
4
|
+
import { HerbWarning } from "./warning.js";
|
|
5
|
+
import type { SerializedHerbError } from "./error.js";
|
|
6
|
+
import type { SerializedHerbWarning } from "./warning.js";
|
|
7
|
+
import type { SerializedDocumentNode } from "./nodes.js";
|
|
8
|
+
import type { Visitor } from "./visitor.js";
|
|
9
|
+
export type SerializedParseResult = {
|
|
10
|
+
value: SerializedDocumentNode;
|
|
11
|
+
source: string;
|
|
12
|
+
warnings: SerializedHerbWarning[];
|
|
13
|
+
errors: SerializedHerbError[];
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Represents the result of a parsing operation, extending the base `Result` class.
|
|
17
|
+
* It contains the parsed document node, source code, warnings, and errors.
|
|
18
|
+
*/
|
|
19
|
+
export declare class ParseResult extends Result {
|
|
20
|
+
/** The document node generated from the source code. */
|
|
21
|
+
readonly value: DocumentNode;
|
|
22
|
+
/**
|
|
23
|
+
* Creates a `ParseResult` instance from a serialized result.
|
|
24
|
+
* @param result - The serialized parse result containing the value and source.
|
|
25
|
+
* @returns A new `ParseResult` instance.
|
|
26
|
+
*/
|
|
27
|
+
static from(result: SerializedParseResult): ParseResult;
|
|
28
|
+
/**
|
|
29
|
+
* Constructs a new `ParseResult`.
|
|
30
|
+
* @param value - The document node.
|
|
31
|
+
* @param source - The source code that was parsed.
|
|
32
|
+
* @param warnings - An array of warnings encountered during parsing.
|
|
33
|
+
* @param errors - An array of errors encountered during parsing.
|
|
34
|
+
*/
|
|
35
|
+
constructor(value: DocumentNode, source: string, warnings?: HerbWarning[], errors?: HerbError[]);
|
|
36
|
+
/**
|
|
37
|
+
* Determines if the parsing failed.
|
|
38
|
+
* @returns `true` if there are errors, otherwise `false`.
|
|
39
|
+
*/
|
|
40
|
+
failed(): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Determines if the parsing was successful.
|
|
43
|
+
* @returns `true` if there are no errors, otherwise `false`.
|
|
44
|
+
*/
|
|
45
|
+
success(): boolean;
|
|
46
|
+
/**
|
|
47
|
+
* Returns a pretty-printed JSON string of the errors.
|
|
48
|
+
* @returns A string representation of the errors.
|
|
49
|
+
*/
|
|
50
|
+
prettyErrors(): string;
|
|
51
|
+
recursiveErrors(): HerbError[];
|
|
52
|
+
/**
|
|
53
|
+
* Returns a pretty-printed string of the parse result.
|
|
54
|
+
* @returns A string representation of the parse result.
|
|
55
|
+
*/
|
|
56
|
+
inspect(): string;
|
|
57
|
+
/**
|
|
58
|
+
* Accepts a visitor to traverse the document node.
|
|
59
|
+
* @param visitor - The visitor instance.
|
|
60
|
+
*/
|
|
61
|
+
visit(visitor: Visitor): void;
|
|
62
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type SerializedPosition = {
|
|
2
|
+
line: number;
|
|
3
|
+
column: number;
|
|
4
|
+
};
|
|
5
|
+
export declare class Position {
|
|
6
|
+
readonly line: number;
|
|
7
|
+
readonly column: number;
|
|
8
|
+
static from(position: SerializedPosition): Position;
|
|
9
|
+
constructor(line: number, column: number);
|
|
10
|
+
toHash(): SerializedPosition;
|
|
11
|
+
toJSON(): SerializedPosition;
|
|
12
|
+
treeInspect(): string;
|
|
13
|
+
inspect(): string;
|
|
14
|
+
toString(): string;
|
|
15
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export type SerializedRange = [number, number];
|
|
2
|
+
export declare class Range {
|
|
3
|
+
readonly start: number;
|
|
4
|
+
readonly end: number;
|
|
5
|
+
static from(range: SerializedRange): Range;
|
|
6
|
+
constructor(start: number, end: number);
|
|
7
|
+
toArray(): SerializedRange;
|
|
8
|
+
toJSON(): SerializedRange;
|
|
9
|
+
treeInspect(): string;
|
|
10
|
+
inspect(): string;
|
|
11
|
+
toString(): string;
|
|
12
|
+
}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { HerbError } from "./error.js";
|
|
2
|
+
import { HerbWarning } from "./warning.js";
|
|
3
|
+
export declare class Result {
|
|
4
|
+
readonly source: string;
|
|
5
|
+
readonly warnings: HerbWarning[];
|
|
6
|
+
readonly errors: HerbError[];
|
|
7
|
+
constructor(source: string, warnings?: HerbWarning[], errors?: HerbError[]);
|
|
8
|
+
success(): boolean;
|
|
9
|
+
failed(): boolean;
|
|
10
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { Token, SerializedToken } from "./token.js";
|
|
2
|
+
export type SerializedTokenList = SerializedToken[];
|
|
3
|
+
export declare class TokenList implements Iterable<Token> {
|
|
4
|
+
private list;
|
|
5
|
+
static from(list: SerializedTokenList): TokenList;
|
|
6
|
+
constructor(list: Token[]);
|
|
7
|
+
get length(): number;
|
|
8
|
+
[Symbol.iterator](): Iterator<Token>;
|
|
9
|
+
at(index: number): Token | undefined;
|
|
10
|
+
forEach(callback: (token: Token, index: number, array: Token[]) => void): void;
|
|
11
|
+
map<U>(callback: (token: Token, index: number, array: Token[]) => U): U[];
|
|
12
|
+
filter(predicate: (token: Token, index: number, array: Token[]) => boolean): Token[];
|
|
13
|
+
__getobj__(): Token[];
|
|
14
|
+
inspect(): string;
|
|
15
|
+
toString(): string;
|
|
16
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { Range, SerializedRange } from "./range.js";
|
|
2
|
+
import { Location, SerializedLocation } from "./location.js";
|
|
3
|
+
export type SerializedToken = {
|
|
4
|
+
value: string;
|
|
5
|
+
range: SerializedRange;
|
|
6
|
+
location: SerializedLocation;
|
|
7
|
+
type: string;
|
|
8
|
+
};
|
|
9
|
+
export declare class Token {
|
|
10
|
+
readonly value: string;
|
|
11
|
+
readonly range: Range;
|
|
12
|
+
readonly location: Location;
|
|
13
|
+
readonly type: string;
|
|
14
|
+
static from(token: SerializedToken): Token;
|
|
15
|
+
constructor(value: string, range: Range, location: Location, type: string);
|
|
16
|
+
toHash(): SerializedToken;
|
|
17
|
+
toJSON(): SerializedToken;
|
|
18
|
+
treeInspect(): string;
|
|
19
|
+
valueInspect(): string;
|
|
20
|
+
inspect(): string;
|
|
21
|
+
toString(): string;
|
|
22
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { Location, SerializedLocation } from "./location.js";
|
|
2
|
+
export interface SerializedHerbWarning {
|
|
3
|
+
message: string;
|
|
4
|
+
location: SerializedLocation;
|
|
5
|
+
}
|
|
6
|
+
export declare class HerbWarning {
|
|
7
|
+
message: string;
|
|
8
|
+
location: Location;
|
|
9
|
+
static from(warning: SerializedHerbWarning): HerbWarning;
|
|
10
|
+
constructor(message: string, location: Location);
|
|
11
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@herb-tools/core",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"homepage": "https://herb-tools.dev",
|
|
7
|
+
"bugs": "https://github.com/marcoroth/herb/issues/new?title=Package%20%60@herb-tools/core%60:%20",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "https://github.com/marcoroth/herb.git",
|
|
11
|
+
"directory": "javascript/packages/core"
|
|
12
|
+
},
|
|
13
|
+
"main": "./dist/herb-core.cjs",
|
|
14
|
+
"module": "./dist/herb-core.esm.js",
|
|
15
|
+
"types": "./dist/types/index.d.ts",
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "yarn clean && rollup -c",
|
|
18
|
+
"dev": "rollup -c -w",
|
|
19
|
+
"clean": "rimraf dist",
|
|
20
|
+
"test": "vitest run",
|
|
21
|
+
"prepublishOnly": "yarn clean && yarn build && yarn test"
|
|
22
|
+
},
|
|
23
|
+
"exports": {
|
|
24
|
+
"./package.json": "./package.json",
|
|
25
|
+
".": {
|
|
26
|
+
"types": "./dist/types/index.d.ts",
|
|
27
|
+
"import": "./dist/herb-core.esm.js",
|
|
28
|
+
"require": "./dist/herb-core.cjs",
|
|
29
|
+
"default": "./dist/herb-core.esm.js"
|
|
30
|
+
}
|
|
31
|
+
},
|
|
32
|
+
"dependencies": {},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@rollup/plugin-json": "^6.1.0",
|
|
35
|
+
"@rollup/plugin-node-resolve": "^16.0.1",
|
|
36
|
+
"@rollup/plugin-typescript": "^12.1.2",
|
|
37
|
+
"rimraf": "^6.0.1",
|
|
38
|
+
"rollup": "^4.35.0",
|
|
39
|
+
"tslib": "^2.8.1",
|
|
40
|
+
"typescript": "^5.8.2",
|
|
41
|
+
"vitest": "^3.0.0"
|
|
42
|
+
},
|
|
43
|
+
"files": [
|
|
44
|
+
"package.json",
|
|
45
|
+
"README.md",
|
|
46
|
+
"dist/",
|
|
47
|
+
"src/"
|
|
48
|
+
]
|
|
49
|
+
}
|
package/src/ast.ts
ADDED
package/src/backend.ts
ADDED
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
import type { SerializedParseResult } from "./parse-result.js"
|
|
2
|
+
import type { SerializedLexResult } from "./lex-result.js"
|
|
3
|
+
|
|
4
|
+
interface LibHerbBackendFunctions {
|
|
5
|
+
lex: (source: string) => SerializedLexResult
|
|
6
|
+
lexFile: (path: string) => SerializedLexResult
|
|
7
|
+
|
|
8
|
+
parse: (source: string) => SerializedParseResult
|
|
9
|
+
parseFile: (path: string) => SerializedParseResult
|
|
10
|
+
|
|
11
|
+
extractRuby: (source: string) => string
|
|
12
|
+
extractHTML: (source: string) => string
|
|
13
|
+
|
|
14
|
+
version: () => string
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export type BackendPromise = () => Promise<LibHerbBackend>
|
|
18
|
+
|
|
19
|
+
const expectedFunctions = [
|
|
20
|
+
"parse",
|
|
21
|
+
"lex",
|
|
22
|
+
"parseFile",
|
|
23
|
+
"lexFile",
|
|
24
|
+
"extractRuby",
|
|
25
|
+
"extractHTML",
|
|
26
|
+
"version",
|
|
27
|
+
] as const
|
|
28
|
+
|
|
29
|
+
type LibHerbBackendFunctionName = (typeof expectedFunctions)[number]
|
|
30
|
+
|
|
31
|
+
type CheckFunctionsExistInInterface =
|
|
32
|
+
LibHerbBackendFunctionName extends keyof LibHerbBackendFunctions
|
|
33
|
+
? true
|
|
34
|
+
: "Error: Not all expectedFunctions are defined in LibHerbBackendFunctions"
|
|
35
|
+
|
|
36
|
+
type CheckInterfaceKeysInFunctions =
|
|
37
|
+
keyof LibHerbBackendFunctions extends LibHerbBackendFunctionName
|
|
38
|
+
? true
|
|
39
|
+
: "Error: LibHerbBackendFunctions has keys not listed in expectedFunctions"
|
|
40
|
+
|
|
41
|
+
// NOTE: This function should never be called and is only for type checking
|
|
42
|
+
// so we can make sure `expectedFunctions` matches the functions defined
|
|
43
|
+
// in `LibHerbBackendFunctions` and the other way around.
|
|
44
|
+
//
|
|
45
|
+
export function _TYPECHECK() {
|
|
46
|
+
const checkFunctionsExist: CheckFunctionsExistInInterface = true
|
|
47
|
+
const checkInterfaceComplete: CheckInterfaceKeysInFunctions = true
|
|
48
|
+
|
|
49
|
+
return { checkFunctionsExist, checkInterfaceComplete }
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Exported Types + Functions
|
|
53
|
+
|
|
54
|
+
export type LibHerbBackend = {
|
|
55
|
+
[K in LibHerbBackendFunctionName]: LibHerbBackendFunctions[K]
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export function isLibHerbBackend(
|
|
59
|
+
object: any,
|
|
60
|
+
libherbpath: string = "unknown",
|
|
61
|
+
): object is LibHerbBackend {
|
|
62
|
+
for (const expectedFunction of expectedFunctions) {
|
|
63
|
+
if (object[expectedFunction] === undefined) {
|
|
64
|
+
throw new Error(
|
|
65
|
+
`Libherb at "${libherbpath}" doesn't expose function "${expectedFunction}".`,
|
|
66
|
+
)
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
if (typeof object[expectedFunction] !== "function") {
|
|
70
|
+
throw new Error(
|
|
71
|
+
`Libherb at "${libherbpath}" has "${expectedFunction}" but it's not a function.`,
|
|
72
|
+
)
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
return true
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export function ensureLibHerbBackend(
|
|
80
|
+
object: any,
|
|
81
|
+
libherbpath: string = "unknown",
|
|
82
|
+
): LibHerbBackend {
|
|
83
|
+
isLibHerbBackend(object, libherbpath)
|
|
84
|
+
return object
|
|
85
|
+
}
|
package/src/error.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Location, SerializedLocation } from "./location.js"
|
|
2
|
+
import { fromSerializedError } from "./errors.js"
|
|
3
|
+
|
|
4
|
+
export interface SerializedHerbError {
|
|
5
|
+
type: string
|
|
6
|
+
message: string
|
|
7
|
+
location: SerializedLocation
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export abstract class HerbError {
|
|
11
|
+
readonly type: string
|
|
12
|
+
readonly message: string
|
|
13
|
+
readonly location: Location
|
|
14
|
+
|
|
15
|
+
static from(error: SerializedHerbError): HerbError {
|
|
16
|
+
return fromSerializedError(error)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
constructor(type: string, message: string, location: Location) {
|
|
20
|
+
this.type = type
|
|
21
|
+
this.message = message
|
|
22
|
+
this.location = location
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
toJSON(): SerializedHerbError {
|
|
26
|
+
return {
|
|
27
|
+
type: this.type,
|
|
28
|
+
message: this.message,
|
|
29
|
+
location: this.location.toJSON(),
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
inspect(): string {
|
|
34
|
+
return this.treeInspect(0)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
abstract treeInspect(indent?: number): string
|
|
38
|
+
}
|