Skip to content

Commit 2a70bf5

Browse files
author
Andy
authored
Don't count a write-only reference as a use (#17752)
* Don't count a write-only reference as a use * Split isWriteAccess to isWriteOnlyAccess and isReadOnlyAccess * Update "unusedParameterUsedInTypeOf" to use "b" * Update diagnostic messages: "is never used" -> "its value is never read" * Use a WriteKind enum * Rename enum and move documentation to enum members
1 parent c3199c7 commit 2a70bf5

File tree

157 files changed

+826
-651
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

157 files changed

+826
-651
lines changed

src/compiler/checker.ts

Lines changed: 56 additions & 46 deletions
Large diffs are not rendered by default.

src/compiler/diagnosticMessages.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3102,7 +3102,7 @@
31023102
"category": "Message",
31033103
"code": 6132
31043104
},
3105-
"'{0}' is declared but never used.": {
3105+
"'{0}' is declared but its value is never read.": {
31063106
"category": "Error",
31073107
"code": 6133
31083108
},
@@ -3122,7 +3122,7 @@
31223122
"category": "Error",
31233123
"code": 6137
31243124
},
3125-
"Property '{0}' is declared but never used.": {
3125+
"Property '{0}' is declared but its value is never read.": {
31263126
"category": "Error",
31273127
"code": 6138
31283128
},

src/compiler/transformers/es2017.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,6 @@ namespace ts {
2121
const compilerOptions = context.getCompilerOptions();
2222
const languageVersion = getEmitScriptTarget(compilerOptions);
2323

24-
// These variables contain state that changes as we descend into the tree.
25-
let currentSourceFile: SourceFile;
26-
2724
/**
2825
* Keeps track of whether expression substitution has been enabled for specific edge cases.
2926
* They are persisted between each SourceFile transformation and should not be reset.
@@ -51,12 +48,8 @@ namespace ts {
5148
return node;
5249
}
5350

54-
currentSourceFile = node;
55-
5651
const visited = visitEachChild(node, visitor, context);
5752
addEmitHelpers(visited, context.readEmitHelpers());
58-
59-
currentSourceFile = undefined;
6053
return visited;
6154
}
6255

src/compiler/transformers/generators.ts

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,6 @@ namespace ts {
244244
const previousOnSubstituteNode = context.onSubstituteNode;
245245
context.onSubstituteNode = onSubstituteNode;
246246

247-
let currentSourceFile: SourceFile;
248247
let renamedCatchVariables: Map<boolean>;
249248
let renamedCatchVariableDeclarations: Identifier[];
250249

@@ -300,12 +299,9 @@ namespace ts {
300299
return node;
301300
}
302301

303-
currentSourceFile = node;
304302

305303
const visited = visitEachChild(node, visitor, context);
306304
addEmitHelpers(visited, context.readEmitHelpers());
307-
308-
currentSourceFile = undefined;
309305
return visited;
310306
}
311307

src/compiler/tsc.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,6 @@ namespace ts {
100100
const commandLine = parseCommandLine(args);
101101
let configFileName: string; // Configuration file name (if any)
102102
let cachedConfigFileText: string; // Cached configuration file text, used for reparsing (if any)
103-
let configFileWatcher: FileWatcher; // Configuration file watcher
104103
let directoryWatcher: FileWatcher; // Directory watcher to monitor source file addition/removal
105104
let cachedProgram: Program; // Program cached from last compilation
106105
let rootFileNames: string[]; // Root fileNames for compilation
@@ -189,7 +188,7 @@ namespace ts {
189188
return sys.exit(ExitStatus.DiagnosticsPresent_OutputsSkipped);
190189
}
191190
if (configFileName) {
192-
configFileWatcher = sys.watchFile(configFileName, configFileChanged);
191+
sys.watchFile(configFileName, configFileChanged);
193192
}
194193
if (sys.watchDirectory && configFileName) {
195194
const directory = ts.getDirectoryPath(configFileName);

src/compiler/utilities.ts

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3502,6 +3502,46 @@ namespace ts {
35023502
export function getCombinedLocalAndExportSymbolFlags(symbol: Symbol): SymbolFlags {
35033503
return symbol.exportSymbol ? symbol.exportSymbol.flags | symbol.flags : symbol.flags;
35043504
}
3505+
3506+
export function isWriteOnlyAccess(node: Node) {
3507+
return accessKind(node) === AccessKind.Write;
3508+
}
3509+
3510+
export function isWriteAccess(node: Node) {
3511+
return accessKind(node) !== AccessKind.Read;
3512+
}
3513+
3514+
const enum AccessKind {
3515+
/** Only reads from a variable. */
3516+
Read,
3517+
/** Only writes to a variable without using the result. E.g.: `x++;`. */
3518+
Write,
3519+
/** Writes to a variable and uses the result as an expression. E.g.: `f(x++);`. */
3520+
ReadWrite
3521+
}
3522+
function accessKind(node: Node): AccessKind {
3523+
const { parent } = node;
3524+
if (!parent) return AccessKind.Read;
3525+
3526+
switch (parent.kind) {
3527+
case SyntaxKind.PostfixUnaryExpression:
3528+
case SyntaxKind.PrefixUnaryExpression:
3529+
const { operator } = parent as PrefixUnaryExpression | PostfixUnaryExpression;
3530+
return operator === SyntaxKind.PlusPlusToken || operator === SyntaxKind.MinusMinusToken ? writeOrReadWrite() : AccessKind.Read;
3531+
case SyntaxKind.BinaryExpression:
3532+
const { left, operatorToken } = parent as BinaryExpression;
3533+
return left === node && isAssignmentOperator(operatorToken.kind) ? writeOrReadWrite() : AccessKind.Read;
3534+
case SyntaxKind.PropertyAccessExpression:
3535+
return (parent as PropertyAccessExpression).name !== node ? AccessKind.Read : accessKind(parent);
3536+
default:
3537+
return AccessKind.Read;
3538+
}
3539+
3540+
function writeOrReadWrite(): AccessKind {
3541+
// If grandparent is not an ExpressionStatement, this is used as an expression in addition to having a side effect.
3542+
return parent.parent && parent.parent.kind === SyntaxKind.ExpressionStatement ? AccessKind.Write : AccessKind.ReadWrite;
3543+
}
3544+
}
35053545
}
35063546

