mirror of
https://github.com/angular/angular-cli.git
synced 2025-05-22 15:02:11 +08:00
64 lines
2.3 KiB
TypeScript
64 lines
2.3 KiB
TypeScript
/**
|
|
* @license
|
|
* Copyright Google Inc. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
import {
|
|
Replacement,
|
|
RuleFailure,
|
|
Rules,
|
|
} from 'tslint'; // tslint:disable-line:no-implicit-dependencies
|
|
import * as ts from '../../../third_party/github.com/Microsoft/TypeScript/lib/typescript';
|
|
|
|
// Constants:
|
|
const LOAD_CHILDREN_SPLIT = '#';
|
|
const FAILURE_MESSAGE = 'Found magic `loadChildren` string. Use a function with `import` instead.';
|
|
|
|
export class Rule extends Rules.AbstractRule {
|
|
public apply (ast: ts.SourceFile): Array<RuleFailure> {
|
|
const ruleName = this.ruleName;
|
|
const changes: RuleFailure[] = [];
|
|
|
|
// NOTE: This should ideally be excluded at a higher level to avoid parsing
|
|
if (ast.isDeclarationFile || /[\\\/]node_modules[\\\/]/.test(ast.fileName)) {
|
|
return [];
|
|
}
|
|
|
|
// Workaround mismatched tslint TS version and vendored TS version
|
|
// The TS SyntaxKind enum numeric values change between versions
|
|
const sourceFile = ts.createSourceFile(ast.fileName, ast.text, ast.languageVersion, true);
|
|
|
|
ts.forEachChild(sourceFile, function analyze(node) {
|
|
if (ts.isPropertyAssignment(node) &&
|
|
(ts.isIdentifier(node.name) || ts.isStringLiteral(node.name)) &&
|
|
node.name.text === 'loadChildren' &&
|
|
ts.isStringLiteral(node.initializer)) {
|
|
const valueNode = node.initializer;
|
|
const parts = valueNode.text.split(LOAD_CHILDREN_SPLIT);
|
|
const path = parts[0];
|
|
const moduleName = parts[1] || 'default';
|
|
|
|
let fix = `() => import('${path}').then(m => m.${moduleName})`;
|
|
|
|
// Try to fix indentation in replacement:
|
|
const { character } = ast.getLineAndCharacterOfPosition(node.getStart());
|
|
fix = fix.replace(/\n/g, `\n${' '.repeat(character)}`);
|
|
|
|
const replacement = new Replacement(valueNode.getStart(), valueNode.getWidth(), fix);
|
|
const start = node.getStart();
|
|
const end = node.getEnd();
|
|
|
|
const change = new RuleFailure(ast, start, end, FAILURE_MESSAGE, ruleName, replacement);
|
|
change.setRuleSeverity('warning');
|
|
changes.push(change);
|
|
}
|
|
|
|
ts.forEachChild(node, analyze);
|
|
});
|
|
|
|
return changes;
|
|
}
|
|
}
|