tailwind-typescript-plugin 1.4.1-beta.2 → 1.4.1-beta.20
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 +123 -0
- package/README.md +375 -77
- package/lib/core/interfaces.d.ts +23 -12
- package/lib/core/interfaces.d.ts.map +1 -1
- package/lib/core/types.d.ts +112 -1
- package/lib/core/types.d.ts.map +1 -1
- package/lib/extractors/BaseExtractor.d.ts +49 -2
- package/lib/extractors/BaseExtractor.d.ts.map +1 -1
- package/lib/extractors/BaseExtractor.js +184 -5
- package/lib/extractors/BaseExtractor.js.map +1 -1
- package/lib/extractors/CvaExtractor.js +1 -1
- package/lib/extractors/CvaExtractor.js.map +1 -1
- package/lib/extractors/ExpressionExtractor.d.ts.map +1 -1
- package/lib/extractors/ExpressionExtractor.js +35 -5
- package/lib/extractors/ExpressionExtractor.js.map +1 -1
- package/lib/extractors/JsxAttributeExtractor.d.ts +2 -1
- package/lib/extractors/JsxAttributeExtractor.d.ts.map +1 -1
- package/lib/extractors/JsxAttributeExtractor.js +15 -8
- package/lib/extractors/JsxAttributeExtractor.js.map +1 -1
- package/lib/extractors/SvelteAttributeExtractor.d.ts +17 -0
- package/lib/extractors/SvelteAttributeExtractor.d.ts.map +1 -0
- package/lib/extractors/SvelteAttributeExtractor.js +27 -0
- package/lib/extractors/SvelteAttributeExtractor.js.map +1 -0
- package/lib/extractors/TailwindVariantsExtractor.d.ts.map +1 -1
- package/lib/extractors/TailwindVariantsExtractor.js +1 -5
- package/lib/extractors/TailwindVariantsExtractor.js.map +1 -1
- package/lib/extractors/VariableReferenceExtractor.d.ts.map +1 -1
- package/lib/extractors/VariableReferenceExtractor.js +21 -0
- package/lib/extractors/VariableReferenceExtractor.js.map +1 -1
- package/lib/extractors/VueAttributeExtractor.d.ts +119 -0
- package/lib/extractors/VueAttributeExtractor.d.ts.map +1 -0
- package/lib/extractors/VueAttributeExtractor.js +911 -0
- package/lib/extractors/VueAttributeExtractor.js.map +1 -0
- package/lib/extractors/VueExpressionExtractor.d.ts +21 -0
- package/lib/extractors/VueExpressionExtractor.d.ts.map +1 -0
- package/lib/extractors/VueExpressionExtractor.js +51 -0
- package/lib/extractors/VueExpressionExtractor.js.map +1 -0
- package/lib/infrastructure/TailwindConflictDetector.d.ts +28 -18
- package/lib/infrastructure/TailwindConflictDetector.d.ts.map +1 -1
- package/lib/infrastructure/TailwindConflictDetector.js +216 -486
- package/lib/infrastructure/TailwindConflictDetector.js.map +1 -1
- package/lib/infrastructure/TailwindValidator.css-vars.spec.js +1 -11
- package/lib/infrastructure/TailwindValidator.css-vars.spec.js.map +1 -1
- package/lib/infrastructure/TailwindValidator.d.ts +16 -3
- package/lib/infrastructure/TailwindValidator.d.ts.map +1 -1
- package/lib/infrastructure/TailwindValidator.js +83 -24
- package/lib/infrastructure/TailwindValidator.js.map +1 -1
- package/lib/infrastructure/TailwindValidator.spec.js +50 -17
- package/lib/infrastructure/TailwindValidator.spec.js.map +1 -1
- package/lib/plugin/TailwindTypescriptPlugin.d.ts +18 -1
- package/lib/plugin/TailwindTypescriptPlugin.d.ts.map +1 -1
- package/lib/plugin/TailwindTypescriptPlugin.js +124 -55
- package/lib/plugin/TailwindTypescriptPlugin.js.map +1 -1
- package/lib/services/ClassNameExtractionService.d.ts +21 -5
- package/lib/services/ClassNameExtractionService.d.ts.map +1 -1
- package/lib/services/ClassNameExtractionService.js +76 -14
- package/lib/services/ClassNameExtractionService.js.map +1 -1
- package/lib/services/ClassNameExtractionService.spec.d.ts +2 -0
- package/lib/services/ClassNameExtractionService.spec.d.ts.map +1 -0
- package/lib/services/ClassNameExtractionService.spec.js +222 -0
- package/lib/services/ClassNameExtractionService.spec.js.map +1 -0
- package/lib/services/CodeActionService.spec.js +1 -2
- package/lib/services/CodeActionService.spec.js.map +1 -1
- package/lib/services/CompletionService.d.ts +121 -0
- package/lib/services/CompletionService.d.ts.map +1 -0
- package/lib/services/CompletionService.js +573 -0
- package/lib/services/CompletionService.js.map +1 -0
- package/lib/services/CompletionService.spec.d.ts +2 -0
- package/lib/services/CompletionService.spec.d.ts.map +1 -0
- package/lib/services/CompletionService.spec.js +1182 -0
- package/lib/services/CompletionService.spec.js.map +1 -0
- package/lib/services/ConflictClassDetection.spec.js +26 -21
- package/lib/services/ConflictClassDetection.spec.js.map +1 -1
- package/lib/services/DiagnosticService.d.ts +8 -8
- package/lib/services/DiagnosticService.d.ts.map +1 -1
- package/lib/services/DiagnosticService.js +29 -13
- package/lib/services/DiagnosticService.js.map +1 -1
- package/lib/services/DuplicateClassDetection.spec.js +61 -81
- package/lib/services/DuplicateClassDetection.spec.js.map +1 -1
- package/lib/services/PluginConfigService.d.ts +47 -15
- package/lib/services/PluginConfigService.d.ts.map +1 -1
- package/lib/services/PluginConfigService.js +203 -75
- package/lib/services/PluginConfigService.js.map +1 -1
- package/lib/services/PluginConfigService.spec.d.ts +2 -0
- package/lib/services/PluginConfigService.spec.d.ts.map +1 -0
- package/lib/services/PluginConfigService.spec.js +93 -0
- package/lib/services/PluginConfigService.spec.js.map +1 -0
- package/lib/services/ValidationService.d.ts +8 -5
- package/lib/services/ValidationService.d.ts.map +1 -1
- package/lib/services/ValidationService.js +49 -49
- package/lib/services/ValidationService.js.map +1 -1
- package/lib/utils/FrameworkDetector.d.ts +24 -0
- package/lib/utils/FrameworkDetector.d.ts.map +1 -0
- package/lib/utils/FrameworkDetector.js +52 -0
- package/lib/utils/FrameworkDetector.js.map +1 -0
- package/lib/utils/FrameworkDetector.spec.d.ts +2 -0
- package/lib/utils/FrameworkDetector.spec.d.ts.map +1 -0
- package/lib/utils/FrameworkDetector.spec.js +75 -0
- package/lib/utils/FrameworkDetector.spec.js.map +1 -0
- package/package.json +4 -2
- package/lib/extractors/StringLiteralExtractor.d.ts +0 -12
- package/lib/extractors/StringLiteralExtractor.d.ts.map +0 -1
- package/lib/extractors/StringLiteralExtractor.js +0 -21
- package/lib/extractors/StringLiteralExtractor.js.map +0 -1
- package/lib/services/ClassNameExtractionService.original.d.ts +0 -20
- package/lib/services/ClassNameExtractionService.original.d.ts.map +0 -1
- package/lib/services/ClassNameExtractionService.original.js +0 -48
- package/lib/services/ClassNameExtractionService.original.js.map +0 -1
|
@@ -3,54 +3,116 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.ClassNameExtractionService = void 0;
|
|
4
4
|
const CvaExtractor_1 = require("../extractors/CvaExtractor");
|
|
5
5
|
const JsxAttributeExtractor_1 = require("../extractors/JsxAttributeExtractor");
|
|
6
|
+
const SvelteAttributeExtractor_1 = require("../extractors/SvelteAttributeExtractor");
|
|
6
7
|
const TailwindVariantsExtractor_1 = require("../extractors/TailwindVariantsExtractor");
|
|
8
|
+
const VueAttributeExtractor_1 = require("../extractors/VueAttributeExtractor");
|
|
9
|
+
const FrameworkDetector_1 = require("../utils/FrameworkDetector");
|
|
7
10
|
/**
|
|
8
11
|
* OPTIMIZED: Service responsible for orchestrating class name extraction
|
|
9
12
|
*
|
|
10
13
|
* Performance improvements:
|
|
11
|
-
* 1. Fast path for
|
|
14
|
+
* 1. Fast path for framework-specific elements (skip non-matching nodes early)
|
|
12
15
|
* 2. Fast path for tv() calls (check only call expressions)
|
|
13
16
|
* 3. Fast path for cva() calls (check only call expressions)
|
|
14
|
-
* 4.
|
|
17
|
+
* 4. Lazy initialization - only creates extractors when needed (memory efficient)
|
|
15
18
|
* 5. Direct node type checking (faster than polymorphic calls)
|
|
16
19
|
* 6. Reduced function call overhead
|
|
17
20
|
* 7. Conditional extractor execution (skip disabled extractors)
|
|
21
|
+
* 8. Framework detection per file (route to appropriate extractor)
|
|
22
|
+
*
|
|
23
|
+
* SOLID Principles:
|
|
24
|
+
* - Single Responsibility: Only orchestrates extraction, doesn't own all extractors
|
|
25
|
+
* - Open/Closed: Can add new frameworks without modifying constructor
|
|
26
|
+
* - Dependency Inversion: Uses IClassNameExtractor interface
|
|
18
27
|
*/
|
|
19
28
|
class ClassNameExtractionService {
|
|
20
29
|
constructor(enableTailwindVariants = true, enableClassVarianceAuthority = true) {
|
|
21
30
|
this.enableTailwindVariants = enableTailwindVariants;
|
|
22
31
|
this.enableClassVarianceAuthority = enableClassVarianceAuthority;
|
|
23
|
-
//
|
|
24
|
-
this.
|
|
32
|
+
// Cache for framework extractors (lazy initialization)
|
|
33
|
+
this.frameworkExtractors = new Map();
|
|
34
|
+
// Only create variant extractors (they work across all frameworks)
|
|
25
35
|
this.tvExtractor = enableTailwindVariants ? new TailwindVariantsExtractor_1.TailwindVariantsExtractor() : null;
|
|
26
36
|
this.cvaExtractor = enableClassVarianceAuthority ? new CvaExtractor_1.CvaExtractor() : null;
|
|
37
|
+
// Framework-specific extractors are created on-demand via getFrameworkExtractor()
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Factory method to create the appropriate extractor for a framework
|
|
41
|
+
* Follows Factory Pattern for object creation
|
|
42
|
+
*/
|
|
43
|
+
createFrameworkExtractor(framework) {
|
|
44
|
+
switch (framework) {
|
|
45
|
+
case FrameworkDetector_1.Framework.JSX:
|
|
46
|
+
return new JsxAttributeExtractor_1.JsxAttributeExtractor();
|
|
47
|
+
case FrameworkDetector_1.Framework.VUE:
|
|
48
|
+
return new VueAttributeExtractor_1.VueAttributeExtractor();
|
|
49
|
+
case FrameworkDetector_1.Framework.SVELTE:
|
|
50
|
+
return new SvelteAttributeExtractor_1.SvelteAttributeExtractor();
|
|
51
|
+
default:
|
|
52
|
+
throw new Error(`Unsupported framework: ${framework}`);
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Gets the extractor for a framework, creating it lazily if needed
|
|
57
|
+
* This ensures we only instantiate extractors we actually use
|
|
58
|
+
*/
|
|
59
|
+
getFrameworkExtractor(framework) {
|
|
60
|
+
if (!this.frameworkExtractors.has(framework)) {
|
|
61
|
+
this.frameworkExtractors.set(framework, this.createFrameworkExtractor(framework));
|
|
62
|
+
}
|
|
63
|
+
return this.frameworkExtractors.get(framework);
|
|
27
64
|
}
|
|
28
65
|
/**
|
|
29
66
|
* Extract all class names from a source file (OPTIMIZED)
|
|
30
67
|
*/
|
|
31
|
-
extractFromSourceFile(typescript, sourceFile, utilityFunctions, typeChecker) {
|
|
68
|
+
extractFromSourceFile(typescript, sourceFile, utilityFunctions, typeChecker, classAttributes) {
|
|
32
69
|
const classNames = [];
|
|
70
|
+
// Detect framework from filename
|
|
71
|
+
const framework = (0, FrameworkDetector_1.detectFramework)(sourceFile.fileName);
|
|
72
|
+
// Skip unsupported files
|
|
73
|
+
if (!framework) {
|
|
74
|
+
return classNames;
|
|
75
|
+
}
|
|
33
76
|
const context = {
|
|
34
77
|
typescript,
|
|
35
78
|
sourceFile,
|
|
36
79
|
utilityFunctions,
|
|
37
|
-
typeChecker
|
|
80
|
+
typeChecker,
|
|
81
|
+
framework,
|
|
82
|
+
classAttributes
|
|
38
83
|
};
|
|
84
|
+
// Get the appropriate extractor for this framework (lazy-loaded)
|
|
85
|
+
const frameworkExtractor = this.getFrameworkExtractor(framework);
|
|
39
86
|
// OPTIMIZATION: Direct node type checking in visit function
|
|
40
87
|
// Avoids canHandle() overhead for every node
|
|
41
88
|
const visit = (node) => {
|
|
42
|
-
// FAST PATH 1:
|
|
43
|
-
//
|
|
44
|
-
if (
|
|
45
|
-
//
|
|
46
|
-
|
|
47
|
-
if (
|
|
48
|
-
|
|
89
|
+
// FAST PATH 1: Framework-specific extraction
|
|
90
|
+
// For JSX, we can optimize by checking node type directly
|
|
91
|
+
if (framework === FrameworkDetector_1.Framework.JSX) {
|
|
92
|
+
// Only process JSX opening/self-closing elements
|
|
93
|
+
// This skips ~98% of nodes immediately
|
|
94
|
+
if (typescript.isJsxOpeningElement(node) || typescript.isJsxSelfClosingElement(node)) {
|
|
95
|
+
// Direct extraction without canHandle() check
|
|
96
|
+
const extracted = frameworkExtractor.extract(node, context);
|
|
97
|
+
if (extracted.length > 0) {
|
|
98
|
+
classNames.push(...extracted);
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
// For Vue and Svelte, use canHandle() since we can't optimize with TS type guards
|
|
104
|
+
// TODO: Optimize Vue/Svelte with direct node type checks when implementing
|
|
105
|
+
if (frameworkExtractor.canHandle(node, context)) {
|
|
106
|
+
const extracted = frameworkExtractor.extract(node, context);
|
|
107
|
+
if (extracted.length > 0) {
|
|
108
|
+
classNames.push(...extracted);
|
|
109
|
+
}
|
|
49
110
|
}
|
|
50
111
|
}
|
|
51
112
|
// FAST PATH 2: Check for variant library calls (tv, cva)
|
|
52
113
|
// Only processes call expressions and only if extractors are enabled
|
|
53
|
-
|
|
114
|
+
// These work across all frameworks
|
|
115
|
+
if (typescript.isCallExpression(node)) {
|
|
54
116
|
// Try tailwind-variants first (if enabled)
|
|
55
117
|
if (this.tvExtractor) {
|
|
56
118
|
const tvExtracted = this.tvExtractor.extract(node, context);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ClassNameExtractionService.js","sourceRoot":"","sources":["../../src/services/ClassNameExtractionService.ts"],"names":[],"mappings":";;;AAIA,6DAA0D;AAC1D,+EAA4E;AAC5E,uFAAoF;
|
|
1
|
+
{"version":3,"file":"ClassNameExtractionService.js","sourceRoot":"","sources":["../../src/services/ClassNameExtractionService.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClassNameExtractionService.spec.d.ts","sourceRoot":"","sources":["../../src/services/ClassNameExtractionService.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
const ts = __importStar(require("typescript/lib/tsserverlibrary"));
|
|
37
|
+
const ClassNameExtractionService_1 = require("./ClassNameExtractionService");
|
|
38
|
+
describe('ClassNameExtractionService', () => {
|
|
39
|
+
let service;
|
|
40
|
+
beforeEach(() => {
|
|
41
|
+
service = new ClassNameExtractionService_1.ClassNameExtractionService(true, true);
|
|
42
|
+
});
|
|
43
|
+
describe('Framework-specific extraction', () => {
|
|
44
|
+
it('should extract classes from JSX files', () => {
|
|
45
|
+
const sourceCode = '<div className="flex items-center">Hello</div>';
|
|
46
|
+
const sourceFile = ts.createSourceFile('App.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
|
|
47
|
+
const classNames = service.extractFromSourceFile(ts, sourceFile, []);
|
|
48
|
+
expect(classNames).toHaveLength(2);
|
|
49
|
+
expect(classNames[0].className).toBe('flex');
|
|
50
|
+
expect(classNames[1].className).toBe('items-center');
|
|
51
|
+
});
|
|
52
|
+
it('should skip unsupported file types', () => {
|
|
53
|
+
const sourceCode = 'body { color: red; }';
|
|
54
|
+
const sourceFile = ts.createSourceFile('styles.css', sourceCode, ts.ScriptTarget.Latest, true);
|
|
55
|
+
const classNames = service.extractFromSourceFile(ts, sourceFile, []);
|
|
56
|
+
expect(classNames).toHaveLength(0);
|
|
57
|
+
});
|
|
58
|
+
it('should handle Vue files with stub extractor', () => {
|
|
59
|
+
const sourceCode = '<template><div class="flex">Hello</div></template>';
|
|
60
|
+
const sourceFile = ts.createSourceFile('App.vue', sourceCode, ts.ScriptTarget.Latest, true);
|
|
61
|
+
// Vue extractor is a stub, should return empty array
|
|
62
|
+
const classNames = service.extractFromSourceFile(ts, sourceFile, []);
|
|
63
|
+
expect(classNames).toHaveLength(0);
|
|
64
|
+
});
|
|
65
|
+
it('should handle Svelte files with stub extractor', () => {
|
|
66
|
+
const sourceCode = '<div class="flex">Hello</div>';
|
|
67
|
+
const sourceFile = ts.createSourceFile('App.svelte', sourceCode, ts.ScriptTarget.Latest, true);
|
|
68
|
+
// Svelte extractor is a stub, should return empty array
|
|
69
|
+
const classNames = service.extractFromSourceFile(ts, sourceFile, []);
|
|
70
|
+
expect(classNames).toHaveLength(0);
|
|
71
|
+
});
|
|
72
|
+
});
|
|
73
|
+
describe('Lazy initialization', () => {
|
|
74
|
+
it('should create JSX extractor only when processing JSX files', () => {
|
|
75
|
+
const service = new ClassNameExtractionService_1.ClassNameExtractionService(true, true);
|
|
76
|
+
// Check that frameworkExtractors map is initially empty
|
|
77
|
+
// We can't directly access private fields, but we can verify behavior
|
|
78
|
+
const sourceFile = ts.createSourceFile('App.tsx', '<div className="flex">Test</div>', ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
|
|
79
|
+
const classNames = service.extractFromSourceFile(ts, sourceFile, []);
|
|
80
|
+
// If lazy initialization works, we should get results
|
|
81
|
+
expect(classNames).toHaveLength(1);
|
|
82
|
+
expect(classNames[0].className).toBe('flex');
|
|
83
|
+
});
|
|
84
|
+
it('should reuse cached extractors for same framework', () => {
|
|
85
|
+
const jsxFile1 = ts.createSourceFile('App.tsx', '<div className="flex">Test</div>', ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
|
|
86
|
+
const jsxFile2 = ts.createSourceFile('Button.tsx', '<button className="btn">Click</button>', ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
|
|
87
|
+
// Process first JSX file
|
|
88
|
+
const classNames1 = service.extractFromSourceFile(ts, jsxFile1, []);
|
|
89
|
+
expect(classNames1).toHaveLength(1);
|
|
90
|
+
// Process second JSX file - should reuse cached extractor
|
|
91
|
+
const classNames2 = service.extractFromSourceFile(ts, jsxFile2, []);
|
|
92
|
+
expect(classNames2).toHaveLength(1);
|
|
93
|
+
// Both should work correctly
|
|
94
|
+
expect(classNames1[0].className).toBe('flex');
|
|
95
|
+
expect(classNames2[0].className).toBe('btn');
|
|
96
|
+
});
|
|
97
|
+
it('should create different extractors for different frameworks', () => {
|
|
98
|
+
const jsxFile = ts.createSourceFile('App.tsx', '<div className="flex">Test</div>', ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
|
|
99
|
+
const vueFile = ts.createSourceFile('App.vue', '<template><div class="flex">Test</div></template>', ts.ScriptTarget.Latest, true);
|
|
100
|
+
// Process JSX file
|
|
101
|
+
const jsxClassNames = service.extractFromSourceFile(ts, jsxFile, []);
|
|
102
|
+
expect(jsxClassNames).toHaveLength(1);
|
|
103
|
+
// Process Vue file (stub, returns empty)
|
|
104
|
+
const vueClassNames = service.extractFromSourceFile(ts, vueFile, []);
|
|
105
|
+
expect(vueClassNames).toHaveLength(0);
|
|
106
|
+
// Both should work independently
|
|
107
|
+
});
|
|
108
|
+
});
|
|
109
|
+
describe('Mixed project support', () => {
|
|
110
|
+
it('should handle projects with multiple framework files', () => {
|
|
111
|
+
const files = [
|
|
112
|
+
{
|
|
113
|
+
name: 'Header.tsx',
|
|
114
|
+
code: '<header className="header">Header</header>',
|
|
115
|
+
kind: ts.ScriptKind.TSX
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
name: 'Footer.tsx',
|
|
119
|
+
code: '<footer className="footer">Footer</footer>',
|
|
120
|
+
kind: ts.ScriptKind.TSX
|
|
121
|
+
},
|
|
122
|
+
{ name: 'Button.vue', code: '<template><button>Click</button></template>', kind: undefined }
|
|
123
|
+
];
|
|
124
|
+
const results = files.map(file => {
|
|
125
|
+
const sourceFile = ts.createSourceFile(file.name, file.code, ts.ScriptTarget.Latest, true, file.kind);
|
|
126
|
+
return service.extractFromSourceFile(ts, sourceFile, []);
|
|
127
|
+
});
|
|
128
|
+
// JSX files should extract classes
|
|
129
|
+
expect(results[0]).toHaveLength(1);
|
|
130
|
+
expect(results[0][0].className).toBe('header');
|
|
131
|
+
expect(results[1]).toHaveLength(1);
|
|
132
|
+
expect(results[1][0].className).toBe('footer');
|
|
133
|
+
// Vue file should return empty (stub)
|
|
134
|
+
expect(results[2]).toHaveLength(0);
|
|
135
|
+
});
|
|
136
|
+
});
|
|
137
|
+
describe('Custom class attributes', () => {
|
|
138
|
+
it('should extract classes from default className attribute', () => {
|
|
139
|
+
const sourceCode = '<div className="flex items-center">Hello</div>';
|
|
140
|
+
const sourceFile = ts.createSourceFile('App.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
|
|
141
|
+
const classNames = service.extractFromSourceFile(ts, sourceFile, [], undefined, [
|
|
142
|
+
'className',
|
|
143
|
+
'class',
|
|
144
|
+
'classList'
|
|
145
|
+
]);
|
|
146
|
+
expect(classNames).toHaveLength(2);
|
|
147
|
+
expect(classNames[0].className).toBe('flex');
|
|
148
|
+
expect(classNames[1].className).toBe('items-center');
|
|
149
|
+
});
|
|
150
|
+
it('should extract classes from custom attributes when configured', () => {
|
|
151
|
+
const sourceCode = '<View colorStyles="bg-blue-500 text-white">Hello</View>';
|
|
152
|
+
const sourceFile = ts.createSourceFile('App.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
|
|
153
|
+
const classNames = service.extractFromSourceFile(ts, sourceFile, [], undefined, [
|
|
154
|
+
'className',
|
|
155
|
+
'class',
|
|
156
|
+
'classList',
|
|
157
|
+
'colorStyles'
|
|
158
|
+
]);
|
|
159
|
+
expect(classNames).toHaveLength(2);
|
|
160
|
+
expect(classNames[0].className).toBe('bg-blue-500');
|
|
161
|
+
expect(classNames[1].className).toBe('text-white');
|
|
162
|
+
});
|
|
163
|
+
it('should extract classes from multiple custom attributes', () => {
|
|
164
|
+
const sourceCode = '<View colorStyles="bg-blue-500" textStyles="font-bold text-lg">Hello</View>';
|
|
165
|
+
const sourceFile = ts.createSourceFile('App.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
|
|
166
|
+
const classNames = service.extractFromSourceFile(ts, sourceFile, [], undefined, [
|
|
167
|
+
'className',
|
|
168
|
+
'colorStyles',
|
|
169
|
+
'textStyles'
|
|
170
|
+
]);
|
|
171
|
+
expect(classNames).toHaveLength(3);
|
|
172
|
+
expect(classNames[0].className).toBe('bg-blue-500');
|
|
173
|
+
expect(classNames[1].className).toBe('font-bold');
|
|
174
|
+
expect(classNames[2].className).toBe('text-lg');
|
|
175
|
+
});
|
|
176
|
+
it('should not extract from non-configured attributes', () => {
|
|
177
|
+
const sourceCode = '<View customProp="flex items-center">Hello</View>';
|
|
178
|
+
const sourceFile = ts.createSourceFile('App.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
|
|
179
|
+
// Only default attributes configured, customProp not included
|
|
180
|
+
const classNames = service.extractFromSourceFile(ts, sourceFile, [], undefined, [
|
|
181
|
+
'className',
|
|
182
|
+
'class',
|
|
183
|
+
'classList'
|
|
184
|
+
]);
|
|
185
|
+
expect(classNames).toHaveLength(0);
|
|
186
|
+
});
|
|
187
|
+
it('should work with JSX expressions in custom attributes', () => {
|
|
188
|
+
const sourceCode = "<View colorStyles={'bg-blue-500 text-white'}>Hello</View>";
|
|
189
|
+
const sourceFile = ts.createSourceFile('App.tsx', sourceCode, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
|
|
190
|
+
const classNames = service.extractFromSourceFile(ts, sourceFile, [], undefined, [
|
|
191
|
+
'className',
|
|
192
|
+
'colorStyles'
|
|
193
|
+
]);
|
|
194
|
+
expect(classNames).toHaveLength(2);
|
|
195
|
+
expect(classNames[0].className).toBe('bg-blue-500');
|
|
196
|
+
expect(classNames[1].className).toBe('text-white');
|
|
197
|
+
});
|
|
198
|
+
});
|
|
199
|
+
describe('Variant extractors', () => {
|
|
200
|
+
it('should work across all frameworks', () => {
|
|
201
|
+
// tv() and cva() should work in any file type
|
|
202
|
+
const jsxWithTv = ts.createSourceFile('App.tsx', `
|
|
203
|
+
import { tv } from 'tailwind-variants';
|
|
204
|
+
const button = tv({ base: 'flex items-center' });
|
|
205
|
+
`, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
|
|
206
|
+
const classNames = service.extractFromSourceFile(ts, jsxWithTv, []);
|
|
207
|
+
// Should extract from tv() call
|
|
208
|
+
expect(classNames.length).toBeGreaterThan(0);
|
|
209
|
+
});
|
|
210
|
+
it('should be disabled when configuration is false', () => {
|
|
211
|
+
const serviceWithoutVariants = new ClassNameExtractionService_1.ClassNameExtractionService(false, false);
|
|
212
|
+
const codeWithTv = ts.createSourceFile('App.tsx', `
|
|
213
|
+
import { tv } from 'tailwind-variants';
|
|
214
|
+
const button = tv({ base: 'flex items-center' });
|
|
215
|
+
`, ts.ScriptTarget.Latest, true, ts.ScriptKind.TSX);
|
|
216
|
+
const classNames = serviceWithoutVariants.extractFromSourceFile(ts, codeWithTv, []);
|
|
217
|
+
// Should not extract from tv() since it's disabled
|
|
218
|
+
expect(classNames).toHaveLength(0);
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
//# sourceMappingURL=ClassNameExtractionService.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ClassNameExtractionService.spec.js","sourceRoot":"","sources":["../../src/services/ClassNameExtractionService.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -35,14 +35,13 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
const ts = __importStar(require("typescript/lib/tsserverlibrary"));
|
|
37
37
|
const TailwindValidator_1 = require("../infrastructure/TailwindValidator");
|
|
38
|
-
const Logger_1 = require("../utils/Logger");
|
|
39
38
|
const CodeActionService_1 = require("./CodeActionService");
|
|
40
39
|
const DiagnosticService_1 = require("./DiagnosticService");
|
|
41
40
|
describe('CodeActionService', () => {
|
|
42
41
|
let validator;
|
|
43
42
|
let codeActionService;
|
|
44
43
|
beforeEach(() => {
|
|
45
|
-
validator = new TailwindValidator_1.TailwindValidator('/fake/path.css'
|
|
44
|
+
validator = new TailwindValidator_1.TailwindValidator('/fake/path.css');
|
|
46
45
|
// Mock the validator methods
|
|
47
46
|
jest.spyOn(validator, 'getSimilarClasses').mockImplementation((invalidClass) => {
|
|
48
47
|
if (invalidClass === 'itms-center') {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CodeActionService.spec.js","sourceRoot":"","sources":["../../src/services/CodeActionService.spec.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,mEAAqD;AAErD,2EAAwE;AACxE,
|
|
1
|
+
{"version":3,"file":"CodeActionService.spec.js","sourceRoot":"","sources":["../../src/services/CodeActionService.spec.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
import * as ts from 'typescript/lib/tsserverlibrary';
|
|
2
|
+
import { UtilityFunction } from '../core/types';
|
|
3
|
+
import { TailwindValidator } from '../infrastructure/TailwindValidator';
|
|
4
|
+
/**
|
|
5
|
+
* Configuration options for completion service
|
|
6
|
+
*/
|
|
7
|
+
export interface CompletionServiceConfig {
|
|
8
|
+
/** Custom utility functions to recognize for completions */
|
|
9
|
+
utilityFunctions: UtilityFunction[];
|
|
10
|
+
/** Whether tailwind-variants (tv) is enabled */
|
|
11
|
+
tailwindVariantsEnabled: boolean;
|
|
12
|
+
/** Whether class-variance-authority (cva) is enabled */
|
|
13
|
+
classVarianceAuthorityEnabled: boolean;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Service that provides autocompletion for Tailwind CSS class names
|
|
17
|
+
*
|
|
18
|
+
* Provides completions when:
|
|
19
|
+
* - Cursor is inside a className attribute's string literal
|
|
20
|
+
* - Cursor is inside a utility function argument (clsx, cn, classnames, etc.)
|
|
21
|
+
* - Cursor is inside tv() or cva() class strings
|
|
22
|
+
*
|
|
23
|
+
* Features:
|
|
24
|
+
* - Filters completions based on what's already typed
|
|
25
|
+
* - Excludes classes already present in the same className
|
|
26
|
+
* - Handles space-separated class lists properly
|
|
27
|
+
*/
|
|
28
|
+
export declare class CompletionService {
|
|
29
|
+
private readonly validator;
|
|
30
|
+
private readonly config;
|
|
31
|
+
/** Cached sorted class list for faster completion generation */
|
|
32
|
+
private cachedClassList;
|
|
33
|
+
/** Cached set of utility function names for quick lookup */
|
|
34
|
+
private utilityFunctionNames;
|
|
35
|
+
constructor(validator: TailwindValidator, config: CompletionServiceConfig);
|
|
36
|
+
/**
|
|
37
|
+
* Get completions at the given position
|
|
38
|
+
*/
|
|
39
|
+
getCompletionsAtPosition(typescript: typeof ts, sourceFile: ts.SourceFile, position: number, existingCompletions: ts.CompletionInfo | undefined): ts.CompletionInfo | undefined;
|
|
40
|
+
/**
|
|
41
|
+
* Get quick info (hover) at position for Tailwind class names
|
|
42
|
+
* Shows the CSS generated by the class when hovering over it
|
|
43
|
+
*/
|
|
44
|
+
getQuickInfoAtPosition(typescript: typeof ts, sourceFile: ts.SourceFile, position: number): ts.QuickInfo | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* Find a Tailwind class name at the given position
|
|
47
|
+
* Returns the class name, its start position, and length if found
|
|
48
|
+
*/
|
|
49
|
+
private findClassNameAtPosition;
|
|
50
|
+
/**
|
|
51
|
+
* Get completion entry details for a specific completion item
|
|
52
|
+
* Formats the documentation with markdown CSS code blocks for syntax highlighting
|
|
53
|
+
*/
|
|
54
|
+
getCompletionEntryDetails(typescript: typeof ts, sourceFile: ts.SourceFile, position: number, entryName: string): ts.CompletionEntryDetails | undefined;
|
|
55
|
+
/**
|
|
56
|
+
* Format CSS output for display in the completion documentation
|
|
57
|
+
* Transforms the raw Tailwind CSS output into a nicely formatted rule block
|
|
58
|
+
*/
|
|
59
|
+
private formatCssForDisplay;
|
|
60
|
+
/**
|
|
61
|
+
* Extract just the CSS declarations from a CSS rule for the detail summary
|
|
62
|
+
* e.g., ".flex { display: flex; }" -> "display: flex;"
|
|
63
|
+
*/
|
|
64
|
+
private extractCssDeclarations;
|
|
65
|
+
/**
|
|
66
|
+
* Check if a name is a valid Tailwind class
|
|
67
|
+
*/
|
|
68
|
+
private isTailwindClass;
|
|
69
|
+
/**
|
|
70
|
+
* Analyze the source file at the given position to determine completion context
|
|
71
|
+
*/
|
|
72
|
+
private getCompletionContext;
|
|
73
|
+
/**
|
|
74
|
+
* Find the deepest node at the given position
|
|
75
|
+
* Uses TypeScript's built-in method which handles edge cases better
|
|
76
|
+
*/
|
|
77
|
+
private findNodeAtPosition;
|
|
78
|
+
/**
|
|
79
|
+
* Check if a string literal node is in a className-like context
|
|
80
|
+
*/
|
|
81
|
+
private isClassNameContext;
|
|
82
|
+
/**
|
|
83
|
+
* Check if an attribute name is a className-like attribute
|
|
84
|
+
*/
|
|
85
|
+
private isClassNameAttribute;
|
|
86
|
+
/**
|
|
87
|
+
* Check if a function name is a configured utility function for class names
|
|
88
|
+
*/
|
|
89
|
+
private isUtilityFunction;
|
|
90
|
+
/**
|
|
91
|
+
* Get the name of a call expression
|
|
92
|
+
*/
|
|
93
|
+
private getCallExpressionName;
|
|
94
|
+
/**
|
|
95
|
+
* Find the parent call expression of a node
|
|
96
|
+
*/
|
|
97
|
+
private findParentCallExpression;
|
|
98
|
+
/**
|
|
99
|
+
* Generate completion entries for Tailwind classes
|
|
100
|
+
*/
|
|
101
|
+
private generateCompletions;
|
|
102
|
+
/**
|
|
103
|
+
* Get the cached class list, initializing if necessary
|
|
104
|
+
*/
|
|
105
|
+
private getClassList;
|
|
106
|
+
/**
|
|
107
|
+
* Clear the cached class list (call when design system reloads)
|
|
108
|
+
*/
|
|
109
|
+
clearCache(): void;
|
|
110
|
+
/**
|
|
111
|
+
* Check if a class name is related to colors
|
|
112
|
+
* Uses a pattern-based approach to detect color classes efficiently
|
|
113
|
+
*/
|
|
114
|
+
private isColorClass;
|
|
115
|
+
/**
|
|
116
|
+
* Generate sort text for completion ordering
|
|
117
|
+
* Classes that start with the prefix get priority
|
|
118
|
+
*/
|
|
119
|
+
private getSortText;
|
|
120
|
+
}
|
|
121
|
+
//# sourceMappingURL=CompletionService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CompletionService.d.ts","sourceRoot":"","sources":["../../src/services/CompletionService.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,gCAAgC,CAAC;AAErD,OAAO,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AAChD,OAAO,EAAE,iBAAiB,EAAE,MAAM,qCAAqC,CAAC;AAkBxE;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACvC,4DAA4D;IAC5D,gBAAgB,EAAE,eAAe,EAAE,CAAC;IACpC,gDAAgD;IAChD,uBAAuB,EAAE,OAAO,CAAC;IACjC,wDAAwD;IACxD,6BAA6B,EAAE,OAAO,CAAC;CACvC;AAED;;;;;;;;;;;;GAYG;AACH,qBAAa,iBAAiB;IAO5B,OAAO,CAAC,QAAQ,CAAC,SAAS;IAC1B,OAAO,CAAC,QAAQ,CAAC,MAAM;IAPxB,gEAAgE;IAChE,OAAO,CAAC,eAAe,CAAyB;IAChD,4DAA4D;IAC5D,OAAO,CAAC,oBAAoB,CAAc;gBAGxB,SAAS,EAAE,iBAAiB,EAC5B,MAAM,EAAE,uBAAuB;IAgBjD;;OAEG;IACH,wBAAwB,CACvB,UAAU,EAAE,OAAO,EAAE,EACrB,UAAU,EAAE,EAAE,CAAC,UAAU,EACzB,QAAQ,EAAE,MAAM,EAChB,mBAAmB,EAAE,EAAE,CAAC,cAAc,GAAG,SAAS,GAChD,EAAE,CAAC,cAAc,GAAG,SAAS;IAwBhC;;;OAGG;IACH,sBAAsB,CACrB,UAAU,EAAE,OAAO,EAAE,EACrB,UAAU,EAAE,EAAE,CAAC,UAAU,EACzB,QAAQ,EAAE,MAAM,GACd,EAAE,CAAC,SAAS,GAAG,SAAS;IA4C3B;;;OAGG;IACH,OAAO,CAAC,uBAAuB;IAqE/B;;;OAGG;IACH,yBAAyB,CACxB,UAAU,EAAE,OAAO,EAAE,EACrB,UAAU,EAAE,EAAE,CAAC,UAAU,EACzB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,GACf,EAAE,CAAC,sBAAsB,GAAG,SAAS;IAuCxC;;;OAGG;IACH,OAAO,CAAC,mBAAmB;IAuC3B;;;OAGG;IACH,OAAO,CAAC,sBAAsB;IAiB9B;;OAEG;IACH,OAAO,CAAC,eAAe;IAIvB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAwE5B;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IA8B1B;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA4D1B;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAU5B;;OAEG;IACH,OAAO,CAAC,iBAAiB;IAIzB;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAiB7B;;OAEG;IACH,OAAO,CAAC,wBAAwB;IAyBhC;;OAEG;IACH,OAAO,CAAC,mBAAmB;IA0C3B;;OAEG;IACH,OAAO,CAAC,YAAY;IAOpB;;OAEG;IACH,UAAU,IAAI,IAAI;IAIlB;;;OAGG;IACH,OAAO,CAAC,YAAY;IA+EpB;;;OAGG;IACH,OAAO,CAAC,WAAW;CAcnB"}
|