35073547
namespace ts {

src/harness/compilerRunner.ts

Lines changed: 0 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,13 @@ const enum CompilerTestType {
1111
class CompilerBaselineRunner extends RunnerBase {
1212
private basePath = "tests/cases";
1313
private testSuiteName: TestRunnerKind;
14-
private errors: boolean;
1514
private emit: boolean;
16-
private decl: boolean;
17-
private output: boolean;
1815

1916
public options: string;
2017

2118
constructor(public testType: CompilerTestType) {
2219
super();
23-
this.errors = true;
2420
this.emit = true;
25-
this.decl = true;
26-
this.output = true;
2721
if (testType === CompilerTestType.Conformance) {
2822
this.testSuiteName = "conformance";
2923
}
@@ -214,26 +208,14 @@ class CompilerBaselineRunner extends RunnerBase {
214208

215209
private parseOptions() {
216210
if (this.options && this.options.length > 0) {
217-
this.errors = false;
218211
this.emit = false;
219-
this.decl = false;
220-
this.output = false;
221212

222213
const opts = this.options.split(",");
223214
for (let i = 0; i < opts.length; i++) {
224215
switch (opts[i]) {
225-
case "error":
226-
this.errors = true;
227-
break;
228216
case "emit":
229217
this.emit = true;
230218
break;
231-
case "decl":
232-
this.decl = true;
233-
break;
234-
case "output":
235-
this.output = true;
236-
break;
237219
default:
238220
throw new Error("unsupported flag");
239221
}

src/harness/unittests/compileOnSave.ts

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,6 @@ namespace ts.projectSystem {
5555
let configFile: FileOrFolder;
5656
let changeModuleFile1ShapeRequest1: server.protocol.Request;
5757
let changeModuleFile1InternalRequest1: server.protocol.Request;
58-
let changeModuleFile1ShapeRequest2: server.protocol.Request;
5958
// A compile on save affected file request using file1
6059
let moduleFile1FileListRequest: server.protocol.Request;
6160

@@ -112,16 +111,6 @@ namespace ts.projectSystem {
112111
insertString: `var T1: number;`
113112
});
114113

115-
// Change the content of file1 to `export var T: number;export function Foo() { };`
116-
changeModuleFile1ShapeRequest2 = makeSessionRequest<server.protocol.ChangeRequestArgs>(CommandNames.Change, {
117-
file: moduleFile1.path,
118-
line: 1,
119-
offset: 1,
120-
endLine: 1,
121-
endOffset: 1,
122-
insertString: `export var T2: number;`
123-
});
124-
125114
moduleFile1FileListRequest = makeSessionRequest<server.protocol.FileRequestArgs>(CommandNames.CompileOnSaveAffectedFileList, { file: moduleFile1.path, projectFileName: configFile.path });
126115
});
127116

src/harness/unittests/typingsInstaller.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -366,13 +366,11 @@ namespace ts.projectSystem {
366366
};
367367

368368
const host = createServerHost([file1, file2]);
369-
let enqueueIsCalled = false;
370369
const installer = new (class extends Installer {
371370
constructor() {
372371
super(host, { typesRegistry: createTypesRegistry("jquery") });
373372
}
374373
enqueueInstallTypingsRequest(project: server.Project, typeAcquisition: TypeAcquisition, unresolvedImports: server.SortedReadonlyArray<string>) {
375-
enqueueIsCalled = true;
376374
super.enqueueInstallTypingsRequest(project, typeAcquisition, unresolvedImports);
377375
}
378376
installWorker(_requestId: number, _args: string[], _cwd: string, cb: TI.RequestCompletedAction): void {

src/server/server.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -585,7 +585,6 @@ namespace ts.server {
585585
function createPollingWatchedFileSet(interval = 2500, chunkSize = 30) {
586586
const watchedFiles: WatchedFile[] = [];
587587
let nextFileToCheck = 0;
588-
let watchTimer: any;
589588
return { getModifiedTime, poll, startWatchTimer, addFile, removeFile };
590589

591590
function getModifiedTime(fileName: string): Date {
@@ -622,7 +621,7 @@ namespace ts.server {
622621
// stat due to inconsistencies of fs.watch
623622
// and efficiency of stat on modern filesystems
624623
function startWatchTimer() {
625-
watchTimer = setInterval(() => {
624+
setInterval(() => {
626625
let count = 0;
627626
let nextToCheck = nextFileToCheck;
628627
let firstCheck = -1;

0 commit comments

Comments
 (0)