@herb-tools/core 0.7.5 → 0.8.1
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 -1
- package/dist/herb-core.browser.js +297 -15
- package/dist/herb-core.browser.js.map +1 -1
- package/dist/herb-core.cjs +301 -14
- package/dist/herb-core.cjs.map +1 -1
- package/dist/herb-core.esm.js +297 -15
- package/dist/herb-core.esm.js.map +1 -1
- package/dist/herb-core.umd.js +301 -14
- package/dist/herb-core.umd.js.map +1 -1
- package/dist/types/ast-utils.d.ts +7 -2
- package/dist/types/didyoumean.d.ts +46 -0
- package/dist/types/errors.d.ts +41 -1
- package/dist/types/index.d.ts +3 -1
- package/dist/types/levenshtein.d.ts +1 -0
- package/dist/types/location.d.ts +2 -0
- package/dist/types/position.d.ts +2 -0
- package/dist/types/range.d.ts +2 -0
- package/package.json +1 -2
- package/src/ast-utils.ts +9 -2
- package/src/didyoumean.ts +88 -0
- package/src/errors.ts +129 -1
- package/src/index.ts +3 -1
- package/src/levenshtein.ts +119 -0
- package/src/location.ts +17 -4
- package/src/node-type-guards.ts +1 -1
- package/src/nodes.ts +1 -1
- package/src/position.ts +12 -2
- package/src/range.ts +12 -2
- package/src/visitor.ts +1 -1
package/dist/herb-core.umd.js
CHANGED
|
@@ -7,8 +7,16 @@
|
|
|
7
7
|
class Position {
|
|
8
8
|
line;
|
|
9
9
|
column;
|
|
10
|
-
static from(
|
|
11
|
-
|
|
10
|
+
static from(positionOrLine, column) {
|
|
11
|
+
if (typeof positionOrLine === "number") {
|
|
12
|
+
return new Position(positionOrLine, column);
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
return new Position(positionOrLine.line, positionOrLine.column);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
static get zero() {
|
|
19
|
+
return new Position(0, 0);
|
|
12
20
|
}
|
|
13
21
|
constructor(line, column) {
|
|
14
22
|
this.line = line;
|
|
@@ -34,10 +42,20 @@
|
|
|
34
42
|
class Location {
|
|
35
43
|
start;
|
|
36
44
|
end;
|
|
37
|
-
static from(
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
45
|
+
static from(locationOrLine, column, endLine, endColumn) {
|
|
46
|
+
if (typeof locationOrLine === "number") {
|
|
47
|
+
const start = Position.from(locationOrLine, column);
|
|
48
|
+
const end = Position.from(endLine, endColumn);
|
|
49
|
+
return new Location(start, end);
|
|
50
|
+
}
|
|
51
|
+
else {
|
|
52
|
+
const start = Position.from(locationOrLine.start);
|
|
53
|
+
const end = Position.from(locationOrLine.end);
|
|
54
|
+
return new Location(start, end);
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
static get zero() {
|
|
58
|
+
return new Location(Position.zero, Position.zero);
|
|
41
59
|
}
|
|
42
60
|
constructor(start, end) {
|
|
43
61
|
this.start = start;
|
|
@@ -69,8 +87,16 @@
|
|
|
69
87
|
class Range {
|
|
70
88
|
start;
|
|
71
89
|
end;
|
|
72
|
-
static from(
|
|
73
|
-
|
|
90
|
+
static from(rangeOrStart, end) {
|
|
91
|
+
if (typeof rangeOrStart === "number") {
|
|
92
|
+
return new Range(rangeOrStart, end);
|
|
93
|
+
}
|
|
94
|
+
else {
|
|
95
|
+
return new Range(rangeOrStart[0], rangeOrStart[1]);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
static get zero() {
|
|
99
|
+
return new Range(0, 0);
|
|
74
100
|
}
|
|
75
101
|
constructor(start, end) {
|
|
76
102
|
this.start = start;
|
|
@@ -135,7 +161,7 @@
|
|
|
135
161
|
}
|
|
136
162
|
|
|
137
163
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
|
138
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release-0.
|
|
164
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.1/templates/javascript/packages/core/src/errors.ts.erb
|
|
139
165
|
class HerbError {
|
|
140
166
|
type;
|
|
141
167
|
message;
|
|
@@ -560,6 +586,84 @@
|
|
|
560
586
|
return output;
|
|
561
587
|
}
|
|
562
588
|
}
|
|
589
|
+
class ERBControlFlowScopeError extends HerbError {
|
|
590
|
+
keyword;
|
|
591
|
+
static from(data) {
|
|
592
|
+
return new ERBControlFlowScopeError({
|
|
593
|
+
type: data.type,
|
|
594
|
+
message: data.message,
|
|
595
|
+
location: Location.from(data.location),
|
|
596
|
+
keyword: data.keyword,
|
|
597
|
+
});
|
|
598
|
+
}
|
|
599
|
+
constructor(props) {
|
|
600
|
+
super(props.type, props.message, props.location);
|
|
601
|
+
this.keyword = props.keyword;
|
|
602
|
+
}
|
|
603
|
+
toJSON() {
|
|
604
|
+
return {
|
|
605
|
+
...super.toJSON(),
|
|
606
|
+
type: "ERB_CONTROL_FLOW_SCOPE_ERROR",
|
|
607
|
+
keyword: this.keyword,
|
|
608
|
+
};
|
|
609
|
+
}
|
|
610
|
+
toMonacoDiagnostic() {
|
|
611
|
+
return {
|
|
612
|
+
line: this.location.start.line,
|
|
613
|
+
column: this.location.start.column,
|
|
614
|
+
endLine: this.location.end.line,
|
|
615
|
+
endColumn: this.location.end.column,
|
|
616
|
+
message: this.message,
|
|
617
|
+
severity: 'error'
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
treeInspect() {
|
|
621
|
+
let output = "";
|
|
622
|
+
output += `@ ERBControlFlowScopeError ${this.location.treeInspectWithLabel()}\n`;
|
|
623
|
+
output += `├── message: "${this.message}"\n`;
|
|
624
|
+
output += `└── keyword: ${JSON.stringify(this.keyword)}\n`;
|
|
625
|
+
return output;
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
class MissingERBEndTagError extends HerbError {
|
|
629
|
+
keyword;
|
|
630
|
+
static from(data) {
|
|
631
|
+
return new MissingERBEndTagError({
|
|
632
|
+
type: data.type,
|
|
633
|
+
message: data.message,
|
|
634
|
+
location: Location.from(data.location),
|
|
635
|
+
keyword: data.keyword,
|
|
636
|
+
});
|
|
637
|
+
}
|
|
638
|
+
constructor(props) {
|
|
639
|
+
super(props.type, props.message, props.location);
|
|
640
|
+
this.keyword = props.keyword;
|
|
641
|
+
}
|
|
642
|
+
toJSON() {
|
|
643
|
+
return {
|
|
644
|
+
...super.toJSON(),
|
|
645
|
+
type: "MISSINGERB_END_TAG_ERROR",
|
|
646
|
+
keyword: this.keyword,
|
|
647
|
+
};
|
|
648
|
+
}
|
|
649
|
+
toMonacoDiagnostic() {
|
|
650
|
+
return {
|
|
651
|
+
line: this.location.start.line,
|
|
652
|
+
column: this.location.start.column,
|
|
653
|
+
endLine: this.location.end.line,
|
|
654
|
+
endColumn: this.location.end.column,
|
|
655
|
+
message: this.message,
|
|
656
|
+
severity: 'error'
|
|
657
|
+
};
|
|
658
|
+
}
|
|
659
|
+
treeInspect() {
|
|
660
|
+
let output = "";
|
|
661
|
+
output += `@ MissingERBEndTagError ${this.location.treeInspectWithLabel()}\n`;
|
|
662
|
+
output += `├── message: "${this.message}"\n`;
|
|
663
|
+
output += `└── keyword: ${JSON.stringify(this.keyword)}\n`;
|
|
664
|
+
return output;
|
|
665
|
+
}
|
|
666
|
+
}
|
|
563
667
|
function fromSerializedError(error) {
|
|
564
668
|
switch (error.type) {
|
|
565
669
|
case "UNEXPECTED_ERROR": return UnexpectedError.from(error);
|
|
@@ -571,6 +675,8 @@
|
|
|
571
675
|
case "VOID_ELEMENT_CLOSING_TAG_ERROR": return VoidElementClosingTagError.from(error);
|
|
572
676
|
case "UNCLOSED_ELEMENT_ERROR": return UnclosedElementError.from(error);
|
|
573
677
|
case "RUBY_PARSE_ERROR": return RubyParseError.from(error);
|
|
678
|
+
case "ERB_CONTROL_FLOW_SCOPE_ERROR": return ERBControlFlowScopeError.from(error);
|
|
679
|
+
case "MISSINGERB_END_TAG_ERROR": return MissingERBEndTagError.from(error);
|
|
574
680
|
default:
|
|
575
681
|
throw new Error(`Unknown node type: ${error.type}`);
|
|
576
682
|
}
|
|
@@ -592,7 +698,7 @@
|
|
|
592
698
|
}
|
|
593
699
|
|
|
594
700
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
|
595
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release-0.
|
|
701
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.1/templates/javascript/packages/core/src/nodes.ts.erb
|
|
596
702
|
class Node {
|
|
597
703
|
type;
|
|
598
704
|
location;
|
|
@@ -2845,7 +2951,7 @@
|
|
|
2845
2951
|
}
|
|
2846
2952
|
|
|
2847
2953
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
|
2848
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release-0.
|
|
2954
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.1/templates/javascript/packages/core/src/node-type-guards.ts.erb
|
|
2849
2955
|
/**
|
|
2850
2956
|
* Type guard functions for AST nodes.
|
|
2851
2957
|
* These functions provide type checking by combining both instanceof
|
|
@@ -3466,7 +3572,7 @@
|
|
|
3466
3572
|
* Checks if a node is an ERB output node (generates content: <%= %> or <%== %>)
|
|
3467
3573
|
*/
|
|
3468
3574
|
function isERBOutputNode(node) {
|
|
3469
|
-
if (!
|
|
3575
|
+
if (!isERBNode(node))
|
|
3470
3576
|
return false;
|
|
3471
3577
|
if (!node.tag_opening?.value)
|
|
3472
3578
|
return false;
|
|
@@ -3738,8 +3844,184 @@
|
|
|
3738
3844
|
};
|
|
3739
3845
|
}
|
|
3740
3846
|
|
|
3847
|
+
/*
|
|
3848
|
+
* The following code is derived from the "js-levenshtein" repository,
|
|
3849
|
+
* Copyright (c) 2017 Gustaf Andersson (https://github.com/gustf/js-levenshtein)
|
|
3850
|
+
* Licensed under the MIT License (https://github.com/gustf/js-levenshtein/blob/master/LICENSE).
|
|
3851
|
+
*
|
|
3852
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
3853
|
+
* of this software and associated documentation files (the "Software"), to deal
|
|
3854
|
+
* in the Software without restriction, including without limitation the rights
|
|
3855
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
3856
|
+
* copies of the Software, and to permit persons to whom the Software is
|
|
3857
|
+
* furnished to do so, subject to the following conditions:
|
|
3858
|
+
*
|
|
3859
|
+
* The above copyright notice and this permission notice shall be included in all
|
|
3860
|
+
* copies or substantial portions of the Software.
|
|
3861
|
+
*
|
|
3862
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
3863
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
3864
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
3865
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
3866
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
3867
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
3868
|
+
* SOFTWARE.
|
|
3869
|
+
*
|
|
3870
|
+
* https://github.com/marcoroth/stimulus-lsp/blob/52268d4a4d06504dde6cb81f505a23b5db5d5759/server/src/levenshtein.ts
|
|
3871
|
+
*
|
|
3872
|
+
*/
|
|
3873
|
+
function levenshtein(a, b) {
|
|
3874
|
+
function _min(d0, d1, d2, bx, ay) {
|
|
3875
|
+
return d0 < d1 || d2 < d1 ? (d0 > d2 ? d2 + 1 : d0 + 1) : bx === ay ? d1 : d1 + 1;
|
|
3876
|
+
}
|
|
3877
|
+
if (a === b) {
|
|
3878
|
+
return 0;
|
|
3879
|
+
}
|
|
3880
|
+
if (a.length > b.length) {
|
|
3881
|
+
const tmp = a;
|
|
3882
|
+
a = b;
|
|
3883
|
+
b = tmp;
|
|
3884
|
+
}
|
|
3885
|
+
let la = a.length;
|
|
3886
|
+
let lb = b.length;
|
|
3887
|
+
while (la > 0 && a.charCodeAt(la - 1) === b.charCodeAt(lb - 1)) {
|
|
3888
|
+
la--;
|
|
3889
|
+
lb--;
|
|
3890
|
+
}
|
|
3891
|
+
let offset = 0;
|
|
3892
|
+
while (offset < la && a.charCodeAt(offset) === b.charCodeAt(offset)) {
|
|
3893
|
+
offset++;
|
|
3894
|
+
}
|
|
3895
|
+
la -= offset;
|
|
3896
|
+
lb -= offset;
|
|
3897
|
+
if (la === 0 || lb < 3) {
|
|
3898
|
+
return lb;
|
|
3899
|
+
}
|
|
3900
|
+
let x = 0;
|
|
3901
|
+
let y;
|
|
3902
|
+
let d0;
|
|
3903
|
+
let d1;
|
|
3904
|
+
let d2;
|
|
3905
|
+
let d3;
|
|
3906
|
+
let dd;
|
|
3907
|
+
let dy;
|
|
3908
|
+
let ay;
|
|
3909
|
+
let bx0;
|
|
3910
|
+
let bx1;
|
|
3911
|
+
let bx2;
|
|
3912
|
+
let bx3;
|
|
3913
|
+
const vector = [];
|
|
3914
|
+
for (y = 0; y < la; y++) {
|
|
3915
|
+
vector.push(y + 1);
|
|
3916
|
+
vector.push(a.charCodeAt(offset + y));
|
|
3917
|
+
}
|
|
3918
|
+
const len = vector.length - 1;
|
|
3919
|
+
for (; x < lb - 3;) {
|
|
3920
|
+
bx0 = b.charCodeAt(offset + (d0 = x));
|
|
3921
|
+
bx1 = b.charCodeAt(offset + (d1 = x + 1));
|
|
3922
|
+
bx2 = b.charCodeAt(offset + (d2 = x + 2));
|
|
3923
|
+
bx3 = b.charCodeAt(offset + (d3 = x + 3));
|
|
3924
|
+
dd = x += 4;
|
|
3925
|
+
for (y = 0; y < len; y += 2) {
|
|
3926
|
+
dy = vector[y];
|
|
3927
|
+
ay = vector[y + 1];
|
|
3928
|
+
d0 = _min(dy, d0, d1, bx0, ay);
|
|
3929
|
+
d1 = _min(d0, d1, d2, bx1, ay);
|
|
3930
|
+
d2 = _min(d1, d2, d3, bx2, ay);
|
|
3931
|
+
dd = _min(d2, d3, dd, bx3, ay);
|
|
3932
|
+
vector[y] = dd;
|
|
3933
|
+
d3 = d2;
|
|
3934
|
+
d2 = d1;
|
|
3935
|
+
d1 = d0;
|
|
3936
|
+
d0 = dy;
|
|
3937
|
+
}
|
|
3938
|
+
}
|
|
3939
|
+
for (; x < lb;) {
|
|
3940
|
+
bx0 = b.charCodeAt(offset + (d0 = x));
|
|
3941
|
+
dd = ++x;
|
|
3942
|
+
for (y = 0; y < len; y += 2) {
|
|
3943
|
+
dy = vector[y];
|
|
3944
|
+
vector[y] = dd = _min(dy, d0, dd, bx0, vector[y + 1]);
|
|
3945
|
+
d0 = dy;
|
|
3946
|
+
}
|
|
3947
|
+
}
|
|
3948
|
+
return dd;
|
|
3949
|
+
}
|
|
3950
|
+
|
|
3951
|
+
/**
|
|
3952
|
+
* Ranks a list of strings by their Levenshtein distance from the input string.
|
|
3953
|
+
* Items are sorted in ascending order by distance, with closer matches first.
|
|
3954
|
+
*
|
|
3955
|
+
* @param input - The string to compare against
|
|
3956
|
+
* @param list - The list of strings to rank
|
|
3957
|
+
* @returns An array of objects containing the item and its distance score, sorted by score
|
|
3958
|
+
*/
|
|
3959
|
+
function rank(input, list) {
|
|
3960
|
+
return list.map(item => {
|
|
3961
|
+
const score = levenshtein(input.toLowerCase(), item.toLowerCase());
|
|
3962
|
+
return { item, score };
|
|
3963
|
+
}).sort((a, b) => a.score - b.score);
|
|
3964
|
+
}
|
|
3965
|
+
/**
|
|
3966
|
+
* Finds the closest matching string from a list using Levenshtein distance.
|
|
3967
|
+
* Performs case-insensitive comparison.
|
|
3968
|
+
*
|
|
3969
|
+
* @param input - The string to match against
|
|
3970
|
+
* @param list - The list of candidate strings to search
|
|
3971
|
+
* @param threshold - Maximum Levenshtein distance to consider a match. If undefined, returns the closest match regardless of distance.
|
|
3972
|
+
* @returns The closest matching string from the list, or null if the list is empty or no match is within the threshold
|
|
3973
|
+
*
|
|
3974
|
+
* @example
|
|
3975
|
+
* ```ts
|
|
3976
|
+
* didyoumean('speling', ['spelling', 'writing', 'reading']) // Returns 'spelling'
|
|
3977
|
+
* didyoumean('test', []) // Returns null
|
|
3978
|
+
* didyoumean('speling', ['spelling', 'writing', 'reading'], 2) // Returns 'spelling' (distance: 1)
|
|
3979
|
+
* didyoumean('xyz', ['spelling', 'writing', 'reading'], 2) // Returns null (all distances > 2)
|
|
3980
|
+
* ```
|
|
3981
|
+
*/
|
|
3982
|
+
function didyoumean(input, list, threshold) {
|
|
3983
|
+
if (list.length === 0)
|
|
3984
|
+
return null;
|
|
3985
|
+
const scores = rank(input, list);
|
|
3986
|
+
if (scores.length === 0)
|
|
3987
|
+
return null;
|
|
3988
|
+
const closest = scores[0];
|
|
3989
|
+
if (threshold !== undefined && closest.score > threshold)
|
|
3990
|
+
return null;
|
|
3991
|
+
return closest.item;
|
|
3992
|
+
}
|
|
3993
|
+
/**
|
|
3994
|
+
* Returns all strings from a list ranked by their Levenshtein distance from the input string.
|
|
3995
|
+
* Performs case-insensitive comparison. Results are sorted with closest matches first.
|
|
3996
|
+
*
|
|
3997
|
+
* @param input - The string to match against
|
|
3998
|
+
* @param list - The list of candidate strings to rank
|
|
3999
|
+
* @param threshold - Maximum Levenshtein distance to include in results. If undefined, returns all ranked results.
|
|
4000
|
+
* @returns An array of ranked results with items and scores, or an empty array if the list is empty or no matches are within the threshold
|
|
4001
|
+
*
|
|
4002
|
+
* @example
|
|
4003
|
+
* ```ts
|
|
4004
|
+
* didyoumeanRanked('speling', ['spelling', 'writing', 'reading'])
|
|
4005
|
+
* // Returns [{ item: 'spelling', score: 1 }, { item: 'reading', score: 5 }, { item: 'writing', score: 6 }]
|
|
4006
|
+
*
|
|
4007
|
+
* didyoumeanRanked('speling', ['spelling', 'writing', 'reading'], 2)
|
|
4008
|
+
* // Returns [{ item: 'spelling', score: 1 }]
|
|
4009
|
+
*
|
|
4010
|
+
* didyoumeanRanked('test', []) // Returns []
|
|
4011
|
+
* ```
|
|
4012
|
+
*/
|
|
4013
|
+
function didyoumeanRanked(input, list, threshold) {
|
|
4014
|
+
if (list.length === 0)
|
|
4015
|
+
return [];
|
|
4016
|
+
const scores = rank(input, list);
|
|
4017
|
+
if (threshold !== undefined) {
|
|
4018
|
+
return scores.filter(result => result.score <= threshold);
|
|
4019
|
+
}
|
|
4020
|
+
return scores;
|
|
4021
|
+
}
|
|
4022
|
+
|
|
3741
4023
|
var name = "@herb-tools/core";
|
|
3742
|
-
var version = "0.
|
|
4024
|
+
var version = "0.8.1";
|
|
3743
4025
|
var packageJSON = {
|
|
3744
4026
|
name: name,
|
|
3745
4027
|
version: version};
|
|
@@ -3962,7 +4244,7 @@
|
|
|
3962
4244
|
}
|
|
3963
4245
|
|
|
3964
4246
|
// NOTE: This file is generated by the templates/template.rb script and should not
|
|
3965
|
-
// be modified manually. See /Users/marcoroth/Development/herb-release-0.
|
|
4247
|
+
// be modified manually. See /Users/marcoroth/Development/herb-release-0.8.1/templates/javascript/packages/core/src/visitor.ts.erb
|
|
3966
4248
|
class Visitor {
|
|
3967
4249
|
visit(node) {
|
|
3968
4250
|
if (!node)
|
|
@@ -4133,6 +4415,7 @@
|
|
|
4133
4415
|
exports.ERBCaseMatchNode = ERBCaseMatchNode;
|
|
4134
4416
|
exports.ERBCaseNode = ERBCaseNode;
|
|
4135
4417
|
exports.ERBContentNode = ERBContentNode;
|
|
4418
|
+
exports.ERBControlFlowScopeError = ERBControlFlowScopeError;
|
|
4136
4419
|
exports.ERBElseNode = ERBElseNode;
|
|
4137
4420
|
exports.ERBEndNode = ERBEndNode;
|
|
4138
4421
|
exports.ERBEnsureNode = ERBEnsureNode;
|
|
@@ -4162,6 +4445,7 @@
|
|
|
4162
4445
|
exports.LiteralNode = LiteralNode;
|
|
4163
4446
|
exports.Location = Location;
|
|
4164
4447
|
exports.MissingClosingTagError = MissingClosingTagError;
|
|
4448
|
+
exports.MissingERBEndTagError = MissingERBEndTagError;
|
|
4165
4449
|
exports.MissingOpeningTagError = MissingOpeningTagError;
|
|
4166
4450
|
exports.NODE_TYPE_GUARDS = NODE_TYPE_GUARDS;
|
|
4167
4451
|
exports.Node = Node;
|
|
@@ -4184,6 +4468,8 @@
|
|
|
4184
4468
|
exports._TYPECHECK = _TYPECHECK;
|
|
4185
4469
|
exports.areAllOfType = areAllOfType;
|
|
4186
4470
|
exports.convertToUTF8 = convertToUTF8;
|
|
4471
|
+
exports.didyoumean = didyoumean;
|
|
4472
|
+
exports.didyoumeanRanked = didyoumeanRanked;
|
|
4187
4473
|
exports.ensureLibHerbBackend = ensureLibHerbBackend;
|
|
4188
4474
|
exports.ensureString = ensureString;
|
|
4189
4475
|
exports.filterCDATANodes = filterCDATANodes;
|
|
@@ -4282,6 +4568,7 @@
|
|
|
4282
4568
|
exports.isToken = isToken;
|
|
4283
4569
|
exports.isWhitespaceNode = isWhitespaceNode;
|
|
4284
4570
|
exports.isXMLDeclarationNode = isXMLDeclarationNode;
|
|
4571
|
+
exports.levenshtein = levenshtein;
|
|
4285
4572
|
exports.splitNodesAroundLocation = splitNodesAroundLocation;
|
|
4286
4573
|
exports.splitNodesAroundPosition = splitNodesAroundPosition;
|
|
4287
4574
|
exports.toMonacoDiagnostic = toMonacoDiagnostic;
|