1 | "use strict";
|
2 | var __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 | };
|
10 | Object.defineProperty(exports, "__esModule", { value: true });
|
11 | const minimatch = require("minimatch");
|
12 | const path = require("path");
|
13 | const linterConfigHelpers_1 = require("./linterConfigHelpers");
|
14 | const NormalizedMessage_1 = require("./NormalizedMessage");
|
15 | const CompilerHost_1 = require("./CompilerHost");
|
16 | const FsHelper_1 = require("./FsHelper");
|
17 | class 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 |
|
42 |
|
43 |
|
44 | this.linterExclusions = this.linterConfig.linterOptions.exclude.map(pattern => new minimatch.Minimatch(path.resolve(pattern)));
|
45 | }
|
46 | }
|
47 | }
|
48 | createLinter(program) {
|
49 |
|
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 |
|
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 |
|
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 |
|
95 | !(e instanceof Error) &&
|
96 | !(e.constructor.name === 'FatalError') &&
|
97 | !(e.message && e.message.trim().startsWith('Invalid source file'))) {
|
98 |
|
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 | continue;
|
120 | }
|
121 | const lints = this.eslinter.getLints(updatedFile);
|
122 | if (lints !== undefined) {
|
123 | this.currentEsLintErrors.set(updatedFile, lints);
|
124 | }
|
125 | else if (this.currentEsLintErrors.has(updatedFile)) {
|
126 | this.currentEsLintErrors.delete(updatedFile);
|
127 | }
|
128 | }
|
129 | return this.eslinter.getFormattedLints(this.currentEsLintErrors.values());
|
130 | }
|
131 | }
|
132 | exports.ApiIncrementalChecker = ApiIncrementalChecker;
|
133 |
|
\ | No newline at end of file |