Initial commit
This commit is contained in:
34
out/analyzer/AngularComponentAnalyzer.js
Normal file
34
out/analyzer/AngularComponentAnalyzer.js
Normal file
@@ -0,0 +1,34 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.AngularComponentAnalyzer = void 0;
|
||||
const CSSAnalyzer_1 = require("./CSSAnalyzer");
|
||||
const HTMLAnalyzer_1 = require("./HTMLAnalyzer");
|
||||
const TypeScriptAnalyzer_1 = require("./TypeScriptAnalyzer");
|
||||
const FileResolver_1 = require("../utils/FileResolver");
|
||||
const UnusedStyleFinder_1 = require("../utils/UnusedStyleFinder");
|
||||
class AngularComponentAnalyzer {
|
||||
constructor() {
|
||||
this.cssAnalyzer = new CSSAnalyzer_1.CSSAnalyzer();
|
||||
this.htmlAnalyzer = new HTMLAnalyzer_1.HTMLAnalyzer();
|
||||
this.tsAnalyzer = new TypeScriptAnalyzer_1.TypeScriptAnalyzer();
|
||||
this.fileResolver = new FileResolver_1.FileResolver();
|
||||
this.unusedStyleFinder = new UnusedStyleFinder_1.UnusedStyleFinder();
|
||||
}
|
||||
async analyzeComponent(componentFiles) {
|
||||
if (!componentFiles.styles) {
|
||||
return [];
|
||||
}
|
||||
const cssSelectors = this.cssAnalyzer.extractSelectors(componentFiles.styles);
|
||||
const htmlUsedSelectors = componentFiles.html ?
|
||||
this.htmlAnalyzer.extractUsedSelectors(componentFiles.html) : new Set();
|
||||
const tsUsedSelectors = componentFiles.typescript ?
|
||||
this.tsAnalyzer.extractDynamicSelectors(componentFiles.typescript) : new Set();
|
||||
const allUsedSelectors = new Set([...htmlUsedSelectors, ...tsUsedSelectors]);
|
||||
return this.unusedStyleFinder.findUnusedStyles(cssSelectors, allUsedSelectors, componentFiles.styles);
|
||||
}
|
||||
async getComponentFiles(document) {
|
||||
return this.fileResolver.getComponentFiles(document);
|
||||
}
|
||||
}
|
||||
exports.AngularComponentAnalyzer = AngularComponentAnalyzer;
|
||||
//# sourceMappingURL=AngularComponentAnalyzer.js.map
|
||||
1
out/analyzer/AngularComponentAnalyzer.js.map
Normal file
1
out/analyzer/AngularComponentAnalyzer.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"AngularComponentAnalyzer.js","sourceRoot":"","sources":["../../src/analyzer/AngularComponentAnalyzer.ts"],"names":[],"mappings":";;;AACA,+CAA4C;AAC5C,iDAA8C;AAC9C,6DAA0D;AAE1D,wDAAqD;AACrD,kEAA+D;AAE/D,MAAa,wBAAwB;IAArC;QACY,gBAAW,GAAG,IAAI,yBAAW,EAAE,CAAC;QAChC,iBAAY,GAAG,IAAI,2BAAY,EAAE,CAAC;QAClC,eAAU,GAAG,IAAI,uCAAkB,EAAE,CAAC;QACtC,iBAAY,GAAG,IAAI,2BAAY,EAAE,CAAC;QAClC,sBAAiB,GAAG,IAAI,qCAAiB,EAAE,CAAC;IAqBxD,CAAC;IAnBG,KAAK,CAAC,gBAAgB,CAAC,cAA8B;QACjD,IAAI,CAAC,cAAc,CAAC,MAAM,EAAE;YACxB,OAAO,EAAE,CAAC;SACb;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,WAAW,CAAC,gBAAgB,CAAC,cAAc,CAAC,MAAM,CAAC,CAAC;QAC9E,MAAM,iBAAiB,GAAgB,cAAc,CAAC,IAAI,CAAC,CAAC;YACxD,IAAI,CAAC,YAAY,CAAC,oBAAoB,CAAC,cAAc,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAU,CAAC;QACpF,MAAM,eAAe,GAAgB,cAAc,CAAC,UAAU,CAAC,CAAC;YAC5D,IAAI,CAAC,UAAU,CAAC,uBAAuB,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAU,CAAC;QAE3F,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAS,CAAC,GAAG,iBAAiB,EAAE,GAAG,eAAe,CAAC,CAAC,CAAC;QAErF,OAAO,IAAI,CAAC,iBAAiB,CAAC,gBAAgB,CAAC,YAAY,EAAE,gBAAgB,EAAE,cAAc,CAAC,MAAM,CAAC,CAAC;IAC1G,CAAC;IAED,KAAK,CAAC,iBAAiB,CAAC,QAA6B;QACjD,OAAO,IAAI,CAAC,YAAY,CAAC,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IACzD,CAAC;CACJ;AA1BD,4DA0BC"}
|
||||
121
out/analyzer/CSSAnalyzer.js
Normal file
121
out/analyzer/CSSAnalyzer.js
Normal file
@@ -0,0 +1,121 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.CSSAnalyzer = void 0;
|
||||
class CSSAnalyzer {
|
||||
extractSelectors(document) {
|
||||
const selectors = new Map();
|
||||
const text = document.getText();
|
||||
// Parse CSS/SCSS using regex-based approach
|
||||
this.parseStylesheet(text, selectors);
|
||||
return selectors;
|
||||
}
|
||||
parseStylesheet(text, selectors) {
|
||||
const lines = text.split('\n');
|
||||
let inComment = false;
|
||||
let inRule = false;
|
||||
let braceCount = 0;
|
||||
for (let i = 0; i < lines.length; i++) {
|
||||
let line = lines[i];
|
||||
// Handle multi-line comments
|
||||
if (inComment) {
|
||||
const commentEnd = line.indexOf('*/');
|
||||
if (commentEnd !== -1) {
|
||||
inComment = false;
|
||||
line = line.substring(commentEnd + 2);
|
||||
}
|
||||
else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
// Remove single-line comments
|
||||
const commentStart = line.indexOf('//');
|
||||
if (commentStart !== -1) {
|
||||
line = line.substring(0, commentStart);
|
||||
}
|
||||
// Handle multi-line comment start
|
||||
const multiCommentStart = line.indexOf('/*');
|
||||
if (multiCommentStart !== -1) {
|
||||
const multiCommentEnd = line.indexOf('*/', multiCommentStart);
|
||||
if (multiCommentEnd !== -1) {
|
||||
line = line.substring(0, multiCommentStart) + line.substring(multiCommentEnd + 2);
|
||||
}
|
||||
else {
|
||||
inComment = true;
|
||||
line = line.substring(0, multiCommentStart);
|
||||
}
|
||||
}
|
||||
// Count braces to track nesting
|
||||
const openBraces = (line.match(/\{/g) || []).length;
|
||||
const closeBraces = (line.match(/\}/g) || []).length;
|
||||
// If we're not in a rule and line contains a selector pattern
|
||||
if (!inRule && braceCount === 0) {
|
||||
const selectorMatch = this.extractSelectorFromLine(line, i);
|
||||
if (selectorMatch) {
|
||||
selectors.set(selectorMatch.selector, {
|
||||
line: i,
|
||||
character: selectorMatch.character,
|
||||
length: selectorMatch.length
|
||||
});
|
||||
}
|
||||
}
|
||||
braceCount += openBraces - closeBraces;
|
||||
inRule = braceCount > 0;
|
||||
}
|
||||
}
|
||||
extractSelectorFromLine(line, lineNumber) {
|
||||
// Remove leading/trailing whitespace
|
||||
const trimmed = line.trim();
|
||||
// Skip empty lines, variables, imports, mixins, etc.
|
||||
if (!trimmed ||
|
||||
trimmed.startsWith('$') ||
|
||||
trimmed.startsWith('@') ||
|
||||
trimmed.startsWith('//') ||
|
||||
trimmed.startsWith('/*') ||
|
||||
!trimmed.includes('{')) {
|
||||
return null;
|
||||
}
|
||||
// Extract selector part (everything before the opening brace)
|
||||
const braceIndex = trimmed.indexOf('{');
|
||||
if (braceIndex === -1) {
|
||||
return null;
|
||||
}
|
||||
const selectorPart = trimmed.substring(0, braceIndex).trim();
|
||||
// Validate that this looks like a CSS selector
|
||||
if (this.isValidSelector(selectorPart)) {
|
||||
const character = line.indexOf(selectorPart);
|
||||
return {
|
||||
selector: selectorPart,
|
||||
character: character >= 0 ? character : 0,
|
||||
length: selectorPart.length
|
||||
};
|
||||
}
|
||||
return null;
|
||||
}
|
||||
isValidSelector(selector) {
|
||||
// Skip SCSS control structures and mixins
|
||||
if (selector.startsWith('@') ||
|
||||
selector.includes('@if') ||
|
||||
selector.includes('@for') ||
|
||||
selector.includes('@while') ||
|
||||
selector.includes('@each') ||
|
||||
selector.includes('@mixin') ||
|
||||
selector.includes('@include')) {
|
||||
return false;
|
||||
}
|
||||
// Basic CSS selector patterns
|
||||
const selectorPatterns = [
|
||||
/^[.#]?[a-zA-Z_-][a-zA-Z0-9_-]*/,
|
||||
/^::[a-zA-Z-]+/,
|
||||
/^:[a-zA-Z-]+/,
|
||||
/^\[.*\]/,
|
||||
/^[*]/, // Universal selector
|
||||
];
|
||||
// Check if selector matches any valid pattern
|
||||
return selectorPatterns.some(pattern => pattern.test(selector.trim())) ||
|
||||
selector.includes('.') ||
|
||||
selector.includes('#') ||
|
||||
selector.includes(':');
|
||||
}
|
||||
}
|
||||
exports.CSSAnalyzer = CSSAnalyzer;
|
||||
//# sourceMappingURL=CSSAnalyzer.js.map
|
||||
1
out/analyzer/CSSAnalyzer.js.map
Normal file
1
out/analyzer/CSSAnalyzer.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"CSSAnalyzer.js","sourceRoot":"","sources":["../../src/analyzer/CSSAnalyzer.ts"],"names":[],"mappings":"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"}
|
||||
42
out/analyzer/HTMLAnalyzer.js
Normal file
42
out/analyzer/HTMLAnalyzer.js
Normal file
@@ -0,0 +1,42 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.HTMLAnalyzer = void 0;
|
||||
class HTMLAnalyzer {
|
||||
extractUsedSelectors(document) {
|
||||
const usedSelectors = new Set();
|
||||
const text = document.getText();
|
||||
// Extract class attributes
|
||||
const classMatches = text.match(/class\s*=\s*["']([^"']+)["']/g) || [];
|
||||
classMatches.forEach(match => {
|
||||
const classes = match.replace(/class\s*=\s*["']([^"']+)["']/, '$1').split(/\s+/);
|
||||
classes.forEach(cls => cls.trim() && usedSelectors.add(cls.trim()));
|
||||
});
|
||||
// Extract id attributes
|
||||
const idMatches = text.match(/id\s*=\s*["']([^"']+)["']/g) || [];
|
||||
idMatches.forEach(match => {
|
||||
const id = match.replace(/id\s*=\s*["']([^"']+)["']/, '$1').trim();
|
||||
if (id)
|
||||
usedSelectors.add(id);
|
||||
});
|
||||
// Extract Angular class bindings
|
||||
const ngClassMatches = text.match(/\[class\.([^\]]+)\]/g) || [];
|
||||
ngClassMatches.forEach(match => {
|
||||
const className = match.replace(/\[class\.([^\]]+)\]/, '$1');
|
||||
usedSelectors.add(className);
|
||||
});
|
||||
// Extract ngClass bindings
|
||||
const ngClassObjectMatches = text.match(/\[ngClass\]\s*=\s*["']([^"']+)["']/g) || [];
|
||||
ngClassObjectMatches.forEach(match => {
|
||||
const expr = match.replace(/\[ngClass\]\s*=\s*["']([^"']+)["']/, '$1');
|
||||
// This would need more sophisticated parsing for object expressions
|
||||
const possibleClasses = expr.match(/['"`]([^'"`]+)['"`]/g) || [];
|
||||
possibleClasses.forEach(cls => {
|
||||
const className = cls.replace(/['"`]/g, '');
|
||||
usedSelectors.add(className);
|
||||
});
|
||||
});
|
||||
return usedSelectors;
|
||||
}
|
||||
}
|
||||
exports.HTMLAnalyzer = HTMLAnalyzer;
|
||||
//# sourceMappingURL=HTMLAnalyzer.js.map
|
||||
1
out/analyzer/HTMLAnalyzer.js.map
Normal file
1
out/analyzer/HTMLAnalyzer.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"HTMLAnalyzer.js","sourceRoot":"","sources":["../../src/analyzer/HTMLAnalyzer.ts"],"names":[],"mappings":";;;AAEA,MAAa,YAAY;IACrB,oBAAoB,CAAC,QAA6B;QAC9C,MAAM,aAAa,GAAG,IAAI,GAAG,EAAU,CAAC;QACxC,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;QAEhC,2BAA2B;QAC3B,MAAM,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,+BAA+B,CAAC,IAAI,EAAE,CAAC;QACvE,YAAY,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YACzB,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,8BAA8B,EAAE,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;YACjF,OAAO,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,aAAa,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;QAEH,wBAAwB;QACxB,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,4BAA4B,CAAC,IAAI,EAAE,CAAC;QACjE,SAAS,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YACtB,MAAM,EAAE,GAAG,KAAK,CAAC,OAAO,CAAC,2BAA2B,EAAE,IAAI,CAAC,CAAC,IAAI,EAAE,CAAC;YACnE,IAAI,EAAE;gBAAE,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClC,CAAC,CAAC,CAAC;QAEH,iCAAiC;QACjC,MAAM,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,IAAI,EAAE,CAAC;QAChE,cAAc,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YAC3B,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,qBAAqB,EAAE,IAAI,CAAC,CAAC;YAC7D,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACjC,CAAC,CAAC,CAAC;QAEH,2BAA2B;QAC3B,MAAM,oBAAoB,GAAG,IAAI,CAAC,KAAK,CAAC,qCAAqC,CAAC,IAAI,EAAE,CAAC;QACrF,oBAAoB,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YACjC,MAAM,IAAI,GAAG,KAAK,CAAC,OAAO,CAAC,oCAAoC,EAAE,IAAI,CAAC,CAAC;YACvE,oEAAoE;YACpE,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,sBAAsB,CAAC,IAAI,EAAE,CAAC;YACjE,eAAe,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE;gBAC1B,MAAM,SAAS,GAAG,GAAG,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;gBAC5C,aAAa,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;YACjC,CAAC,CAAC,CAAC;QACP,CAAC,CAAC,CAAC;QAEH,OAAO,aAAa,CAAC;IACzB,CAAC;CACJ;AAxCD,oCAwCC"}
|
||||
39
out/analyzer/TypeScriptAnalyzer.js
Normal file
39
out/analyzer/TypeScriptAnalyzer.js
Normal file
@@ -0,0 +1,39 @@
|
||||
"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.TypeScriptAnalyzer = void 0;
|
||||
class TypeScriptAnalyzer {
|
||||
extractDynamicSelectors(document) {
|
||||
const dynamicSelectors = new Set();
|
||||
const text = document.getText();
|
||||
// Look for renderer.addClass, renderer.removeClass calls
|
||||
const rendererMatches = text.match(/renderer\.(addClass|removeClass)\s*\(\s*[^,]+,\s*['"`]([^'"`]+)['"`]/g) || [];
|
||||
rendererMatches.forEach(match => {
|
||||
const className = match.replace(/.*['"`]([^'"`]+)['"`].*/, '$1');
|
||||
dynamicSelectors.add(className);
|
||||
});
|
||||
// Look for element.classList operations
|
||||
const classListMatches = text.match(/\.classList\.(add|remove|toggle)\s*\(\s*['"`]([^'"`]+)['"`]/g) || [];
|
||||
classListMatches.forEach(match => {
|
||||
const className = match.replace(/.*['"`]([^'"`]+)['"`].*/, '$1');
|
||||
dynamicSelectors.add(className);
|
||||
});
|
||||
// Look for HostBinding decorators
|
||||
const hostBindingMatches = text.match(/@HostBinding\s*\(\s*['"`]class\.([^'"`]+)['"`]/g) || [];
|
||||
hostBindingMatches.forEach(match => {
|
||||
const className = match.replace(/@HostBinding\s*\(\s*['"`]class\.([^'"`]+)['"`].*/, '$1');
|
||||
dynamicSelectors.add(className);
|
||||
});
|
||||
// Look for string literals that might be class names
|
||||
const stringLiteralMatches = text.match(/['"`][a-zA-Z_-][a-zA-Z0-9_-]*['"`]/g) || [];
|
||||
stringLiteralMatches.forEach(match => {
|
||||
const str = match.replace(/['"`]/g, '');
|
||||
// Only consider strings that look like CSS class names
|
||||
if (str.match(/^[a-zA-Z_-][a-zA-Z0-9_-]*$/) && str.length > 2) {
|
||||
dynamicSelectors.add(str);
|
||||
}
|
||||
});
|
||||
return dynamicSelectors;
|
||||
}
|
||||
}
|
||||
exports.TypeScriptAnalyzer = TypeScriptAnalyzer;
|
||||
//# sourceMappingURL=TypeScriptAnalyzer.js.map
|
||||
1
out/analyzer/TypeScriptAnalyzer.js.map
Normal file
1
out/analyzer/TypeScriptAnalyzer.js.map
Normal file
@@ -0,0 +1 @@
|
||||
{"version":3,"file":"TypeScriptAnalyzer.js","sourceRoot":"","sources":["../../src/analyzer/TypeScriptAnalyzer.ts"],"names":[],"mappings":";;;AAEA,MAAa,kBAAkB;IAC3B,uBAAuB,CAAC,QAA6B;QACjD,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAU,CAAC;QAC3C,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,EAAE,CAAC;QAEhC,yDAAyD;QACzD,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,uEAAuE,CAAC,IAAI,EAAE,CAAC;QAClH,eAAe,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YAC5B,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,yBAAyB,EAAE,IAAI,CAAC,CAAC;YACjE,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,wCAAwC;QACxC,MAAM,gBAAgB,GAAG,IAAI,CAAC,KAAK,CAAC,8DAA8D,CAAC,IAAI,EAAE,CAAC;QAC1G,gBAAgB,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YAC7B,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,yBAAyB,EAAE,IAAI,CAAC,CAAC;YACjE,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,kCAAkC;QAClC,MAAM,kBAAkB,GAAG,IAAI,CAAC,KAAK,CAAC,iDAAiD,CAAC,IAAI,EAAE,CAAC;QAC/F,kBAAkB,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YAC/B,MAAM,SAAS,GAAG,KAAK,CAAC,OAAO,CAAC,kDAAkD,EAAE,IAAI,CAAC,CAAC;YAC1F,gBAAgB,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC;QACpC,CAAC,CAAC,CAAC;QAEH,qDAAqD;QACrD,MAAM,oBAAoB,GAAG,IAAI,CAAC,KAAK,CAAC,qCAAqC,CAAC,IAAI,EAAE,CAAC;QACrF,oBAAoB,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE;YACjC,MAAM,GAAG,GAAG,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YACxC,uDAAuD;YACvD,IAAI,GAAG,CAAC,KAAK,CAAC,4BAA4B,CAAC,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,EAAE;gBAC3D,gBAAgB,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;aAC7B;QACL,CAAC,CAAC,CAAC;QAEH,OAAO,gBAAgB,CAAC;IAC5B,CAAC;CACJ;AAtCD,gDAsCC"}
|
||||
Reference in New Issue
Block a user