UNPKG

7.5 kBJavaScriptView Raw
1"use strict";
2var __extends = (this && this.__extends) || (function () {
3 var extendStatics = function (d, b) {
4 extendStatics = Object.setPrototypeOf ||
5 ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
6 function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
7 return extendStatics(d, b);
8 }
9 return function (d, b) {
10 extendStatics(d, b);
11 function __() { this.constructor = d; }
12 d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
13 };
14})();
15Object.defineProperty(exports, "__esModule", { value: true });
16var ts = require("typescript");
17var Lint = require("tslint");
18var tsutils = require("tsutils");
19var Utils_1 = require("./utils/Utils");
20var AstUtils_1 = require("./utils/AstUtils");
21exports.OPTION_IGNORE_CASE = 'ignore-case';
22var Rule = (function (_super) {
23 __extends(Rule, _super);
24 function Rule() {
25 return _super !== null && _super.apply(this, arguments) || this;
26 }
27 Rule.prototype.apply = function (sourceFile) {
28 return this.applyWithFunction(sourceFile, walk, this.parseOptions(this.getOptions()));
29 };
30 Rule.prototype.parseOptions = function (options) {
31 return {
32 allExceptions: this.getExceptions(options),
33 ignoreCase: this.getIgnoreCase(options)
34 };
35 };
36 Rule.prototype.getExceptions = function (options) {
37 if (options.ruleArguments instanceof Array) {
38 var ruleArg = options.ruleArguments[0];
39 return typeof ruleArg === 'object' ? ruleArg.allow : options.ruleArguments;
40 }
41 if (options instanceof Array) {
42 return typeof options[0] === 'object' ? options[0].allow : options;
43 }
44 return undefined;
45 };
46 Rule.prototype.getIgnoreCase = function (options) {
47 if (options instanceof Array) {
48 return typeof options[0] === 'object' ? options[0]['ignore-case'] : true;
49 }
50 return true;
51 };
52 Rule.metadata = {
53 ruleName: 'export-name',
54 type: 'maintainability',
55 description: 'The name of the exported module must match the filename of the source file',
56 options: {
57 type: 'list',
58 listType: {
59 anyOf: [
60 {
61 type: 'string'
62 },
63 {
64 type: 'object',
65 properties: {
66 'ignore-case': {
67 type: 'boolean'
68 },
69 allow: {
70 type: 'array',
71 items: {
72 type: 'string'
73 }
74 }
75 }
76 }
77 ]
78 }
79 },
80 optionsDescription: '',
81 typescriptOnly: true,
82 issueClass: 'Ignored',
83 issueType: 'Warning',
84 severity: 'Low',
85 level: 'Opportunity for Excellence',
86 group: 'Clarity',
87 commonWeaknessEnumeration: '710'
88 };
89 Rule.FAILURE_STRING = 'The exported module or identifier name must match the file name. Found: ';
90 return Rule;
91}(Lint.Rules.AbstractRule));
92exports.Rule = Rule;
93function isExportedDeclaration(element) {
94 return element.modifiers !== undefined && AstUtils_1.AstUtils.hasModifier(element.modifiers, ts.SyntaxKind.ExportKeyword);
95}
96function isExportStatement(node) {
97 return ts.isExportAssignment(node) || ts.isExportDeclaration(node);
98}
99function getExportsFromStatement(node) {
100 if (ts.isExportAssignment(node)) {
101 return [[node.expression.getText(), node.expression]];
102 }
103 else if (node.exportClause) {
104 var symbolAndNodes_1 = [];
105 node.exportClause.elements.forEach(function (e) {
106 symbolAndNodes_1.push([e.name.getText(), node]);
107 });
108 return symbolAndNodes_1;
109 }
110 else {
111 return [];
112 }
113}
114function walk(ctx) {
115 var _a = ctx.options, allExceptions = _a.allExceptions, ignoreCase = _a.ignoreCase;
116 function getExportStatementsWithinModules(moduleDeclaration) {
117 if (moduleDeclaration.body === undefined) {
118 return undefined;
119 }
120 if (moduleDeclaration.body.kind === ts.SyntaxKind.ModuleDeclaration) {
121 return getExportStatementsWithinModules(moduleDeclaration.body);
122 }
123 else if (moduleDeclaration.body.kind === ts.SyntaxKind.ModuleBlock) {
124 var moduleBlock = moduleDeclaration.body;
125 return moduleBlock.statements.filter(isExportedDeclaration);
126 }
127 return undefined;
128 }
129 function validateExportedElements(exportedElements) {
130 if (exportedElements.length === 1) {
131 var element = exportedElements[0];
132 if (ts.isModuleDeclaration(element) || ts.isClassDeclaration(element) || ts.isFunctionDeclaration(element)) {
133 if (element.name !== undefined) {
134 validateExport(element.name.text, exportedElements[0]);
135 }
136 }
137 else if (exportedElements[0].kind === ts.SyntaxKind.VariableStatement) {
138 var variableStatement = exportedElements[0];
139 if (variableStatement.declarationList.declarations.length === 1) {
140 var variableDeclaration = variableStatement.declarationList.declarations[0];
141 validateExport(variableDeclaration.name.getText(), variableDeclaration);
142 }
143 }
144 }
145 }
146 function validateExport(exportedName, tsNode) {
147 var flags = ignoreCase ? 'i' : '';
148 var regex = new RegExp("^" + exportedName + "\\..+", flags);
149 var fileName = Utils_1.Utils.fileBasename(ctx.sourceFile.fileName);
150 if (!regex.test(fileName)) {
151 if (!isSuppressed(exportedName)) {
152 var failureString = Rule.FAILURE_STRING + fileName + ' and ' + exportedName;
153 ctx.addFailureAt(tsNode.getStart(), tsNode.getWidth(), failureString);
154 }
155 }
156 }
157 function isSuppressed(exportedName) {
158 return Utils_1.Utils.exists(allExceptions, function (exception) {
159 return new RegExp(exception).test(exportedName);
160 });
161 }
162 var node = ctx.sourceFile;
163 var singleExport = node.statements.filter(isExportStatement);
164 if (singleExport.length === 1) {
165 var symbolsAndNodes = getExportsFromStatement(singleExport[0]);
166 if (symbolsAndNodes.length === 1) {
167 validateExport(symbolsAndNodes[0][0], symbolsAndNodes[0][1]);
168 }
169 return;
170 }
171 var exportedTopLevelElements = node.statements.filter(isExportedDeclaration);
172 if (exportedTopLevelElements.length === 0) {
173 node.statements.forEach(function (element) {
174 if (tsutils.isModuleDeclaration(element)) {
175 var exportStatements = getExportStatementsWithinModules(element) || [];
176 exportedTopLevelElements = exportedTopLevelElements.concat(exportStatements);
177 }
178 });
179 }
180 validateExportedElements(exportedTopLevelElements);
181}
182//# sourceMappingURL=exportNameRule.js.map
\No newline at end of file