UNPKG

6.71 kBJavaScriptView Raw
1"use strict";
2var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3 return new (P || (P = Promise))(function (resolve, reject) {
4 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6 function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
7 step((generator = generator.apply(thisArg, _arguments || [])).next());
8 });
9};
10Object.defineProperty(exports, "__esModule", { value: true });
11const minimatch = require("minimatch");
12const path = require("path");
13const linterConfigHelpers_1 = require("./linterConfigHelpers");
14const NormalizedMessage_1 = require("./NormalizedMessage");
15const CompilerHost_1 = require("./CompilerHost");
16const FsHelper_1 = require("./FsHelper");
17class ApiIncrementalChecker {
18 constructor({ typescript, context, programConfigFile, compilerOptions, createNormalizedMessageFromDiagnostic, linterConfigFile, linterAutoFix, createNormalizedMessageFromRuleFailure, eslinter, checkSyntacticErrors = false, resolveModuleName, resolveTypeReferenceDirective }) {
19 this.linterConfigs = {};
20 this.linterExclusions = [];
21 this.currentLintErrors = new Map();
22 this.currentEsLintErrors = new Map();
23 this.lastUpdatedFiles = [];
24 this.lastRemovedFiles = [];
25 this.getLinterConfig = linterConfigHelpers_1.makeGetLinterConfig(this.linterConfigs, this.linterExclusions, this.context);
26 this.context = context;
27 this.createNormalizedMessageFromDiagnostic = createNormalizedMessageFromDiagnostic;
28 this.linterConfigFile = linterConfigFile;
29 this.linterAutoFix = linterAutoFix;
30 this.createNormalizedMessageFromRuleFailure = createNormalizedMessageFromRuleFailure;
31 this.eslinter = eslinter;
32 this.hasFixedConfig = typeof this.linterConfigFile === 'string';
33 this.initLinterConfig();
34 this.tsIncrementalCompiler = new CompilerHost_1.CompilerHost(typescript, programConfigFile, compilerOptions, checkSyntacticErrors, resolveModuleName, resolveTypeReferenceDirective);
35 }
36 initLinterConfig() {
37 if (!this.linterConfig && this.hasFixedConfig) {
38 this.linterConfig = linterConfigHelpers_1.loadLinterConfig(this.linterConfigFile);
39 if (this.linterConfig.linterOptions &&
40 this.linterConfig.linterOptions.exclude) {
41 // Pre-build minimatch patterns to avoid additional overhead later on.
42 // Note: Resolving the path is required to properly match against the full file paths,
43 // and also deals with potential cross-platform problems regarding path separators.
44 this.linterExclusions = this.linterConfig.linterOptions.exclude.map(pattern => new minimatch.Minimatch(path.resolve(pattern)));
45 }
46 }
47 }
48 createLinter(program) {
49 // tslint:disable-next-line:no-implicit-dependencies
50 const tslint = require('tslint');
51 return new tslint.Linter({ fix: this.linterAutoFix }, program);
52 }
53 hasLinter() {
54 return !!this.linterConfigFile;
55 }
56 hasEsLinter() {
57 return this.eslinter !== undefined;
58 }
59 isFileExcluded(filePath) {
60 return (filePath.endsWith('.d.ts') ||
61 this.linterExclusions.some(matcher => matcher.match(filePath)));
62 }
63 nextIteration() {
64 // do nothing
65 }
66 getDiagnostics(_cancellationToken) {
67 return __awaiter(this, void 0, void 0, function* () {
68 const diagnostics = yield this.tsIncrementalCompiler.processChanges();
69 this.lastUpdatedFiles = diagnostics.updatedFiles;
70 this.lastRemovedFiles = diagnostics.removedFiles;
71 return NormalizedMessage_1.NormalizedMessage.deduplicate(diagnostics.results.map(this.createNormalizedMessageFromDiagnostic));
72 });
73 }
74 getLints(_cancellationToken) {
75 for (const updatedFile of this.lastUpdatedFiles) {
76 if (this.isFileExcluded(updatedFile)) {
77 continue;
78 }
79 try {
80 const linter = this.createLinter(this.tsIncrementalCompiler.getProgram());
81 const config = this.hasFixedConfig
82 ? this.linterConfig
83 : this.getLinterConfig(updatedFile);
84 if (!config) {
85 continue;
86 }
87 // const source = fs.readFileSync(updatedFile, 'utf-8');
88 linter.lint(updatedFile, undefined, config);
89 const lints = linter.getResult();
90 this.currentLintErrors.set(updatedFile, lints);
91 }
92 catch (e) {
93 if (FsHelper_1.fileExistsSync(updatedFile) &&
94 // check the error type due to file system lag
95 !(e instanceof Error) &&
96 !(e.constructor.name === 'FatalError') &&
97 !(e.message && e.message.trim().startsWith('Invalid source file'))) {
98 // it's not because file doesn't exist - throw error
99 throw e;
100 }
101 }
102 for (const removedFile of this.lastRemovedFiles) {
103 this.currentLintErrors.delete(removedFile);
104 }
105 }
106 const allLints = [];
107 for (const [, value] of this.currentLintErrors) {
108 allLints.push(...value.failures);
109 }
110 return NormalizedMessage_1.NormalizedMessage.deduplicate(allLints.map(this.createNormalizedMessageFromRuleFailure));
111 }
112 getEsLints(cancellationToken) {
113 for (const removedFile of this.lastRemovedFiles) {
114 this.currentEsLintErrors.delete(removedFile);
115 }
116 for (const updatedFile of this.lastUpdatedFiles) {
117 cancellationToken.throwIfCancellationRequested();
118 if (this.isFileExcluded(updatedFile) ||
119 updatedFile.endsWith('tsconfig.json')) {
120 continue;
121 }
122 const lints = this.eslinter.getLints(updatedFile);
123 if (lints !== undefined) {
124 this.currentEsLintErrors.set(updatedFile, lints);
125 }
126 else if (this.currentEsLintErrors.has(updatedFile)) {
127 this.currentEsLintErrors.delete(updatedFile);
128 }
129 }
130 return this.eslinter.getFormattedLints(this.currentEsLintErrors.values());
131 }
132}
133exports.ApiIncrementalChecker = ApiIncrementalChecker;
134//# sourceMappingURL=ApiIncrementalChecker.js.map
\No newline at end of file