Initial commit
This commit is contained in:
77
out/utils/FileResolver.js
Normal file
77
out/utils/FileResolver.js
Normal file
@@ -0,0 +1,77 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.FileResolver = void 0;
|
||||
const vscode = __importStar(require("vscode"));
|
||||
class FileResolver {
|
||||
async getComponentFiles(document) {
|
||||
const basePath = this.getBasePath(document.fileName);
|
||||
const componentFiles = {};
|
||||
if (document.fileName.endsWith('.component.ts')) {
|
||||
componentFiles.typescript = document;
|
||||
}
|
||||
else if (document.fileName.endsWith('.component.html')) {
|
||||
componentFiles.html = document;
|
||||
}
|
||||
else if (document.fileName.endsWith('.component.scss') || document.fileName.endsWith('.component.css')) {
|
||||
componentFiles.styles = document;
|
||||
}
|
||||
// Try to find related files
|
||||
try {
|
||||
if (!componentFiles.typescript) {
|
||||
const tsFile = await vscode.workspace.openTextDocument(basePath + '.component.ts');
|
||||
componentFiles.typescript = tsFile;
|
||||
}
|
||||
if (!componentFiles.html) {
|
||||
const htmlFile = await vscode.workspace.openTextDocument(basePath + '.component.html');
|
||||
componentFiles.html = htmlFile;
|
||||
}
|
||||
if (!componentFiles.styles) {
|
||||
try {
|
||||
const scssFile = await vscode.workspace.openTextDocument(basePath + '.component.scss');
|
||||
componentFiles.styles = scssFile;
|
||||
}
|
||||
catch {
|
||||
try {
|
||||
const cssFile = await vscode.workspace.openTextDocument(basePath + '.component.css');
|
||||
componentFiles.styles = cssFile;
|
||||
}
|
||||
catch {
|
||||
// No styles file found
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (error) {
|
||||
// Some files might not exist, which is fine
|
||||
}
|
||||
return componentFiles;
|
||||
}
|
||||
getBasePath(fileName) {
|
||||
return fileName.replace(/\.(component\.(ts|html|scss|css))$/, '');
|
||||
}
|
||||
}
|
||||
exports.FileResolver = FileResolver;
|
||||
//# sourceMappingURL=FileResolver.js.map
|
||||
1
out/utils/FileResolver.js.map
Normal file
1
out/utils/FileResolver.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"FileResolver.js","sourceRoot":"","sources":["../../src/utils/FileResolver.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAiC;AAGjC,MAAa,YAAY;IACrB,KAAK,CAAC,iBAAiB,CAAC,QAA6B;QACjD,MAAM,QAAQ,GAAG,IAAI,CAAC,WAAW,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACrD,MAAM,cAAc,GAAmB,EAAE,CAAC;QAE1C,IAAI,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,eAAe,CAAC,EAAE;YAC7C,cAAc,CAAC,UAAU,GAAG,QAAQ,CAAC;SACxC;aAAM,IAAI,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,iBAAiB,CAAC,EAAE;YACtD,cAAc,CAAC,IAAI,GAAG,QAAQ,CAAC;SAClC;aAAM,IAAI,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,iBAAiB,CAAC,IAAI,QAAQ,CAAC,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE;YACtG,cAAc,CAAC,MAAM,GAAG,QAAQ,CAAC;SACpC;QAED,4BAA4B;QAC5B,IAAI;YACA,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE;gBAC5B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,QAAQ,GAAG,eAAe,CAAC,CAAC;gBACnF,cAAc,CAAC,UAAU,GAAG,MAAM,CAAC;aACtC;YACD,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE;gBACtB,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,QAAQ,GAAG,iBAAiB,CAAC,CAAC;gBACvF,cAAc,CAAC,IAAI,GAAG,QAAQ,CAAC;aAClC;YACD,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE;gBACxB,IAAI;oBACA,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,QAAQ,GAAG,iBAAiB,CAAC,CAAC;oBACvF,cAAc,CAAC,MAAM,GAAG,QAAQ,CAAC;iBACpC;gBAAC,MAAM;oBACJ,IAAI;wBACA,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,QAAQ,GAAG,gBAAgB,CAAC,CAAC;wBACrF,cAAc,CAAC,MAAM,GAAG,OAAO,CAAC;qBACnC;oBAAC,MAAM;wBACJ,uBAAuB;qBAC1B;iBACJ;aACJ;SACJ;QAAC,OAAO,KAAK,EAAE;YACZ,4CAA4C;SAC/C;QAED,OAAO,cAAc,CAAC;IAC1B,CAAC;IAEO,WAAW,CAAC,QAAgB;QAChC,OAAO,QAAQ,CAAC,OAAO,CAAC,oCAAoC,EAAE,EAAE,CAAC,CAAC;IACtE,CAAC;CACJ;AA9CD,oCA8CC"}
|
||||
41
out/utils/SelectorMatcher.js
Normal file
41
out/utils/SelectorMatcher.js
Normal file
@@ -0,0 +1,41 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.SelectorMatcher = void 0;
|
||||
class SelectorMatcher {
|
||||
isSelectorUsed(cssSelector, usedSelectors) {
|
||||
// Clean the CSS selector for comparison
|
||||
const cleanSelector = this.cleanCSSSelector(cssSelector);
|
||||
// Check for exact matches
|
||||
if (usedSelectors.has(cleanSelector)) {
|
||||
return true;
|
||||
}
|
||||
// Check for partial matches (class and ID selectors)
|
||||
for (const used of usedSelectors) {
|
||||
if (this.selectorsMatch(cleanSelector, used)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
shouldIgnoreSelector(selector, ignoredSelectors) {
|
||||
return ignoredSelectors.some(ignored => selector.includes(ignored) ||
|
||||
selector.match(new RegExp(ignored.replace(/[.*+?^${}()|[\]\\]/g, '\\$&'))));
|
||||
}
|
||||
cleanCSSSelector(selector) {
|
||||
// Remove pseudo-classes, pseudo-elements, and complex selectors
|
||||
return selector
|
||||
.replace(/::?[a-zA-Z-]+(\([^)]*\))?/g, '') // Remove pseudo-classes/elements
|
||||
.replace(/\s*[>+~]\s*/g, ' ') // Simplify combinators
|
||||
.replace(/\[.*?\]/g, '') // Remove attribute selectors
|
||||
.trim();
|
||||
}
|
||||
selectorsMatch(cssSelector, usedSelector) {
|
||||
// Extract class names and IDs
|
||||
const cssClasses = cssSelector.match(/\.[a-zA-Z_-][a-zA-Z0-9_-]*/g) || [];
|
||||
const cssIds = cssSelector.match(/#[a-zA-Z_-][a-zA-Z0-9_-]*/g) || [];
|
||||
return [...cssClasses, ...cssIds].some(sel => usedSelector.includes(sel.substring(1)) // Remove . or # prefix
|
||||
);
|
||||
}
|
||||
}
|
||||
exports.SelectorMatcher = SelectorMatcher;
|
||||
//# sourceMappingURL=SelectorMatcher.js.map
|
||||
1
out/utils/SelectorMatcher.js.map
Normal file
1
out/utils/SelectorMatcher.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"SelectorMatcher.js","sourceRoot":"","sources":["../../src/utils/SelectorMatcher.ts"],"names":[],"mappings":";;;AAAA,MAAa,eAAe;IACxB,cAAc,CAAC,WAAmB,EAAE,aAA0B;QAC1D,wCAAwC;QACxC,MAAM,aAAa,GAAG,IAAI,CAAC,gBAAgB,CAAC,WAAW,CAAC,CAAC;QAEzD,0BAA0B;QAC1B,IAAI,aAAa,CAAC,GAAG,CAAC,aAAa,CAAC,EAAE;YAClC,OAAO,IAAI,CAAC;SACf;QAED,qDAAqD;QACrD,KAAK,MAAM,IAAI,IAAI,aAAa,EAAE;YAC9B,IAAI,IAAI,CAAC,cAAc,CAAC,aAAa,EAAE,IAAI,CAAC,EAAE;gBAC1C,OAAO,IAAI,CAAC;aACf;SACJ;QAED,OAAO,KAAK,CAAC;IACjB,CAAC;IAED,oBAAoB,CAAC,QAAgB,EAAE,gBAA0B;QAC7D,OAAO,gBAAgB,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CACnC,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC;YAC1B,QAAQ,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC,CAAC,CAC7E,CAAC;IACN,CAAC;IAEO,gBAAgB,CAAC,QAAgB;QACrC,gEAAgE;QAChE,OAAO,QAAQ;aACV,OAAO,CAAC,4BAA4B,EAAE,EAAE,CAAC,CAAC,iCAAiC;aAC3E,OAAO,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC,uBAAuB;aACpD,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC,6BAA6B;aACrD,IAAI,EAAE,CAAC;IAChB,CAAC;IAEO,cAAc,CAAC,WAAmB,EAAE,YAAoB;QAC5D,8BAA8B;QAC9B,MAAM,UAAU,GAAG,WAAW,CAAC,KAAK,CAAC,6BAA6B,CAAC,IAAI,EAAE,CAAC;QAC1E,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,4BAA4B,CAAC,IAAI,EAAE,CAAC;QAErE,OAAO,CAAC,GAAG,UAAU,EAAE,GAAG,MAAM,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CACzC,YAAY,CAAC,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,uBAAuB;SAClE,CAAC;IACN,CAAC;CACJ;AA7CD,0CA6CC"}
|
||||
55
out/utils/UnusedStyleFinder.js
Normal file
55
out/utils/UnusedStyleFinder.js
Normal file
@@ -0,0 +1,55 @@
|
||||
"use strict";
|
||||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
var desc = Object.getOwnPropertyDescriptor(m, k);
|
||||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
||||
desc = { enumerable: true, get: function() { return m[k]; } };
|
||||
}
|
||||
Object.defineProperty(o, k2, desc);
|
||||
}) : (function(o, m, k, k2) {
|
||||
if (k2 === undefined) k2 = k;
|
||||
o[k2] = m[k];
|
||||
}));
|
||||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
||||
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
||||
}) : function(o, v) {
|
||||
o["default"] = v;
|
||||
});
|
||||
var __importStar = (this && this.__importStar) || function (mod) {
|
||||
if (mod && mod.__esModule) return mod;
|
||||
var result = {};
|
||||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
|
||||
__setModuleDefault(result, mod);
|
||||
return result;
|
||||
};
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.UnusedStyleFinder = void 0;
|
||||
const vscode = __importStar(require("vscode"));
|
||||
const SelectorMatcher_1 = require("./SelectorMatcher");
|
||||
class UnusedStyleFinder {
|
||||
constructor() {
|
||||
this.selectorMatcher = new SelectorMatcher_1.SelectorMatcher();
|
||||
}
|
||||
findUnusedStyles(cssSelectors, usedSelectors, styleDocument) {
|
||||
const unused = [];
|
||||
const config = vscode.workspace.getConfiguration('angularUnusedStyles');
|
||||
const ignoredSelectors = config.get('ignoredSelectors', []);
|
||||
for (const [selector, position] of cssSelectors.entries()) {
|
||||
if (this.selectorMatcher.shouldIgnoreSelector(selector, ignoredSelectors)) {
|
||||
continue;
|
||||
}
|
||||
if (!this.selectorMatcher.isSelectorUsed(selector, usedSelectors)) {
|
||||
unused.push({
|
||||
selector,
|
||||
line: position.line,
|
||||
character: position.character,
|
||||
length: position.length,
|
||||
reason: `Style '${selector}' appears to be unused`
|
||||
});
|
||||
}
|
||||
}
|
||||
return unused;
|
||||
}
|
||||
}
|
||||
exports.UnusedStyleFinder = UnusedStyleFinder;
|
||||
//# sourceMappingURL=UnusedStyleFinder.js.map
|
||||
1
out/utils/UnusedStyleFinder.js.map
Normal file
1
out/utils/UnusedStyleFinder.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"UnusedStyleFinder.js","sourceRoot":"","sources":["../../src/utils/UnusedStyleFinder.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,+CAAiC;AAEjC,uDAAoD;AAEpD,MAAa,iBAAiB;IAA9B;QACY,oBAAe,GAAG,IAAI,iCAAe,EAAE,CAAC;IA6BpD,CAAC;IA3BG,gBAAgB,CACZ,YAA2C,EAC3C,aAA0B,EAC1B,aAAkC;QAElC,MAAM,MAAM,GAAkB,EAAE,CAAC;QACjC,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,gBAAgB,CAAC,qBAAqB,CAAC,CAAC;QACxE,MAAM,gBAAgB,GAAa,MAAM,CAAC,GAAG,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC;QAEtE,KAAK,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,YAAY,CAAC,OAAO,EAAE,EAAE;YACvD,IAAI,IAAI,CAAC,eAAe,CAAC,oBAAoB,CAAC,QAAQ,EAAE,gBAAgB,CAAC,EAAE;gBACvE,SAAS;aACZ;YAED,IAAI,CAAC,IAAI,CAAC,eAAe,CAAC,cAAc,CAAC,QAAQ,EAAE,aAAa,CAAC,EAAE;gBAC/D,MAAM,CAAC,IAAI,CAAC;oBACR,QAAQ;oBACR,IAAI,EAAE,QAAQ,CAAC,IAAI;oBACnB,SAAS,EAAE,QAAQ,CAAC,SAAS;oBAC7B,MAAM,EAAE,QAAQ,CAAC,MAAM;oBACvB,MAAM,EAAE,UAAU,QAAQ,wBAAwB;iBACrD,CAAC,CAAC;aACN;SACJ;QAED,OAAO,MAAM,CAAC;IAClB,CAAC;CACJ;AA9BD,8CA8BC"}
|
||||
Reference in New Issue
Block a user