@f12io/maple-language-core 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 +42 -0
- package/dist/LanguageService.d.ts +104 -0
- package/dist/LanguageService.js +16 -0
- package/dist/LanguageService.js.map +1 -0
- package/dist/extractor.helper.d.ts +66 -0
- package/dist/extractor.helper.js +319 -0
- package/dist/extractor.helper.js.map +1 -0
- package/dist/formatter.d.ts +26 -0
- package/dist/formatter.js +206 -0
- package/dist/formatter.js.map +1 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.js +50 -0
- package/dist/index.js.map +1 -0
- package/dist/language-definitions.d.ts +9 -0
- package/dist/language-definitions.js +35 -0
- package/dist/language-definitions.js.map +1 -0
- package/dist/languages/AngularLanguageService.d.ts +6 -0
- package/dist/languages/AngularLanguageService.js +66 -0
- package/dist/languages/AngularLanguageService.js.map +1 -0
- package/dist/languages/BaseLanguageService.d.ts +80 -0
- package/dist/languages/BaseLanguageService.js +409 -0
- package/dist/languages/BaseLanguageService.js.map +1 -0
- package/dist/languages/HtmlLanguageService.d.ts +5 -0
- package/dist/languages/HtmlLanguageService.js +29 -0
- package/dist/languages/HtmlLanguageService.js.map +1 -0
- package/dist/languages/JavascriptLanguageService.d.ts +10 -0
- package/dist/languages/JavascriptLanguageService.js +95 -0
- package/dist/languages/JavascriptLanguageService.js.map +1 -0
- package/dist/languages/PhpLanguageService.d.ts +22 -0
- package/dist/languages/PhpLanguageService.js +242 -0
- package/dist/languages/PhpLanguageService.js.map +1 -0
- package/dist/languages/RazorLanguageService.d.ts +33 -0
- package/dist/languages/RazorLanguageService.js +338 -0
- package/dist/languages/RazorLanguageService.js.map +1 -0
- package/dist/languages/ReactLanguageService.d.ts +6 -0
- package/dist/languages/ReactLanguageService.js +31 -0
- package/dist/languages/ReactLanguageService.js.map +1 -0
- package/dist/languages/SvelteLanguageService.d.ts +9 -0
- package/dist/languages/SvelteLanguageService.js +65 -0
- package/dist/languages/SvelteLanguageService.js.map +1 -0
- package/dist/languages/TwigLanguageService.d.ts +4 -0
- package/dist/languages/TwigLanguageService.js +12 -0
- package/dist/languages/TwigLanguageService.js.map +1 -0
- package/dist/languages/VueLanguageService.d.ts +6 -0
- package/dist/languages/VueLanguageService.js +36 -0
- package/dist/languages/VueLanguageService.js.map +1 -0
- package/dist/regex.d.ts +63 -0
- package/dist/regex.js +92 -0
- package/dist/regex.js.map +1 -0
- package/dist/registry.d.ts +7 -0
- package/dist/registry.js +86 -0
- package/dist/registry.js.map +1 -0
- package/package.json +38 -0
package/README.md
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
# @f12io/maple-language-core
|
|
2
|
+
|
|
3
|
+
Editor-agnostic language tooling for [Maple CSS](https://github.com/f12io/maple):
|
|
4
|
+
region discovery, class extraction, string grammar, and the class layout
|
|
5
|
+
engine. This package is the single source of truth consumed by the
|
|
6
|
+
[Maple VS Code extension](https://github.com/f12io/maple-vscode-extension)
|
|
7
|
+
and [`@f12io/prettier-plugin-maple`](https://www.npmjs.com/package/@f12io/prettier-plugin-maple).
|
|
8
|
+
|
|
9
|
+
## What it provides
|
|
10
|
+
|
|
11
|
+
- **`LanguageServiceRegistry.getService(languageId)`** — a language service
|
|
12
|
+
for `html`, `javascript(react)`, `typescript(react)`, `vue`, `svelte`,
|
|
13
|
+
`php`, `razor`, `aspnetcorerazor`, and `twig`.
|
|
14
|
+
- **`service.collectRegions(text)`** — every maple region in a document
|
|
15
|
+
(class attributes, `className={...}`, `clsx()`/`cva()` arguments,
|
|
16
|
+
`/* maple */` opt-in expressions, framework bindings), typed as raw class
|
|
17
|
+
text or code expressions.
|
|
18
|
+
- **`service.extractClasses(text)`** — class instances with exact document
|
|
19
|
+
offsets, interpolation-aware per language (JS template literals, C#
|
|
20
|
+
interpolated strings, PHP blocks, Razor expressions).
|
|
21
|
+
- **`formatClasses` / `computeFormattingEdits` / `formatText`** — the layout
|
|
22
|
+
engine: wraps class lists by property group, preserves ternary and
|
|
23
|
+
concatenation structure, and upgrades string delimiters only when the host
|
|
24
|
+
language allows multi-line strings.
|
|
25
|
+
|
|
26
|
+
## Usage
|
|
27
|
+
|
|
28
|
+
```ts
|
|
29
|
+
import {
|
|
30
|
+
LanguageServiceRegistry,
|
|
31
|
+
formatText,
|
|
32
|
+
} from '@f12io/maple-language-core';
|
|
33
|
+
|
|
34
|
+
const service = LanguageServiceRegistry.getService('javascriptreact');
|
|
35
|
+
const instances = service.extractClasses(source);
|
|
36
|
+
|
|
37
|
+
const formatted = formatText(source, 'javascriptreact', 4);
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## License
|
|
41
|
+
|
|
42
|
+
Released under the [Root Source License (ROOT)](https://github.com/f12io/maple-vscode-extension/blob/main/LICENSE), an MIT-style permissive license with an additional distribution condition for systems that can recreate the source on demand. © [f12.io](https://f12.io)
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
export interface ClassInstance {
|
|
2
|
+
value: string;
|
|
3
|
+
start: number;
|
|
4
|
+
end: number;
|
|
5
|
+
tagName?: string;
|
|
6
|
+
}
|
|
7
|
+
/** A [start, end) offset range whose contents are excluded via disable comments. */
|
|
8
|
+
export interface DisabledBlock {
|
|
9
|
+
start: number;
|
|
10
|
+
end: number;
|
|
11
|
+
}
|
|
12
|
+
/** Keeps the first instance seen for each start offset. */
|
|
13
|
+
export declare function dedupeInstancesByStart(instances: Array<ClassInstance>): Array<ClassInstance>;
|
|
14
|
+
/** A string literal located by a language service's `matchStringLiteral`. */
|
|
15
|
+
export interface StringLiteralMatch {
|
|
16
|
+
/** Index of the opening delimiter (including any prefix, e.g. `$@`) */
|
|
17
|
+
start: number;
|
|
18
|
+
contentStart: number;
|
|
19
|
+
contentEnd: number;
|
|
20
|
+
/** Index just after the closing delimiter */
|
|
21
|
+
endIndex: number;
|
|
22
|
+
/** The opening delimiter as written: `$@"`, `$"`, `"`, `'` or `` ` `` */
|
|
23
|
+
rawDelimiter: string;
|
|
24
|
+
/** Content contains interpolation holes this service can parse */
|
|
25
|
+
isInterpolated: boolean;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* A document range that holds maple classes. This is the single source of
|
|
29
|
+
* truth for "where do maple strings live" — extraction, formatting, and every
|
|
30
|
+
* feature built on them consume the same regions.
|
|
31
|
+
*/
|
|
32
|
+
export interface MapleRegion {
|
|
33
|
+
start: number;
|
|
34
|
+
end: number;
|
|
35
|
+
/**
|
|
36
|
+
* `class-text`: the range is raw class text (a class attribute value).
|
|
37
|
+
* `expression`: the range is code whose string literals are maple
|
|
38
|
+
* (opt-in expressions, clsx/cva arguments, className={...}, :class="...").
|
|
39
|
+
*/
|
|
40
|
+
kind: 'class-text' | 'expression';
|
|
41
|
+
/**
|
|
42
|
+
* Anchor offset of the construct that produced the region (attribute or
|
|
43
|
+
* call start). Used for tag-name lookup, disable-comment checks, and
|
|
44
|
+
* formatter indentation.
|
|
45
|
+
*/
|
|
46
|
+
anchor: number;
|
|
47
|
+
/** Extract unquoted object keys as classes (clsx objects, :class objects) */
|
|
48
|
+
includeObjectKeys?: boolean;
|
|
49
|
+
/**
|
|
50
|
+
* False when the host syntax cannot hold multi-line string literals
|
|
51
|
+
* (e.g. Angular template expressions); the formatter then only applies
|
|
52
|
+
* single-line normalizations. Defaults to true.
|
|
53
|
+
*/
|
|
54
|
+
allowMultilineLiterals?: boolean;
|
|
55
|
+
}
|
|
56
|
+
/** Callback invoked for each interpolated string found during extraction. */
|
|
57
|
+
export type StringExtractionCallback = (value: string, offset: number, text: string, matchIndex: number, literal?: StringLiteralMatch) => void;
|
|
58
|
+
export interface Token {
|
|
59
|
+
value: string;
|
|
60
|
+
start: number;
|
|
61
|
+
end: number;
|
|
62
|
+
hasInterpolation?: boolean;
|
|
63
|
+
}
|
|
64
|
+
export interface ILanguageService {
|
|
65
|
+
languageIds: Array<string>;
|
|
66
|
+
extractClasses(text: string): Array<ClassInstance>;
|
|
67
|
+
/**
|
|
68
|
+
* Reports every maple region in the document. Single implementation per
|
|
69
|
+
* language; extraction and formatting both consume it.
|
|
70
|
+
*/
|
|
71
|
+
collectRegions(text: string): Array<MapleRegion>;
|
|
72
|
+
tokenizeClassesWithIndices(str: string): Array<Token>;
|
|
73
|
+
/**
|
|
74
|
+
* Resolves source-escaped class text to what the framework actually renders
|
|
75
|
+
* into the DOM (e.g. Razor renders `@@md:p-2` as `@md:p-2`). Used where the
|
|
76
|
+
* runtime CSS matters (hover), not for document ranges.
|
|
77
|
+
*/
|
|
78
|
+
getRenderedClassText(word: string): string;
|
|
79
|
+
/**
|
|
80
|
+
* Returns the delimiters to use when a formatted string must span multiple
|
|
81
|
+
* lines, or undefined when the string cannot legally hold newlines in this
|
|
82
|
+
* language (the formatter then leaves it untouched). `rawQuote` is the
|
|
83
|
+
* opening delimiter as written ($@", $", ", ' or `).
|
|
84
|
+
*/
|
|
85
|
+
getMultilineStringDelimiters(rawQuote: string, content: string): {
|
|
86
|
+
open: string;
|
|
87
|
+
close: string;
|
|
88
|
+
} | undefined;
|
|
89
|
+
/**
|
|
90
|
+
* Matches a string literal of this language starting at `index`, or
|
|
91
|
+
* undefined when no (terminated) literal starts there. This is the single
|
|
92
|
+
* place a language's string grammar lives — generic helpers delegate here
|
|
93
|
+
* instead of hardcoding delimiter knowledge.
|
|
94
|
+
*/
|
|
95
|
+
matchStringLiteral(text: string, index: number): StringLiteralMatch | undefined;
|
|
96
|
+
/**
|
|
97
|
+
* Formats a bare class-bearing expression (e.g. a ternary with string
|
|
98
|
+
* arms), preserving its structure — the same treatment interpolations get
|
|
99
|
+
* inside class attributes. Returns undefined when the expression has no
|
|
100
|
+
* structure this language knows how to format.
|
|
101
|
+
*/
|
|
102
|
+
formatExpression(expr: string, baseIndent: string, maxClassesPerLine: number, formatClassesFn: (value: string, indent: string, maxClasses: number) => string): string | undefined;
|
|
103
|
+
formatInterpolation(cls: string, baseIndent: string, maxClassesPerLine: number, formatClassesFn: (value: string, indent: string, maxClasses: number) => string): string;
|
|
104
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.dedupeInstancesByStart = dedupeInstancesByStart;
|
|
4
|
+
/** Keeps the first instance seen for each start offset. */
|
|
5
|
+
function dedupeInstancesByStart(instances) {
|
|
6
|
+
const uniqueInstances = [];
|
|
7
|
+
const seenStarts = new Set();
|
|
8
|
+
for (const instance of instances) {
|
|
9
|
+
if (!seenStarts.has(instance.start)) {
|
|
10
|
+
seenStarts.add(instance.start);
|
|
11
|
+
uniqueInstances.push(instance);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
return uniqueInstances;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=LanguageService.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"LanguageService.js","sourceRoot":"","sources":["../src/LanguageService.ts"],"names":[],"mappings":";;AAcA,wDAcC;AAfD,2DAA2D;AAC3D,SAAgB,sBAAsB,CACpC,SAA+B;IAE/B,MAAM,eAAe,GAAyB,EAAE,CAAC;IACjD,MAAM,UAAU,GAAG,IAAI,GAAG,EAAU,CAAC;IAErC,KAAK,MAAM,QAAQ,IAAI,SAAS,EAAE,CAAC;QACjC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YACpC,UAAU,CAAC,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC;YAC/B,eAAe,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjC,CAAC;IACH,CAAC;IAED,OAAO,eAAe,CAAC;AACzB,CAAC"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
import { ClassInstance, ILanguageService, StringExtractionCallback, StringLiteralMatch } from './LanguageService';
|
|
2
|
+
export declare function isQuote(char: string): boolean;
|
|
3
|
+
/**
|
|
4
|
+
* Upper bound on how far a single scan may advance before giving up.
|
|
5
|
+
* Guards every hand-rolled scanner against runaway scans on malformed input
|
|
6
|
+
* (e.g. an unterminated attribute in a huge minified file).
|
|
7
|
+
*/
|
|
8
|
+
export declare const MAX_SCAN_LENGTH = 5000;
|
|
9
|
+
/**
|
|
10
|
+
* Skips a quoted string literal. `index` must hold the opening quote (`'` or
|
|
11
|
+
* `"`); backslash escapes are honored, so an escaped quote does not close the
|
|
12
|
+
* string. Returns the index just after the closing quote, or the scan bound
|
|
13
|
+
* when the string is unterminated.
|
|
14
|
+
*/
|
|
15
|
+
export declare function skipStringLiteral(text: string, index: number): number;
|
|
16
|
+
export declare function findClosingQuote(text: string, startIndex: number, quote: string): number;
|
|
17
|
+
export declare function getTagNameBackwards(text: string, index: number): string | undefined;
|
|
18
|
+
export declare function isCommentedOut(text: string, index: number): boolean;
|
|
19
|
+
export declare function isLineDisabled(text: string, index: number): boolean;
|
|
20
|
+
export declare function getDisabledBlocks(text: string): Array<{
|
|
21
|
+
start: number;
|
|
22
|
+
end: number;
|
|
23
|
+
}>;
|
|
24
|
+
export declare function shouldSkipMatch(text: string, index: number, disabledBlocks?: Array<{
|
|
25
|
+
start: number;
|
|
26
|
+
end: number;
|
|
27
|
+
}>): boolean;
|
|
28
|
+
export declare function pushInstance(instances: Array<ClassInstance>, value: string, start: number, text: string, matchIndex: number, disabledBlocks?: Array<{
|
|
29
|
+
start: number;
|
|
30
|
+
end: number;
|
|
31
|
+
}>): void;
|
|
32
|
+
export declare function extractUnquotedObjectKeys(expr: string, exprStart: number, text: string, matchIndex: number, instances: Array<ClassInstance>, disabledBlocks?: Array<{
|
|
33
|
+
start: number;
|
|
34
|
+
end: number;
|
|
35
|
+
}>): void;
|
|
36
|
+
export interface OptInRegion {
|
|
37
|
+
/** Index of the opt-in comment match */
|
|
38
|
+
matchIndex: number;
|
|
39
|
+
/** Start of the opted-in expression (first non-whitespace after comment) */
|
|
40
|
+
regionStart: number;
|
|
41
|
+
/** End of the opted-in expression (exclusive of the terminator) */
|
|
42
|
+
regionEnd: number;
|
|
43
|
+
/** Every string literal found in the region, in document order */
|
|
44
|
+
literals: Array<StringLiteralMatch>;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Locates all string literals opted in by a maple comment. The comment marks
|
|
48
|
+
* the whole following expression — like a class attribute, every string
|
|
49
|
+
* literal in it is maple (ternary arms, concatenation parts, ...). String
|
|
50
|
+
* boundaries are delegated to the language service, so each language's
|
|
51
|
+
* string grammar lives in exactly one place.
|
|
52
|
+
*
|
|
53
|
+
* The region ends at a `;` or `,` at bracket depth 0, at a closing bracket
|
|
54
|
+
* that was never opened inside the region, or at a plain assignment `=`
|
|
55
|
+
* (guarding against swallowing the next statement in semicolon-less code;
|
|
56
|
+
* comparison/arrow operators like `==`, `=>`, `<=` do not terminate).
|
|
57
|
+
*/
|
|
58
|
+
export declare function findOptInRegions(service: ILanguageService, text: string): Array<OptInRegion>;
|
|
59
|
+
export declare function extractStringLiterals(service: ILanguageService, expr: string, exprStart: number, text: string, matchIndex: number, instances: Array<ClassInstance>, disabledBlocks?: Array<{
|
|
60
|
+
start: number;
|
|
61
|
+
end: number;
|
|
62
|
+
}>, extractCallback?: StringExtractionCallback): void;
|
|
63
|
+
export declare function getExactWordRangeAtPosition(document: any, position: any): {
|
|
64
|
+
wordRange: any | undefined;
|
|
65
|
+
currentWord: string;
|
|
66
|
+
};
|
|
@@ -0,0 +1,319 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.MAX_SCAN_LENGTH = void 0;
|
|
4
|
+
exports.isQuote = isQuote;
|
|
5
|
+
exports.skipStringLiteral = skipStringLiteral;
|
|
6
|
+
exports.findClosingQuote = findClosingQuote;
|
|
7
|
+
exports.getTagNameBackwards = getTagNameBackwards;
|
|
8
|
+
exports.isCommentedOut = isCommentedOut;
|
|
9
|
+
exports.isLineDisabled = isLineDisabled;
|
|
10
|
+
exports.getDisabledBlocks = getDisabledBlocks;
|
|
11
|
+
exports.shouldSkipMatch = shouldSkipMatch;
|
|
12
|
+
exports.pushInstance = pushInstance;
|
|
13
|
+
exports.extractUnquotedObjectKeys = extractUnquotedObjectKeys;
|
|
14
|
+
exports.findOptInRegions = findOptInRegions;
|
|
15
|
+
exports.extractStringLiterals = extractStringLiterals;
|
|
16
|
+
exports.getExactWordRangeAtPosition = getExactWordRangeAtPosition;
|
|
17
|
+
const regex_1 = require("./regex");
|
|
18
|
+
function isQuote(char) {
|
|
19
|
+
return char === '"' || char === "'" || char === '`';
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Upper bound on how far a single scan may advance before giving up.
|
|
23
|
+
* Guards every hand-rolled scanner against runaway scans on malformed input
|
|
24
|
+
* (e.g. an unterminated attribute in a huge minified file).
|
|
25
|
+
*/
|
|
26
|
+
exports.MAX_SCAN_LENGTH = 5000;
|
|
27
|
+
/**
|
|
28
|
+
* Skips a quoted string literal. `index` must hold the opening quote (`'` or
|
|
29
|
+
* `"`); backslash escapes are honored, so an escaped quote does not close the
|
|
30
|
+
* string. Returns the index just after the closing quote, or the scan bound
|
|
31
|
+
* when the string is unterminated.
|
|
32
|
+
*/
|
|
33
|
+
function skipStringLiteral(text, index) {
|
|
34
|
+
const quote = text[index];
|
|
35
|
+
const limit = Math.min(text.length, index + exports.MAX_SCAN_LENGTH);
|
|
36
|
+
let i = index + 1;
|
|
37
|
+
while (i < limit) {
|
|
38
|
+
if (text[i] === '\\') {
|
|
39
|
+
i += 2;
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
if (text[i] === quote) {
|
|
43
|
+
return i + 1;
|
|
44
|
+
}
|
|
45
|
+
i++;
|
|
46
|
+
}
|
|
47
|
+
return limit;
|
|
48
|
+
}
|
|
49
|
+
function findClosingQuote(text, startIndex, quote) {
|
|
50
|
+
let parenDepth = 0;
|
|
51
|
+
let braceDepth = 0;
|
|
52
|
+
let i = startIndex;
|
|
53
|
+
while (i < text.length) {
|
|
54
|
+
const char = text[i];
|
|
55
|
+
const prevChar = i > 0 ? text[i - 1] : '';
|
|
56
|
+
if (prevChar === '\\') {
|
|
57
|
+
i++;
|
|
58
|
+
continue;
|
|
59
|
+
}
|
|
60
|
+
if (parenDepth > 0 && (char === '"' || char === "'")) {
|
|
61
|
+
// Inside a Razor @(...) expression a quote starts a C# string literal,
|
|
62
|
+
// which may legally contain parens, braces, or the attribute's own
|
|
63
|
+
// quote char. Skip it entirely.
|
|
64
|
+
i = skipStringLiteral(text, i);
|
|
65
|
+
continue;
|
|
66
|
+
}
|
|
67
|
+
if (char === '(' && prevChar === '@') {
|
|
68
|
+
parenDepth++;
|
|
69
|
+
}
|
|
70
|
+
else if (char === '(' && parenDepth > 0) {
|
|
71
|
+
parenDepth++;
|
|
72
|
+
}
|
|
73
|
+
else if (char === ')') {
|
|
74
|
+
if (parenDepth > 0)
|
|
75
|
+
parenDepth--;
|
|
76
|
+
}
|
|
77
|
+
else if (char === '{') {
|
|
78
|
+
braceDepth++;
|
|
79
|
+
}
|
|
80
|
+
else if (char === '}') {
|
|
81
|
+
if (braceDepth > 0)
|
|
82
|
+
braceDepth--;
|
|
83
|
+
}
|
|
84
|
+
else if (char === quote) {
|
|
85
|
+
if (parenDepth === 0 && braceDepth === 0) {
|
|
86
|
+
return i;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (i - startIndex > exports.MAX_SCAN_LENGTH) {
|
|
90
|
+
return -1; // safety timeout
|
|
91
|
+
}
|
|
92
|
+
i++;
|
|
93
|
+
}
|
|
94
|
+
return -1;
|
|
95
|
+
}
|
|
96
|
+
function getTagNameBackwards(text, index) {
|
|
97
|
+
const prefix = text.substring(0, index);
|
|
98
|
+
const lastOpen = prefix.lastIndexOf('<');
|
|
99
|
+
const lastClose = prefix.lastIndexOf('>');
|
|
100
|
+
if (lastOpen !== -1 && lastOpen > lastClose) {
|
|
101
|
+
const match = text.substring(lastOpen + 1).match(regex_1.START_TAG_NAME_REGEX);
|
|
102
|
+
if (match) {
|
|
103
|
+
return match[1].toLowerCase();
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
return undefined;
|
|
107
|
+
}
|
|
108
|
+
function isCommentedOut(text, index) {
|
|
109
|
+
const lastNewline = text.lastIndexOf('\n', index);
|
|
110
|
+
const lineToMatch = text.substring(lastNewline + 1, index);
|
|
111
|
+
if (lineToMatch.includes('//'))
|
|
112
|
+
return true;
|
|
113
|
+
if (lineToMatch.includes('<!--'))
|
|
114
|
+
return true;
|
|
115
|
+
if (regex_1.START_COMMENT_STAR_REGEX.test(lineToMatch))
|
|
116
|
+
return true;
|
|
117
|
+
const lastSlashStar = lineToMatch.lastIndexOf('/*');
|
|
118
|
+
if (lastSlashStar !== -1) {
|
|
119
|
+
const lastStarSlash = lineToMatch.lastIndexOf('*/');
|
|
120
|
+
if (lastStarSlash < lastSlashStar) {
|
|
121
|
+
return true;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
return false;
|
|
125
|
+
}
|
|
126
|
+
function isLineDisabled(text, index) {
|
|
127
|
+
const lastNewline = text.lastIndexOf('\n', index);
|
|
128
|
+
let nextNewline = text.indexOf('\n', index);
|
|
129
|
+
if (nextNewline === -1)
|
|
130
|
+
nextNewline = text.length;
|
|
131
|
+
const fullLine = text.substring(lastNewline + 1, nextNewline);
|
|
132
|
+
if (fullLine.includes('maple-disable-line'))
|
|
133
|
+
return true;
|
|
134
|
+
if (lastNewline !== -1) {
|
|
135
|
+
const prevNewline = text.lastIndexOf('\n', lastNewline - 1);
|
|
136
|
+
const prevLine = text.substring(prevNewline + 1, lastNewline);
|
|
137
|
+
if (prevLine.includes('maple-disable-next-line'))
|
|
138
|
+
return true;
|
|
139
|
+
}
|
|
140
|
+
return false;
|
|
141
|
+
}
|
|
142
|
+
function getDisabledBlocks(text) {
|
|
143
|
+
const blocks = [];
|
|
144
|
+
const disableMatches = [...text.matchAll(regex_1.DISABLE_REGEX)];
|
|
145
|
+
const enableMatches = [...text.matchAll(regex_1.ENABLE_REGEX)];
|
|
146
|
+
let currentEnd = 0;
|
|
147
|
+
for (const disableMatch of disableMatches) {
|
|
148
|
+
const start = disableMatch.index;
|
|
149
|
+
if (start < currentEnd)
|
|
150
|
+
continue;
|
|
151
|
+
const enableMatch = enableMatches.find((m) => m.index > start);
|
|
152
|
+
const end = enableMatch
|
|
153
|
+
? enableMatch.index + enableMatch[0].length
|
|
154
|
+
: text.length;
|
|
155
|
+
blocks.push({ start, end });
|
|
156
|
+
currentEnd = end;
|
|
157
|
+
}
|
|
158
|
+
return blocks;
|
|
159
|
+
}
|
|
160
|
+
function shouldSkipMatch(text, index, disabledBlocks = []) {
|
|
161
|
+
if (isCommentedOut(text, index) || isLineDisabled(text, index))
|
|
162
|
+
return true;
|
|
163
|
+
for (const block of disabledBlocks) {
|
|
164
|
+
if (index >= block.start && index <= block.end)
|
|
165
|
+
return true;
|
|
166
|
+
}
|
|
167
|
+
return false;
|
|
168
|
+
}
|
|
169
|
+
function pushInstance(instances, value, start, text, matchIndex, disabledBlocks = []) {
|
|
170
|
+
if (shouldSkipMatch(text, start, disabledBlocks))
|
|
171
|
+
return;
|
|
172
|
+
instances.push({
|
|
173
|
+
value,
|
|
174
|
+
start,
|
|
175
|
+
end: start + value.length,
|
|
176
|
+
tagName: getTagNameBackwards(text, matchIndex),
|
|
177
|
+
});
|
|
178
|
+
}
|
|
179
|
+
function extractUnquotedObjectKeys(expr, exprStart, text, matchIndex, instances, disabledBlocks = []) {
|
|
180
|
+
for (const keyMatch of expr.matchAll(regex_1.OBJECT_KEY_REGEX)) {
|
|
181
|
+
const value = keyMatch[1];
|
|
182
|
+
const keyIdx = keyMatch[0].indexOf(value);
|
|
183
|
+
const start = exprStart + keyMatch.index + keyIdx;
|
|
184
|
+
pushInstance(instances, value, start, text, matchIndex, disabledBlocks);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
/**
|
|
188
|
+
* Locates all string literals opted in by a maple comment. The comment marks
|
|
189
|
+
* the whole following expression — like a class attribute, every string
|
|
190
|
+
* literal in it is maple (ternary arms, concatenation parts, ...). String
|
|
191
|
+
* boundaries are delegated to the language service, so each language's
|
|
192
|
+
* string grammar lives in exactly one place.
|
|
193
|
+
*
|
|
194
|
+
* The region ends at a `;` or `,` at bracket depth 0, at a closing bracket
|
|
195
|
+
* that was never opened inside the region, or at a plain assignment `=`
|
|
196
|
+
* (guarding against swallowing the next statement in semicolon-less code;
|
|
197
|
+
* comparison/arrow operators like `==`, `=>`, `<=` do not terminate).
|
|
198
|
+
*/
|
|
199
|
+
function findOptInRegions(service, text) {
|
|
200
|
+
const results = [];
|
|
201
|
+
let currentEnd = 0;
|
|
202
|
+
for (const match of text.matchAll(regex_1.OPT_IN_COMMENT_REGEX)) {
|
|
203
|
+
if (match.index < currentEnd)
|
|
204
|
+
continue;
|
|
205
|
+
let i = match.index + match[0].length;
|
|
206
|
+
while (i < text.length && text[i].trim() === '')
|
|
207
|
+
i++;
|
|
208
|
+
// Objects (/* maple */ { ... }) are handled by the object opt-in path
|
|
209
|
+
if (text[i] === '{')
|
|
210
|
+
continue;
|
|
211
|
+
const regionStart = i;
|
|
212
|
+
const regionLimit = Math.min(text.length, i + exports.MAX_SCAN_LENGTH);
|
|
213
|
+
const literals = [];
|
|
214
|
+
let depth = 0;
|
|
215
|
+
while (i < regionLimit) {
|
|
216
|
+
const literal = service.matchStringLiteral(text, i);
|
|
217
|
+
if (literal) {
|
|
218
|
+
literals.push(literal);
|
|
219
|
+
i = literal.endIndex;
|
|
220
|
+
continue;
|
|
221
|
+
}
|
|
222
|
+
const ch = text[i];
|
|
223
|
+
if (ch === '(' || ch === '[' || ch === '{') {
|
|
224
|
+
depth++;
|
|
225
|
+
}
|
|
226
|
+
else if (ch === ')' || ch === ']' || ch === '}') {
|
|
227
|
+
if (depth === 0)
|
|
228
|
+
break; // closes a bracket opened before the region
|
|
229
|
+
depth--;
|
|
230
|
+
}
|
|
231
|
+
else if (depth === 0 && (ch === ';' || ch === ',')) {
|
|
232
|
+
break;
|
|
233
|
+
}
|
|
234
|
+
else if (depth === 0 &&
|
|
235
|
+
ch === '=' &&
|
|
236
|
+
text[i + 1] !== '=' &&
|
|
237
|
+
text[i + 1] !== '>' &&
|
|
238
|
+
!'=<>!+-*/%&|^'.includes(text[i - 1] ?? '')) {
|
|
239
|
+
break; // plain assignment: the next statement has begun
|
|
240
|
+
}
|
|
241
|
+
i++;
|
|
242
|
+
}
|
|
243
|
+
if (literals.length > 0) {
|
|
244
|
+
results.push({
|
|
245
|
+
matchIndex: match.index,
|
|
246
|
+
regionStart,
|
|
247
|
+
regionEnd: i,
|
|
248
|
+
literals,
|
|
249
|
+
});
|
|
250
|
+
}
|
|
251
|
+
currentEnd = i;
|
|
252
|
+
}
|
|
253
|
+
return results;
|
|
254
|
+
}
|
|
255
|
+
function extractStringLiterals(service, expr, exprStart, text, matchIndex, instances, disabledBlocks = [], extractCallback) {
|
|
256
|
+
let j = 0;
|
|
257
|
+
while (j < expr.length) {
|
|
258
|
+
const literal = service.matchStringLiteral(expr, j);
|
|
259
|
+
if (!literal) {
|
|
260
|
+
j++;
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
const value = expr.substring(literal.contentStart, literal.contentEnd);
|
|
264
|
+
const start = exprStart + literal.contentStart;
|
|
265
|
+
if (literal.isInterpolated) {
|
|
266
|
+
extractCallback?.(value, start, text, matchIndex, literal);
|
|
267
|
+
}
|
|
268
|
+
else {
|
|
269
|
+
pushInstance(instances, value, start, text, matchIndex, disabledBlocks);
|
|
270
|
+
}
|
|
271
|
+
j = literal.endIndex;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
function getExactWordRangeAtPosition(document, position) {
|
|
275
|
+
const wordRange = document.getWordRangeAtPosition(position, regex_1.MAPLE_CLASS_REGEX_NON_GLOBAL);
|
|
276
|
+
const currentWord = wordRange ? document.getText(wordRange) : '';
|
|
277
|
+
if (!wordRange) {
|
|
278
|
+
return { wordRange: undefined, currentWord: '' };
|
|
279
|
+
}
|
|
280
|
+
const cursorOffsetInWord = position.character - wordRange.start.character;
|
|
281
|
+
const tokens = currentWord.split(regex_1.TOKEN_SPLIT_REGEX);
|
|
282
|
+
let currentOffset = 0;
|
|
283
|
+
let finalRange = wordRange;
|
|
284
|
+
let finalWord = '';
|
|
285
|
+
for (const token of tokens) {
|
|
286
|
+
const start = currentOffset;
|
|
287
|
+
const end = currentOffset + token.length;
|
|
288
|
+
if (cursorOffsetInWord > start && cursorOffsetInWord <= end) {
|
|
289
|
+
if (!isQuote(token) && token.trim() !== '') {
|
|
290
|
+
finalWord = token;
|
|
291
|
+
finalRange = wordRange.with(wordRange.start.translate(0, start), wordRange.start.translate(0, end));
|
|
292
|
+
}
|
|
293
|
+
else {
|
|
294
|
+
finalRange = undefined;
|
|
295
|
+
finalWord = '';
|
|
296
|
+
}
|
|
297
|
+
break;
|
|
298
|
+
}
|
|
299
|
+
else if (cursorOffsetInWord === 0 && start === 0) {
|
|
300
|
+
if (!isQuote(token) && token.trim() !== '') {
|
|
301
|
+
finalWord = token;
|
|
302
|
+
finalRange = wordRange.with(wordRange.start.translate(0, start), wordRange.start.translate(0, end));
|
|
303
|
+
break;
|
|
304
|
+
}
|
|
305
|
+
}
|
|
306
|
+
currentOffset = end;
|
|
307
|
+
}
|
|
308
|
+
if (finalWord && finalRange) {
|
|
309
|
+
// Strip trailing HTML characters if it still bled (e.g. `bgc-red>`)
|
|
310
|
+
const cleanWord = finalWord.replace(/[><]+$/, '').replace(/<![\-]*$/, '');
|
|
311
|
+
if (cleanWord !== finalWord) {
|
|
312
|
+
const diff = finalWord.length - cleanWord.length;
|
|
313
|
+
finalRange = finalRange.with(undefined, finalRange.end.translate(0, -diff));
|
|
314
|
+
finalWord = cleanWord;
|
|
315
|
+
}
|
|
316
|
+
}
|
|
317
|
+
return { wordRange: finalRange, currentWord: finalWord };
|
|
318
|
+
}
|
|
319
|
+
//# sourceMappingURL=extractor.helper.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractor.helper.js","sourceRoot":"","sources":["../src/extractor.helper.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { ILanguageService } from './LanguageService';
|
|
2
|
+
/** A plain text replacement, editor-agnostic. Offsets refer to the input text. */
|
|
3
|
+
export interface TextReplacement {
|
|
4
|
+
start: number;
|
|
5
|
+
end: number;
|
|
6
|
+
newText: string;
|
|
7
|
+
}
|
|
8
|
+
/**
|
|
9
|
+
* Formats a maple class string: wraps onto multiple lines when it exceeds
|
|
10
|
+
* `maxClassesPerLine`, grouping classes by property type, and recursing into
|
|
11
|
+
* interpolation expressions via the language service.
|
|
12
|
+
*/
|
|
13
|
+
export declare function formatClasses(classStr: string, baseIndent: string, maxClassesPerLine: number, service: ILanguageService): string;
|
|
14
|
+
/**
|
|
15
|
+
* Computes formatting replacements for every maple region in the document —
|
|
16
|
+
* class attributes, opt-in expressions, and framework-specific regions — as
|
|
17
|
+
* plain offsets, usable from any host (VS Code, Prettier, CLI).
|
|
18
|
+
*/
|
|
19
|
+
export declare function computeFormattingEdits(text: string, service: ILanguageService, maxClassesPerLine: number): Array<TextReplacement>;
|
|
20
|
+
/** Applies non-overlapping replacements to a string. */
|
|
21
|
+
export declare function applyTextEdits(text: string, edits: Array<TextReplacement>): string;
|
|
22
|
+
/**
|
|
23
|
+
* Formats every maple region in a document and returns the new text.
|
|
24
|
+
* Convenience entry point for non-editor hosts (Prettier plugin, CLI).
|
|
25
|
+
*/
|
|
26
|
+
export declare function formatText(text: string, languageId: string, maxClassesPerLine: number): string;
|