Skip to content

Commit 51fd41b

Browse files
committed
Merge pull request microsoft#6212 from Microsoft/lint-nested-++
Lint nested ++
2 parents 0debd2b + b01de71 commit 51fd41b

17 files changed

Lines changed: 188 additions & 95 deletions

Jakefile.js

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -108,17 +108,6 @@ var serverCoreSources = [
108108
return path.join(serverDirectory, f);
109109
});
110110

111-
var scriptSources = [
112-
"tslint/booleanTriviaRule.ts",
113-
"tslint/nextLineRule.ts",
114-
"tslint/noNullRule.ts",
115-
"tslint/preferConstRule.ts",
116-
"tslint/typeOperatorSpacingRule.ts",
117-
"tslint/noInOperatorRule.ts"
118-
].map(function (f) {
119-
return path.join(scriptsDirectory, f);
120-
});
121-
122111
var serverSources = serverCoreSources.concat(servicesSources);
123112

124113
var languageServiceLibrarySources = [
@@ -878,7 +867,8 @@ var tslintRules = ([
878867
"preferConstRule",
879868
"booleanTriviaRule",
880869
"typeOperatorSpacingRule",
881-
"noInOperatorRule"
870+
"noInOperatorRule",
871+
"noIncrementDecrementRule"
882872
]);
883873
var tslintRulesFiles = tslintRules.map(function(p) {
884874
return path.join(tslintRuleDir, p + ".ts");
@@ -932,7 +922,7 @@ var servicesLintTargets = [
932922
var lintTargets = compilerSources
933923
.concat(harnessCoreSources)
934924
.concat(serverCoreSources)
935-
.concat(scriptSources)
925+
.concat(tslintRulesFiles)
936926
.concat(servicesLintTargets);
937927

938928
desc("Runs tslint on the compiler sources");
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import * as Lint from "tslint/lib/lint";
2+
import * as ts from "typescript";
3+
4+
5+
export class Rule extends Lint.Rules.AbstractRule {
6+
public static POSTFIX_FAILURE_STRING = "Don't use '++' or '--' postfix operators outside statements or for loops.";
7+
public static PREFIX_FAILURE_STRING = "Don't use '++' or '--' prefix operators.";
8+
9+
public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] {
10+
return this.applyWithWalker(new IncrementDecrementWalker(sourceFile, this.getOptions()));
11+
}
12+
}
13+
14+
class IncrementDecrementWalker extends Lint.RuleWalker {
15+
16+
visitPostfixUnaryExpression(node: ts.PostfixUnaryExpression) {
17+
super.visitPostfixUnaryExpression(node);
18+
if (node.operator === ts.SyntaxKind.PlusPlusToken || node.operator == ts.SyntaxKind.MinusMinusToken) {
19+
this.visitIncrementDecrement(node);
20+
}
21+
}
22+
23+
visitPrefixUnaryExpression(node: ts.PrefixUnaryExpression) {
24+
super.visitPrefixUnaryExpression(node);
25+
if (node.operator === ts.SyntaxKind.PlusPlusToken || node.operator == ts.SyntaxKind.MinusMinusToken) {
26+
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.PREFIX_FAILURE_STRING));
27+
}
28+
}
29+
30+
visitIncrementDecrement(node: ts.UnaryExpression) {
31+
if (node.parent && (node.parent.kind === ts.SyntaxKind.ExpressionStatement ||
32+
node.parent.kind === ts.SyntaxKind.ForStatement)) {
33+
return;
34+
}
35+
this.addFailure(this.createFailure(node.getStart(), node.getWidth(), Rule.POSTFIX_FAILURE_STRING));
36+
}
37+
}

src/compiler/checker.ts

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,19 @@ namespace ts {
77
let nextMergeId = 1;
88

99
export function getNodeId(node: Node): number {
10-
if (!node.id) node.id = nextNodeId++;
10+
if (!node.id) {
11+
node.id = nextNodeId;
12+
nextNodeId++;
13+
}
1114
return node.id;
1215
}
1316

1417
export let checkTime = 0;
1518

1619
export function getSymbolId(symbol: Symbol): number {
1720
if (!symbol.id) {
18-
symbol.id = nextSymbolId++;
21+
symbol.id = nextSymbolId;
22+
nextSymbolId++;
1923
}
2024

2125
return symbol.id;
@@ -287,7 +291,10 @@ namespace ts {
287291
}
288292

289293
function recordMergedSymbol(target: Symbol, source: Symbol) {
290-
if (!source.mergeId) source.mergeId = nextMergeId++;
294+
if (!source.mergeId) {
295+
source.mergeId = nextMergeId;
296+
nextMergeId++;
297+
}
291298
mergedSymbols[source.mergeId] = target;
292299
}
293300

@@ -1267,7 +1274,8 @@ namespace ts {
12671274

12681275
function createType(flags: TypeFlags): Type {
12691276
const result = new Type(checker, flags);
1270-
result.id = typeCount++;
1277+
result.id = typeCount;
1278+
typeCount++;
12711279
return result;
12721280
}
12731281

@@ -1823,11 +1831,13 @@ namespace ts {
18231831
}
18241832
if (pos < end) {
18251833
writePunctuation(writer, SyntaxKind.LessThanToken);
1826-
writeType(typeArguments[pos++], TypeFormatFlags.None);
1834+
writeType(typeArguments[pos], TypeFormatFlags.None);
1835+
pos++;
18271836
while (pos < end) {
18281837
writePunctuation(writer, SyntaxKind.CommaToken);
18291838
writeSpace(writer);
1830-
writeType(typeArguments[pos++], TypeFormatFlags.None);
1839+
writeType(typeArguments[pos], TypeFormatFlags.None);
1840+
pos++;
18311841
}
18321842
writePunctuation(writer, SyntaxKind.GreaterThanToken);
18331843
}
@@ -5676,7 +5686,7 @@ namespace ts {
56765686
return Ternary.False;
56775687
}
56785688
let result = Ternary.True;
5679-
for (let i = 0, len = sourceSignatures.length; i < len; ++i) {
5689+
for (let i = 0, len = sourceSignatures.length; i < len; i++) {
56805690
const related = compareSignaturesIdentical(sourceSignatures[i], targetSignatures[i], /*partialMatch*/ false, /*ignoreReturnTypes*/ false, isRelatedTo);
56815691
if (!related) {
56825692
return Ternary.False;
@@ -13839,7 +13849,8 @@ namespace ts {
1383913849
}
1384013850

1384113851
if (autoValue !== undefined) {
13842-
getNodeLinks(member).enumMemberValue = autoValue++;
13852+
getNodeLinks(member).enumMemberValue = autoValue;
13853+
autoValue++;
1384313854
}
1384413855
}
1384513856

src/compiler/commandLineParser.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,8 @@ namespace ts {
334334
function parseStrings(args: string[]) {
335335
let i = 0;
336336
while (i < args.length) {
337-
let s = args[i++];
337+
let s = args[i];
338+
i++;
338339
if (s.charCodeAt(0) === CharacterCodes.at) {
339340
parseResponseFile(s.slice(1));
340341
}
@@ -356,18 +357,21 @@ namespace ts {
356357

357358
switch (opt.type) {
358359
case "number":
359-
options[opt.name] = parseInt(args[i++]);
360+
options[opt.name] = parseInt(args[i]);
361+
i++;
360362
break;
361363
case "boolean":
362364
options[opt.name] = true;
363365
break;
364366
case "string":
365-
options[opt.name] = args[i++] || "";
367+
options[opt.name] = args[i] || "";
368+
i++;
366369
break;
367370
// If not a primitive, the possible types are specified in what is effectively a map of options.
368371
default:
369372
let map = <Map<number>>opt.type;
370-
let key = (args[i++] || "").toLowerCase();
373+
let key = (args[i] || "").toLowerCase();
374+
i++;
371375
if (hasProperty(map, key)) {
372376
options[opt.name] = map[key];
373377
}

src/compiler/core.ts

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,11 @@ namespace ts {
244244
const count = array.length;
245245
if (count > 0) {
246246
let pos = 0;
247-
let result = arguments.length <= 2 ? array[pos++] : initial;
247+
let result = arguments.length <= 2 ? array[pos] : initial;
248+
pos++;
248249
while (pos < count) {
249-
result = f(<U>result, array[pos++]);
250+
result = f(<U>result, array[pos]);
251+
pos++;
250252
}
251253
return <U>result;
252254
}
@@ -260,9 +262,11 @@ namespace ts {
260262
if (array) {
261263
let pos = array.length - 1;
262264
if (pos >= 0) {
263-
let result = arguments.length <= 2 ? array[pos--] : initial;
265+
let result = arguments.length <= 2 ? array[pos] : initial;
266+
pos--;
264267
while (pos >= 0) {
265-
result = f(<U>result, array[pos--]);
268+
result = f(<U>result, array[pos]);
269+
pos--;
266270
}
267271
return <U>result;
268272
}

src/compiler/declarationEmitter.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,7 +501,8 @@ namespace ts {
501501
}
502502
let count = 0;
503503
while (true) {
504-
const name = baseName + "_" + (++count);
504+
count++;
505+
const name = baseName + "_" + count;
505506
if (!hasProperty(currentIdentifiers, name)) {
506507
return name;
507508
}

src/compiler/emitter.ts

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5464,7 +5464,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
54645464
});
54655465
leadingComma = true;
54665466
}
5467-
++parameterIndex;
5467+
parameterIndex++;
54685468
}
54695469
}
54705470
return argumentsWritten;
@@ -6488,7 +6488,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
64886488

64896489
let started = false;
64906490
if (exportedDeclarations) {
6491-
for (let i = 0; i < exportedDeclarations.length; ++i) {
6491+
for (let i = 0; i < exportedDeclarations.length; i++) {
64926492
// write name of exported declaration, i.e 'export var x...'
64936493
writeExportedName(exportedDeclarations[i]);
64946494
}
@@ -6604,7 +6604,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
66046604
writeLine();
66056605
write("var ");
66066606
const seen: Map<string> = {};
6607-
for (let i = 0; i < hoistedVars.length; ++i) {
6607+
for (let i = 0; i < hoistedVars.length; i++) {
66086608
const local = hoistedVars[i];
66096609
const name = local.kind === SyntaxKind.Identifier
66106610
? <Identifier>local
@@ -6816,7 +6816,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
68166816
function emitSetters(exportStarFunction: string, dependencyGroups: DependencyGroup[]) {
68176817
write("setters:[");
68186818

6819-
for (let i = 0; i < dependencyGroups.length; ++i) {
6819+
for (let i = 0; i < dependencyGroups.length; i++) {
68206820
if (i !== 0) {
68216821
write(",");
68226822
}
@@ -6864,7 +6864,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
68646864
write(`${exportFunctionForFile}({`);
68656865
writeLine();
68666866
increaseIndent();
6867-
for (let i = 0, len = (<ExportDeclaration>entry).exportClause.elements.length; i < len; ++i) {
6867+
for (let i = 0, len = (<ExportDeclaration>entry).exportClause.elements.length; i < len; i++) {
68686868
if (i !== 0) {
68696869
write(",");
68706870
writeLine();
@@ -6909,7 +6909,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
69096909
write("execute: function() {");
69106910
increaseIndent();
69116911
writeLine();
6912-
for (let i = startIndex; i < node.statements.length; ++i) {
6912+
for (let i = startIndex; i < node.statements.length; i++) {
69136913
const statement = node.statements[i];
69146914
switch (statement.kind) {
69156915
// - function declarations are not emitted because they were already hoisted
@@ -6971,7 +6971,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
69716971
const groupIndices: Map<number> = {};
69726972
const dependencyGroups: DependencyGroup[] = [];
69736973

6974-
for (let i = 0; i < externalImports.length; ++i) {
6974+
for (let i = 0; i < externalImports.length; i++) {
69756975
const text = getExternalModuleNameText(externalImports[i], emitRelativePathAsModuleName);
69766976
if (hasProperty(groupIndices, text)) {
69776977
// deduplicate/group entries in dependency list by the dependency name
@@ -7296,7 +7296,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
72967296

72977297
function emitDirectivePrologues(statements: Node[], startWithNewLine: boolean, ensureUseStrict?: boolean): number {
72987298
let foundUseStrict = false;
7299-
for (let i = 0; i < statements.length; ++i) {
7299+
for (let i = 0; i < statements.length; i++) {
73007300
if (isPrologueDirective(statements[i])) {
73017301
if (isUseStrictPrologue(statements[i] as ExpressionStatement)) {
73027302
foundUseStrict = true;
@@ -7318,7 +7318,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, Promi
73187318

73197319
function writeLines(text: string): void {
73207320
const lines = text.split(/\r\n|\r|\n/g);
7321-
for (let i = 0; i < lines.length; ++i) {
7321+
for (let i = 0; i < lines.length; i++) {
73227322
const line = lines[i];
73237323
if (line.length) {
73247324
writeLine();

src/compiler/program.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -495,7 +495,7 @@ namespace ts {
495495
const moduleNames = map(newSourceFile.imports, name => name.text);
496496
const resolutions = resolveModuleNamesWorker(moduleNames, getNormalizedAbsolutePath(newSourceFile.fileName, currentDirectory));
497497
// ensure that module resolution results are still correct
498-
for (let i = 0; i < moduleNames.length; ++i) {
498+
for (let i = 0; i < moduleNames.length; i++) {
499499
const newResolution = resolutions[i];
500500
const oldResolution = getResolvedModule(oldSourceFile, moduleNames[i]);
501501
const resolutionChanged = oldResolution
@@ -523,7 +523,7 @@ namespace ts {
523523
}
524524

525525
// update fileName -> file mapping
526-
for (let i = 0, len = newSourceFiles.length; i < len; ++i) {
526+
for (let i = 0, len = newSourceFiles.length; i < len; i++) {
527527
filesByName.set(filePaths[i], newSourceFiles[i]);
528528
}
529529

@@ -1073,7 +1073,7 @@ namespace ts {
10731073
file.resolvedModules = {};
10741074
const moduleNames = map(file.imports, name => name.text);
10751075
const resolutions = resolveModuleNamesWorker(moduleNames, getNormalizedAbsolutePath(file.fileName, currentDirectory));
1076-
for (let i = 0; i < file.imports.length; ++i) {
1076+
for (let i = 0; i < file.imports.length; i++) {
10771077
const resolution = resolutions[i];
10781078
setResolvedModule(file, moduleNames[i], resolution);
10791079
if (resolution && !options.noResolve) {

0 commit comments

Comments
 (0)