Enable 'no-unused-expression' tslint rule (#19734)

This commit is contained in:
Andy 2017-11-06 13:01:07 -08:00 committed by GitHub
parent 5c173f4436
commit ed38889ca6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 77 additions and 70 deletions

View File

@ -1904,8 +1904,9 @@ namespace ts {
* Extends one symbol table with another while collecting information on name collisions for error message generation into the `lookupTable` argument
* Not passing `lookupTable` and `exportNode` disables this collection, and just extends the tables
*/
function extendExportSymbols(target: SymbolTable, source: SymbolTable, lookupTable?: ExportCollisionTrackerTable, exportNode?: ExportDeclaration) {
source && source.forEach((sourceSymbol, id) => {
function extendExportSymbols(target: SymbolTable, source: SymbolTable | undefined, lookupTable?: ExportCollisionTrackerTable, exportNode?: ExportDeclaration) {
if (!source) return;
source.forEach((sourceSymbol, id) => {
if (id === "default") return;
const targetSymbol = target.get(id);
@ -17016,8 +17017,7 @@ namespace ts {
* @returns On success, the expression's signature's return type. On failure, anyType.
*/
function checkCallExpression(node: CallExpression | NewExpression): Type {
// Grammar checking; stop grammar-checking if checkGrammarTypeArguments return true
checkGrammarTypeArguments(node, node.typeArguments) || checkGrammarArguments(node.arguments);
if (!checkGrammarTypeArguments(node, node.typeArguments)) checkGrammarArguments(node.arguments);
const signature = getResolvedSignature(node);
@ -17064,7 +17064,7 @@ namespace ts {
function checkImportCallExpression(node: ImportCall): Type {
// Check grammar of dynamic import
checkGrammarArguments(node.arguments) || checkGrammarImportCallExpression(node);
if (!checkGrammarArguments(node.arguments)) checkGrammarImportCallExpression(node);
if (node.arguments.length === 0) {
return createPromiseReturnType(node, anyType);
@ -18739,9 +18739,7 @@ namespace ts {
// It is a SyntaxError if the Identifier "eval" or the Identifier "arguments" occurs as the
// Identifier in a PropertySetParameterList of a PropertyAssignment that is contained in strict code
// or if its FunctionBody is strict code(11.1.5).
// Grammar checking
checkGrammarDecorators(node) || checkGrammarModifiers(node);
checkGrammarDecoratorsAndModifiers(node);
checkVariableLikeDeclaration(node);
const func = getContainingFunction(node);
@ -19131,14 +19129,13 @@ namespace ts {
function checkPropertyDeclaration(node: PropertyDeclaration) {
// Grammar checking
checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarProperty(node) || checkGrammarComputedPropertyName(node.name);
if (!checkGrammarDecoratorsAndModifiers(node) && !checkGrammarProperty(node)) checkGrammarComputedPropertyName(node.name);
checkVariableLikeDeclaration(node);
}
function checkMethodDeclaration(node: MethodDeclaration) {
// Grammar checking
checkGrammarMethod(node) || checkGrammarComputedPropertyName(node.name);
if (!checkGrammarMethod(node)) checkGrammarComputedPropertyName(node.name);
// Grammar checking for modifiers is done inside the function checkGrammarFunctionLikeDeclaration
checkFunctionOrMethodDeclaration(node);
@ -19154,7 +19151,7 @@ namespace ts {
// Grammar check on signature of constructor and modifier of the constructor is done in checkSignatureDeclaration function.
checkSignatureDeclaration(node);
// Grammar check for checking only related to constructorDeclaration
checkGrammarConstructorTypeParameters(node) || checkGrammarConstructorTypeAnnotation(node);
if (!checkGrammarConstructorTypeParameters(node)) checkGrammarConstructorTypeAnnotation(node);
checkSourceElement(node.body);
registerForUnusedIdentifiersCheck(node);
@ -19251,7 +19248,7 @@ namespace ts {
function checkAccessorDeclaration(node: AccessorDeclaration) {
if (produceDiagnostics) {
// Grammar checking accessors
checkGrammarFunctionLikeDeclaration(node) || checkGrammarAccessor(node) || checkGrammarComputedPropertyName(node.name);
if (!checkGrammarFunctionLikeDeclaration(node) && !checkGrammarAccessor(node)) checkGrammarComputedPropertyName(node.name);
checkDecorators(node);
checkSignatureDeclaration(node);
@ -21013,8 +21010,7 @@ namespace ts {
function checkVariableStatement(node: VariableStatement) {
// Grammar checking
checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarVariableDeclarationList(node.declarationList) || checkGrammarForDisallowedLetOrConstStatement(node);
if (!checkGrammarDecoratorsAndModifiers(node) && !checkGrammarVariableDeclarationList(node.declarationList)) checkGrammarForDisallowedLetOrConstStatement(node);
forEach(node.declarationList.declarations, checkSourceElement);
}
@ -21522,7 +21518,7 @@ namespace ts {
function checkBreakOrContinueStatement(node: BreakOrContinueStatement) {
// Grammar checking
checkGrammarStatementInAmbientContext(node) || checkGrammarBreakOrContinueStatement(node);
if (!checkGrammarStatementInAmbientContext(node)) checkGrammarBreakOrContinueStatement(node);
// TODO: Check that target label is valid
}
@ -22203,7 +22199,7 @@ namespace ts {
function checkInterfaceDeclaration(node: InterfaceDeclaration) {
// Grammar checking
checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarInterfaceDeclaration(node);
if (!checkGrammarDecoratorsAndModifiers(node)) checkGrammarInterfaceDeclaration(node);
checkTypeParameters(node.typeParameters);
if (produceDiagnostics) {
@ -22245,7 +22241,7 @@ namespace ts {
function checkTypeAliasDeclaration(node: TypeAliasDeclaration) {
// Grammar checking
checkGrammarDecorators(node) || checkGrammarModifiers(node);
checkGrammarDecoratorsAndModifiers(node);
checkTypeNameIsReserved(node.name, Diagnostics.Type_alias_name_cannot_be_0);
checkTypeParameters(node.typeParameters);
@ -22415,7 +22411,7 @@ namespace ts {
}
// Grammar checking
checkGrammarDecorators(node) || checkGrammarModifiers(node);
checkGrammarDecoratorsAndModifiers(node);
checkTypeNameIsReserved(node.name, Diagnostics.Enum_name_cannot_be_0);
checkCollisionWithCapturedThisVariable(node, node.name);
@ -22518,7 +22514,7 @@ namespace ts {
return;
}
if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node)) {
if (!checkGrammarDecoratorsAndModifiers(node)) {
if (!inAmbientContext && node.name.kind === SyntaxKind.StringLiteral) {
grammarErrorOnNode(node.name, Diagnostics.Only_ambient_modules_can_use_quoted_names);
}
@ -22741,7 +22737,7 @@ namespace ts {
// If we hit an import declaration in an illegal context, just bail out to avoid cascading errors.
return;
}
if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && hasModifiers(node)) {
if (!checkGrammarDecoratorsAndModifiers(node) && hasModifiers(node)) {
grammarErrorOnFirstToken(node, Diagnostics.An_import_declaration_cannot_have_modifiers);
}
if (checkExternalImportOrExportDeclaration(node)) {
@ -22768,7 +22764,7 @@ namespace ts {
return;
}
checkGrammarDecorators(node) || checkGrammarModifiers(node);
checkGrammarDecoratorsAndModifiers(node);
if (isInternalModuleImportEqualsDeclaration(node) || checkExternalImportOrExportDeclaration(node)) {
checkImportBinding(node);
if (hasModifier(node, ModifierFlags.Export)) {
@ -22804,7 +22800,7 @@ namespace ts {
return;
}
if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && hasModifiers(node)) {
if (!checkGrammarDecoratorsAndModifiers(node) && hasModifiers(node)) {
grammarErrorOnFirstToken(node, Diagnostics.An_export_declaration_cannot_have_modifiers);
}
@ -22877,7 +22873,7 @@ namespace ts {
return;
}
// Grammar checking
if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && hasModifiers(node)) {
if (!checkGrammarDecoratorsAndModifiers(node) && hasModifiers(node)) {
grammarErrorOnFirstToken(node, Diagnostics.An_export_assignment_cannot_have_modifiers);
}
if (node.expression.kind === SyntaxKind.Identifier) {
@ -22922,29 +22918,31 @@ namespace ts {
}
// Checks for export * conflicts
const exports = getExportsOfModule(moduleSymbol);
exports && exports.forEach(({ declarations, flags }, id) => {
if (id === "__export") {
return;
}
// ECMA262: 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries.
// (TS Exceptions: namespaces, function overloads, enums, and interfaces)
if (flags & (SymbolFlags.Namespace | SymbolFlags.Interface | SymbolFlags.Enum)) {
return;
}
const exportedDeclarationsCount = countWhere(declarations, isNotOverloadAndNotAccessor);
if (flags & SymbolFlags.TypeAlias && exportedDeclarationsCount <= 2) {
// it is legal to merge type alias with other values
// so count should be either 1 (just type alias) or 2 (type alias + merged value)
return;
}
if (exportedDeclarationsCount > 1) {
for (const declaration of declarations) {
if (isNotOverload(declaration)) {
diagnostics.add(createDiagnosticForNode(declaration, Diagnostics.Cannot_redeclare_exported_variable_0, unescapeLeadingUnderscores(id)));
if (exports) {
exports.forEach(({ declarations, flags }, id) => {
if (id === "__export") {
return;
}
// ECMA262: 15.2.1.1 It is a Syntax Error if the ExportedNames of ModuleItemList contains any duplicate entries.
// (TS Exceptions: namespaces, function overloads, enums, and interfaces)
if (flags & (SymbolFlags.Namespace | SymbolFlags.Interface | SymbolFlags.Enum)) {
return;
}
const exportedDeclarationsCount = countWhere(declarations, isNotOverloadAndNotAccessor);
if (flags & SymbolFlags.TypeAlias && exportedDeclarationsCount <= 2) {
// it is legal to merge type alias with other values
// so count should be either 1 (just type alias) or 2 (type alias + merged value)
return;
}
if (exportedDeclarationsCount > 1) {
for (const declaration of declarations) {
if (isNotOverload(declaration)) {
diagnostics.add(createDiagnosticForNode(declaration, Diagnostics.Cannot_redeclare_exported_variable_0, unescapeLeadingUnderscores(id)));
}
}
}
}
});
});
}
links.exportsChecked = true;
}
}
@ -24577,12 +24575,16 @@ namespace ts {
}
// GRAMMAR CHECKING
function checkGrammarDecoratorsAndModifiers(node: Node): boolean {
return checkGrammarDecorators(node) || checkGrammarModifiers(node);
}
function checkGrammarDecorators(node: Node): boolean {
if (!node.decorators) {
return false;
}
if (!nodeCanBeDecorated(node)) {
if (node.kind === SyntaxKind.MethodDeclaration && !ts.nodeIsPresent((<MethodDeclaration>node).body)) {
if (node.kind === SyntaxKind.MethodDeclaration && !nodeIsPresent((<MethodDeclaration>node).body)) {
return grammarErrorOnFirstToken(node, Diagnostics.A_decorator_can_only_decorate_a_method_implementation_not_an_overload);
}
else {
@ -24932,7 +24934,7 @@ namespace ts {
function checkGrammarFunctionLikeDeclaration(node: FunctionLikeDeclaration): boolean {
// Prevent cascading error by short-circuit
const file = getSourceFileOfNode(node);
return checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarTypeParameterList(node.typeParameters, file) ||
return checkGrammarDecoratorsAndModifiers(node) || checkGrammarTypeParameterList(node.typeParameters, file) ||
checkGrammarParameterList(node.parameters) || checkGrammarArrowFunction(node, file);
}
@ -24988,7 +24990,7 @@ namespace ts {
function checkGrammarIndexSignature(node: SignatureDeclaration) {
// Prevent cascading error by short-circuit
return checkGrammarDecorators(node) || checkGrammarModifiers(node) || checkGrammarIndexSignatureParameters(node);
return checkGrammarDecoratorsAndModifiers(node) || checkGrammarIndexSignatureParameters(node);
}
function checkGrammarForAtLeastOneTypeArgument(node: Node, typeArguments: NodeArray<TypeNode>): boolean {
@ -25039,7 +25041,7 @@ namespace ts {
let seenExtendsClause = false;
let seenImplementsClause = false;
if (!checkGrammarDecorators(node) && !checkGrammarModifiers(node) && node.heritageClauses) {
if (!checkGrammarDecoratorsAndModifiers(node) && node.heritageClauses) {
for (const heritageClause of node.heritageClauses) {
if (heritageClause.token === SyntaxKind.ExtendsKeyword) {
if (seenExtendsClause) {

View File

@ -221,11 +221,9 @@ namespace FourSlash {
private addMatchedInputFile(referenceFilePath: string, extensions: ReadonlyArray<string>) {
const inputFiles = this.inputFiles;
const languageServiceAdapterHost = this.languageServiceAdapterHost;
if (!extensions) {
tryAdd(referenceFilePath);
}
else {
tryAdd(referenceFilePath) || ts.forEach(extensions, ext => tryAdd(referenceFilePath + ext));
const didAdd = tryAdd(referenceFilePath);
if (extensions && !didAdd) {
ts.forEach(extensions, ext => tryAdd(referenceFilePath + ext));
}
function tryAdd(path: string) {

View File

@ -57,7 +57,9 @@ namespace Harness.Parallel.Worker {
return cleanup();
}
try {
beforeFunc && beforeFunc();
if (beforeFunc) {
beforeFunc();
}
}
catch (e) {
errors.push({ error: `Error executing before function: ${e.message}`, stack: e.stack, name: [...namestack] });
@ -69,7 +71,9 @@ namespace Harness.Parallel.Worker {
testList.forEach(({ name, callback, kind }) => executeCallback(name, callback, kind));
try {
afterFunc && afterFunc();
if (afterFunc) {
afterFunc();
}
}
catch (e) {
errors.push({ error: `Error executing after function: ${e.message}`, stack: e.stack, name: [...namestack] });

View File

@ -45,7 +45,7 @@ export function Component(x: Config): any;`
readDirectory: noop as any,
});
const definitions = languageService.getDefinitionAtPosition("foo.ts", 160); // 160 is the latter `vueTemplateHtml` position
expect(definitions).to.exist;
expect(definitions).to.exist; // tslint:disable-line no-unused-expression
});
});
}

View File

@ -317,7 +317,7 @@ namespace ts.server {
session.send = Session.prototype.send;
assert(session.send);
expect(session.send(msg)).to.not.exist;
expect(session.send(msg)).to.not.exist; // tslint:disable-line no-unused-expression
expect(lastWrittenToHost).to.equal(resultMsg);
});
});
@ -524,14 +524,14 @@ namespace ts.server {
});
});
it("has access to the project service", () => {
class ServiceSession extends TestSession {
// tslint:disable-next-line no-unused-expression
new class extends TestSession {
constructor() {
super();
assert(this.projectService);
expect(this.projectService).to.be.instanceOf(ProjectService);
}
}
new ServiceSession();
}();
});
});

View File

@ -1870,7 +1870,7 @@ namespace ts.projectSystem {
// Specify .html extension as mixed content
const extraFileExtensions = [{ extension: ".html", scriptKind: ScriptKind.JS, isMixedContent: true }];
const configureHostRequest = makeSessionRequest<protocol.ConfigureRequestArguments>(CommandNames.Configure, { extraFileExtensions });
session.executeCommand(configureHostRequest).response;
session.executeCommand(configureHostRequest);
// The configured project should now be updated to include html file
checkNumberOfProjects(projectService, { configuredProjects: 1 });
@ -1929,7 +1929,7 @@ namespace ts.projectSystem {
// Specify .html extension as mixed content in a configure host request
const extraFileExtensions = [{ extension: ".html", scriptKind: ScriptKind.JS, isMixedContent: true }];
const configureHostRequest = makeSessionRequest<protocol.ConfigureRequestArguments>(CommandNames.Configure, { extraFileExtensions });
session.executeCommand(configureHostRequest).response;
session.executeCommand(configureHostRequest);
openFilesForSession([file1], session);
let projectService = session.getProjectService();
@ -1948,7 +1948,7 @@ namespace ts.projectSystem {
host = createServerHost([file1, file2, config2, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") });
session = createSession(host);
session.executeCommand(configureHostRequest).response;
session.executeCommand(configureHostRequest);
openFilesForSession([file1], session);
projectService = session.getProjectService();
@ -1967,7 +1967,7 @@ namespace ts.projectSystem {
host = createServerHost([file1, file2, config3, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") });
session = createSession(host);
session.executeCommand(configureHostRequest).response;
session.executeCommand(configureHostRequest);
openFilesForSession([file1], session);
projectService = session.getProjectService();
@ -1986,7 +1986,7 @@ namespace ts.projectSystem {
host = createServerHost([file1, file2, config4, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") });
session = createSession(host);
session.executeCommand(configureHostRequest).response;
session.executeCommand(configureHostRequest);
openFilesForSession([file1], session);
projectService = session.getProjectService();
@ -2005,7 +2005,7 @@ namespace ts.projectSystem {
host = createServerHost([file1, file2, config5, libFile], { executingFilePath: combinePaths(getDirectoryPath(libFile.path), "tsc.js") });
session = createSession(host);
session.executeCommand(configureHostRequest).response;
session.executeCommand(configureHostRequest);
openFilesForSession([file1], session);
projectService = session.getProjectService();

View File

@ -1398,7 +1398,9 @@ namespace ts {
addEmitFlags(node, EmitFlags.NoLeadingComments);
const firstChild = forEachChild(node, child => child);
firstChild && suppressLeading(firstChild);
if (firstChild) {
suppressLeading(firstChild);
}
}
function suppressTrailing(node: Node) {
@ -1415,7 +1417,9 @@ namespace ts {
}
return undefined;
});
lastChild && suppressTrailing(lastChild);
if (lastChild) {
suppressTrailing(lastChild);
}
}
}
}

View File

@ -93,7 +93,6 @@
"no-object-literal-type-assertion": false,
"no-shadowed-variable": false,
"no-submodule-imports": false,
"no-unused-expression": false,
"no-unnecessary-initializer": false,
"no-var-requires": false,
"object-literal-key-quotes": false,