From d6888b2834f37f880822c40953149d5d9b57550f Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 16 Sep 2014 15:30:19 -0700 Subject: [PATCH 01/38] Moved nav bar functionality into more 'functional' style. --- .../getScriptLexicalStructureWalker.ts | 269 +++++++++--------- src/services/services.ts | 6 +- 2 files changed, 137 insertions(+), 138 deletions(-) diff --git a/src/services/getScriptLexicalStructureWalker.ts b/src/services/getScriptLexicalStructureWalker.ts index bfce8e0067c..f30810ee2f4 100644 --- a/src/services/getScriptLexicalStructureWalker.ts +++ b/src/services/getScriptLexicalStructureWalker.ts @@ -1,15 +1,17 @@ /// module TypeScript.Services { - export class NavigationBarItemGetter { - private hasGlobalNode = false; + export function getNavigationBarItemsHelper(sourceUnit: TypeScript.SourceUnitSyntax): ts.NavigationBarItem[] { + var hasGlobalNode = false; - private getIndent(node: ISyntaxNode): number { - var indent = this.hasGlobalNode ? 1 : 0; + return getItemsWorker(getTopLevelNodes(sourceUnit), createTopLevelItem); + + function getIndent(node: ISyntaxNode): number { + var indent = hasGlobalNode ? 1 : 0; var current = node.parent; - while (current != null) { - if (current.kind() == SyntaxKind.ModuleDeclaration || current.kind() === SyntaxKind.FunctionDeclaration) { + while (current) { + if (current.kind() === SyntaxKind.ModuleDeclaration || current.kind() === SyntaxKind.FunctionDeclaration) { indent++; } @@ -19,7 +21,7 @@ module TypeScript.Services { return indent; } - private getKindModifiers(modifiers: TypeScript.ISyntaxToken[]): string { + function getKindModifiers(modifiers: TypeScript.ISyntaxToken[]): string { var result: string[] = []; for (var i = 0, n = modifiers.length; i < n; i++) { @@ -29,11 +31,7 @@ module TypeScript.Services { return result.length > 0 ? result.join(',') : ts.ScriptElementKindModifier.none; } - public getItems(node: TypeScript.SourceUnitSyntax): ts.NavigationBarItem[] { - return this.getItemsWorker(() => this.getTopLevelNodes(node), n => this.createTopLevelItem(n)); - } - - private getChildNodes(nodes: IModuleElementSyntax[]): ISyntaxNode[] { + function getChildNodes(nodes: IModuleElementSyntax[]): ISyntaxNode[] { var childNodes: ISyntaxNode[] = []; for (var i = 0, n = nodes.length; i < n; i++) { @@ -51,16 +49,16 @@ module TypeScript.Services { return childNodes; } - private getTopLevelNodes(node: SourceUnitSyntax): ISyntaxNode[] { + function getTopLevelNodes(node: SourceUnitSyntax): ISyntaxNode[] { var topLevelNodes: ISyntaxNode[] = []; topLevelNodes.push(node); - this.addTopLevelNodes(node.moduleElements, topLevelNodes); + addTopLevelNodes(node.moduleElements, topLevelNodes); return topLevelNodes; } - private addTopLevelNodes(nodes: IModuleElementSyntax[], topLevelNodes: ISyntaxNode[]): void { + function addTopLevelNodes(nodes: IModuleElementSyntax[], topLevelNodes: ISyntaxNode[]): void { for (var i = 0, n = nodes.length; i < n; i++) { var node = nodes[i]; switch (node.kind()) { @@ -73,43 +71,42 @@ module TypeScript.Services { case SyntaxKind.ModuleDeclaration: var moduleDeclaration = node; topLevelNodes.push(node); - this.addTopLevelNodes(moduleDeclaration.moduleElements, topLevelNodes); + addTopLevelNodes(moduleDeclaration.moduleElements, topLevelNodes); break; case SyntaxKind.FunctionDeclaration: var functionDeclaration = node; - if (this.isTopLevelFunctionDeclaration(functionDeclaration)) { + if (isTopLevelFunctionDeclaration(functionDeclaration)) { topLevelNodes.push(node); - this.addTopLevelNodes(functionDeclaration.block.statements, topLevelNodes); + addTopLevelNodes(functionDeclaration.block.statements, topLevelNodes); } break; } } } - public isTopLevelFunctionDeclaration(functionDeclaration: FunctionDeclarationSyntax) { + function isTopLevelFunctionDeclaration(functionDeclaration: FunctionDeclarationSyntax) { // A function declaration is 'top level' if it contains any function declarations // within it. return functionDeclaration.block && ArrayUtilities.any(functionDeclaration.block.statements, s => s.kind() === SyntaxKind.FunctionDeclaration); } - private getItemsWorker(getNodes: () => ISyntaxNode[], createItem: (n: ISyntaxNode) => ts.NavigationBarItem): ts.NavigationBarItem[] { + function getItemsWorker(nodes: ISyntaxNode[], createItem: (n: ISyntaxNode) => ts.NavigationBarItem): ts.NavigationBarItem[] { var items: ts.NavigationBarItem[] = []; var keyToItem = createIntrinsicsObject(); - var nodes = getNodes(); for (var i = 0, n = nodes.length; i < n; i++) { var child = nodes[i]; var item = createItem(child); - if (item != null) { + if (item !== undefined) { if (item.text.length > 0) { var key = item.text + "-" + item.kind; var itemWithSameName = keyToItem[key]; if (itemWithSameName) { // We had an item with the same name. Merge these items together. - this.merge(itemWithSameName, item); + merge(itemWithSameName, item); } else { keyToItem[key] = item; @@ -122,7 +119,7 @@ module TypeScript.Services { return items; } - private merge(target: ts.NavigationBarItem, source: ts.NavigationBarItem) { + function merge(target: ts.NavigationBarItem, source: ts.NavigationBarItem) { // First, add any spans in the source to the target. target.spans.push.apply(target.spans, source.spans); @@ -141,7 +138,7 @@ module TypeScript.Services { if (targetChild.text === sourceChild.text && targetChild.kind === sourceChild.kind) { // Found a match. merge them. - this.merge(targetChild, sourceChild); + merge(targetChild, sourceChild); continue outer; } } @@ -152,26 +149,26 @@ module TypeScript.Services { } } - private createChildItem(node: ISyntaxNode): ts.NavigationBarItem { + function createChildItem(node: ISyntaxNode): ts.NavigationBarItem { switch (node.kind()) { case SyntaxKind.Parameter: var parameter = node; if (parameter.modifiers.length === 0) { - return null; + return undefined; } - return new ts.NavigationBarItem(parameter.identifier.text(), ts.ScriptElementKind.memberVariableElement, this.getKindModifiers(parameter.modifiers), [TextSpan.fromBounds(start(node), end(node))]); + return new ts.NavigationBarItem(parameter.identifier.text(), ts.ScriptElementKind.memberVariableElement, getKindModifiers(parameter.modifiers), [TextSpan.fromBounds(start(node), end(node))]); case SyntaxKind.MemberFunctionDeclaration: var memberFunction = node; - return new ts.NavigationBarItem(memberFunction.propertyName.text(), ts.ScriptElementKind.memberFunctionElement, this.getKindModifiers(memberFunction.modifiers), [TextSpan.fromBounds(start(node), end(node))]); + return new ts.NavigationBarItem(memberFunction.propertyName.text(), ts.ScriptElementKind.memberFunctionElement, getKindModifiers(memberFunction.modifiers), [TextSpan.fromBounds(start(node), end(node))]); case SyntaxKind.GetAccessor: var getAccessor = node; - return new ts.NavigationBarItem(getAccessor.propertyName.text(), ts.ScriptElementKind.memberGetAccessorElement, this.getKindModifiers(getAccessor.modifiers), [TextSpan.fromBounds(start(node), end(node))]); + return new ts.NavigationBarItem(getAccessor.propertyName.text(), ts.ScriptElementKind.memberGetAccessorElement, getKindModifiers(getAccessor.modifiers), [TextSpan.fromBounds(start(node), end(node))]); case SyntaxKind.SetAccessor: var setAccessor = node; - return new ts.NavigationBarItem(setAccessor.propertyName.text(), ts.ScriptElementKind.memberSetAccessorElement, this.getKindModifiers(setAccessor.modifiers), [TextSpan.fromBounds(start(node), end(node))]); + return new ts.NavigationBarItem(setAccessor.propertyName.text(), ts.ScriptElementKind.memberSetAccessorElement, getKindModifiers(setAccessor.modifiers), [TextSpan.fromBounds(start(node), end(node))]); case SyntaxKind.IndexSignature: var indexSignature = node; @@ -199,14 +196,14 @@ module TypeScript.Services { case SyntaxKind.FunctionDeclaration: var functionDeclaration = node; - if (!this.isTopLevelFunctionDeclaration(functionDeclaration)) { - return new ts.NavigationBarItem(functionDeclaration.identifier.text(), ts.ScriptElementKind.functionElement, this.getKindModifiers(functionDeclaration.modifiers), [TextSpan.fromBounds(start(node), end(node))]); + if (!isTopLevelFunctionDeclaration(functionDeclaration)) { + return new ts.NavigationBarItem(functionDeclaration.identifier.text(), ts.ScriptElementKind.functionElement, getKindModifiers(functionDeclaration.modifiers), [TextSpan.fromBounds(start(node), end(node))]); } break; case SyntaxKind.MemberVariableDeclaration: var memberVariableDeclaration = node; - return new ts.NavigationBarItem(memberVariableDeclaration.variableDeclarator.propertyName.text(), ts.ScriptElementKind.memberVariableElement, this.getKindModifiers(memberVariableDeclaration.modifiers), [TextSpan.fromBounds(start(memberVariableDeclaration.variableDeclarator), end(memberVariableDeclaration.variableDeclarator))]); + return new ts.NavigationBarItem(memberVariableDeclaration.variableDeclarator.propertyName.text(), ts.ScriptElementKind.memberVariableElement, getKindModifiers(memberVariableDeclaration.modifiers), [TextSpan.fromBounds(start(memberVariableDeclaration.variableDeclarator), end(memberVariableDeclaration.variableDeclarator))]); case SyntaxKind.VariableDeclarator: var variableDeclarator = node; @@ -217,135 +214,135 @@ module TypeScript.Services { return new ts.NavigationBarItem("constructor", ts.ScriptElementKind.constructorImplementationElement, ts.ScriptElementKindModifier.none, [TextSpan.fromBounds(start(node), end(node))]); } - return null; + return undefined; } - private createTopLevelItem(node: ISyntaxNode): ts.NavigationBarItem { + function createTopLevelItem(node: ISyntaxNode): ts.NavigationBarItem { switch (node.kind()) { case SyntaxKind.SourceUnit: - return this.createSourceUnitItem(node); + return createSourceUnitItem(node); case SyntaxKind.ClassDeclaration: - return this.createClassItem(node); + return createClassItem(node); case SyntaxKind.EnumDeclaration: - return this.createEnumItem(node); + return createEnumItem(node); case SyntaxKind.InterfaceDeclaration: - return this.createIterfaceItem(node); + return createIterfaceItem(node); case SyntaxKind.ModuleDeclaration: - return this.createModuleItem(node); + return createModuleItem(node); case SyntaxKind.FunctionDeclaration: - return this.createFunctionItem(node); + return createFunctionItem(node); } - return null; - } + return undefined; - private getModuleNames(node: TypeScript.ModuleDeclarationSyntax): string[] { - var result: string[] = []; + function getModuleNames(node: TypeScript.ModuleDeclarationSyntax): string[] { + var result: string[] = []; - if (node.stringLiteral) { - result.push(node.stringLiteral.text()); - } - else { - this.getModuleNamesHelper(node.name, result); + if (node.stringLiteral) { + result.push(node.stringLiteral.text()); + } + else { + getModuleNamesHelper(node.name, result); + } + + return result; } - return result; - } - - private getModuleNamesHelper(name: TypeScript.INameSyntax, result: string[]): void { - if (name.kind() === TypeScript.SyntaxKind.QualifiedName) { - var qualifiedName = name; - this.getModuleNamesHelper(qualifiedName.left, result); - result.push(qualifiedName.right.text()); - } - else { - result.push((name).text()); - } - } - - private createModuleItem(node: ModuleDeclarationSyntax): ts.NavigationBarItem { - var moduleNames = this.getModuleNames(node); - - var childItems = this.getItemsWorker(() => this.getChildNodes(node.moduleElements), n => this.createChildItem(n)); - - return new ts.NavigationBarItem(moduleNames.join("."), - ts.ScriptElementKind.moduleElement, - this.getKindModifiers(node.modifiers), - [TextSpan.fromBounds(start(node), end(node))], - childItems, - this.getIndent(node)); - } - - private createFunctionItem(node: FunctionDeclarationSyntax) { - var childItems = this.getItemsWorker(() => node.block.statements, n => this.createChildItem(n)); - - return new ts.NavigationBarItem(node.identifier.text(), - ts.ScriptElementKind.functionElement, - this.getKindModifiers(node.modifiers), - [TextSpan.fromBounds(start(node), end(node))], - childItems, - this.getIndent(node)); - } - - private createSourceUnitItem(node: SourceUnitSyntax): ts.NavigationBarItem { - var childItems = this.getItemsWorker(() => this.getChildNodes(node.moduleElements), n => this.createChildItem(n)); - - if (childItems === null || childItems.length === 0) { - return null; + function getModuleNamesHelper(name: TypeScript.INameSyntax, result: string[]): void { + if (name.kind() === TypeScript.SyntaxKind.QualifiedName) { + var qualifiedName = name; + getModuleNamesHelper(qualifiedName.left, result); + result.push(qualifiedName.right.text()); + } + else { + result.push((name).text()); + } } - this.hasGlobalNode = true; - return new ts.NavigationBarItem("", - ts.ScriptElementKind.moduleElement, - ts.ScriptElementKindModifier.none, - [TextSpan.fromBounds(start(node), end(node))], - childItems); - } + function createModuleItem(node: ModuleDeclarationSyntax): ts.NavigationBarItem { + var moduleNames = getModuleNames(node); - private createClassItem(node: ClassDeclarationSyntax): ts.NavigationBarItem { - var constructor = ArrayUtilities.firstOrDefault( - node.classElements, n => n.kind() === SyntaxKind.ConstructorDeclaration); + var childItems = getItemsWorker(getChildNodes(node.moduleElements), n => createChildItem(n)); - // Add the constructor parameters in as children of hte class (for property parameters). - var nodes: ISyntaxNode[] = constructor - ? (constructor.callSignature.parameterList.parameters).concat(node.classElements) - : node.classElements; + return new ts.NavigationBarItem(moduleNames.join("."), + ts.ScriptElementKind.moduleElement, + getKindModifiers(node.modifiers), + [TextSpan.fromBounds(start(node), end(node))], + childItems, + getIndent(node)); + } - var childItems = this.getItemsWorker(() => nodes, n => this.createChildItem(n)); - return new ts.NavigationBarItem( - node.identifier.text(), - ts.ScriptElementKind.classElement, - this.getKindModifiers(node.modifiers), - [TextSpan.fromBounds(start(node), end(node))], - childItems, - this.getIndent(node)); - } + function createFunctionItem(node: FunctionDeclarationSyntax) { + var childItems = getItemsWorker(node.block.statements, n => createChildItem(n)); - private createEnumItem(node: TypeScript.EnumDeclarationSyntax): ts.NavigationBarItem { - var childItems = this.getItemsWorker(() => node.enumElements, n => this.createChildItem(n)); - return new ts.NavigationBarItem( - node.identifier.text(), - ts.ScriptElementKind.enumElement, - this.getKindModifiers(node.modifiers), - [TextSpan.fromBounds(start(node), end(node))], - childItems, - this.getIndent(node)); - } + return new ts.NavigationBarItem(node.identifier.text(), + ts.ScriptElementKind.functionElement, + getKindModifiers(node.modifiers), + [TextSpan.fromBounds(start(node), end(node))], + childItems, + getIndent(node)); + } - private createIterfaceItem(node: TypeScript.InterfaceDeclarationSyntax): ts.NavigationBarItem { - var childItems = this.getItemsWorker(() => node.body.typeMembers, n => this.createChildItem(n)); - return new ts.NavigationBarItem( - node.identifier.text(), - ts.ScriptElementKind.interfaceElement, - this.getKindModifiers(node.modifiers), - [TextSpan.fromBounds(start(node), end(node))], - childItems, - this.getIndent(node)); + function createSourceUnitItem(node: SourceUnitSyntax): ts.NavigationBarItem { + var childItems = getItemsWorker(getChildNodes(node.moduleElements), n => createChildItem(n)); + + if (childItems === undefined || childItems.length === 0) { + return undefined; + } + + hasGlobalNode = true; + return new ts.NavigationBarItem("", + ts.ScriptElementKind.moduleElement, + ts.ScriptElementKindModifier.none, + [TextSpan.fromBounds(start(node), end(node))], + childItems); + } + + function createClassItem(node: ClassDeclarationSyntax): ts.NavigationBarItem { + var constructor = ArrayUtilities.firstOrDefault( + node.classElements, n => n.kind() === SyntaxKind.ConstructorDeclaration); + + // Add the constructor parameters in as children of the class (for property parameters). + var nodes: ISyntaxNode[] = constructor + ? (constructor.callSignature.parameterList.parameters).concat(node.classElements) + : node.classElements; + + var childItems = getItemsWorker(nodes, n => createChildItem(n)); + return new ts.NavigationBarItem( + node.identifier.text(), + ts.ScriptElementKind.classElement, + getKindModifiers(node.modifiers), + [TextSpan.fromBounds(start(node), end(node))], + childItems, + getIndent(node)); + } + + function createEnumItem(node: TypeScript.EnumDeclarationSyntax): ts.NavigationBarItem { + var childItems = getItemsWorker(node.enumElements, n => createChildItem(n)); + return new ts.NavigationBarItem( + node.identifier.text(), + ts.ScriptElementKind.enumElement, + getKindModifiers(node.modifiers), + [TextSpan.fromBounds(start(node), end(node))], + childItems, + getIndent(node)); + } + + function createIterfaceItem(node: TypeScript.InterfaceDeclarationSyntax): ts.NavigationBarItem { + var childItems = getItemsWorker(node.body.typeMembers, n => createChildItem(n)); + return new ts.NavigationBarItem( + node.identifier.text(), + ts.ScriptElementKind.interfaceElement, + getKindModifiers(node.modifiers), + [TextSpan.fromBounds(start(node), end(node))], + childItems, + getIndent(node)); + } } } } \ No newline at end of file diff --git a/src/services/services.ts b/src/services/services.ts index d51eeee97c0..ed32721a1ac 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3118,10 +3118,12 @@ module ts { return TypeScript.Services.Breakpoints.getBreakpointLocation(syntaxtree, position); } - function getNavigationBarItems(filename: string) { + function getNavigationBarItems(filename: string): NavigationBarItem[] { filename = TypeScript.switchToForwardSlashes(filename); + + var syntaxTree = getSyntaxTree(filename); - return new TypeScript.Services.NavigationBarItemGetter().getItems(syntaxTree.sourceUnit()); + return TypeScript.Services.getNavigationBarItemsHelper(syntaxTree.sourceUnit()); } function getOutliningSpans(filename: string): OutliningSpan[] { From e69b9e6362aeb8a8fa3cf1ae076e5b7618d26543 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 17 Sep 2014 15:28:41 -0700 Subject: [PATCH 02/38] Fixed issue where parser improperly parses a function declaration with no identifier. --- src/compiler/checker.ts | 4 ++++ src/compiler/parser.ts | 5 ++++- .../parserEqualsGreaterThanAfterFunction1.errors.txt | 6 ++---- .../parserEqualsGreaterThanAfterFunction2.errors.txt | 6 ++---- 4 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index b99d6d27d20..db876da3b9f 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5379,6 +5379,10 @@ module ts { var isConstructor = (symbol.flags & SymbolFlags.Constructor) !== 0; function reportImplementationExpectedError(node: FunctionDeclaration): void { + if (node.name && node.name.kind === SyntaxKind.Missing) { + return; + } + var seen = false; var subsequentNode = forEachChild(node.parent, c => { if (seen) { diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 25ca24ae61b..6fa2cdd244a 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -953,7 +953,10 @@ module ts { return finishNode(node); } error(Diagnostics.Identifier_expected); - return createMissingNode(); + + var node = createMissingNode(); + node.text = ""; + return node; } function parseIdentifier(): Identifier { diff --git a/tests/baselines/reference/parserEqualsGreaterThanAfterFunction1.errors.txt b/tests/baselines/reference/parserEqualsGreaterThanAfterFunction1.errors.txt index 9f428d7fea7..fd3e1c42779 100644 --- a/tests/baselines/reference/parserEqualsGreaterThanAfterFunction1.errors.txt +++ b/tests/baselines/reference/parserEqualsGreaterThanAfterFunction1.errors.txt @@ -1,6 +1,4 @@ -==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserEqualsGreaterThanAfterFunction1.ts (2 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserEqualsGreaterThanAfterFunction1.ts (1 errors) ==== function => ~~ -!!! Identifier expected. - -!!! Function implementation is missing or not immediately following the declaration. \ No newline at end of file +!!! Identifier expected. \ No newline at end of file diff --git a/tests/baselines/reference/parserEqualsGreaterThanAfterFunction2.errors.txt b/tests/baselines/reference/parserEqualsGreaterThanAfterFunction2.errors.txt index 4e9b5fbaa86..0d81cd7f35d 100644 --- a/tests/baselines/reference/parserEqualsGreaterThanAfterFunction2.errors.txt +++ b/tests/baselines/reference/parserEqualsGreaterThanAfterFunction2.errors.txt @@ -1,4 +1,4 @@ -==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserEqualsGreaterThanAfterFunction2.ts (5 errors) ==== +==== tests/cases/conformance/parser/ecmascript5/ErrorRecovery/parserEqualsGreaterThanAfterFunction2.ts (4 errors) ==== function (a => b; ~ !!! Identifier expected. @@ -7,6 +7,4 @@ ~ !!! ',' expected. -!!! ')' expected. - -!!! Function implementation is missing or not immediately following the declaration. \ No newline at end of file +!!! ')' expected. \ No newline at end of file From 55e772cfe086e69c2336c17f89a745a903d942e9 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 17 Sep 2014 15:30:26 -0700 Subject: [PATCH 03/38] Re-added tests. --- .../scriptLexicalStructureItemsContainsNoAnonymouseFunctions.ts | 0 .../scriptLexicalStructureItemsModuleVariables.ts | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename tests/cases/{fourslash_old => fourslash}/scriptLexicalStructureItemsContainsNoAnonymouseFunctions.ts (100%) rename tests/cases/{fourslash_old => fourslash}/scriptLexicalStructureItemsModuleVariables.ts (100%) diff --git a/tests/cases/fourslash_old/scriptLexicalStructureItemsContainsNoAnonymouseFunctions.ts b/tests/cases/fourslash/scriptLexicalStructureItemsContainsNoAnonymouseFunctions.ts similarity index 100% rename from tests/cases/fourslash_old/scriptLexicalStructureItemsContainsNoAnonymouseFunctions.ts rename to tests/cases/fourslash/scriptLexicalStructureItemsContainsNoAnonymouseFunctions.ts diff --git a/tests/cases/fourslash_old/scriptLexicalStructureItemsModuleVariables.ts b/tests/cases/fourslash/scriptLexicalStructureItemsModuleVariables.ts similarity index 100% rename from tests/cases/fourslash_old/scriptLexicalStructureItemsModuleVariables.ts rename to tests/cases/fourslash/scriptLexicalStructureItemsModuleVariables.ts From b285ef165bfe6f16994e610bb2dbde6ca0180c60 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 17 Sep 2014 17:40:32 -0700 Subject: [PATCH 04/38] Added fourslash tests. --- .../scriptLexicalStructureFunctions.ts | 23 ++++++++++ .../scriptLexicalStructureFunctionsBroken.ts | 12 +++++ .../scriptLexicalStructureFunctionsBroken2.ts | 13 ++++++ .../fourslash/scriptLexicalStructureItems.ts | 1 + ...iptLexicalStructureItemsExternalModules.ts | 4 +- .../scriptLexicalStructureModules.ts | 44 +++++++++++++++++++ 6 files changed, 95 insertions(+), 2 deletions(-) create mode 100644 tests/cases/fourslash/scriptLexicalStructureFunctions.ts create mode 100644 tests/cases/fourslash/scriptLexicalStructureFunctionsBroken.ts create mode 100644 tests/cases/fourslash/scriptLexicalStructureFunctionsBroken2.ts create mode 100644 tests/cases/fourslash/scriptLexicalStructureModules.ts diff --git a/tests/cases/fourslash/scriptLexicalStructureFunctions.ts b/tests/cases/fourslash/scriptLexicalStructureFunctions.ts new file mode 100644 index 00000000000..7723bd0ee68 --- /dev/null +++ b/tests/cases/fourslash/scriptLexicalStructureFunctions.ts @@ -0,0 +1,23 @@ +/// + +////{| "itemName": "", "kind": "module" |} +//// +////{| "itemName": "foo", "kind": "function" |}function foo() { +//// var x = 10; +//// {| "itemName": "bar", "kind": "function", "parentName": "foo" |}function bar() { +//// var y = 10; +//// {| "itemName": "biz", "kind": "function", "parentName": "bar" |}function biz() { +//// var z = 10; +//// } +//// } +////} +//// +////{| "itemName": "baz", "kind": "function" |}function baz() { +//// var v = 10; +////} + +test.markers().forEach((marker) => { + verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); +}); + +verify.getScriptLexicalStructureListCount(5); // 4 functions + global diff --git a/tests/cases/fourslash/scriptLexicalStructureFunctionsBroken.ts b/tests/cases/fourslash/scriptLexicalStructureFunctionsBroken.ts new file mode 100644 index 00000000000..687b9b87296 --- /dev/null +++ b/tests/cases/fourslash/scriptLexicalStructureFunctionsBroken.ts @@ -0,0 +1,12 @@ +/// + +////{| "itemName": "f", "kind": "function" |} +////function f() { +//// function; +////} + +test.markers().forEach((marker) => { + verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); +}); + +verify.getScriptLexicalStructureListCount(1); // 1 function - no global since the inner function thinks it has a declaration. diff --git a/tests/cases/fourslash/scriptLexicalStructureFunctionsBroken2.ts b/tests/cases/fourslash/scriptLexicalStructureFunctionsBroken2.ts new file mode 100644 index 00000000000..1ac7ed09ad8 --- /dev/null +++ b/tests/cases/fourslash/scriptLexicalStructureFunctionsBroken2.ts @@ -0,0 +1,13 @@ +/// + +////function; +////{| "itemName": "f", "kind": "function" |} +////function f() { +//// function; +////} + +test.markers().forEach((marker) => { + verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); +}); + +verify.getScriptLexicalStructureListCount(1); // 1 function with no global - the broken declaration adds nothing for us at the global scope. diff --git a/tests/cases/fourslash/scriptLexicalStructureItems.ts b/tests/cases/fourslash/scriptLexicalStructureItems.ts index 025fd223fb9..e18f49c1db9 100644 --- a/tests/cases/fourslash/scriptLexicalStructureItems.ts +++ b/tests/cases/fourslash/scriptLexicalStructureItems.ts @@ -49,3 +49,4 @@ test.markers().forEach((marker) => { } }); +verify.getScriptLexicalStructureListCount(23); diff --git a/tests/cases/fourslash/scriptLexicalStructureItemsExternalModules.ts b/tests/cases/fourslash/scriptLexicalStructureItemsExternalModules.ts index dd8f64d87a2..550f1aed783 100644 --- a/tests/cases/fourslash/scriptLexicalStructureItemsExternalModules.ts +++ b/tests/cases/fourslash/scriptLexicalStructureItemsExternalModules.ts @@ -4,8 +4,8 @@ //// {| "itemName": "s", "kind": "property", "parentName": "Bar" |}public s: string; ////} -verify.getScriptLexicalStructureListCount(2); // external module node + class + property - test.markers().forEach((marker) => { verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); }); + +verify.getScriptLexicalStructureListCount(2); // external module node + class + property diff --git a/tests/cases/fourslash/scriptLexicalStructureModules.ts b/tests/cases/fourslash/scriptLexicalStructureModules.ts new file mode 100644 index 00000000000..c7446111a0a --- /dev/null +++ b/tests/cases/fourslash/scriptLexicalStructureModules.ts @@ -0,0 +1,44 @@ + +////{| "itemName": "\"X.Y.Z\"", "kind": "module" |} +////declare module "X.Y.Z" { +////} +//// +////{| "itemName": "A.B.C", "kind": "module" |} +////module A.B.C { +//// {| "itemName": "x", "kind": "var", "parent": "A.B.C" |} +//// export var x; +////} +//// +////{| "itemName": "A.B", "kind": "module" |} +////module A.B { +//// {| "itemName": "y", "kind": "var", "parent": "A.B" |} +//// export var y; +////} +//// +////{| "itemName": "A", "kind": "module" |} +////module A { +//// {| "itemName": "z", "kind": "var", "parent": "A" |} +//// export var z; +////} +//// +////{| "itemName": "A", "kind": "module" |} +////module A { +//// {| "itemName": "B", "kind": "module", "parent": "E" |} +//// module B { +//// {| "itemName": "C", "kind": "module", "parent": "F" |} +//// module C { +//// {| "itemName": "x", "kind": "var", "parent": "C" |} +//// declare var x; +//// } +//// } +////} + + +test.markers().forEach((marker) => { + verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); +}); + +/// We have 7 module keywords, and 4 var keywords. +/// The declarations of A.B.C.x do not get merged, so the 4 vars are independent. +/// The two 'A' modules, however, do get merged, so in reality we have 6 modules. +verify.getScriptLexicalStructureListCount(10); From a9e071c9604c3d397611eb956c15a93c77ead953 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 17 Sep 2014 17:52:57 -0700 Subject: [PATCH 05/38] Renamed file. --- ...=> scriptLexicalStructureItemsContainsNoAnonymousFunctions.ts} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename tests/cases/fourslash/{scriptLexicalStructureItemsContainsNoAnonymouseFunctions.ts => scriptLexicalStructureItemsContainsNoAnonymousFunctions.ts} (100%) diff --git a/tests/cases/fourslash/scriptLexicalStructureItemsContainsNoAnonymouseFunctions.ts b/tests/cases/fourslash/scriptLexicalStructureItemsContainsNoAnonymousFunctions.ts similarity index 100% rename from tests/cases/fourslash/scriptLexicalStructureItemsContainsNoAnonymouseFunctions.ts rename to tests/cases/fourslash/scriptLexicalStructureItemsContainsNoAnonymousFunctions.ts From e3077e34b7532c582ed3859063663caad201b71d Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 17 Sep 2014 18:11:37 -0700 Subject: [PATCH 06/38] Amended test for quoted module names. --- tests/cases/fourslash/scriptLexicalStructureModules.ts | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/tests/cases/fourslash/scriptLexicalStructureModules.ts b/tests/cases/fourslash/scriptLexicalStructureModules.ts index c7446111a0a..4331e64e0b0 100644 --- a/tests/cases/fourslash/scriptLexicalStructureModules.ts +++ b/tests/cases/fourslash/scriptLexicalStructureModules.ts @@ -3,6 +3,10 @@ ////declare module "X.Y.Z" { ////} //// +////{| "itemName": "'X2.Y2.Z2'", "kind": "module" |} +////declare module 'X2.Y2.Z2' { +////} +//// ////{| "itemName": "A.B.C", "kind": "module" |} ////module A.B.C { //// {| "itemName": "x", "kind": "var", "parent": "A.B.C" |} @@ -38,7 +42,7 @@ test.markers().forEach((marker) => { verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); }); -/// We have 7 module keywords, and 4 var keywords. +/// We have 8 module keywords, and 4 var keywords. /// The declarations of A.B.C.x do not get merged, so the 4 vars are independent. -/// The two 'A' modules, however, do get merged, so in reality we have 6 modules. -verify.getScriptLexicalStructureListCount(10); +/// The two 'A' modules, however, do get merged, so in reality we have 7 modules. +verify.getScriptLexicalStructureListCount(11); From ad12b8bf765decfebb5b818564ea274bda0f5f16 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 17 Sep 2014 18:12:16 -0700 Subject: [PATCH 07/38] Changed order of count check. --- tests/cases/fourslash/navbar_contains-no-duplicates.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cases/fourslash/navbar_contains-no-duplicates.ts b/tests/cases/fourslash/navbar_contains-no-duplicates.ts index 4334d30229f..49d570ed770 100644 --- a/tests/cases/fourslash/navbar_contains-no-duplicates.ts +++ b/tests/cases/fourslash/navbar_contains-no-duplicates.ts @@ -27,7 +27,6 @@ //// export var {| "itemName": "x", "kind": "var" |}x = 3; //// } -verify.getScriptLexicalStructureListCount(12); test.markers().forEach(marker => { if (marker.data) { verify.getScriptLexicalStructureListContains( @@ -39,3 +38,4 @@ test.markers().forEach(marker => { marker.position); } }); +verify.getScriptLexicalStructureListCount(12); \ No newline at end of file From be18ada22f2560fd0a2790a780fd89ba1095c66a Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 17 Sep 2014 18:13:06 -0700 Subject: [PATCH 08/38] Finally using new tree. --- .../getScriptLexicalStructureWalker.ts | 297 ++++++++++-------- src/services/services.ts | 4 +- 2 files changed, 159 insertions(+), 142 deletions(-) diff --git a/src/services/getScriptLexicalStructureWalker.ts b/src/services/getScriptLexicalStructureWalker.ts index f30810ee2f4..d65e1d4a48d 100644 --- a/src/services/getScriptLexicalStructureWalker.ts +++ b/src/services/getScriptLexicalStructureWalker.ts @@ -1,17 +1,17 @@ /// -module TypeScript.Services { - export function getNavigationBarItemsHelper(sourceUnit: TypeScript.SourceUnitSyntax): ts.NavigationBarItem[] { +module ts { + export function getNavigationBarItemsHelper(sourceFile: SourceFile): ts.NavigationBarItem[] { var hasGlobalNode = false; - return getItemsWorker(getTopLevelNodes(sourceUnit), createTopLevelItem); + return getItemsWorker(getTopLevelNodes(sourceFile), createTopLevelItem); - function getIndent(node: ISyntaxNode): number { + function getIndent(node: Node): number { var indent = hasGlobalNode ? 1 : 0; var current = node.parent; while (current) { - if (current.kind() === SyntaxKind.ModuleDeclaration || current.kind() === SyntaxKind.FunctionDeclaration) { + if (current.kind === SyntaxKind.ModuleDeclaration || current.kind === SyntaxKind.FunctionDeclaration) { indent++; } @@ -21,47 +21,38 @@ module TypeScript.Services { return indent; } - function getKindModifiers(modifiers: TypeScript.ISyntaxToken[]): string { - var result: string[] = []; - - for (var i = 0, n = modifiers.length; i < n; i++) { - result.push(modifiers[i].text()); - } - - return result.length > 0 ? result.join(',') : ts.ScriptElementKindModifier.none; - } - - function getChildNodes(nodes: IModuleElementSyntax[]): ISyntaxNode[] { - var childNodes: ISyntaxNode[] = []; + function getChildNodes(nodes: Node[]): Node[] { + var childNodes: Node[] = []; for (var i = 0, n = nodes.length; i < n; i++) { - var node = nodes[i]; + var node = nodes[i]; - if (node.kind() === SyntaxKind.FunctionDeclaration) { + if (node.kind === SyntaxKind.FunctionDeclaration) { childNodes.push(node); } - else if (node.kind() === SyntaxKind.VariableStatement) { - var variableDeclaration = (node).variableDeclaration; - childNodes.push.apply(childNodes, variableDeclaration.variableDeclarators); + else if (node.kind === SyntaxKind.VariableStatement) { + forEach((node).declarations, declaration => { + childNodes.push(declaration); + }); } } return childNodes; } - function getTopLevelNodes(node: SourceUnitSyntax): ISyntaxNode[] { - var topLevelNodes: ISyntaxNode[] = []; + function getTopLevelNodes(node: SourceFile): Node[] { + var topLevelNodes: Node[] = []; topLevelNodes.push(node); - addTopLevelNodes(node.moduleElements, topLevelNodes); + addTopLevelNodes(node.statements, topLevelNodes); return topLevelNodes; } - function addTopLevelNodes(nodes: IModuleElementSyntax[], topLevelNodes: ISyntaxNode[]): void { + function addTopLevelNodes(nodes: Node[], topLevelNodes: Node[]): void { for (var i = 0, n = nodes.length; i < n; i++) { var node = nodes[i]; - switch (node.kind()) { + switch (node.kind) { case SyntaxKind.ClassDeclaration: case SyntaxKind.EnumDeclaration: case SyntaxKind.InterfaceDeclaration: @@ -69,32 +60,39 @@ module TypeScript.Services { break; case SyntaxKind.ModuleDeclaration: - var moduleDeclaration = node; + var moduleDeclaration = node; topLevelNodes.push(node); - addTopLevelNodes(moduleDeclaration.moduleElements, topLevelNodes); + addTopLevelNodes((getInnermostModule(moduleDeclaration).body).statements, topLevelNodes); break; case SyntaxKind.FunctionDeclaration: - var functionDeclaration = node; + var functionDeclaration = node; if (isTopLevelFunctionDeclaration(functionDeclaration)) { topLevelNodes.push(node); - addTopLevelNodes(functionDeclaration.block.statements, topLevelNodes); + addTopLevelNodes((functionDeclaration.body).statements, topLevelNodes); } break; } } } - function isTopLevelFunctionDeclaration(functionDeclaration: FunctionDeclarationSyntax) { + function isTopLevelFunctionDeclaration(functionDeclaration: FunctionDeclaration) { // A function declaration is 'top level' if it contains any function declarations // within it. - return functionDeclaration.block && ArrayUtilities.any(functionDeclaration.block.statements, s => s.kind() === SyntaxKind.FunctionDeclaration); + return functionDeclaration.kind === SyntaxKind.FunctionDeclaration && + functionDeclaration.body && + functionDeclaration.body.kind === SyntaxKind.FunctionBlock && + forEach((functionDeclaration.body).statements, s => s.kind === SyntaxKind.FunctionDeclaration); } - function getItemsWorker(nodes: ISyntaxNode[], createItem: (n: ISyntaxNode) => ts.NavigationBarItem): ts.NavigationBarItem[] { + function getItemsWorker(nodes: Node[], createItem: (n: Node) => ts.NavigationBarItem): ts.NavigationBarItem[]{ var items: ts.NavigationBarItem[] = []; - var keyToItem = createIntrinsicsObject(); + if (!nodes) { + return items; + } + + var keyToItem: Map = {}; for (var i = 0, n = nodes.length; i < n; i++) { var child = nodes[i]; @@ -149,147 +147,135 @@ module TypeScript.Services { } } - function createChildItem(node: ISyntaxNode): ts.NavigationBarItem { - switch (node.kind()) { + function createChildItem(node: Node): ts.NavigationBarItem { + switch (node.kind) { case SyntaxKind.Parameter: - var parameter = node; - if (parameter.modifiers.length === 0) { + var parameter = node; + if ((node.flags & NodeFlags.Modifier) === 0) { return undefined; } - return new ts.NavigationBarItem(parameter.identifier.text(), ts.ScriptElementKind.memberVariableElement, getKindModifiers(parameter.modifiers), [TextSpan.fromBounds(start(node), end(node))]); + return new ts.NavigationBarItem(parameter.name.text, ts.ScriptElementKind.memberVariableElement, getNodeModifiers(node), [getNodeSpan(node)]); - case SyntaxKind.MemberFunctionDeclaration: - var memberFunction = node; - return new ts.NavigationBarItem(memberFunction.propertyName.text(), ts.ScriptElementKind.memberFunctionElement, getKindModifiers(memberFunction.modifiers), [TextSpan.fromBounds(start(node), end(node))]); + case SyntaxKind.Method: + var memberFunction = node; + return new ts.NavigationBarItem(memberFunction.name.text, ts.ScriptElementKind.memberFunctionElement, getNodeModifiers(node), [getNodeSpan(node)]); case SyntaxKind.GetAccessor: - var getAccessor = node; - return new ts.NavigationBarItem(getAccessor.propertyName.text(), ts.ScriptElementKind.memberGetAccessorElement, getKindModifiers(getAccessor.modifiers), [TextSpan.fromBounds(start(node), end(node))]); + var getAccessor = node; + return new ts.NavigationBarItem(getAccessor.name.text, ts.ScriptElementKind.memberGetAccessorElement, getNodeModifiers(node), [getNodeSpan(node)]); case SyntaxKind.SetAccessor: - var setAccessor = node; - return new ts.NavigationBarItem(setAccessor.propertyName.text(), ts.ScriptElementKind.memberSetAccessorElement, getKindModifiers(setAccessor.modifiers), [TextSpan.fromBounds(start(node), end(node))]); + var setAccessor = node; + return new ts.NavigationBarItem(setAccessor.name.text, ts.ScriptElementKind.memberSetAccessorElement, getNodeModifiers(node), [getNodeSpan(node)]); case SyntaxKind.IndexSignature: - var indexSignature = node; - return new ts.NavigationBarItem("[]", ts.ScriptElementKind.indexSignatureElement, ts.ScriptElementKindModifier.none, [TextSpan.fromBounds(start(node), end(node))]); + return new ts.NavigationBarItem("[]", ts.ScriptElementKind.indexSignatureElement, ts.ScriptElementKindModifier.none, [getNodeSpan(node)]); - case SyntaxKind.EnumElement: - var enumElement = node; - return new ts.NavigationBarItem(enumElement.propertyName.text(), ts.ScriptElementKind.memberVariableElement, ts.ScriptElementKindModifier.none, [TextSpan.fromBounds(start(node), end(node))]); + case SyntaxKind.EnumMember: + var enumElement = node; + return new ts.NavigationBarItem(enumElement.name.text, ts.ScriptElementKind.memberVariableElement, ts.ScriptElementKindModifier.none, [getNodeSpan(node)]); case SyntaxKind.CallSignature: - var callSignature = node; - return new ts.NavigationBarItem("()", ts.ScriptElementKind.callSignatureElement, ts.ScriptElementKindModifier.none, [TextSpan.fromBounds(start(node), end(node))]); + return new ts.NavigationBarItem("()", ts.ScriptElementKind.callSignatureElement, ts.ScriptElementKindModifier.none, []); case SyntaxKind.ConstructSignature: - var constructSignature = node; - return new ts.NavigationBarItem("new()", ts.ScriptElementKind.constructSignatureElement, ts.ScriptElementKindModifier.none, [TextSpan.fromBounds(start(node), end(node))]); + return new ts.NavigationBarItem("new()", ts.ScriptElementKind.constructSignatureElement, ts.ScriptElementKindModifier.none, [getNodeSpan(node)]); - case SyntaxKind.MethodSignature: - var methodSignature = node; - return new ts.NavigationBarItem(methodSignature.propertyName.text(), ts.ScriptElementKind.memberFunctionElement, ts.ScriptElementKindModifier.none, [TextSpan.fromBounds(start(node), end(node))]); - - case SyntaxKind.PropertySignature: - var propertySignature = node; - return new ts.NavigationBarItem(propertySignature.propertyName.text(), ts.ScriptElementKind.memberVariableElement, ts.ScriptElementKindModifier.none, [TextSpan.fromBounds(start(node), end(node))]); + case SyntaxKind.Property: + var propertySignature = node; + return new ts.NavigationBarItem(propertySignature.name.text, ts.ScriptElementKind.memberVariableElement, getNodeModifiers(node), [getNodeSpan(node)]); case SyntaxKind.FunctionDeclaration: - var functionDeclaration = node; + var functionDeclaration = node; if (!isTopLevelFunctionDeclaration(functionDeclaration)) { - return new ts.NavigationBarItem(functionDeclaration.identifier.text(), ts.ScriptElementKind.functionElement, getKindModifiers(functionDeclaration.modifiers), [TextSpan.fromBounds(start(node), end(node))]); + return new ts.NavigationBarItem(functionDeclaration.name.text, ts.ScriptElementKind.functionElement, getNodeModifiers(node), [getNodeSpan(node)]); } break; - case SyntaxKind.MemberVariableDeclaration: - var memberVariableDeclaration = node; - return new ts.NavigationBarItem(memberVariableDeclaration.variableDeclarator.propertyName.text(), ts.ScriptElementKind.memberVariableElement, getKindModifiers(memberVariableDeclaration.modifiers), [TextSpan.fromBounds(start(memberVariableDeclaration.variableDeclarator), end(memberVariableDeclaration.variableDeclarator))]); + case SyntaxKind.VariableDeclaration: + var variableDeclaration = node; + return new ts.NavigationBarItem(variableDeclaration.name.text, ts.ScriptElementKind.variableElement, ts.ScriptElementKindModifier.none, [getNodeSpan(node)]); - case SyntaxKind.VariableDeclarator: - var variableDeclarator = node; - return new ts.NavigationBarItem(variableDeclarator.propertyName.text(), ts.ScriptElementKind.variableElement, ts.ScriptElementKindModifier.none, [TextSpan.fromBounds(start(variableDeclarator), end(variableDeclarator))]); - - case SyntaxKind.ConstructorDeclaration: - var constructorDeclaration = node; - return new ts.NavigationBarItem("constructor", ts.ScriptElementKind.constructorImplementationElement, ts.ScriptElementKindModifier.none, [TextSpan.fromBounds(start(node), end(node))]); + case SyntaxKind.Constructor: + return new ts.NavigationBarItem("constructor", ts.ScriptElementKind.constructorImplementationElement, ts.ScriptElementKindModifier.none, [getNodeSpan(node)]); } return undefined; } - function createTopLevelItem(node: ISyntaxNode): ts.NavigationBarItem { - switch (node.kind()) { - case SyntaxKind.SourceUnit: - return createSourceUnitItem(node); + function createTopLevelItem(node: Node): ts.NavigationBarItem { + switch (node.kind) { + case SyntaxKind.SourceFile: + return createSourceFileItem(node); case SyntaxKind.ClassDeclaration: - return createClassItem(node); + return createClassItem(node); case SyntaxKind.EnumDeclaration: - return createEnumItem(node); + return createEnumItem(node); case SyntaxKind.InterfaceDeclaration: - return createIterfaceItem(node); + return createIterfaceItem(node); case SyntaxKind.ModuleDeclaration: - return createModuleItem(node); + return createModuleItem(node); case SyntaxKind.FunctionDeclaration: - return createFunctionItem(node); + return createFunctionItem(node); } return undefined; - function getModuleNames(node: TypeScript.ModuleDeclarationSyntax): string[] { + function getModuleNames(moduleDeclaration: ModuleDeclaration): string[]{ + // We want to maintain quotation marks. + if (moduleDeclaration.name.kind === SyntaxKind.StringLiteral) { + return [getSourceTextOfNode(moduleDeclaration.name)]; + } + + // Otherwise, we need to aggregate each identifier of the qualified name. var result: string[] = []; - if (node.stringLiteral) { - result.push(node.stringLiteral.text()); - } - else { - getModuleNamesHelper(node.name, result); - } + result.push(moduleDeclaration.name.text); + + while (moduleDeclaration.body && moduleDeclaration.body.kind === SyntaxKind.ModuleDeclaration) { + moduleDeclaration = moduleDeclaration.body; + + result.push(moduleDeclaration.name.text); + } return result; } - function getModuleNamesHelper(name: TypeScript.INameSyntax, result: string[]): void { - if (name.kind() === TypeScript.SyntaxKind.QualifiedName) { - var qualifiedName = name; - getModuleNamesHelper(qualifiedName.left, result); - result.push(qualifiedName.right.text()); - } - else { - result.push((name).text()); - } - } - - function createModuleItem(node: ModuleDeclarationSyntax): ts.NavigationBarItem { + function createModuleItem(node: ModuleDeclaration): NavigationBarItem { var moduleNames = getModuleNames(node); - - var childItems = getItemsWorker(getChildNodes(node.moduleElements), n => createChildItem(n)); + + var childItems = getItemsWorker(getChildNodes((getInnermostModule(node).body).statements), createChildItem); return new ts.NavigationBarItem(moduleNames.join("."), ts.ScriptElementKind.moduleElement, - getKindModifiers(node.modifiers), - [TextSpan.fromBounds(start(node), end(node))], + getNodeModifiers(node), + [getNodeSpan(node)], childItems, getIndent(node)); } - function createFunctionItem(node: FunctionDeclarationSyntax) { - var childItems = getItemsWorker(node.block.statements, n => createChildItem(n)); + function createFunctionItem(node: FunctionDeclaration) { + if (node.name && node.body && node.body.kind === SyntaxKind.FunctionBlock) { + var childItems = getItemsWorker((node.body).statements, createChildItem); - return new ts.NavigationBarItem(node.identifier.text(), - ts.ScriptElementKind.functionElement, - getKindModifiers(node.modifiers), - [TextSpan.fromBounds(start(node), end(node))], - childItems, - getIndent(node)); + return new ts.NavigationBarItem(node.name.text, + ts.ScriptElementKind.functionElement, + getNodeModifiers(node), + [getNodeSpan(node)], + childItems, + getIndent(node)); + } + + return undefined; } - function createSourceUnitItem(node: SourceUnitSyntax): ts.NavigationBarItem { - var childItems = getItemsWorker(getChildNodes(node.moduleElements), n => createChildItem(n)); + function createSourceFileItem(node: SourceFile): ts.NavigationBarItem { + var childItems = getItemsWorker(getChildNodes(node.statements), createChildItem); if (childItems === undefined || childItems.length === 0) { return undefined; @@ -299,50 +285,83 @@ module TypeScript.Services { return new ts.NavigationBarItem("", ts.ScriptElementKind.moduleElement, ts.ScriptElementKindModifier.none, - [TextSpan.fromBounds(start(node), end(node))], + [getNodeSpan(node)], childItems); } - function createClassItem(node: ClassDeclarationSyntax): ts.NavigationBarItem { - var constructor = ArrayUtilities.firstOrDefault( - node.classElements, n => n.kind() === SyntaxKind.ConstructorDeclaration); + function createClassItem(node: ClassDeclaration): ts.NavigationBarItem { + var childItems: NavigationBarItem[]; - // Add the constructor parameters in as children of the class (for property parameters). - var nodes: ISyntaxNode[] = constructor - ? (constructor.callSignature.parameterList.parameters).concat(node.classElements) - : node.classElements; + if (node.members) { + var constructor = forEach(node.members, member => { + return member.kind === SyntaxKind.Constructor && member; + }); + + // Add the constructor parameters in as children of the class (for property parameters). + var nodes: Node[] = constructor + ? (constructor.parameters).concat(node.members) + : node.members; + + var childItems = getItemsWorker(nodes, createChildItem); + } - var childItems = getItemsWorker(nodes, n => createChildItem(n)); return new ts.NavigationBarItem( - node.identifier.text(), + node.name.text, ts.ScriptElementKind.classElement, - getKindModifiers(node.modifiers), - [TextSpan.fromBounds(start(node), end(node))], + getNodeModifiers(node), + [getNodeSpan(node)], childItems, getIndent(node)); } - function createEnumItem(node: TypeScript.EnumDeclarationSyntax): ts.NavigationBarItem { - var childItems = getItemsWorker(node.enumElements, n => createChildItem(n)); + function createEnumItem(node: EnumDeclaration): ts.NavigationBarItem { + var childItems = getItemsWorker(node.members, createChildItem); return new ts.NavigationBarItem( - node.identifier.text(), + node.name.text, ts.ScriptElementKind.enumElement, - getKindModifiers(node.modifiers), - [TextSpan.fromBounds(start(node), end(node))], + getNodeModifiers(node), + [getNodeSpan(node)], childItems, getIndent(node)); } - function createIterfaceItem(node: TypeScript.InterfaceDeclarationSyntax): ts.NavigationBarItem { - var childItems = getItemsWorker(node.body.typeMembers, n => createChildItem(n)); + function createIterfaceItem(node: InterfaceDeclaration): ts.NavigationBarItem { + var childItems = getItemsWorker(node.members, createChildItem); return new ts.NavigationBarItem( - node.identifier.text(), + node.name.text, ts.ScriptElementKind.interfaceElement, - getKindModifiers(node.modifiers), - [TextSpan.fromBounds(start(node), end(node))], + getNodeModifiers(node), + [getNodeSpan(node)], childItems, getIndent(node)); } } + + // TODO: use implementation in services.ts + function getNodeModifiers(node: Node): string { + var flags = node.flags; + var result: string[] = []; + + if (flags & NodeFlags.Private) result.push(ScriptElementKindModifier.privateMemberModifier); + if (flags & NodeFlags.Public) result.push(ScriptElementKindModifier.publicMemberModifier); + if (flags & NodeFlags.Static) result.push(ScriptElementKindModifier.staticModifier); + if (flags & NodeFlags.Export) result.push(ScriptElementKindModifier.exportedModifier); + if (isInAmbientContext(node)) result.push(ScriptElementKindModifier.ambientModifier); + + return result.length > 0 ? result.join(',') : ScriptElementKindModifier.none; + } + + function getInnermostModule(node: ModuleDeclaration): ModuleDeclaration { + + while (node.body.kind === SyntaxKind.ModuleDeclaration) { + node = node.body; + } + + return node; + } + + function getNodeSpan(node: Node) { + return TypeScript.TextSpan.fromBounds(node.getStart(), node.getEnd()); + } } } \ No newline at end of file diff --git a/src/services/services.ts b/src/services/services.ts index ed32721a1ac..daaeb6d21bc 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3121,9 +3121,7 @@ module ts { function getNavigationBarItems(filename: string): NavigationBarItem[] { filename = TypeScript.switchToForwardSlashes(filename); - - var syntaxTree = getSyntaxTree(filename); - return TypeScript.Services.getNavigationBarItemsHelper(syntaxTree.sourceUnit()); + return getNavigationBarItemsHelper(getCurrentSourceFile(filename)); } function getOutliningSpans(filename: string): OutliningSpan[] { From 915a27fc1aa24f252ab72d0f45b2f1a496a84ea5 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 18 Sep 2014 12:36:06 -0700 Subject: [PATCH 09/38] Added helper function for creating child items. --- .../getScriptLexicalStructureWalker.ts | 28 +++++++++++-------- 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/services/getScriptLexicalStructureWalker.ts b/src/services/getScriptLexicalStructureWalker.ts index d65e1d4a48d..653d2ffaf29 100644 --- a/src/services/getScriptLexicalStructureWalker.ts +++ b/src/services/getScriptLexicalStructureWalker.ts @@ -154,55 +154,59 @@ module ts { if ((node.flags & NodeFlags.Modifier) === 0) { return undefined; } - return new ts.NavigationBarItem(parameter.name.text, ts.ScriptElementKind.memberVariableElement, getNodeModifiers(node), [getNodeSpan(node)]); + return basicChildItem(node, parameter.name.text, ts.ScriptElementKind.memberVariableElement); case SyntaxKind.Method: var memberFunction = node; - return new ts.NavigationBarItem(memberFunction.name.text, ts.ScriptElementKind.memberFunctionElement, getNodeModifiers(node), [getNodeSpan(node)]); + return basicChildItem(node, memberFunction.name.text, ts.ScriptElementKind.memberFunctionElement); case SyntaxKind.GetAccessor: var getAccessor = node; - return new ts.NavigationBarItem(getAccessor.name.text, ts.ScriptElementKind.memberGetAccessorElement, getNodeModifiers(node), [getNodeSpan(node)]); + return basicChildItem(node, getAccessor.name.text, ts.ScriptElementKind.memberGetAccessorElement); case SyntaxKind.SetAccessor: var setAccessor = node; - return new ts.NavigationBarItem(setAccessor.name.text, ts.ScriptElementKind.memberSetAccessorElement, getNodeModifiers(node), [getNodeSpan(node)]); + return basicChildItem(node, setAccessor.name.text, ts.ScriptElementKind.memberSetAccessorElement); case SyntaxKind.IndexSignature: - return new ts.NavigationBarItem("[]", ts.ScriptElementKind.indexSignatureElement, ts.ScriptElementKindModifier.none, [getNodeSpan(node)]); + return basicChildItem(node, "[]", ts.ScriptElementKind.indexSignatureElement); case SyntaxKind.EnumMember: var enumElement = node; - return new ts.NavigationBarItem(enumElement.name.text, ts.ScriptElementKind.memberVariableElement, ts.ScriptElementKindModifier.none, [getNodeSpan(node)]); + return basicChildItem(node, enumElement.name.text, ts.ScriptElementKind.memberVariableElement); case SyntaxKind.CallSignature: - return new ts.NavigationBarItem("()", ts.ScriptElementKind.callSignatureElement, ts.ScriptElementKindModifier.none, []); + return basicChildItem(node, "()", ts.ScriptElementKind.callSignatureElement); case SyntaxKind.ConstructSignature: - return new ts.NavigationBarItem("new()", ts.ScriptElementKind.constructSignatureElement, ts.ScriptElementKindModifier.none, [getNodeSpan(node)]); + return basicChildItem(node, "new()", ts.ScriptElementKind.constructSignatureElement); case SyntaxKind.Property: var propertySignature = node; - return new ts.NavigationBarItem(propertySignature.name.text, ts.ScriptElementKind.memberVariableElement, getNodeModifiers(node), [getNodeSpan(node)]); + return basicChildItem(node, propertySignature.name.text, ts.ScriptElementKind.memberVariableElement); case SyntaxKind.FunctionDeclaration: var functionDeclaration = node; if (!isTopLevelFunctionDeclaration(functionDeclaration)) { - return new ts.NavigationBarItem(functionDeclaration.name.text, ts.ScriptElementKind.functionElement, getNodeModifiers(node), [getNodeSpan(node)]); + return basicChildItem(node, functionDeclaration.name.text, ts.ScriptElementKind.functionElement); } break; case SyntaxKind.VariableDeclaration: var variableDeclaration = node; - return new ts.NavigationBarItem(variableDeclaration.name.text, ts.ScriptElementKind.variableElement, ts.ScriptElementKindModifier.none, [getNodeSpan(node)]); + return basicChildItem(node, variableDeclaration.name.text, ts.ScriptElementKind.variableElement); case SyntaxKind.Constructor: - return new ts.NavigationBarItem("constructor", ts.ScriptElementKind.constructorImplementationElement, ts.ScriptElementKindModifier.none, [getNodeSpan(node)]); + return basicChildItem(node, "constructor", ts.ScriptElementKind.constructorImplementationElement); } return undefined; } + function basicChildItem(node: Node, name: string, scriptElementKind: string): NavigationBarItem { + return new NavigationBarItem(name, scriptElementKind, getNodeModifiers(node), [getNodeSpan(node)]); + } + function createTopLevelItem(node: Node): ts.NavigationBarItem { switch (node.kind) { case SyntaxKind.SourceFile: From 84c1d03dd2336fcaf48051838e5d209fb2ce3adc Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 18 Sep 2014 16:52:22 -0700 Subject: [PATCH 10/38] Removed duplicate 'getNodeModifiers'. --- .../getScriptLexicalStructureWalker.ts | 16 +----------- src/services/services.ts | 26 +++++++++---------- 2 files changed, 14 insertions(+), 28 deletions(-) diff --git a/src/services/getScriptLexicalStructureWalker.ts b/src/services/getScriptLexicalStructureWalker.ts index 653d2ffaf29..565c580c3b4 100644 --- a/src/services/getScriptLexicalStructureWalker.ts +++ b/src/services/getScriptLexicalStructureWalker.ts @@ -85,7 +85,7 @@ module ts { forEach((functionDeclaration.body).statements, s => s.kind === SyntaxKind.FunctionDeclaration); } - function getItemsWorker(nodes: Node[], createItem: (n: Node) => ts.NavigationBarItem): ts.NavigationBarItem[]{ + function getItemsWorker(nodes: Node[], createItem: (n: Node) => ts.NavigationBarItem): ts.NavigationBarItem[] { var items: ts.NavigationBarItem[] = []; if (!nodes) { @@ -341,20 +341,6 @@ module ts { } } - // TODO: use implementation in services.ts - function getNodeModifiers(node: Node): string { - var flags = node.flags; - var result: string[] = []; - - if (flags & NodeFlags.Private) result.push(ScriptElementKindModifier.privateMemberModifier); - if (flags & NodeFlags.Public) result.push(ScriptElementKindModifier.publicMemberModifier); - if (flags & NodeFlags.Static) result.push(ScriptElementKindModifier.staticModifier); - if (flags & NodeFlags.Export) result.push(ScriptElementKindModifier.exportedModifier); - if (isInAmbientContext(node)) result.push(ScriptElementKindModifier.ambientModifier); - - return result.length > 0 ? result.join(',') : ScriptElementKindModifier.none; - } - function getInnermostModule(node: ModuleDeclaration): ModuleDeclaration { while (node.body.kind === SyntaxKind.ModuleDeclaration) { diff --git a/src/services/services.ts b/src/services/services.ts index 5bb632ba975..8d22c964e09 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1351,6 +1351,19 @@ module ts { } /// Helpers + export function getNodeModifiers(node: Node): string { + var flags = node.flags; + var result: string[] = []; + + if (flags & NodeFlags.Private) result.push(ScriptElementKindModifier.privateMemberModifier); + if (flags & NodeFlags.Public) result.push(ScriptElementKindModifier.publicMemberModifier); + if (flags & NodeFlags.Static) result.push(ScriptElementKindModifier.staticModifier); + if (flags & NodeFlags.Export) result.push(ScriptElementKindModifier.exportedModifier); + if (isInAmbientContext(node)) result.push(ScriptElementKindModifier.ambientModifier); + + return result.length > 0 ? result.join(',') : ScriptElementKindModifier.none; + } + function getTargetLabel(referenceNode: Node, labelName: string): Identifier { while (referenceNode) { if (referenceNode.kind === SyntaxKind.LabeledStatement && (referenceNode).label.text === labelName) { @@ -2198,19 +2211,6 @@ module ts { } } - function getNodeModifiers(node: Node): string { - var flags = node.flags; - var result: string[] = []; - - if (flags & NodeFlags.Private) result.push(ScriptElementKindModifier.privateMemberModifier); - if (flags & NodeFlags.Public) result.push(ScriptElementKindModifier.publicMemberModifier); - if (flags & NodeFlags.Static) result.push(ScriptElementKindModifier.staticModifier); - if (flags & NodeFlags.Export) result.push(ScriptElementKindModifier.exportedModifier); - if (isInAmbientContext(node)) result.push(ScriptElementKindModifier.ambientModifier); - - return result.length > 0 ? result.join(',') : ScriptElementKindModifier.none; - } - /// QuickInfo function getTypeAtPosition(fileName: string, position: number): TypeInfo { synchronizeHostData(); From 7bcab8b616672d16e3e662f73e8bd719e7c6989c Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 19 Sep 2014 12:28:49 -0700 Subject: [PATCH 11/38] Minor edit to test. --- tests/cases/fourslash/scriptLexicalStructureFunctions.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/cases/fourslash/scriptLexicalStructureFunctions.ts b/tests/cases/fourslash/scriptLexicalStructureFunctions.ts index 7723bd0ee68..a42a226c2c0 100644 --- a/tests/cases/fourslash/scriptLexicalStructureFunctions.ts +++ b/tests/cases/fourslash/scriptLexicalStructureFunctions.ts @@ -12,7 +12,7 @@ //// } ////} //// -////{| "itemName": "baz", "kind": "function" |}function baz() { +////{| "itemName": "baz", "kind": "function", "parentName": "" |}function baz() { //// var v = 10; ////} From 01d93b22ba88bc06ff9026f0d94f0047c8576d23 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 19 Sep 2014 13:54:34 -0700 Subject: [PATCH 12/38] External module items now display their base file name in quotes. --- src/compiler/core.ts | 14 ++++++++++++++ src/compiler/parser.ts | 9 +-------- src/services/getScriptLexicalStructureWalker.ts | 8 ++++++-- ...scriptLexicalStructureItemsExternalModules2.ts | 15 +++++++++++++++ 4 files changed, 36 insertions(+), 10 deletions(-) create mode 100644 tests/cases/fourslash/scriptLexicalStructureItemsExternalModules2.ts diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 6bfa537c9f2..e6935afd599 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -521,6 +521,20 @@ module ts { return pathLen > extLen && path.substr(pathLen - extLen, extLen) === extension; } + var supportedExtensions = [".d.ts", ".ts", ".js"]; + export function removeFileExtension(path: string): string { + + for (var i = 0; i < supportedExtensions.length; i++) { + var ext = supportedExtensions[i]; + + if (fileExtensionIs(path, ext)) { + return path.substr(0, path.length - ext.length); + } + } + + return path; + } + export interface ObjectAllocator { getNodeConstructor(kind: SyntaxKind): new () => Node; getSymbolConstructor(): new (flags: SymbolFlags, name: string) => Symbol; diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 4005a000dc8..8a977c8c764 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -17,20 +17,13 @@ module ts { return node; } - var moduleExtensions = [".d.ts", ".ts", ".js"]; - interface ReferenceComments { referencedFiles: FileReference[]; amdDependencies: string[]; } export function getModuleNameFromFilename(filename: string) { - for (var i = 0; i < moduleExtensions.length; i++) { - var ext = moduleExtensions[i]; - var len = filename.length - ext.length; - if (len > 0 && filename.substr(len) === ext) return filename.substr(0, len); - } - return filename; + return removeFileExtension(filename); } export function getSourceFileOfNode(node: Node): SourceFile { diff --git a/src/services/getScriptLexicalStructureWalker.ts b/src/services/getScriptLexicalStructureWalker.ts index 565c580c3b4..6c3de09af67 100644 --- a/src/services/getScriptLexicalStructureWalker.ts +++ b/src/services/getScriptLexicalStructureWalker.ts @@ -195,7 +195,7 @@ module ts { case SyntaxKind.VariableDeclaration: var variableDeclaration = node; return basicChildItem(node, variableDeclaration.name.text, ts.ScriptElementKind.variableElement); - + case SyntaxKind.Constructor: return basicChildItem(node, "constructor", ts.ScriptElementKind.constructorImplementationElement); } @@ -286,7 +286,11 @@ module ts { } hasGlobalNode = true; - return new ts.NavigationBarItem("", + var rootName = isExternalModule(node) ? + "\"" + getBaseFilename(removeFileExtension(normalizePath(node.filename))) + "\"" : + "" + + return new ts.NavigationBarItem(rootName, ts.ScriptElementKind.moduleElement, ts.ScriptElementKindModifier.none, [getNodeSpan(node)], diff --git a/tests/cases/fourslash/scriptLexicalStructureItemsExternalModules2.ts b/tests/cases/fourslash/scriptLexicalStructureItemsExternalModules2.ts new file mode 100644 index 00000000000..b0bf6eb3fa2 --- /dev/null +++ b/tests/cases/fourslash/scriptLexicalStructureItemsExternalModules2.ts @@ -0,0 +1,15 @@ +/// + +// @Filename: test/file.ts +////{| "itemName": "Bar", "kind": "class" |}export class Bar { +//// {| "itemName": "s", "kind": "property", "parentName": "Bar" |}public s: string; +////} +////{| "itemName": "\"file\"", "kind": "module" |} +////{| "itemName": "x", "kind": "var", "parentName": "\"file\"" |} +////export var x: number; + +test.markers().forEach((marker) => { + verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); +}); + +verify.getScriptLexicalStructureListCount(4); // external module node + variable in module + class + property From be373647d0f78d4e78a5866323dac00b8b738a25 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 22 Sep 2014 11:43:52 -0700 Subject: [PATCH 13/38] Addressed CR feedback. --- src/compiler/core.ts | 2 +- .../getScriptLexicalStructureWalker.ts | 24 ++++++++----------- .../scriptLexicalStructureModules.ts | 12 +++++----- 3 files changed, 17 insertions(+), 21 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index e6935afd599..2ca50ae4923 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -522,8 +522,8 @@ module ts { } var supportedExtensions = [".d.ts", ".ts", ".js"]; - export function removeFileExtension(path: string): string { + export function removeFileExtension(path: string): string { for (var i = 0; i < supportedExtensions.length; i++) { var ext = supportedExtensions[i]; diff --git a/src/services/getScriptLexicalStructureWalker.ts b/src/services/getScriptLexicalStructureWalker.ts index 6c3de09af67..7dbfb0fbd14 100644 --- a/src/services/getScriptLexicalStructureWalker.ts +++ b/src/services/getScriptLexicalStructureWalker.ts @@ -88,10 +88,6 @@ module ts { function getItemsWorker(nodes: Node[], createItem: (n: Node) => ts.NavigationBarItem): ts.NavigationBarItem[] { var items: ts.NavigationBarItem[] = []; - if (!nodes) { - return items; - } - var keyToItem: Map = {}; for (var i = 0, n = nodes.length; i < n; i++) { @@ -162,39 +158,39 @@ module ts { case SyntaxKind.GetAccessor: var getAccessor = node; - return basicChildItem(node, getAccessor.name.text, ts.ScriptElementKind.memberGetAccessorElement); + return basicChildItem(node, getAccessor.name.text, ts.ScriptElementKind.memberGetAccessorElement); case SyntaxKind.SetAccessor: var setAccessor = node; - return basicChildItem(node, setAccessor.name.text, ts.ScriptElementKind.memberSetAccessorElement); + return basicChildItem(node, setAccessor.name.text, ts.ScriptElementKind.memberSetAccessorElement); case SyntaxKind.IndexSignature: - return basicChildItem(node, "[]", ts.ScriptElementKind.indexSignatureElement); + return basicChildItem(node, "[]", ts.ScriptElementKind.indexSignatureElement); case SyntaxKind.EnumMember: var enumElement = node; - return basicChildItem(node, enumElement.name.text, ts.ScriptElementKind.memberVariableElement); + return basicChildItem(node, enumElement.name.text, ts.ScriptElementKind.memberVariableElement); case SyntaxKind.CallSignature: - return basicChildItem(node, "()", ts.ScriptElementKind.callSignatureElement); + return basicChildItem(node, "()", ts.ScriptElementKind.callSignatureElement); case SyntaxKind.ConstructSignature: - return basicChildItem(node, "new()", ts.ScriptElementKind.constructSignatureElement); + return basicChildItem(node, "new()", ts.ScriptElementKind.constructSignatureElement); case SyntaxKind.Property: var propertySignature = node; - return basicChildItem(node, propertySignature.name.text, ts.ScriptElementKind.memberVariableElement); + return basicChildItem(node, propertySignature.name.text, ts.ScriptElementKind.memberVariableElement); case SyntaxKind.FunctionDeclaration: var functionDeclaration = node; if (!isTopLevelFunctionDeclaration(functionDeclaration)) { - return basicChildItem(node, functionDeclaration.name.text, ts.ScriptElementKind.functionElement); + return basicChildItem(node, functionDeclaration.name.text, ts.ScriptElementKind.functionElement); } break; case SyntaxKind.VariableDeclaration: var variableDeclaration = node; - return basicChildItem(node, variableDeclaration.name.text, ts.ScriptElementKind.variableElement); + return basicChildItem(node, variableDeclaration.name.text, ts.ScriptElementKind.variableElement); case SyntaxKind.Constructor: return basicChildItem(node, "constructor", ts.ScriptElementKind.constructorImplementationElement); @@ -307,7 +303,7 @@ module ts { // Add the constructor parameters in as children of the class (for property parameters). var nodes: Node[] = constructor - ? (constructor.parameters).concat(node.members) + ? constructor.parameters.concat(node.members) : node.members; var childItems = getItemsWorker(nodes, createChildItem); diff --git a/tests/cases/fourslash/scriptLexicalStructureModules.ts b/tests/cases/fourslash/scriptLexicalStructureModules.ts index 4331e64e0b0..ee0f91cc73c 100644 --- a/tests/cases/fourslash/scriptLexicalStructureModules.ts +++ b/tests/cases/fourslash/scriptLexicalStructureModules.ts @@ -9,29 +9,29 @@ //// ////{| "itemName": "A.B.C", "kind": "module" |} ////module A.B.C { -//// {| "itemName": "x", "kind": "var", "parent": "A.B.C" |} +//// {| "itemName": "x", "kind": "var", "parentName": "A.B.C" |} //// export var x; ////} //// ////{| "itemName": "A.B", "kind": "module" |} ////module A.B { -//// {| "itemName": "y", "kind": "var", "parent": "A.B" |} +//// {| "itemName": "y", "kind": "var", "parentName": "A.B" |} //// export var y; ////} //// ////{| "itemName": "A", "kind": "module" |} ////module A { -//// {| "itemName": "z", "kind": "var", "parent": "A" |} +//// {| "itemName": "z", "kind": "var", "parentName": "A" |} //// export var z; ////} //// ////{| "itemName": "A", "kind": "module" |} ////module A { -//// {| "itemName": "B", "kind": "module", "parent": "E" |} +//// {| "itemName": "B", "kind": "module", "parentName": "E" |} //// module B { -//// {| "itemName": "C", "kind": "module", "parent": "F" |} +//// {| "itemName": "C", "kind": "module", "parentName": "F" |} //// module C { -//// {| "itemName": "x", "kind": "var", "parent": "C" |} +//// {| "itemName": "x", "kind": "var", "parentName": "C" |} //// declare var x; //// } //// } From 2c99556b3122bec68993d09b05156f00459f60d0 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 23 Sep 2014 08:18:37 -0700 Subject: [PATCH 14/38] Use push.apply to push multiple elements. --- src/services/getScriptLexicalStructureWalker.ts | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/services/getScriptLexicalStructureWalker.ts b/src/services/getScriptLexicalStructureWalker.ts index 7dbfb0fbd14..7013460598f 100644 --- a/src/services/getScriptLexicalStructureWalker.ts +++ b/src/services/getScriptLexicalStructureWalker.ts @@ -31,9 +31,7 @@ module ts { childNodes.push(node); } else if (node.kind === SyntaxKind.VariableStatement) { - forEach((node).declarations, declaration => { - childNodes.push(declaration); - }); + childNodes.push.apply(childNodes, (node).declarations); } } From a98cca77234583adc13ae7e0b40ba4e5baea9d99 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Thu, 25 Sep 2014 13:10:04 -0700 Subject: [PATCH 15/38] Properly support string-literal property names and escape external module names. --- src/compiler/core.ts | 23 +++++++++ src/compiler/emitter.ts | 23 --------- .../getScriptLexicalStructureWalker.ts | 50 +++++++++++++------ ...ptLexicalStructureItemsExternalModules3.ts | 15 ++++++ .../scriptLexicalStructureModules.ts | 2 +- ...icalStructureMultilineStringIdentifiers.ts | 40 +++++++++++++++ 6 files changed, 113 insertions(+), 40 deletions(-) create mode 100644 tests/cases/fourslash/scriptLexicalStructureItemsExternalModules3.ts create mode 100644 tests/cases/fourslash/scriptLexicalStructureMultilineStringIdentifiers.ts diff --git a/src/compiler/core.ts b/src/compiler/core.ts index 2ca50ae4923..d95bc4f89ce 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -535,6 +535,29 @@ module ts { return path; } + var escapedCharsRegExp = /[\t\v\f\b\0\r\n\"\\\u2028\u2029\u0085]/g; + var escapedCharsMap: Map = { + "\t": "\\t", + "\v": "\\v", + "\f": "\\f", + "\b": "\\b", + "\0": "\\0", + "\r": "\\r", + "\n": "\\n", + "\"": "\\\"", + "\u2028": "\\u2028", // lineSeparator + "\u2029": "\\u2029", // paragraphSeparator + "\u0085": "\\u0085" // nextLine + }; + + /** NOTE: This *does not* support the full escape characters, it only supports the subset that can be used in file names + * or string literals. If the information encoded in the map changes, this needs to be revisited. */ + export function escapeString(s: string): string { + return escapedCharsRegExp.test(s) ? s.replace(escapedCharsRegExp, c => { + return escapedCharsMap[c] || c; + }) : s; + } + export interface ObjectAllocator { getNodeConstructor(kind: SyntaxKind): new () => Node; getSymbolConstructor(): new (flags: SymbolFlags, name: string) => Symbol; diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 74b0533e5b4..793660763a9 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -591,21 +591,6 @@ module ts { recordSourceMapSpan(comment.end); } - var escapedCharsRegExp = /[\t\v\f\b\0\r\n\"\u2028\u2029\u0085]/g; - var escapedCharsMap: Map = { - "\t": "\\t", - "\v": "\\v", - "\f": "\\f", - "\b": "\\b", - "\0": "\\0", - "\r": "\\r", - "\n": "\\n", - "\"": "\\\"", - "\u2028": "\\u2028", // lineSeparator - "\u2029": "\\u2029", // paragraphSeparator - "\u0085": "\\u0085" // nextLine - }; - function serializeSourceMapContents(version: number, file: string, sourceRoot: string, sources: string[], names: string[], mappings: string) { if (typeof JSON !== "undefined") { return JSON.stringify({ @@ -620,14 +605,6 @@ module ts { return "{\"version\":" + version + ",\"file\":\"" + escapeString(file) + "\",\"sourceRoot\":\"" + escapeString(sourceRoot) + "\",\"sources\":[" + serializeStringArray(sources) + "],\"names\":[" + serializeStringArray(names) + "],\"mappings\":\"" + escapeString(mappings) + "\"}"; - /** This does not support the full escape characters, it only supports the subset that can be used in file names - * or string literals. If the information encoded in the map changes, this needs to be revisited. */ - function escapeString(s: string): string { - return escapedCharsRegExp.test(s) ? s.replace(escapedCharsRegExp, c => { - return escapedCharsMap[c] || c; - }) : s; - } - function serializeStringArray(list: string[]): string { var output = ""; for (var i = 0, n = list.length; i < n; i++) { diff --git a/src/services/getScriptLexicalStructureWalker.ts b/src/services/getScriptLexicalStructureWalker.ts index 7013460598f..c6158bfead7 100644 --- a/src/services/getScriptLexicalStructureWalker.ts +++ b/src/services/getScriptLexicalStructureWalker.ts @@ -151,23 +151,23 @@ module ts { return basicChildItem(node, parameter.name.text, ts.ScriptElementKind.memberVariableElement); case SyntaxKind.Method: - var memberFunction = node; - return basicChildItem(node, memberFunction.name.text, ts.ScriptElementKind.memberFunctionElement); + var method = node; + return basicChildItem(node, getPropertyText(method.name), ts.ScriptElementKind.memberFunctionElement); case SyntaxKind.GetAccessor: var getAccessor = node; - return basicChildItem(node, getAccessor.name.text, ts.ScriptElementKind.memberGetAccessorElement); + return basicChildItem(node, getPropertyText(getAccessor.name), ts.ScriptElementKind.memberGetAccessorElement); case SyntaxKind.SetAccessor: var setAccessor = node; - return basicChildItem(node, setAccessor.name.text, ts.ScriptElementKind.memberSetAccessorElement); + return basicChildItem(node, getPropertyText(setAccessor.name), ts.ScriptElementKind.memberSetAccessorElement); case SyntaxKind.IndexSignature: return basicChildItem(node, "[]", ts.ScriptElementKind.indexSignatureElement); case SyntaxKind.EnumMember: - var enumElement = node; - return basicChildItem(node, enumElement.name.text, ts.ScriptElementKind.memberVariableElement); + var enumMember = node; + return basicChildItem(node, getPropertyText(enumMember.name), ts.ScriptElementKind.memberVariableElement); case SyntaxKind.CallSignature: return basicChildItem(node, "()", ts.ScriptElementKind.callSignatureElement); @@ -176,8 +176,8 @@ module ts { return basicChildItem(node, "new()", ts.ScriptElementKind.constructSignatureElement); case SyntaxKind.Property: - var propertySignature = node; - return basicChildItem(node, propertySignature.name.text, ts.ScriptElementKind.memberVariableElement); + var property = node; + return basicChildItem(node, getPropertyText(property.name), ts.ScriptElementKind.memberVariableElement); case SyntaxKind.FunctionDeclaration: var functionDeclaration = node; @@ -224,13 +224,13 @@ module ts { return undefined; - function getModuleNames(moduleDeclaration: ModuleDeclaration): string[]{ + function getModuleName(moduleDeclaration: ModuleDeclaration): string { // We want to maintain quotation marks. if (moduleDeclaration.name.kind === SyntaxKind.StringLiteral) { - return [getSourceTextOfNode(moduleDeclaration.name)]; + return getPropertyText(moduleDeclaration.name); } - // Otherwise, we need to aggregate each identifier of the qualified name. + // Otherwise, we need to aggregate each identifier to build up the qualified name. var result: string[] = []; result.push(moduleDeclaration.name.text); @@ -241,15 +241,15 @@ module ts { result.push(moduleDeclaration.name.text); } - return result; + return result.join("."); } function createModuleItem(node: ModuleDeclaration): NavigationBarItem { - var moduleNames = getModuleNames(node); + var moduleName = getModuleName(node); var childItems = getItemsWorker(getChildNodes((getInnermostModule(node).body).statements), createChildItem); - return new ts.NavigationBarItem(moduleNames.join("."), + return new ts.NavigationBarItem(moduleName, ts.ScriptElementKind.moduleElement, getNodeModifiers(node), [getNodeSpan(node)], @@ -281,7 +281,7 @@ module ts { hasGlobalNode = true; var rootName = isExternalModule(node) ? - "\"" + getBaseFilename(removeFileExtension(normalizePath(node.filename))) + "\"" : + "\"" + escapeString(getBaseFilename(removeFileExtension(normalizePath(node.filename)))) + "\"" : "" return new ts.NavigationBarItem(rootName, @@ -340,7 +340,6 @@ module ts { } function getInnermostModule(node: ModuleDeclaration): ModuleDeclaration { - while (node.body.kind === SyntaxKind.ModuleDeclaration) { node = node.body; } @@ -351,5 +350,24 @@ module ts { function getNodeSpan(node: Node) { return TypeScript.TextSpan.fromBounds(node.getStart(), node.getEnd()); } + + function getPropertyText(node: Node): string { + if (node.kind === SyntaxKind.Identifier) { + return (node).text; + } + + if (node.kind === SyntaxKind.StringLiteral) { + // normalize the quotes and remove all '\{newline}'s from the original text. + var text = getSourceTextOfNodeFromSourceText(sourceFile.text, node); + text = text.substring(1, text.length - 1).replace(/\\\r?\n/g, ""); + return "\"" + text + "\""; + } + + if (node.kind === SyntaxKind.NumericLiteral) { + return (node).text; + } + + Debug.fail("getPropertyText given a property that is neither an identifier nor a literal expression."); + } } } \ No newline at end of file diff --git a/tests/cases/fourslash/scriptLexicalStructureItemsExternalModules3.ts b/tests/cases/fourslash/scriptLexicalStructureItemsExternalModules3.ts new file mode 100644 index 00000000000..9ef49e38776 --- /dev/null +++ b/tests/cases/fourslash/scriptLexicalStructureItemsExternalModules3.ts @@ -0,0 +1,15 @@ +/// + +// @Filename: test/my fil"e.ts +////{| "itemName": "Bar", "kind": "class" |}export class Bar { +//// {| "itemName": "s", "kind": "property", "parentName": "Bar" |}public s: string; +////} +////{| "itemName": "\"my fil\\\"e\"", "kind": "module" |} +////{| "itemName": "x", "kind": "var", "parentName": "\"file\"" |} +////export var x: number; + +test.markers().forEach((marker) => { + verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); +}); + +verify.getScriptLexicalStructureListCount(4); // external module node + variable in module + class + property diff --git a/tests/cases/fourslash/scriptLexicalStructureModules.ts b/tests/cases/fourslash/scriptLexicalStructureModules.ts index ee0f91cc73c..602cc170dee 100644 --- a/tests/cases/fourslash/scriptLexicalStructureModules.ts +++ b/tests/cases/fourslash/scriptLexicalStructureModules.ts @@ -3,7 +3,7 @@ ////declare module "X.Y.Z" { ////} //// -////{| "itemName": "'X2.Y2.Z2'", "kind": "module" |} +////{| "itemName": "\"X2.Y2.Z2\"", "kind": "module" |} ////declare module 'X2.Y2.Z2' { ////} //// diff --git a/tests/cases/fourslash/scriptLexicalStructureMultilineStringIdentifiers.ts b/tests/cases/fourslash/scriptLexicalStructureMultilineStringIdentifiers.ts new file mode 100644 index 00000000000..e0a44ba2685 --- /dev/null +++ b/tests/cases/fourslash/scriptLexicalStructureMultilineStringIdentifiers.ts @@ -0,0 +1,40 @@ + +////{| "itemName": "\"Multiline\\r\\nMadness\"", "kind": "module" |} +////declare module "Multiline\r\nMadness" { +////} +//// +////{| "itemName": "\"MultilineMadness\"", "kind": "module" |} +////declare module "Multiline\ +////Madness" { +////} +////declare module "MultilineMadness" {} +//// +////{| "itemName": "Foo", "kind": "interface" |} +////interface Foo { +//// {| "itemName": "\"a1\\\\\\r\\nb\"", "kind": "property", "parentName": "Foo" |} +//// "a1\\\r\nb"; +//// {| "itemName": "\"a2 b\"", "kind": "method", "parentName": "Foo" |} +//// "a2\ +//// \ +//// b"(): Foo; +////} +//// +////{| "itemName": "Bar", "kind": "class" |} +////class Bar implements Foo { +//// {| "itemName": "\"a1\\\\\\r\\nb\"", "kind": "property", "parentName": "Bar" |} +//// 'a1\\\r\nb': Foo; +//// +//// {| "itemName": "\"a2 b\"", "kind": "method", "parentName": "Bar" |} +//// 'a2\ +//// \ +//// b'(): Foo { +//// return this; +//// } +////} + + +test.markers().forEach((marker) => { + verify.getScriptLexicalStructureListContains(marker.data.itemName, marker.data.kind, marker.fileName, marker.data.parentName); +}); + +verify.getScriptLexicalStructureListCount(8); // interface w/ 2 properties, class w/ 2 properties, 1 merged module, and 1 independent module From a87685b0d2a73d97bcc516e1a1cb112d0b3268fc Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Mon, 29 Sep 2014 17:58:58 -0700 Subject: [PATCH 16/38] Simply use source text from now on. --- .../getScriptLexicalStructureWalker.ts | 37 ++++++------------- 1 file changed, 11 insertions(+), 26 deletions(-) diff --git a/src/services/getScriptLexicalStructureWalker.ts b/src/services/getScriptLexicalStructureWalker.ts index c6158bfead7..bafc7c5dd16 100644 --- a/src/services/getScriptLexicalStructureWalker.ts +++ b/src/services/getScriptLexicalStructureWalker.ts @@ -148,26 +148,26 @@ module ts { if ((node.flags & NodeFlags.Modifier) === 0) { return undefined; } - return basicChildItem(node, parameter.name.text, ts.ScriptElementKind.memberVariableElement); + return basicChildItem(node, getSourceText(parameter.name), ts.ScriptElementKind.memberVariableElement); case SyntaxKind.Method: var method = node; - return basicChildItem(node, getPropertyText(method.name), ts.ScriptElementKind.memberFunctionElement); + return basicChildItem(node, getSourceText(method.name), ts.ScriptElementKind.memberFunctionElement); case SyntaxKind.GetAccessor: var getAccessor = node; - return basicChildItem(node, getPropertyText(getAccessor.name), ts.ScriptElementKind.memberGetAccessorElement); + return basicChildItem(node, getSourceText(getAccessor.name), ts.ScriptElementKind.memberGetAccessorElement); case SyntaxKind.SetAccessor: var setAccessor = node; - return basicChildItem(node, getPropertyText(setAccessor.name), ts.ScriptElementKind.memberSetAccessorElement); + return basicChildItem(node, getSourceText(setAccessor.name), ts.ScriptElementKind.memberSetAccessorElement); case SyntaxKind.IndexSignature: return basicChildItem(node, "[]", ts.ScriptElementKind.indexSignatureElement); case SyntaxKind.EnumMember: var enumMember = node; - return basicChildItem(node, getPropertyText(enumMember.name), ts.ScriptElementKind.memberVariableElement); + return basicChildItem(node, getSourceText(enumMember.name), ts.ScriptElementKind.memberVariableElement); case SyntaxKind.CallSignature: return basicChildItem(node, "()", ts.ScriptElementKind.callSignatureElement); @@ -177,18 +177,18 @@ module ts { case SyntaxKind.Property: var property = node; - return basicChildItem(node, getPropertyText(property.name), ts.ScriptElementKind.memberVariableElement); + return basicChildItem(node, getSourceText(property.name), ts.ScriptElementKind.memberVariableElement); case SyntaxKind.FunctionDeclaration: var functionDeclaration = node; if (!isTopLevelFunctionDeclaration(functionDeclaration)) { - return basicChildItem(node, functionDeclaration.name.text, ts.ScriptElementKind.functionElement); + return basicChildItem(node, getSourceText(functionDeclaration.name), ts.ScriptElementKind.functionElement); } break; case SyntaxKind.VariableDeclaration: var variableDeclaration = node; - return basicChildItem(node, variableDeclaration.name.text, ts.ScriptElementKind.variableElement); + return basicChildItem(node, getSourceText(variableDeclaration.name), ts.ScriptElementKind.variableElement); case SyntaxKind.Constructor: return basicChildItem(node, "constructor", ts.ScriptElementKind.constructorImplementationElement); @@ -227,7 +227,7 @@ module ts { function getModuleName(moduleDeclaration: ModuleDeclaration): string { // We want to maintain quotation marks. if (moduleDeclaration.name.kind === SyntaxKind.StringLiteral) { - return getPropertyText(moduleDeclaration.name); + return getSourceText(moduleDeclaration.name); } // Otherwise, we need to aggregate each identifier to build up the qualified name. @@ -351,23 +351,8 @@ module ts { return TypeScript.TextSpan.fromBounds(node.getStart(), node.getEnd()); } - function getPropertyText(node: Node): string { - if (node.kind === SyntaxKind.Identifier) { - return (node).text; - } - - if (node.kind === SyntaxKind.StringLiteral) { - // normalize the quotes and remove all '\{newline}'s from the original text. - var text = getSourceTextOfNodeFromSourceText(sourceFile.text, node); - text = text.substring(1, text.length - 1).replace(/\\\r?\n/g, ""); - return "\"" + text + "\""; - } - - if (node.kind === SyntaxKind.NumericLiteral) { - return (node).text; - } - - Debug.fail("getPropertyText given a property that is neither an identifier nor a literal expression."); + function getSourceText(node: Node): string { + return getSourceTextOfNodeFromSourceText(sourceFile.text, node); } } } \ No newline at end of file From 379f6ce75857524a652b2e3e2fb5d73d29909526 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Tue, 30 Sep 2014 11:58:56 -0700 Subject: [PATCH 17/38] Minor cleanup, added getScriptLexicalStructureWalker.ts Jakefile. --- Jakefile | 1 + .../scriptLexicalStructureItemsContainsNoAnonymousFunctions.ts | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/Jakefile b/Jakefile index 0bdb573914f..553372f43ec 100644 --- a/Jakefile +++ b/Jakefile @@ -54,6 +54,7 @@ var servicesSources = [ }).concat([ "services.ts", "shims.ts", + "getScriptLexicalStructureWalker.ts" ].map(function (f) { return path.join(servicesDirectory, f); })); diff --git a/tests/cases/fourslash/scriptLexicalStructureItemsContainsNoAnonymousFunctions.ts b/tests/cases/fourslash/scriptLexicalStructureItemsContainsNoAnonymousFunctions.ts index 2c8ef5825db..531575d6d10 100644 --- a/tests/cases/fourslash/scriptLexicalStructureItemsContainsNoAnonymousFunctions.ts +++ b/tests/cases/fourslash/scriptLexicalStructureItemsContainsNoAnonymousFunctions.ts @@ -28,7 +28,7 @@ ////} ////function bar() { ////} -debugger; + goTo.marker("file1"); verify.getScriptLexicalStructureListCount(0); From a6e991a3db04ca8b77e52aa323d1e1b528d9bced Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Wed, 1 Oct 2014 12:44:17 -0700 Subject: [PATCH 18/38] Fixed bug where value-space identifiers got classified as interfaces when sharing the same name as an interface. --- src/compiler/checker.ts | 86 ----------------- src/compiler/parser.ts | 94 +++++++++++++++++++ src/harness/fourslash.ts | 6 +- src/services/services.ts | 16 ++-- .../fourslash/semanticClassification1.ts | 1 - .../fourslash/semanticClassification2.ts | 11 +++ 6 files changed, 117 insertions(+), 97 deletions(-) create mode 100644 tests/cases/fourslash/semanticClassification2.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 99b387dd18c..6b288ccbae7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -7077,23 +7077,6 @@ module ts { return mapToArray(symbols); } - // True if the given identifier is the name of a type declaration node (class, interface, enum, type parameter, etc) - function isTypeDeclarationName(name: Node): boolean { - return name.kind == SyntaxKind.Identifier && - isTypeDeclaration(name.parent) && - (name.parent).name === name; - } - - function isTypeDeclaration(node: Node): boolean { - switch (node.kind) { - case SyntaxKind.TypeParameter: - case SyntaxKind.ClassDeclaration: - case SyntaxKind.InterfaceDeclaration: - case SyntaxKind.EnumDeclaration: - return true; - } - } - // True if the given identifier is part of a type reference function isTypeReferenceIdentifier(entityName: EntityName): boolean { var node: Node = entityName; @@ -7172,75 +7155,6 @@ module ts { return false; } - function isTypeNode(node: Node): boolean { - if (node.kind >= SyntaxKind.FirstTypeNode && node.kind <= SyntaxKind.LastTypeNode) { - return true; - } - - switch (node.kind) { - case SyntaxKind.AnyKeyword: - case SyntaxKind.NumberKeyword: - case SyntaxKind.StringKeyword: - case SyntaxKind.BooleanKeyword: - return true; - case SyntaxKind.VoidKeyword: - return node.parent.kind !== SyntaxKind.PrefixOperator; - case SyntaxKind.StringLiteral: - // Specialized signatures can have string literals as their parameters' type names - return node.parent.kind === SyntaxKind.Parameter; - // Identifiers and qualified names may be type nodes, depending on their context. Climb - // above them to find the lowest container - case SyntaxKind.Identifier: - // If the identifier is the RHS of a qualified name, then it's a type iff its parent is. - if (node.parent.kind === SyntaxKind.QualifiedName) { - node = node.parent; - } - // Fall through - case SyntaxKind.QualifiedName: - // At this point, node is either a qualified name or an identifier - var parent = node.parent; - if (parent.kind === SyntaxKind.TypeQuery) { - return false; - } - // Do not recursively call isTypeNode on the parent. In the example: - // - // var a: A.B.C; - // - // Calling isTypeNode would consider the qualified name A.B a type node. Only C or - // A.B.C is a type node. - if (parent.kind >= SyntaxKind.FirstTypeNode && parent.kind <= SyntaxKind.LastTypeNode) { - return true; - } - switch (parent.kind) { - case SyntaxKind.TypeParameter: - return node === (parent).constraint; - case SyntaxKind.Property: - case SyntaxKind.Parameter: - case SyntaxKind.VariableDeclaration: - return node === (parent).type; - case SyntaxKind.FunctionDeclaration: - case SyntaxKind.FunctionExpression: - case SyntaxKind.ArrowFunction: - case SyntaxKind.Constructor: - case SyntaxKind.Method: - case SyntaxKind.GetAccessor: - case SyntaxKind.SetAccessor: - return node === (parent).type; - case SyntaxKind.CallSignature: - case SyntaxKind.ConstructSignature: - case SyntaxKind.IndexSignature: - return node === (parent).type; - case SyntaxKind.TypeAssertion: - return node === (parent).type; - case SyntaxKind.CallExpression: - case SyntaxKind.NewExpression: - return (parent).typeArguments.indexOf(node) >= 0; - } - } - - return false; - } - function isInRightSideOfImportOrExportAssignment(node: EntityName) { while (node.parent.kind === SyntaxKind.QualifiedName) { node = node.parent; diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index b06326f6925..6b8b857d476 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -402,6 +402,100 @@ module ts { return false; } + /** + * Note: this function only works when given a node with valid parent pointers. + */ + export function isTypeNode(node: Node): boolean { + if (node.kind >= SyntaxKind.FirstTypeNode && node.kind <= SyntaxKind.LastTypeNode) { + return true; + } + + switch (node.kind) { + case SyntaxKind.AnyKeyword: + case SyntaxKind.NumberKeyword: + case SyntaxKind.StringKeyword: + case SyntaxKind.BooleanKeyword: + return true; + case SyntaxKind.VoidKeyword: + return node.parent.kind !== SyntaxKind.PrefixOperator; + case SyntaxKind.StringLiteral: + // Specialized signatures can have string literals as their parameters' type names + return node.parent.kind === SyntaxKind.Parameter; + // Identifiers and qualified names may be type nodes, depending on their context. Climb + // above them to find the lowest container + case SyntaxKind.Identifier: + // If the identifier is the RHS of a qualified name, then it's a type iff its parent is. + if (node.parent.kind === SyntaxKind.QualifiedName) { + node = node.parent; + } + // Fall through + case SyntaxKind.QualifiedName: + // At this point, node is either a qualified name or an identifier + var parent = node.parent; + if (parent.kind === SyntaxKind.TypeQuery) { + return false; + } + // Do not recursively call isTypeNode on the parent. In the example: + // + // var a: A.B.C; + // + // Calling isTypeNode would consider the qualified name A.B a type node. Only C or + // A.B.C is a type node. + if (parent.kind >= SyntaxKind.FirstTypeNode && parent.kind <= SyntaxKind.LastTypeNode) { + return true; + } + switch (parent.kind) { + case SyntaxKind.TypeParameter: + return node === (parent).constraint; + case SyntaxKind.Property: + case SyntaxKind.Parameter: + case SyntaxKind.VariableDeclaration: + return node === (parent).type; + case SyntaxKind.FunctionDeclaration: + case SyntaxKind.FunctionExpression: + case SyntaxKind.ArrowFunction: + case SyntaxKind.Constructor: + case SyntaxKind.Method: + case SyntaxKind.GetAccessor: + case SyntaxKind.SetAccessor: + return node === (parent).type; + case SyntaxKind.CallSignature: + case SyntaxKind.ConstructSignature: + case SyntaxKind.IndexSignature: + return node === (parent).type; + case SyntaxKind.TypeAssertion: + return node === (parent).type; + case SyntaxKind.CallExpression: + case SyntaxKind.NewExpression: + return (parent).typeArguments.indexOf(node) >= 0; + } + } + + return false; + } + + /** + * Note: this function only works when given a node with valid parent pointers. + * + * returns true if the given identifier is the name of a type declaration node (class, interface, enum, type parameter, etc) + */ + export function isTypeDeclarationName(name: Node): boolean { + return name.kind == SyntaxKind.Identifier && + isTypeDeclaration(name.parent) && + (name.parent).name === name; + } + + + export function isTypeDeclaration(node: Node): boolean { + switch (node.kind) { + case SyntaxKind.TypeParameter: + case SyntaxKind.ClassDeclaration: + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.EnumDeclaration: + return true; + } + } + export function getContainingFunction(node: Node): SignatureDeclaration { while (true) { node = node.parent; diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index c264c59348f..228648f04bb 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -1582,7 +1582,7 @@ module FourSlash { private verifyClassifications(expected: { classificationType: string; text: string }[], actual: ts.ClassifiedSpan[]) { if (actual.length !== expected.length) { - this.raiseError('verifySyntacticClassification failed - expected total classifications to be ' + expected.length + ', but was ' + actual.length); + this.raiseError('verifyClassifications failed - expected total classifications to be ' + expected.length + ', but was ' + actual.length); } for (var i = 0; i < expected.length; i++) { @@ -1591,7 +1591,7 @@ module FourSlash { var expectedType: string = (ts.ClassificationTypeNames)[expectedClassification.classificationType]; if (expectedType !== actualClassification.classificationType) { - this.raiseError('verifySyntacticClassification failed - expected classifications type to be ' + + this.raiseError('verifyClassifications failed - expected classifications type to be ' + expectedType + ', but was ' + actualClassification.classificationType); } @@ -1599,7 +1599,7 @@ module FourSlash { var actualSpan = actualClassification.textSpan; var actualText = this.activeFile.content.substr(actualSpan.start(), actualSpan.length()); if (expectedClassification.text !== actualText) { - this.raiseError('verifySyntacticClassification failed - expected classificatied text to be ' + + this.raiseError('verifyClassifications failed - expected classificatied text to be ' + expectedClassification.text + ', but was ' + actualText); } diff --git a/src/services/services.ts b/src/services/services.ts index e2089e0ade7..e1bd0feefb9 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -4034,7 +4034,7 @@ module ts { return result; - function classifySymbol(symbol: Symbol) { + function classifySymbol(symbol: Symbol, isInTypePosition: boolean) { var flags = symbol.getFlags(); if (flags & SymbolFlags.Class) { @@ -4043,14 +4043,16 @@ module ts { else if (flags & SymbolFlags.Enum) { return ClassificationTypeNames.enumName; } - else if (flags & SymbolFlags.Interface) { - return ClassificationTypeNames.interfaceName; - } else if (flags & SymbolFlags.Module) { return ClassificationTypeNames.moduleName; } - else if (flags & SymbolFlags.TypeParameter) { - return ClassificationTypeNames.typeParameterName; + else if (isInTypePosition) { + if (flags & SymbolFlags.Interface) { + return ClassificationTypeNames.interfaceName; + } + else if (flags & SymbolFlags.TypeParameter) { + return ClassificationTypeNames.typeParameterName; + } } } @@ -4060,7 +4062,7 @@ module ts { if (node.kind === SyntaxKind.Identifier && node.getWidth() > 0) { var symbol = typeInfoResolver.getSymbolInfo(node); if (symbol) { - var type = classifySymbol(symbol); + var type = classifySymbol(symbol, isTypeNode(node) || isTypeDeclarationName(node)); if (type) { result.push({ textSpan: new TypeScript.TextSpan(node.getStart(), node.getWidth()), diff --git a/tests/cases/fourslash/semanticClassification1.ts b/tests/cases/fourslash/semanticClassification1.ts index 0a0cc68250e..ad9e88ea842 100644 --- a/tests/cases/fourslash/semanticClassification1.ts +++ b/tests/cases/fourslash/semanticClassification1.ts @@ -6,7 +6,6 @@ //// } //// interface X extends M.I { } -debugger; var c = classification; verify.semanticClassificationsAre( c.moduleName("M"), c.interfaceName("I"), c.interfaceName("X"), c.moduleName("M"), c.interfaceName("I")); diff --git a/tests/cases/fourslash/semanticClassification2.ts b/tests/cases/fourslash/semanticClassification2.ts new file mode 100644 index 00000000000..810636dba3e --- /dev/null +++ b/tests/cases/fourslash/semanticClassification2.ts @@ -0,0 +1,11 @@ +/// + +//// interface Thing { +//// toExponential(): number; +//// } +//// +//// var Thing = 0; +//// Thing.toExponential(); + +var c = classification; +verify.semanticClassificationsAre(c.interfaceName("Thing")); \ No newline at end of file From 12e1566af15d232a4d2fddeb6479f55356df73a2 Mon Sep 17 00:00:00 2001 From: ChrisBubernak Date: Thu, 2 Oct 2014 16:02:29 -0700 Subject: [PATCH 19/38] First changes to checker for this fix --- src/compiler/checker.ts | 47 ++++++++++++++++--- .../diagnosticInformationMap.generated.ts | 2 + src/compiler/diagnosticMessages.json | 8 ++++ 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index cf35c1c02f5..bcd0adfb40d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5022,12 +5022,16 @@ module ts { if (leftType.flags & (TypeFlags.Undefined | TypeFlags.Null)) leftType = rightType; if (rightType.flags & (TypeFlags.Undefined | TypeFlags.Null)) rightType = leftType; - var leftOk = checkArithmeticOperandType(node.left, leftType, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type); - var rightOk = checkArithmeticOperandType(node.right, rightType, Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type); - if (leftOk && rightOk) { - checkAssignmentOperator(numberType); - } - + var boolean = typeToString(booleanType); + if (typeToString(leftType) === boolean && typeToString(rightType) === boolean) { + error(node, Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_1, tokenToString(node.operator), preferredBooleanOperator(node.operator)); + } else { + var leftOk = checkArithmeticOperandType(node.left, leftType, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type); + var rightOk = checkArithmeticOperandType(node.right, rightType, Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type); + if (leftOk && rightOk) { + checkAssignmentOperator(numberType); + } + } return numberType; case SyntaxKind.PlusToken: case SyntaxKind.PlusEqualsToken: @@ -5091,6 +5095,37 @@ module ts { return rightType; } + function preferredBooleanOperator(operator: any): string { + var message = ""; + var suggestion:SyntaxKind; + switch (operator) { + case SyntaxKind.BarToken: + suggestion = SyntaxKind.BarBarToken; + break; + case SyntaxKind.CaretToken: + suggestion = SyntaxKind.ExclamationEqualsEqualsToken; + break; + case SyntaxKind.AmpersandToken: + suggestion = SyntaxKind.AmpersandAmpersandToken; + break; + case SyntaxKind.CaretEqualsToken: + suggestion = SyntaxKind.CaretEqualsToken; + break; + case SyntaxKind.BarEqualsToken: + suggestion = SyntaxKind.BarEqualsToken; + break; + case SyntaxKind.AmpersandEqualsToken: + suggestion = SyntaxKind.AmpersandEqualsToken; + break; + } + if (suggestion !== undefined) { + return "Consider using " + tokenToString(suggestion) + "."; + //message = createCompilerDiagnostic(Diagnostics.Consider_using_0_instead, tokenToString(suggestion)); + //message = message(node, Diagnostics.Consider_using_0_instead, tokenToString(suggestion)); + } + return message; + } + function checkAssignmentOperator(valueType: Type): void { if (fullTypeCheck && operator >= SyntaxKind.FirstAssignment && operator <= SyntaxKind.LastAssignment) { // TypeScript 1.0 spec (April 2014): 4.17 diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index ba6f742c4c1..e4889cd5741 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -260,6 +260,7 @@ module ts { Property_0_is_protected_in_type_1_but_public_in_type_2: { code: 2444, category: DiagnosticCategory.Error, key: "Property '{0}' is protected in type '{1}' but public in type '{2}'." }, Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses: { code: 2445, category: DiagnosticCategory.Error, key: "Property '{0}' is protected and only accessible within class '{1}' and its subclasses." }, Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1: { code: 2446, category: DiagnosticCategory.Error, key: "Property '{0}' is protected and only accessible through an instance of class '{1}'." }, + The_0_operator_is_not_allowed_for_boolean_types_1: { code: 2447, category: DiagnosticCategory.Error, key: "The '{0}' operator is not allowed for boolean types {1}." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: { code: 4001, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using name '{1}' from private module '{2}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, @@ -353,6 +354,7 @@ module ts { Specifies_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations: { code: 6004, category: DiagnosticCategory.Message, key: "Specifies the location where debugger should locate TypeScript files instead of source locations." }, Watch_input_files: { code: 6005, category: DiagnosticCategory.Message, key: "Watch input files." }, Redirect_output_structure_to_the_directory: { code: 6006, category: DiagnosticCategory.Message, key: "Redirect output structure to the directory." }, + Consider_using_0_instead: { code: 6007, category: DiagnosticCategory.Message, key: "Consider using '{0}' instead." }, Do_not_emit_comments_to_output: { code: 6009, category: DiagnosticCategory.Message, key: "Do not emit comments to output." }, Specify_ECMAScript_target_version_Colon_ES3_default_or_ES5: { code: 6015, category: DiagnosticCategory.Message, key: "Specify ECMAScript target version: 'ES3' (default), or 'ES5'" }, Specify_module_code_generation_Colon_commonjs_or_amd: { code: 6016, category: DiagnosticCategory.Message, key: "Specify module code generation: 'commonjs' or 'amd'" }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 0480cd3000c..7cce4be878b 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1032,6 +1032,10 @@ "category": "Error", "code": 2446 }, + "The '{0}' operator is not allowed for boolean types {1}.": { + "category": "Error", + "code": 2447 + }, "Import declaration '{0}' is using private name '{1}'.": { "category": "Error", @@ -1407,6 +1411,10 @@ "category": "Message", "code": 6006 }, + "Consider using '{0}' instead.": { + "category": "Message", + "code": 6007 + }, "Do not emit comments to output.": { "category": "Message", "code": 6009 From 183bed1bb8b19ff1138ec1f2780ef7c7f5a0a62d Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 2 Oct 2014 17:35:48 -0700 Subject: [PATCH 20/38] Specify which outlining spans should auto-collapse if the user choose "collapse to definitions". --- src/compiler/parser.ts | 2 +- src/services/outliningElementsCollector.ts | 22 +++++++++++++++++----- 2 files changed, 18 insertions(+), 6 deletions(-) diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index b9865772c06..5318e679c4e 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -467,7 +467,7 @@ module ts { return node === (parent).type; case SyntaxKind.CallExpression: case SyntaxKind.NewExpression: - return (parent).typeArguments.indexOf(node) >= 0; + return (parent).typeArguments && (parent).typeArguments.indexOf(node) >= 0; } } diff --git a/src/services/outliningElementsCollector.ts b/src/services/outliningElementsCollector.ts index 134508bc067..c9a513ee2aa 100644 --- a/src/services/outliningElementsCollector.ts +++ b/src/services/outliningElementsCollector.ts @@ -34,18 +34,30 @@ module ts { export function collectElements(sourceFile: SourceFile): OutliningSpan[] { var elements: OutliningSpan[] = []; - function addOutlineRange(hintSpanNode: Node, startElement: Node, endElement: Node) { + function addOutliningSpan(hintSpanNode: Node, startElement: Node, endElement: Node, autoCollapse: boolean) { if (hintSpanNode && startElement && endElement) { var span: OutliningSpan = { textSpan: TypeScript.TextSpan.fromBounds(startElement.pos, endElement.end), hintSpan: TypeScript.TextSpan.fromBounds(hintSpanNode.getStart(), hintSpanNode.end), bannerText: "...", - autoCollapse: false + autoCollapse: autoCollapse }; elements.push(span); } } + function autoCollapse(node: Node) { + switch (node.kind) { + case SyntaxKind.ModuleBlock: + case SyntaxKind.ClassDeclaration: + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.EnumDeclaration: + return false; + } + + return true; + } + var depth = 0; var maxDepth = 20; function walk(n: Node): void { @@ -62,7 +74,7 @@ module ts { case SyntaxKind.FinallyBlock: var openBrace = findChildOfKind(n, SyntaxKind.OpenBraceToken, sourceFile); var closeBrace = findChildOfKind(n, SyntaxKind.CloseBraceToken, sourceFile); - addOutlineRange(n.parent, openBrace, closeBrace); + addOutliningSpan(n.parent, openBrace, closeBrace, autoCollapse(n)); break; case SyntaxKind.ClassDeclaration: case SyntaxKind.InterfaceDeclaration: @@ -71,12 +83,12 @@ module ts { case SyntaxKind.SwitchStatement: var openBrace = findChildOfKind(n, SyntaxKind.OpenBraceToken, sourceFile); var closeBrace = findChildOfKind(n, SyntaxKind.CloseBraceToken, sourceFile); - addOutlineRange(n, openBrace, closeBrace); + addOutliningSpan(n, openBrace, closeBrace, autoCollapse(n)); break; case SyntaxKind.ArrayLiteral: var openBracket = findChildOfKind(n, SyntaxKind.OpenBracketToken, sourceFile); var closeBracket = findChildOfKind(n, SyntaxKind.CloseBracketToken, sourceFile); - addOutlineRange(n, openBracket, closeBracket); + addOutliningSpan(n, openBracket, closeBracket, autoCollapse(n)); break; } depth++; From a14e46a5e73c6e9694782a4c41ece0cce07e40e2 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Thu, 2 Oct 2014 17:58:05 -0700 Subject: [PATCH 21/38] Update compiler localized messages with those provided by the language service. --- src/compiler/core.ts | 8 +++----- src/services/core/diagnosticCore.ts | 2 -- src/services/services.ts | 4 ++-- src/services/shims.ts | 1 + 4 files changed, 6 insertions(+), 9 deletions(-) diff --git a/src/compiler/core.ts b/src/compiler/core.ts index fb2bde52453..123bde2e719 100644 --- a/src/compiler/core.ts +++ b/src/compiler/core.ts @@ -209,11 +209,9 @@ module ts { export var localizedDiagnosticMessages: Map = undefined; export function getLocaleSpecificMessage(message: string) { - if (ts.localizedDiagnosticMessages) { - message = localizedDiagnosticMessages[message]; - } - - return message; + return localizedDiagnosticMessages && localizedDiagnosticMessages[message] + ? localizedDiagnosticMessages[message] + : message; } export function createFileDiagnostic(file: SourceFile, start: number, length: number, message: DiagnosticMessage, ...args: any[]): Diagnostic; diff --git a/src/services/core/diagnosticCore.ts b/src/services/core/diagnosticCore.ts index b4d95a1c60b..369b8114eac 100644 --- a/src/services/core/diagnosticCore.ts +++ b/src/services/core/diagnosticCore.ts @@ -1,8 +1,6 @@ /// module TypeScript { - export var LocalizedDiagnosticMessages: ts.Map = null; - export class Location { private _fileName: string; private _lineMap: LineMap; diff --git a/src/services/services.ts b/src/services/services.ts index 7463acc6c68..88efbaf2a2a 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1650,8 +1650,8 @@ module ts { var writer: (filename: string, data: string, writeByteOrderMark: boolean) => void = undefined; // Check if the localized messages json is set, otherwise query the host for it - if (!TypeScript.LocalizedDiagnosticMessages) { - TypeScript.LocalizedDiagnosticMessages = host.getLocalizedDiagnosticMessages(); + if (!localizedDiagnosticMessages) { + localizedDiagnosticMessages = host.getLocalizedDiagnosticMessages(); } function getSourceFile(filename: string): SourceFile { diff --git a/src/services/shims.ts b/src/services/shims.ts index a1e616f6c77..f2b259ffa93 100644 --- a/src/services/shims.ts +++ b/src/services/shims.ts @@ -369,6 +369,7 @@ module ts { if (diagnosticMessagesJson == null || diagnosticMessagesJson == "") { return null; } + try { return JSON.parse(diagnosticMessagesJson); } From e751c34fcb90e1ff8a15d04ec72ae4019355f0cf Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 3 Oct 2014 01:54:43 -0700 Subject: [PATCH 22/38] Add some heuristics in the lexical classifier to make it play better with the syntactic classifier when classifying expressions involving generics. --- src/services/services.ts | 46 ++++++++++++++++++- .../cases/unittests/services/colorization.ts | 38 +++++++++++++++ 2 files changed, 83 insertions(+), 1 deletion(-) diff --git a/src/services/services.ts b/src/services/services.ts index 88efbaf2a2a..ebea261d41d 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1,4 +1,4 @@ -/// + /// /// /// /// @@ -4692,6 +4692,27 @@ module ts { entries: [] }; + // We can run into an unfortunate interaction between the lexical and syntactic classifier + // when the user is typing something generic. Consider the case where the user types: + // + // Foo tokens. It's a weak heuristic, but should + // work well enough in practice. + var inGenericStack = 0; + do { token = scanner.scan(); @@ -4711,6 +4732,29 @@ module ts { // we recognize that 'var' is actually an identifier here. token = SyntaxKind.Identifier; } + else if (lastNonTriviaToken === SyntaxKind.Identifier && + token === SyntaxKind.LessThanToken) { + // Could be the start of something generic. Keep track of that by bumping + // up the current count of generic contexts we may be in. + inGenericStack++; + } + else if (token === SyntaxKind.GreaterThanToken && inGenericStack > 0) { + // If we think we're currently in something generic, then mark that that + // generic entity is complete. + inGenericStack--; + } + else if (token === SyntaxKind.AnyKeyword || + token === SyntaxKind.StringKeyword || + token === SyntaxKind.NumberKeyword || + token === SyntaxKind.BooleanKeyword || + token === SyntaxKind.VoidKeyword) { + if (inGenericStack > 0) { + // If it looks like we're could be in something generic, don't classify this + // as a keyword. We may just get overwritten by the syntactic classifier, + // causing a noisy experience for the user. + token = SyntaxKind.Identifier; + } + } lastNonTriviaToken = token; } diff --git a/tests/cases/unittests/services/colorization.ts b/tests/cases/unittests/services/colorization.ts index 18b157f26b0..ee5350a25eb 100644 --- a/tests/cases/unittests/services/colorization.ts +++ b/tests/cases/unittests/services/colorization.ts @@ -231,5 +231,43 @@ describe('Colorization', function () { identifier("var"), finalEndOfLineState(ts.EndOfLineState.Start)); }); + + it("classifies partially written generics correctly.", function () { + test("Foo number", + ts.EndOfLineState.Start, + identifier("Foo"), + operator("<"), + identifier("Foo"), + operator(">" + identifier("keyword"), + finalEndOfLineState(ts.EndOfLineState.Start)); + }); }); }); \ No newline at end of file From 4714c2654372229931204e85f948150f87501bf8 Mon Sep 17 00:00:00 2001 From: Chris Bubernak Date: Fri, 3 Oct 2014 08:09:57 -0700 Subject: [PATCH 23/38] rewrote changes to the checker --- src/compiler/checker.ts | 44 +++++++------------ .../diagnosticInformationMap.generated.ts | 3 +- src/compiler/diagnosticMessages.json | 6 +-- 3 files changed, 18 insertions(+), 35 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index bcd0adfb40d..48433984c4d 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5022,9 +5022,11 @@ module ts { if (leftType.flags & (TypeFlags.Undefined | TypeFlags.Null)) leftType = rightType; if (rightType.flags & (TypeFlags.Undefined | TypeFlags.Null)) rightType = leftType; - var boolean = typeToString(booleanType); - if (typeToString(leftType) === boolean && typeToString(rightType) === boolean) { - error(node, Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_1, tokenToString(node.operator), preferredBooleanOperator(node.operator)); + if (leftType.flags & TypeFlags.Boolean && rightType.flags & TypeFlags.Boolean) { + var suggestedOperator = suggestedBooleanOperator(node.operator); + if (suggestedOperator !== undefined) { + error(node, Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, tokenToString(node.operator), tokenToString(suggestedOperator)); + } } else { var leftOk = checkArithmeticOperandType(node.left, leftType, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type); var rightOk = checkArithmeticOperandType(node.right, rightType, Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type); @@ -5094,36 +5096,22 @@ module ts { case SyntaxKind.CommaToken: return rightType; } - - function preferredBooleanOperator(operator: any): string { - var message = ""; - var suggestion:SyntaxKind; + + // if a user tries to apply an innappropriate operator to 2 boolean operands try and return them a helpful suggestion + function suggestedBooleanOperator(operator: any): SyntaxKind { switch (operator) { case SyntaxKind.BarToken: - suggestion = SyntaxKind.BarBarToken; - break; - case SyntaxKind.CaretToken: - suggestion = SyntaxKind.ExclamationEqualsEqualsToken; - break; - case SyntaxKind.AmpersandToken: - suggestion = SyntaxKind.AmpersandAmpersandToken; - break; - case SyntaxKind.CaretEqualsToken: - suggestion = SyntaxKind.CaretEqualsToken; - break; case SyntaxKind.BarEqualsToken: - suggestion = SyntaxKind.BarEqualsToken; - break; + return SyntaxKind.BarBarToken; + case SyntaxKind.CaretToken: + case SyntaxKind.CaretEqualsToken: + return SyntaxKind.ExclamationEqualsEqualsToken; + case SyntaxKind.AmpersandToken: case SyntaxKind.AmpersandEqualsToken: - suggestion = SyntaxKind.AmpersandEqualsToken; - break; + return SyntaxKind.AmpersandAmpersandToken; + default: + return undefined; } - if (suggestion !== undefined) { - return "Consider using " + tokenToString(suggestion) + "."; - //message = createCompilerDiagnostic(Diagnostics.Consider_using_0_instead, tokenToString(suggestion)); - //message = message(node, Diagnostics.Consider_using_0_instead, tokenToString(suggestion)); - } - return message; } function checkAssignmentOperator(valueType: Type): void { diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index e4889cd5741..a430799ba50 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -260,7 +260,7 @@ module ts { Property_0_is_protected_in_type_1_but_public_in_type_2: { code: 2444, category: DiagnosticCategory.Error, key: "Property '{0}' is protected in type '{1}' but public in type '{2}'." }, Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses: { code: 2445, category: DiagnosticCategory.Error, key: "Property '{0}' is protected and only accessible within class '{1}' and its subclasses." }, Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1: { code: 2446, category: DiagnosticCategory.Error, key: "Property '{0}' is protected and only accessible through an instance of class '{1}'." }, - The_0_operator_is_not_allowed_for_boolean_types_1: { code: 2447, category: DiagnosticCategory.Error, key: "The '{0}' operator is not allowed for boolean types {1}." }, + The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead: { code: 2447, category: DiagnosticCategory.Error, key: "The '{0}' operator is not allowed for boolean types. Consider using {1} instead." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: { code: 4001, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using name '{1}' from private module '{2}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, @@ -354,7 +354,6 @@ module ts { Specifies_the_location_where_debugger_should_locate_TypeScript_files_instead_of_source_locations: { code: 6004, category: DiagnosticCategory.Message, key: "Specifies the location where debugger should locate TypeScript files instead of source locations." }, Watch_input_files: { code: 6005, category: DiagnosticCategory.Message, key: "Watch input files." }, Redirect_output_structure_to_the_directory: { code: 6006, category: DiagnosticCategory.Message, key: "Redirect output structure to the directory." }, - Consider_using_0_instead: { code: 6007, category: DiagnosticCategory.Message, key: "Consider using '{0}' instead." }, Do_not_emit_comments_to_output: { code: 6009, category: DiagnosticCategory.Message, key: "Do not emit comments to output." }, Specify_ECMAScript_target_version_Colon_ES3_default_or_ES5: { code: 6015, category: DiagnosticCategory.Message, key: "Specify ECMAScript target version: 'ES3' (default), or 'ES5'" }, Specify_module_code_generation_Colon_commonjs_or_amd: { code: 6016, category: DiagnosticCategory.Message, key: "Specify module code generation: 'commonjs' or 'amd'" }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index 7cce4be878b..d715c898510 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1032,7 +1032,7 @@ "category": "Error", "code": 2446 }, - "The '{0}' operator is not allowed for boolean types {1}.": { + "The '{0}' operator is not allowed for boolean types. Consider using {1} instead.": { "category": "Error", "code": 2447 }, @@ -1411,10 +1411,6 @@ "category": "Message", "code": 6006 }, - "Consider using '{0}' instead.": { - "category": "Message", - "code": 6007 - }, "Do not emit comments to output.": { "category": "Message", "code": 6009 From 8533b592e11323b5354b3bc9a34a02dc6789550b Mon Sep 17 00:00:00 2001 From: ChrisBubernak Date: Fri, 3 Oct 2014 14:52:16 -0700 Subject: [PATCH 24/38] refactored checker again --- src/compiler/checker.ts | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 48433984c4d..4ee96be9bd7 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5022,18 +5022,20 @@ module ts { if (leftType.flags & (TypeFlags.Undefined | TypeFlags.Null)) leftType = rightType; if (rightType.flags & (TypeFlags.Undefined | TypeFlags.Null)) rightType = leftType; - if (leftType.flags & TypeFlags.Boolean && rightType.flags & TypeFlags.Boolean) { - var suggestedOperator = suggestedBooleanOperator(node.operator); - if (suggestedOperator !== undefined) { - error(node, Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, tokenToString(node.operator), tokenToString(suggestedOperator)); - } - } else { + var suggestedOperator: SyntaxKind; + // if both operands are booleans and we have a guess as to what the user meant to do return a helpful error + if ((leftType.flags & TypeFlags.Boolean) && (rightType.flags & TypeFlags.Boolean) && (suggestedOperator = getSuggestedBooleanOperator(node.operator)) !== undefined) { + error(node, Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, tokenToString(node.operator), tokenToString(suggestedOperator)); + } + // otherwise just check each operand seperately and report errors as normal + else { var leftOk = checkArithmeticOperandType(node.left, leftType, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type); var rightOk = checkArithmeticOperandType(node.right, rightType, Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type); if (leftOk && rightOk) { checkAssignmentOperator(numberType); - } - } + } + } + return numberType; case SyntaxKind.PlusToken: case SyntaxKind.PlusEqualsToken: @@ -5098,7 +5100,7 @@ module ts { } // if a user tries to apply an innappropriate operator to 2 boolean operands try and return them a helpful suggestion - function suggestedBooleanOperator(operator: any): SyntaxKind { + function getSuggestedBooleanOperator(operator: any): SyntaxKind { switch (operator) { case SyntaxKind.BarToken: case SyntaxKind.BarEqualsToken: From 2a8b9ef21f4605c68a7d2e64a4932efa8f3e6f26 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 3 Oct 2014 14:53:50 -0700 Subject: [PATCH 25/38] Support rename in comments and strings. --- src/compiler/checker.ts | 4 +- src/compiler/parser.ts | 8 +-- src/harness/typeWriter.ts | 2 +- src/services/services.ts | 103 ++++++++++++++++++++++++++++++++++++-- src/services/shims.ts | 14 ++++++ src/services/utilities.ts | 2 +- 6 files changed, 121 insertions(+), 12 deletions(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index a0e55520237..c2df5760e4e 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -2575,7 +2575,7 @@ module ts { function getStringLiteralType(node: StringLiteralTypeNode): StringLiteralType { if (hasProperty(stringLiteralTypes, node.text)) return stringLiteralTypes[node.text]; var type = stringLiteralTypes[node.text] = createType(TypeFlags.StringLiteral); - type.text = getSourceTextOfNode(node); + type.text = getTextOfNode(node); return type; } @@ -7430,7 +7430,7 @@ module ts { while (!isUniqueLocalName(escapeIdentifier(prefix + name), container)) { prefix += "_"; } - links.localModuleName = prefix + getSourceTextOfNode(container.name); + links.localModuleName = prefix + getTextOfNode(container.name); } return links.localModuleName; } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index 5318e679c4e..13fe69cf1ba 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -54,11 +54,11 @@ module ts { return skipTrivia((sourceFile || getSourceFileOfNode(node)).text, node.pos); } - export function getSourceTextOfNodeFromSourceText(sourceText: string, node: Node): string { + export function getTextOfNodeFromSourceText(sourceText: string, node: Node): string { return sourceText.substring(skipTrivia(sourceText, node.pos), node.end); } - export function getSourceTextOfNode(node: Node): string { + export function getTextOfNode(node: Node): string { var text = getSourceFileOfNode(node).text; return text.substring(skipTrivia(text, node.pos), node.end); } @@ -75,7 +75,7 @@ module ts { // Return display name of an identifier export function identifierToString(identifier: Identifier) { - return identifier.kind === SyntaxKind.Missing ? "(Missing)" : getSourceTextOfNode(identifier); + return identifier.kind === SyntaxKind.Missing ? "(Missing)" : getTextOfNode(identifier); } export function createDiagnosticForNode(node: Node, message: DiagnosticMessage, arg0?: any, arg1?: any, arg2?: any): Diagnostic { @@ -3045,7 +3045,7 @@ module ts { parseExpected(SyntaxKind.ColonToken); if (labelledStatementInfo.nodeIsNestedInLabel(node.label, /*requireIterationStatement*/ false, /*stopAtFunctionBoundary*/ true)) { - grammarErrorOnNode(node.label, Diagnostics.Duplicate_label_0, getSourceTextOfNodeFromSourceText(sourceText, node.label)); + grammarErrorOnNode(node.label, Diagnostics.Duplicate_label_0, getTextOfNodeFromSourceText(sourceText, node.label)); } labelledStatementInfo.addLabel(node.label); diff --git a/src/harness/typeWriter.ts b/src/harness/typeWriter.ts index 3b5d8cd3fff..8169531c27e 100644 --- a/src/harness/typeWriter.ts +++ b/src/harness/typeWriter.ts @@ -76,7 +76,7 @@ class TypeWriterWalker { private log(node: ts.Node, type: ts.Type): void { var actualPos = ts.skipTrivia(this.currentSourceFile.text, node.pos); var lineAndCharacter = this.currentSourceFile.getLineAndCharacterFromPosition(actualPos); - var sourceText = ts.getSourceTextOfNodeFromSourceText(this.currentSourceFile.text, node); + var sourceText = ts.getTextOfNodeFromSourceText(this.currentSourceFile.text, node); // If we got an unknown type, we temporarily want to fall back to just pretending the name // (source text) of the node is the type. This is to align with the old typeWriter to make diff --git a/src/services/services.ts b/src/services/services.ts index 88efbaf2a2a..16d2bd9dffd 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -666,6 +666,8 @@ module ts { getSignatureAtPosition(fileName: string, position: number): SignatureInfo; getRenameInfo(fileName: string, position: number): RenameInfo; + findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[]; + getDefinitionAtPosition(fileName: string, position: number): DefinitionInfo[]; getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[]; getOccurrencesAtPosition(fileName: string, position: number): ReferenceEntry[]; @@ -757,6 +759,11 @@ module ts { newText: string; } + export interface RenameLocation { + textSpan: TypeScript.TextSpan; + fileName: string; + } + export interface ReferenceEntry { textSpan: TypeScript.TextSpan; fileName: string; @@ -3062,11 +3069,19 @@ module ts { } } - function getReferencesAtPosition(filename: string, position: number): ReferenceEntry[] { + function findRenameLocations(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): RenameLocation[] { + return findReferences(fileName, position, findInStrings, findInComments); + } + + function getReferencesAtPosition(fileName: string, position: number): ReferenceEntry[] { + return findReferences(fileName, position, /*findInStrings:*/ false, /*findInComments:*/ false); + } + + function findReferences(fileName: string, position: number, findInStrings: boolean, findInComments: boolean): ReferenceEntry[] { synchronizeHostData(); - filename = TypeScript.switchToForwardSlashes(filename); - var sourceFile = getSourceFile(filename); + fileName = TypeScript.switchToForwardSlashes(fileName); + var sourceFile = getSourceFile(fileName); var node = getTouchingPropertyName(sourceFile, position); if (!node) { @@ -3082,7 +3097,86 @@ module ts { return undefined; } - return getReferencesForNode(node, program.getSourceFiles()); + Debug.assert(node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.NumericLiteral || node.kind === SyntaxKind.StringLiteral); + var references = getReferencesForNode(node, program.getSourceFiles()); + + var name = (node).text; + var tripleSlashDirectivePrefixRegex = /^\/\/\/\s*= 0) { + // Only consider it a match if there isn't a letter/number before or after + // the match. + var indexInSourceText = rawTextPositionInSourceText + matchIndex; + + if (indexInSourceText === 0 || !isIdentifierPart(sourceText.charCodeAt(indexInSourceText - 1), ScriptTarget.ES5)) { + var matchEnd = indexInSourceText + name.length; + if (matchEnd >= sourceText.length || !isIdentifierPart(sourceText.charCodeAt(matchEnd), ScriptTarget.ES5)) { + + references.push({ + fileName: sourceFile.filename, + textSpan: new TypeScript.TextSpan(indexInSourceText, name.length), + isWriteAccess: false + }); + } + } + + matchIndex++; + } + } + + function addCommentReferences(sourceFile: SourceFile) { + var sourceText = sourceFile.text; + forEachChild(sourceFile, addCommentReferencesInNode); + + function addCommentReferencesInNode(node: Node) { + if (isToken(node)) { + // Found a token, walk its comments (if it has any) for matches). + forEach(getLeadingCommentRanges(sourceText, node.pos), addReferencesInCommentRange); + } + else { + forEach(node.getChildren(), addCommentReferencesInNode); + } + } + + function addReferencesInCommentRange(range: CommentRange) { + var commentText = sourceText.substring(range.pos, range.end); + + // Don't add matches in /// { + return this.languageService.findRenameLocations(fileName, position, findInStrings, findInComments); + }); + } + /// GET BRACE MATCHING public getBraceMatchingAtPosition(fileName: string, position: number): string { return this.forwardJSONCall( diff --git a/src/services/utilities.ts b/src/services/utilities.ts index caa324fcc7b..af320ea0a0c 100644 --- a/src/services/utilities.ts +++ b/src/services/utilities.ts @@ -222,7 +222,7 @@ module ts { return n.kind !== SyntaxKind.SyntaxList || n.getChildCount() !== 0; } - function isToken(n: Node): boolean { + export function isToken(n: Node): boolean { return n.kind >= SyntaxKind.FirstToken && n.kind <= SyntaxKind.LastToken; } From 422324f0af459438e60e2e31b38715b207addf48 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 3 Oct 2014 15:06:04 -0700 Subject: [PATCH 26/38] CodeReview feedback. --- src/services/services.ts | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index ebea261d41d..36ea451497b 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -1,4 +1,4 @@ - /// +/// /// /// /// @@ -4711,7 +4711,7 @@ module ts { // In order to determine if the user is potentially typing something generic, we use a // weak heuristic where we track < and > tokens. It's a weak heuristic, but should // work well enough in practice. - var inGenericStack = 0; + var angleBracketStack = 0; do { token = scanner.scan(); @@ -4736,19 +4736,18 @@ module ts { token === SyntaxKind.LessThanToken) { // Could be the start of something generic. Keep track of that by bumping // up the current count of generic contexts we may be in. - inGenericStack++; + angleBracketStack++; } - else if (token === SyntaxKind.GreaterThanToken && inGenericStack > 0) { + else if (token === SyntaxKind.GreaterThanToken && angleBracketStack > 0) { // If we think we're currently in something generic, then mark that that // generic entity is complete. - inGenericStack--; + angleBracketStack--; } else if (token === SyntaxKind.AnyKeyword || token === SyntaxKind.StringKeyword || token === SyntaxKind.NumberKeyword || - token === SyntaxKind.BooleanKeyword || - token === SyntaxKind.VoidKeyword) { - if (inGenericStack > 0) { + token === SyntaxKind.BooleanKeyword) { + if (angleBracketStack > 0) { // If it looks like we're could be in something generic, don't classify this // as a keyword. We may just get overwritten by the syntactic classifier, // causing a noisy experience for the user. From 1f045e1227cf1a15acff83c827f9a0d232ef32ec Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 3 Oct 2014 15:33:29 -0700 Subject: [PATCH 27/38] Adding rename tests. --- src/harness/fourslash.ts | 58 +++++++++++++++++++++++------- tests/cases/fourslash/fourslash.ts | 5 ++- 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/src/harness/fourslash.ts b/src/harness/fourslash.ts index e746bd9e7c9..ebc6ec61d8f 100644 --- a/src/harness/fourslash.ts +++ b/src/harness/fourslash.ts @@ -758,6 +758,10 @@ module FourSlash { return this.languageService.getImplementorsAtPosition(this.activeFile.fileName, this.currentCaretPosition); } + private assertionMessage(name: string, actualValue: any, expectedValue: any) { + return "\nActual " + name + ":\n\t" + actualValue + "\nExpected value:\n\t" + expectedValue; + } + public verifyQuickInfo(negative: boolean, expectedTypeName?: string, docComment?: string, symbolName?: string, kind?: string) { [expectedTypeName, docComment, symbolName, kind].forEach(str => { if (str) { @@ -772,40 +776,68 @@ module FourSlash { var actualQuickInfoSymbolName = actualQuickInfo ? actualQuickInfo.fullSymbolName : ""; var actualQuickInfoKind = actualQuickInfo ? actualQuickInfo.kind : ""; - function assertionMessage(name: string, actualValue: string, expectedValue: string) { - return "\nActual " + name + ":\n\t" + actualValue + "\nExpected value:\n\t" + expectedValue; - } - if (negative) { if (expectedTypeName !== undefined) { - assert.notEqual(actualQuickInfoMemberName, expectedTypeName, assertionMessage("quick info member name", actualQuickInfoMemberName, expectedTypeName)); + assert.notEqual(actualQuickInfoMemberName, expectedTypeName, this.assertionMessage("quick info member name", actualQuickInfoMemberName, expectedTypeName)); } if (docComment != undefined) { - assert.notEqual(actualQuickInfoDocComment, docComment, assertionMessage("quick info doc comment", actualQuickInfoDocComment, docComment)); + assert.notEqual(actualQuickInfoDocComment, docComment, this.assertionMessage("quick info doc comment", actualQuickInfoDocComment, docComment)); } if (symbolName !== undefined) { - assert.notEqual(actualQuickInfoSymbolName, symbolName, assertionMessage("quick info symbol name", actualQuickInfoSymbolName, symbolName)); + assert.notEqual(actualQuickInfoSymbolName, symbolName, this.assertionMessage("quick info symbol name", actualQuickInfoSymbolName, symbolName)); } if (kind !== undefined) { - assert.notEqual(actualQuickInfoKind, kind, assertionMessage("quick info kind", actualQuickInfoKind, kind)); + assert.notEqual(actualQuickInfoKind, kind, this.assertionMessage("quick info kind", actualQuickInfoKind, kind)); } } else { if (expectedTypeName !== undefined) { - assert.equal(actualQuickInfoMemberName, expectedTypeName, assertionMessage("quick info member", actualQuickInfoMemberName, expectedTypeName)); + assert.equal(actualQuickInfoMemberName, expectedTypeName, this.assertionMessage("quick info member", actualQuickInfoMemberName, expectedTypeName)); } if (docComment != undefined) { - assert.equal(actualQuickInfoDocComment, docComment, assertionMessage("quick info doc", actualQuickInfoDocComment, docComment)); + assert.equal(actualQuickInfoDocComment, docComment, this.assertionMessage("quick info doc", actualQuickInfoDocComment, docComment)); } if (symbolName !== undefined) { - assert.equal(actualQuickInfoSymbolName, symbolName, assertionMessage("quick info symbol name", actualQuickInfoSymbolName, symbolName)); + assert.equal(actualQuickInfoSymbolName, symbolName, this.assertionMessage("quick info symbol name", actualQuickInfoSymbolName, symbolName)); } if (kind !== undefined) { - assert.equal(actualQuickInfoKind, kind, assertionMessage("quick info kind", actualQuickInfoKind, kind)); + assert.equal(actualQuickInfoKind, kind, this.assertionMessage("quick info kind", actualQuickInfoKind, kind)); } } } - public verifyQuickInfoExists(negative: number) { + public verifyRenameLocations(findInStrings: boolean, findInComments: boolean) { + var renameInfo = this.languageService.getRenameInfo(this.activeFile.fileName, this.currentCaretPosition); + if (renameInfo.canRename) { + var references = this.languageService.findRenameLocations( + this.activeFile.fileName, this.currentCaretPosition, findInStrings, findInComments); + + var ranges = this.getRanges(); + if (ranges.length !== references.length) { + this.raiseError(this.assertionMessage("Rename locations", references.length, ranges.length)); + } + + ranges = ranges.sort((r1, r2) => r1.start - r2.start); + references = references.sort((r1, r2) => r1.textSpan.start() - r2.textSpan.start()); + + for (var i = 0, n = ranges.length; i < n; i++) { + var reference = references[i]; + var range = ranges[i]; + + if (reference.textSpan.start() !== range.start || + reference.textSpan.end() !== range.end) { + + this.raiseError(this.assertionMessage("Rename location", + "[" + reference.textSpan.start() + "," + reference.textSpan.end() + ")", + "[" + range.start + "," + range.end + ")")); + } + } + } + else { + this.raiseError("Expected rename to succeed, but it actually failed."); + } + } + + public verifyQuickInfoExists(negative: boolean) { this.taoInvalidReason = 'verifyQuickInfoExists NYI'; var actualQuickInfo = this.languageService.getTypeAtPosition(this.activeFile.fileName, this.currentCaretPosition); diff --git a/tests/cases/fourslash/fourslash.ts b/tests/cases/fourslash/fourslash.ts index c204a98c4a4..537ff8527d6 100644 --- a/tests/cases/fourslash/fourslash.ts +++ b/tests/cases/fourslash/fourslash.ts @@ -240,7 +240,6 @@ module FourSlashInterface { } export class verify extends verifyNegatable { - public caretAtMarker(markerName?: string) { FourSlash.currentTestState.verifyCaretAtMarker(markerName); } @@ -417,6 +416,10 @@ module FourSlashInterface { public renameInfoFailed(message?: string) { FourSlash.currentTestState.verifyRenameInfoFailed(message) } + + public renameLocations(findInStrings: boolean, findInComments: boolean) { + FourSlash.currentTestState.verifyRenameLocations(findInStrings, findInComments); + } } export class edit { From 8aaee0740911f9b94398bed465cf2775e2620179 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 3 Oct 2014 15:56:44 -0700 Subject: [PATCH 28/38] CodeReview feedback, and some tests. --- src/services/services.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/services/services.ts b/src/services/services.ts index 16d2bd9dffd..0d397eef6f3 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -3132,6 +3132,8 @@ module ts { } } + // Advance the matchIndex forward (if we don't, then we'll simply find the same + // match at the same position again). matchIndex++; } } From a39064457ed23101366e5b22b0006c7afc4106e1 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 3 Oct 2014 15:59:20 -0700 Subject: [PATCH 29/38] Adding tests. --- tests/cases/fourslash/renameCommentsAndStrings1.ts | 11 +++++++++++ tests/cases/fourslash/renameCommentsAndStrings2.ts | 11 +++++++++++ tests/cases/fourslash/renameCommentsAndStrings3.ts | 11 +++++++++++ tests/cases/fourslash/renameCommentsAndStrings4.ts | 11 +++++++++++ 4 files changed, 44 insertions(+) create mode 100644 tests/cases/fourslash/renameCommentsAndStrings1.ts create mode 100644 tests/cases/fourslash/renameCommentsAndStrings2.ts create mode 100644 tests/cases/fourslash/renameCommentsAndStrings3.ts create mode 100644 tests/cases/fourslash/renameCommentsAndStrings4.ts diff --git a/tests/cases/fourslash/renameCommentsAndStrings1.ts b/tests/cases/fourslash/renameCommentsAndStrings1.ts new file mode 100644 index 00000000000..b5c8ac6aacc --- /dev/null +++ b/tests/cases/fourslash/renameCommentsAndStrings1.ts @@ -0,0 +1,11 @@ +/// + +/////// + +////function /**/[|Bar|]() { +//// // This is a reference to Bar in a comment. +//// "this is a reference to Bar in a string" +////} + +goTo.marker(); +verify.renameLocations(/*findInStrings:*/ false, /*findInComments:*/ false); \ No newline at end of file diff --git a/tests/cases/fourslash/renameCommentsAndStrings2.ts b/tests/cases/fourslash/renameCommentsAndStrings2.ts new file mode 100644 index 00000000000..590f3a0833f --- /dev/null +++ b/tests/cases/fourslash/renameCommentsAndStrings2.ts @@ -0,0 +1,11 @@ +/// + +/////// + +////function /**/[|Bar|]() { +//// // This is a reference to Bar in a comment. +//// "this is a reference to [|Bar|] in a string" +////} + +goTo.marker(); +verify.renameLocations(/*findInStrings:*/ true, /*findInComments:*/ false); \ No newline at end of file diff --git a/tests/cases/fourslash/renameCommentsAndStrings3.ts b/tests/cases/fourslash/renameCommentsAndStrings3.ts new file mode 100644 index 00000000000..5f1aa09a948 --- /dev/null +++ b/tests/cases/fourslash/renameCommentsAndStrings3.ts @@ -0,0 +1,11 @@ +/// + +/////// + +////function /**/[|Bar|]() { +//// // This is a reference to [|Bar|] in a comment. +//// "this is a reference to Bar in a string" +////} + +goTo.marker(); +verify.renameLocations(/*findInStrings:*/ false, /*findInComments:*/ true); \ No newline at end of file diff --git a/tests/cases/fourslash/renameCommentsAndStrings4.ts b/tests/cases/fourslash/renameCommentsAndStrings4.ts new file mode 100644 index 00000000000..4f8b7b98cd4 --- /dev/null +++ b/tests/cases/fourslash/renameCommentsAndStrings4.ts @@ -0,0 +1,11 @@ +/// + +/////// + +////function /**/[|Bar|]() { +//// // This is a reference to [|Bar|] in a comment. +//// "this is a reference to [|Bar|] in a string" +////} + +goTo.marker(); +verify.renameLocations(/*findInStrings:*/ true, /*findInComments:*/ true); \ No newline at end of file From 4ba0ce433f84daf42aa70764e2a4754610eb614a Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 3 Oct 2014 16:12:59 -0700 Subject: [PATCH 30/38] Renamed 'getScriptLexicalItemsWalkerSuperCala[...].ts' to 'navigationBar.ts'. --- Jakefile | 2 +- .../{getScriptLexicalStructureWalker.ts => navigationBar.ts} | 4 ++-- src/services/services.ts | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) rename src/services/{getScriptLexicalStructureWalker.ts => navigationBar.ts} (96%) diff --git a/Jakefile b/Jakefile index 4929a9e1468..4f2808dcbd1 100644 --- a/Jakefile +++ b/Jakefile @@ -58,7 +58,7 @@ var servicesSources = [ "shims.ts", "signatureHelp.ts", "utilities.ts", - "getScriptLexicalStructureWalker.ts" + "navigationBar.ts" ].map(function (f) { return path.join(servicesDirectory, f); })); diff --git a/src/services/getScriptLexicalStructureWalker.ts b/src/services/navigationBar.ts similarity index 96% rename from src/services/getScriptLexicalStructureWalker.ts rename to src/services/navigationBar.ts index 2162c619fa9..4b5904e3cff 100644 --- a/src/services/getScriptLexicalStructureWalker.ts +++ b/src/services/navigationBar.ts @@ -1,8 +1,8 @@ /// /// -module ts { - export function getNavigationBarItemsHelper(sourceFile: SourceFile): ts.NavigationBarItem[] { +module ts.NavigationBar { + export function getNavigationBarItems(sourceFile: SourceFile): ts.NavigationBarItem[] { var hasGlobalNode = false; return getItemsWorker(getTopLevelNodes(sourceFile), createTopLevelItem); diff --git a/src/services/services.ts b/src/services/services.ts index 5605d0f6c84..320e0072d97 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -6,7 +6,7 @@ /// /// -/// +/// /// /// /// @@ -3907,7 +3907,7 @@ module ts { function getNavigationBarItems(filename: string): NavigationBarItem[] { filename = TypeScript.switchToForwardSlashes(filename); - return getNavigationBarItemsHelper(getCurrentSourceFile(filename)); + return NavigationBar.getNavigationBarItems(getCurrentSourceFile(filename)); } function getSemanticClassifications(fileName: string, span: TypeScript.TextSpan): ClassifiedSpan[] { From 7d9bf5093bcebc68620aa906d2f41c0df24dcc7d Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 3 Oct 2014 16:19:30 -0700 Subject: [PATCH 31/38] Replaced 'getModuleNameFromFilename' with 'removeFileExtension'. --- src/compiler/binder.ts | 2 +- src/compiler/emitter.ts | 8 ++++---- src/compiler/parser.ts | 4 ---- 3 files changed, 5 insertions(+), 9 deletions(-) diff --git a/src/compiler/binder.ts b/src/compiler/binder.ts index 3959335542c..16302ecf4b5 100644 --- a/src/compiler/binder.ts +++ b/src/compiler/binder.ts @@ -332,7 +332,7 @@ module ts { break; case SyntaxKind.SourceFile: if (isExternalModule(node)) { - bindAnonymousDeclaration(node, SymbolFlags.ValueModule, '"' + getModuleNameFromFilename((node).filename) + '"'); + bindAnonymousDeclaration(node, SymbolFlags.ValueModule, '"' + removeFileExtension((node).filename) + '"'); break; } default: diff --git a/src/compiler/emitter.ts b/src/compiler/emitter.ts index 1b7fff6747f..5dfedc37e0a 100644 --- a/src/compiler/emitter.ts +++ b/src/compiler/emitter.ts @@ -56,10 +56,10 @@ module ts { function getOwnEmitOutputFilePath(sourceFile: SourceFile, extension: string) { if (compilerOptions.outDir) { - var emitOutputFilePathWithoutExtension = getModuleNameFromFilename(getSourceFilePathInNewDir(compilerOptions.outDir, sourceFile)); + var emitOutputFilePathWithoutExtension = removeFileExtension(getSourceFilePathInNewDir(compilerOptions.outDir, sourceFile)); } else { - var emitOutputFilePathWithoutExtension = getModuleNameFromFilename(sourceFile.filename); + var emitOutputFilePathWithoutExtension = removeFileExtension(sourceFile.filename); } return emitOutputFilePathWithoutExtension + extension; @@ -3141,7 +3141,7 @@ module ts { ? referencedFile.filename // Declaration file, use declaration file name : shouldEmitToOwnFile(referencedFile, compilerOptions) ? getOwnEmitOutputFilePath(referencedFile, ".d.ts") // Own output file so get the .d.ts file - : getModuleNameFromFilename(compilerOptions.out) + ".d.ts";// Global out file + : removeFileExtension(compilerOptions.out) + ".d.ts";// Global out file declFileName = getRelativePathToDirectoryOrUrl( getDirectoryPath(normalizeSlashes(jsFilePath)), @@ -3214,7 +3214,7 @@ module ts { } }); declarationOutput += synchronousDeclarationOutput.substring(appliedSyncOutputPos); - writeFile(getModuleNameFromFilename(jsFilePath) + ".d.ts", declarationOutput, compilerOptions.emitBOM); + writeFile(removeFileExtension(jsFilePath) + ".d.ts", declarationOutput, compilerOptions.emitBOM); } } diff --git a/src/compiler/parser.ts b/src/compiler/parser.ts index ede29fba891..9a11fef88b0 100644 --- a/src/compiler/parser.ts +++ b/src/compiler/parser.ts @@ -22,10 +22,6 @@ module ts { amdDependencies: string[]; } - export function getModuleNameFromFilename(filename: string) { - return removeFileExtension(filename); - } - export function getSourceFileOfNode(node: Node): SourceFile { while (node && node.kind !== SyntaxKind.SourceFile) node = node.parent; return node; From 1814261269dcfb450cc54c87963e5629004bd0bc Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 3 Oct 2014 16:57:41 -0700 Subject: [PATCH 32/38] Moved 'basicChildItem' to 'createChildItem' and renamed it 'createItem'. --- src/services/navigationBar.ts | 34 +++++++++++++++++++--------------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index 4b5904e3cff..e9a8a75c8f0 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -3,11 +3,15 @@ module ts.NavigationBar { export function getNavigationBarItems(sourceFile: SourceFile): ts.NavigationBarItem[] { + // If the source file has any child items, then it included in the tree + // and takes lexical ownership of all other top-level items. var hasGlobalNode = false; return getItemsWorker(getTopLevelNodes(sourceFile), createTopLevelItem); function getIndent(node: Node): number { + // If we have a global node in the tree, + // then it adds an extra layer of depth to all subnodes. var indent = hasGlobalNode ? 1 : 0; var current = node.parent; @@ -150,57 +154,57 @@ module ts.NavigationBar { return undefined; } - return basicChildItem(node, getSourceText(parameter.name), ts.ScriptElementKind.memberVariableElement); + return createItem(node, getSourceText(parameter.name), ts.ScriptElementKind.memberVariableElement); case SyntaxKind.Method: var method = node; - return basicChildItem(node, getSourceText(method.name), ts.ScriptElementKind.memberFunctionElement); + return createItem(node, getSourceText(method.name), ts.ScriptElementKind.memberFunctionElement); case SyntaxKind.GetAccessor: var getAccessor = node; - return basicChildItem(node, getSourceText(getAccessor.name), ts.ScriptElementKind.memberGetAccessorElement); + return createItem(node, getSourceText(getAccessor.name), ts.ScriptElementKind.memberGetAccessorElement); case SyntaxKind.SetAccessor: var setAccessor = node; - return basicChildItem(node, getSourceText(setAccessor.name), ts.ScriptElementKind.memberSetAccessorElement); + return createItem(node, getSourceText(setAccessor.name), ts.ScriptElementKind.memberSetAccessorElement); case SyntaxKind.IndexSignature: - return basicChildItem(node, "[]", ts.ScriptElementKind.indexSignatureElement); + return createItem(node, "[]", ts.ScriptElementKind.indexSignatureElement); case SyntaxKind.EnumMember: var enumMember = node; - return basicChildItem(node, getSourceText(enumMember.name), ts.ScriptElementKind.memberVariableElement); + return createItem(node, getSourceText(enumMember.name), ts.ScriptElementKind.memberVariableElement); case SyntaxKind.CallSignature: - return basicChildItem(node, "()", ts.ScriptElementKind.callSignatureElement); + return createItem(node, "()", ts.ScriptElementKind.callSignatureElement); case SyntaxKind.ConstructSignature: - return basicChildItem(node, "new()", ts.ScriptElementKind.constructSignatureElement); + return createItem(node, "new()", ts.ScriptElementKind.constructSignatureElement); case SyntaxKind.Property: var property = node; - return basicChildItem(node, getSourceText(property.name), ts.ScriptElementKind.memberVariableElement); + return createItem(node, getSourceText(property.name), ts.ScriptElementKind.memberVariableElement); case SyntaxKind.FunctionDeclaration: var functionDeclaration = node; if (!isTopLevelFunctionDeclaration(functionDeclaration)) { - return basicChildItem(node, getSourceText(functionDeclaration.name), ts.ScriptElementKind.functionElement); + return createItem(node, getSourceText(functionDeclaration.name), ts.ScriptElementKind.functionElement); } break; case SyntaxKind.VariableDeclaration: var variableDeclaration = node; - return basicChildItem(node, getSourceText(variableDeclaration.name), ts.ScriptElementKind.variableElement); + return createItem(node, getSourceText(variableDeclaration.name), ts.ScriptElementKind.variableElement); case SyntaxKind.Constructor: - return basicChildItem(node, "constructor", ts.ScriptElementKind.constructorImplementationElement); + return createItem(node, "constructor", ts.ScriptElementKind.constructorImplementationElement); } return undefined; - } - function basicChildItem(node: Node, name: string, scriptElementKind: string): NavigationBarItem { - return getNavigationBarItem(name, scriptElementKind, getNodeModifiers(node), [getNodeSpan(node)]); + function createItem(node: Node, name: string, scriptElementKind: string): NavigationBarItem { + return getNavigationBarItem(name, scriptElementKind, getNodeModifiers(node), [getNodeSpan(node)]); + } } function getNavigationBarItem(text: string, kind: string, kindModifiers: string, spans: TypeScript.TextSpan[], childItems: ts.NavigationBarItem[]= [], indent: number = 0): ts.NavigationBarItem { From 208e36d294c18efe84cf663dda01d51579aa3824 Mon Sep 17 00:00:00 2001 From: Daniel Rosenwasser Date: Fri, 3 Oct 2014 17:28:48 -0700 Subject: [PATCH 33/38] Cover all top-level items in 'getIndent'. --- src/services/navigationBar.ts | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/services/navigationBar.ts b/src/services/navigationBar.ts index e9a8a75c8f0..825d46a1f65 100644 --- a/src/services/navigationBar.ts +++ b/src/services/navigationBar.ts @@ -16,8 +16,20 @@ module ts.NavigationBar { var current = node.parent; while (current) { - if (current.kind === SyntaxKind.ModuleDeclaration || current.kind === SyntaxKind.FunctionDeclaration) { - indent++; + switch (current.kind) { + case SyntaxKind.ModuleDeclaration: + // If we have a module declared as A.B.C, it is more "intuitive" + // to say it only has a single layer of depth + do { + current = current.parent; + } while (current.kind === SyntaxKind.ModuleDeclaration); + + // fall through + case SyntaxKind.ClassDeclaration: + case SyntaxKind.EnumDeclaration: + case SyntaxKind.InterfaceDeclaration: + case SyntaxKind.FunctionDeclaration: + indent++; } current = current.parent; @@ -207,7 +219,7 @@ module ts.NavigationBar { } } - function getNavigationBarItem(text: string, kind: string, kindModifiers: string, spans: TypeScript.TextSpan[], childItems: ts.NavigationBarItem[]= [], indent: number = 0): ts.NavigationBarItem { + function getNavigationBarItem(text: string, kind: string, kindModifiers: string, spans: TypeScript.TextSpan[], childItems: ts.NavigationBarItem[] = [], indent: number = 0): ts.NavigationBarItem { return { text: text, kind: kind, From 3fa17eff27d9f68aabcf7e6b84a3fa96d994d168 Mon Sep 17 00:00:00 2001 From: Cyrus Najmabadi Date: Fri, 3 Oct 2014 17:33:03 -0700 Subject: [PATCH 34/38] Cleaning up the new rename-comments/strings code. Mohamed rightly pointed out we were triplicating work and we could just roll the new checks into the existing tree walking code. --- src/services/services.ts | 137 +++++++++++++++------------------------ 1 file changed, 51 insertions(+), 86 deletions(-) diff --git a/src/services/services.ts b/src/services/services.ts index bb3fe8e3bf4..33bdd4956ec 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -2637,7 +2637,7 @@ module ts { if (node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.ThisKeyword || node.kind === SyntaxKind.SuperKeyword || isLiteralNameOfPropertyDeclarationOrIndexAccess(node) || isNameOfExternalModuleImportOrDeclaration(node)) { - return getReferencesForNode(node, [sourceFile]); + return getReferencesForNode(node, [sourceFile], /*findInStrings:*/ false, /*findInComments:*/ false); } switch (node.kind) { @@ -3098,90 +3098,10 @@ module ts { } Debug.assert(node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.NumericLiteral || node.kind === SyntaxKind.StringLiteral); - var references = getReferencesForNode(node, program.getSourceFiles()); - - var name = (node).text; - var tripleSlashDirectivePrefixRegex = /^\/\/\/\s*= 0) { - // Only consider it a match if there isn't a letter/number before or after - // the match. - var indexInSourceText = rawTextPositionInSourceText + matchIndex; - - if (indexInSourceText === 0 || !isIdentifierPart(sourceText.charCodeAt(indexInSourceText - 1), ScriptTarget.ES5)) { - var matchEnd = indexInSourceText + name.length; - if (matchEnd >= sourceText.length || !isIdentifierPart(sourceText.charCodeAt(matchEnd), ScriptTarget.ES5)) { - - references.push({ - fileName: sourceFile.filename, - textSpan: new TypeScript.TextSpan(indexInSourceText, name.length), - isWriteAccess: false - }); - } - } - - // Advance the matchIndex forward (if we don't, then we'll simply find the same - // match at the same position again). - matchIndex++; - } - } - - function addCommentReferences(sourceFile: SourceFile) { - var sourceText = sourceFile.text; - forEachChild(sourceFile, addCommentReferencesInNode); - - function addCommentReferencesInNode(node: Node) { - if (isToken(node)) { - // Found a token, walk its comments (if it has any) for matches). - forEach(getLeadingCommentRanges(sourceText, node.pos), addReferencesInCommentRange); - } - else { - forEach(node.getChildren(), addCommentReferencesInNode); - } - } - - function addReferencesInCommentRange(range: CommentRange) { - var commentText = sourceText.substring(range.pos, range.end); - - // Don't add matches in /// { @@ -3239,7 +3159,7 @@ module ts { if (lookUp(sourceFile.identifiers, symbolName)) { result = result || []; - getReferencesInNode(sourceFile, symbol, symbolName, node, searchMeaning, result); + getReferencesInNode(sourceFile, symbol, symbolName, node, searchMeaning, findInStrings, findInComments, result); } }); } @@ -3391,8 +3311,16 @@ module ts { * tuple of(searchSymbol, searchText, searchLocation, and searchMeaning). * searchLocation: a node where the search value */ - function getReferencesInNode(container: Node, searchSymbol: Symbol, searchText: string, searchLocation: Node, searchMeaning: SearchMeaning, result: ReferenceEntry[]): void { + function getReferencesInNode(container: Node, + searchSymbol: Symbol, + searchText: string, + searchLocation: Node, + searchMeaning: SearchMeaning, + findInStrings: boolean, + findInComments: boolean, + result: ReferenceEntry[]): void { var sourceFile = container.getSourceFile(); + var tripleSlashDirectivePrefixRegex = /^\/\/\/\s* token.getStart(); + } + + function isInComment(position: number) { + var token = getTokenAtPosition(sourceFile, position); + if (token && position < token.getStart()) { + // First, we have to see if this position actually landed in a comment. + var commentRanges = getLeadingCommentRanges(sourceFile.text, token.pos); + + // Then we want to make sure that it wasn't in a "///<" directive comment + // We don't want to unintentionally update a file name. + return forEach(commentRanges, c => { + if (c.pos < position && position < c.end) { + var commentText = sourceFile.text.substring(c.pos, c.end); + if (!tripleSlashDirectivePrefixRegex.test(commentText)) { + return true; + } + } + }); + } + + return false; + } } function getReferencesForSuperKeyword(superKeyword: Node): ReferenceEntry[]{ From e6b5591ae91c96a706623b22e881162bd3edaffe Mon Sep 17 00:00:00 2001 From: Chris Bubernak Date: Fri, 3 Oct 2014 18:50:48 -0700 Subject: [PATCH 35/38] Updated baselines --- ...eticOperatorWithInvalidOperands.errors.txt | 29 ++--- ...WithNullValueAndInvalidOperands.errors.txt | 110 ++++++------------ ...ndefinedValueAndInvalidOperands.errors.txt | 110 ++++++------------ ...torWithIncompleteTypeAnnotation.errors.txt | 11 +- 4 files changed, 88 insertions(+), 172 deletions(-) diff --git a/tests/baselines/reference/arithmeticOperatorWithInvalidOperands.errors.txt b/tests/baselines/reference/arithmeticOperatorWithInvalidOperands.errors.txt index 668a7bef6a0..f58d2107e9f 100644 --- a/tests/baselines/reference/arithmeticOperatorWithInvalidOperands.errors.txt +++ b/tests/baselines/reference/arithmeticOperatorWithInvalidOperands.errors.txt @@ -395,8 +395,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(417,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(418,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(420,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(421,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(421,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(421,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(422,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(423,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(423,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -451,8 +450,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(474,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(475,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(477,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(478,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(478,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(478,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(479,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(480,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(480,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -507,8 +505,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(531,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(532,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(534,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(535,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(535,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(535,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(536,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(537,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(537,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -560,7 +557,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(581,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -==== tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts (560 errors) ==== +==== tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts (557 errors) ==== // these operators require their operands to be of type Any, the Number primitive type, or // an enum type enum E { a, b, c } @@ -1776,10 +1773,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r8b2 = b & b; - ~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~ +!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. var r8b3 = b & c; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -1945,10 +1940,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r9b2 = b ^ b; - ~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~ +!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. var r9b3 = b ^ c; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -2114,10 +2107,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r10b2 = b | b; - ~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~ +!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. var r10b3 = b | c; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. diff --git a/tests/baselines/reference/arithmeticOperatorWithNullValueAndInvalidOperands.errors.txt b/tests/baselines/reference/arithmeticOperatorWithNullValueAndInvalidOperands.errors.txt index 5ad26655c3c..3dd18398d58 100644 --- a/tests/baselines/reference/arithmeticOperatorWithNullValueAndInvalidOperands.errors.txt +++ b/tests/baselines/reference/arithmeticOperatorWithNullValueAndInvalidOperands.errors.txt @@ -166,81 +166,69 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(124,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(125,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(125,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(128,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(128,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(128,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(129,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(129,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(130,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(130,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(132,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(132,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(132,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(133,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(133,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(134,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(134,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(136,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(136,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(136,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(137,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(137,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(138,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(138,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(140,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(140,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(140,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(141,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(141,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(142,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(142,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(145,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(145,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(145,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(146,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(146,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(147,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(147,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(149,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(149,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(149,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(150,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(150,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(151,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(151,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(153,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(153,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(153,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(154,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(154,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(155,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(155,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(157,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(157,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(157,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(158,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(158,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(159,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(159,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(162,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(162,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(162,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(163,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(163,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(164,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(164,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(166,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(166,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(166,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(167,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(167,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(168,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(168,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(170,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(170,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(170,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(171,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(171,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(172,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(172,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(174,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(174,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(174,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(175,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(175,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(176,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(176,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -==== tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts (240 errors) ==== +==== tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts (228 errors) ==== // If one operand is the null or undefined value, it is treated as having the type of the // other operand. @@ -705,10 +693,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti // operator & var r8a1 = null & a; - ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~ +!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. var r8a2 = null & b; ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -721,10 +707,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r8b1 = a & null; - ~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~ +!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. var r8b2 = b & null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -737,10 +721,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r8c1 = null & true; - ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~~~ +!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. var r8c2 = null & ''; ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -753,10 +735,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r8d1 = true & null; - ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~~~ +!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. var r8d2 = '' & null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -770,10 +750,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti // operator ^ var r9a1 = null ^ a; - ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~ +!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. var r9a2 = null ^ b; ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -786,10 +764,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r9b1 = a ^ null; - ~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~ +!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. var r9b2 = b ^ null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -802,10 +778,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r9c1 = null ^ true; - ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~~~ +!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. var r9c2 = null ^ ''; ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -818,10 +792,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r9d1 = true ^ null; - ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~~~ +!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. var r9d2 = '' ^ null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -835,10 +807,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti // operator | var r10a1 = null | a; - ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~ +!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. var r10a2 = null | b; ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -851,10 +821,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r10b1 = a | null; - ~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~ +!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. var r10b2 = b | null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -867,10 +835,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r10c1 = null | true; - ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~~~ +!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. var r10c2 = null | ''; ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -883,10 +849,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r10d1 = true | null; - ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~~~ +!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. var r10d2 = '' | null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. diff --git a/tests/baselines/reference/arithmeticOperatorWithUndefinedValueAndInvalidOperands.errors.txt b/tests/baselines/reference/arithmeticOperatorWithUndefinedValueAndInvalidOperands.errors.txt index 7bd250ae661..994af459282 100644 --- a/tests/baselines/reference/arithmeticOperatorWithUndefinedValueAndInvalidOperands.errors.txt +++ b/tests/baselines/reference/arithmeticOperatorWithUndefinedValueAndInvalidOperands.errors.txt @@ -166,81 +166,69 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(124,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(125,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(125,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(128,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(128,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(128,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(129,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(129,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(130,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(130,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(132,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(132,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(132,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(133,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(133,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(134,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(134,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(136,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(136,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(136,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(137,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(137,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(138,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(138,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(140,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(140,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(140,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(141,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(141,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(142,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(142,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(145,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(145,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(145,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(146,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(146,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(147,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(147,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(149,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(149,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(149,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(150,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(150,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(151,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(151,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(153,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(153,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(153,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(154,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(154,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(155,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(155,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(157,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(157,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(157,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(158,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(158,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(159,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(159,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(162,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(162,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(162,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(163,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(163,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(164,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(164,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(166,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(166,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(166,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(167,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(167,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(168,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(168,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(170,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(170,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(170,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(171,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(171,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(172,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(172,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(174,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(174,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(174,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(175,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(175,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(176,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(176,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -==== tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts (240 errors) ==== +==== tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts (228 errors) ==== // If one operand is the undefined or undefined value, it is treated as having the type of the // other operand. @@ -705,10 +693,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti // operator & var r8a1 = undefined & a; - ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~~~~~ +!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. var r8a2 = undefined & b; ~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -721,10 +707,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r8b1 = a & undefined; - ~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~~~~~ +!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. var r8b2 = b & undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -737,10 +721,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r8c1 = undefined & true; - ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~~~~~~~~ +!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. var r8c2 = undefined & ''; ~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -753,10 +735,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r8d1 = true & undefined; - ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~~~~~~~~ +!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. var r8d2 = '' & undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -770,10 +750,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti // operator ^ var r9a1 = undefined ^ a; - ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~~~~~ +!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. var r9a2 = undefined ^ b; ~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -786,10 +764,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r9b1 = a ^ undefined; - ~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~~~~~ +!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. var r9b2 = b ^ undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -802,10 +778,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r9c1 = undefined ^ true; - ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~~~~~~~~ +!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. var r9c2 = undefined ^ ''; ~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -818,10 +792,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r9d1 = true ^ undefined; - ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~~~~~~~~ +!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. var r9d2 = '' ^ undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -835,10 +807,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti // operator | var r10a1 = undefined | a; - ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~~~~~ +!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. var r10a2 = undefined | b; ~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -851,10 +821,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r10b1 = a | undefined; - ~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~~~~~ +!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. var r10b2 = b | undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -867,10 +835,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r10c1 = undefined | true; - ~~~~~~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~~~~~~~~ +!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. var r10c2 = undefined | ''; ~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -883,10 +849,8 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti !!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r10d1 = true | undefined; - ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~~~~~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~~~~~~~~ +!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. var r10d2 = '' | undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. diff --git a/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt b/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt index 17b5398475a..ab82d01a819 100644 --- a/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt +++ b/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt @@ -72,8 +72,7 @@ tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(89,23): error TS tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(108,24): error TS2365: Operator '+' cannot be applied to types 'number' and 'boolean'. tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(159,31): error TS2304: Cannot find name 'Property'. tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(166,13): error TS2365: Operator '+=' cannot be applied to types 'number' and 'void'. -tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(180,40): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(180,47): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(180,40): error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(213,16): error TS2304: Cannot find name 'bool'. tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(218,29): error TS2304: Cannot find name 'yield'. tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(223,23): error TS2304: Cannot find name 'bool'. @@ -96,7 +95,7 @@ tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(259,29): error T tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(259,37): error TS2304: Cannot find name 'string'. -==== tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts (96 errors) ==== +==== tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts (95 errors) ==== declare module "fs" { export class File { constructor(filename: string); @@ -370,10 +369,8 @@ tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(259,37): error T var i = a[1];/*[]*/ i = i + i - i * i / i % i & i | i ^ i;/*+ - * / % & | ^*/ var b = true && false || true ^ false;/*& | ^*/ - ~~~~ -!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. - ~~~~~ -!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + ~~~~~~~~~~~~ +!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. b = !b;/*!*/ i = ~i;/*~i*/ b = i < (i - 1) && (i + 1) > i;/*< && >*/ From a500ac226629bbb230c8e37b6ffda71ca8f7a048 Mon Sep 17 00:00:00 2001 From: Chris Bubernak Date: Fri, 3 Oct 2014 18:58:50 -0700 Subject: [PATCH 36/38] specific type for function param --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index 4ee96be9bd7..d0e28b356b5 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5100,7 +5100,7 @@ module ts { } // if a user tries to apply an innappropriate operator to 2 boolean operands try and return them a helpful suggestion - function getSuggestedBooleanOperator(operator: any): SyntaxKind { + function getSuggestedBooleanOperator(operator: SyntaxKind): SyntaxKind { switch (operator) { case SyntaxKind.BarToken: case SyntaxKind.BarEqualsToken: From 6044e3aea3b29c18e47f90168c69d9ff2976da2c Mon Sep 17 00:00:00 2001 From: Chris Bubernak Date: Sat, 4 Oct 2014 10:10:55 -0700 Subject: [PATCH 37/38] Made fixes based on CR feedback --- src/compiler/checker.ts | 10 +-- .../diagnosticInformationMap.generated.ts | 2 +- src/compiler/diagnosticMessages.json | 2 +- ...eticOperatorWithInvalidOperands.errors.txt | 12 ++-- ...WithNullValueAndInvalidOperands.errors.txt | 48 +++++++------- ...ndefinedValueAndInvalidOperands.errors.txt | 48 +++++++------- ...wiseCompoundAssignmentOperators.errors.txt | 59 +++++++++++++++++ .../bitwiseCompoundAssignmentOperators.js | 63 +++++++++++++++++++ ...torWithIncompleteTypeAnnotation.errors.txt | 4 +- .../bitwiseCompoundAssignmentOperators.ts | 31 +++++++++ 10 files changed, 217 insertions(+), 62 deletions(-) create mode 100644 tests/baselines/reference/bitwiseCompoundAssignmentOperators.errors.txt create mode 100644 tests/baselines/reference/bitwiseCompoundAssignmentOperators.js create mode 100644 tests/cases/compiler/bitwiseCompoundAssignmentOperators.ts diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d0e28b356b5..d93df28b20b 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5023,12 +5023,15 @@ module ts { if (rightType.flags & (TypeFlags.Undefined | TypeFlags.Null)) rightType = leftType; var suggestedOperator: SyntaxKind; - // if both operands are booleans and we have a guess as to what the user meant to do return a helpful error - if ((leftType.flags & TypeFlags.Boolean) && (rightType.flags & TypeFlags.Boolean) && (suggestedOperator = getSuggestedBooleanOperator(node.operator)) !== undefined) { + // if a user tries to apply a bitwise operator to 2 boolean operands + // try and return them a helpful suggestion + if ((leftType.flags & TypeFlags.Boolean) && + (rightType.flags & TypeFlags.Boolean) && + (suggestedOperator = getSuggestedBooleanOperator(node.operator)) !== undefined) { error(node, Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, tokenToString(node.operator), tokenToString(suggestedOperator)); } - // otherwise just check each operand seperately and report errors as normal else { + // otherwise just check each operand seperately and report errors as normal var leftOk = checkArithmeticOperandType(node.left, leftType, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type); var rightOk = checkArithmeticOperandType(node.right, rightType, Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type); if (leftOk && rightOk) { @@ -5099,7 +5102,6 @@ module ts { return rightType; } - // if a user tries to apply an innappropriate operator to 2 boolean operands try and return them a helpful suggestion function getSuggestedBooleanOperator(operator: SyntaxKind): SyntaxKind { switch (operator) { case SyntaxKind.BarToken: diff --git a/src/compiler/diagnosticInformationMap.generated.ts b/src/compiler/diagnosticInformationMap.generated.ts index a430799ba50..ae51de69fa4 100644 --- a/src/compiler/diagnosticInformationMap.generated.ts +++ b/src/compiler/diagnosticInformationMap.generated.ts @@ -260,7 +260,7 @@ module ts { Property_0_is_protected_in_type_1_but_public_in_type_2: { code: 2444, category: DiagnosticCategory.Error, key: "Property '{0}' is protected in type '{1}' but public in type '{2}'." }, Property_0_is_protected_and_only_accessible_within_class_1_and_its_subclasses: { code: 2445, category: DiagnosticCategory.Error, key: "Property '{0}' is protected and only accessible within class '{1}' and its subclasses." }, Property_0_is_protected_and_only_accessible_through_an_instance_of_class_1: { code: 2446, category: DiagnosticCategory.Error, key: "Property '{0}' is protected and only accessible through an instance of class '{1}'." }, - The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead: { code: 2447, category: DiagnosticCategory.Error, key: "The '{0}' operator is not allowed for boolean types. Consider using {1} instead." }, + The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead: { code: 2447, category: DiagnosticCategory.Error, key: "The '{0}' operator is not allowed for boolean types. Consider using '{1}' instead." }, Import_declaration_0_is_using_private_name_1: { code: 4000, category: DiagnosticCategory.Error, key: "Import declaration '{0}' is using private name '{1}'." }, Type_parameter_0_of_exported_class_has_or_is_using_name_1_from_private_module_2: { code: 4001, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using name '{1}' from private module '{2}'." }, Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: { code: 4002, category: DiagnosticCategory.Error, key: "Type parameter '{0}' of exported class has or is using private name '{1}'." }, diff --git a/src/compiler/diagnosticMessages.json b/src/compiler/diagnosticMessages.json index d715c898510..12418bff929 100644 --- a/src/compiler/diagnosticMessages.json +++ b/src/compiler/diagnosticMessages.json @@ -1032,7 +1032,7 @@ "category": "Error", "code": 2446 }, - "The '{0}' operator is not allowed for boolean types. Consider using {1} instead.": { + "The '{0}' operator is not allowed for boolean types. Consider using '{1}' instead.": { "category": "Error", "code": 2447 }, diff --git a/tests/baselines/reference/arithmeticOperatorWithInvalidOperands.errors.txt b/tests/baselines/reference/arithmeticOperatorWithInvalidOperands.errors.txt index f58d2107e9f..0d376912b8d 100644 --- a/tests/baselines/reference/arithmeticOperatorWithInvalidOperands.errors.txt +++ b/tests/baselines/reference/arithmeticOperatorWithInvalidOperands.errors.txt @@ -395,7 +395,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(417,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(418,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(420,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(421,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(421,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(422,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(423,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(423,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -450,7 +450,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(474,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(475,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(477,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(478,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(478,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(479,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(480,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(480,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -505,7 +505,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(531,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(532,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(534,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(535,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(535,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(536,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(537,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithInvalidOperands.ts(537,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -1774,7 +1774,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r8b2 = b & b; ~~~~~ -!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. +!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. var r8b3 = b & c; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -1941,7 +1941,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r9b2 = b ^ b; ~~~~~ -!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. +!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. var r9b3 = b ^ c; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -2108,7 +2108,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. var r10b2 = b | b; ~~~~~ -!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. +!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. var r10b3 = b | c; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. diff --git a/tests/baselines/reference/arithmeticOperatorWithNullValueAndInvalidOperands.errors.txt b/tests/baselines/reference/arithmeticOperatorWithNullValueAndInvalidOperands.errors.txt index 3dd18398d58..c043cda8e68 100644 --- a/tests/baselines/reference/arithmeticOperatorWithNullValueAndInvalidOperands.errors.txt +++ b/tests/baselines/reference/arithmeticOperatorWithNullValueAndInvalidOperands.errors.txt @@ -166,62 +166,62 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(124,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(125,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(125,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(128,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(128,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(129,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(129,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(130,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(130,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(132,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(132,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(133,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(133,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(134,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(134,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(136,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(136,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(137,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(137,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(138,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(138,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(140,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(140,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(141,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(141,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(142,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(142,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(145,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(145,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(146,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(146,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(147,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(147,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(149,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(149,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(150,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(150,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(151,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(151,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(153,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(153,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(154,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(154,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(155,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(155,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(157,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(157,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(158,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(158,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(159,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(159,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(162,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(162,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(163,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(163,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(164,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(164,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(166,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(166,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(167,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(167,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(168,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(168,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(170,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(170,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(171,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(171,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(172,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(172,20): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(174,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(174,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(175,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(175,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithNullValueAndInvalidOperands.ts(176,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -694,7 +694,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti // operator & var r8a1 = null & a; ~~~~~~~~ -!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. +!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. var r8a2 = null & b; ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -708,7 +708,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti var r8b1 = a & null; ~~~~~~~~ -!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. +!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. var r8b2 = b & null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -722,7 +722,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti var r8c1 = null & true; ~~~~~~~~~~~ -!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. +!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. var r8c2 = null & ''; ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -736,7 +736,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti var r8d1 = true & null; ~~~~~~~~~~~ -!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. +!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. var r8d2 = '' & null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -751,7 +751,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti // operator ^ var r9a1 = null ^ a; ~~~~~~~~ -!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. +!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. var r9a2 = null ^ b; ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -765,7 +765,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti var r9b1 = a ^ null; ~~~~~~~~ -!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. +!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. var r9b2 = b ^ null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -779,7 +779,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti var r9c1 = null ^ true; ~~~~~~~~~~~ -!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. +!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. var r9c2 = null ^ ''; ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -793,7 +793,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti var r9d1 = true ^ null; ~~~~~~~~~~~ -!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. +!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. var r9d2 = '' ^ null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -808,7 +808,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti // operator | var r10a1 = null | a; ~~~~~~~~ -!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. +!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. var r10a2 = null | b; ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -822,7 +822,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti var r10b1 = a | null; ~~~~~~~~ -!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. +!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. var r10b2 = b | null; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -836,7 +836,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti var r10c1 = null | true; ~~~~~~~~~~~ -!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. +!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. var r10c2 = null | ''; ~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -850,7 +850,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti var r10d1 = true | null; ~~~~~~~~~~~ -!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. +!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. var r10d2 = '' | null; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. diff --git a/tests/baselines/reference/arithmeticOperatorWithUndefinedValueAndInvalidOperands.errors.txt b/tests/baselines/reference/arithmeticOperatorWithUndefinedValueAndInvalidOperands.errors.txt index 994af459282..9ee53c2f15c 100644 --- a/tests/baselines/reference/arithmeticOperatorWithUndefinedValueAndInvalidOperands.errors.txt +++ b/tests/baselines/reference/arithmeticOperatorWithUndefinedValueAndInvalidOperands.errors.txt @@ -166,62 +166,62 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(124,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(125,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(125,19): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(128,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(128,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(129,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(129,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(130,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(130,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(132,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(132,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(133,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(133,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(134,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(134,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(136,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(136,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(137,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(137,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(138,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(138,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(140,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(140,12): error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(141,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(141,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(142,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(142,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(145,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(145,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(146,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(146,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(147,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(147,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(149,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(149,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(150,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(150,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(151,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(151,16): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(153,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(153,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(154,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(154,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(155,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(155,24): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(157,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(157,12): error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(158,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(158,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(159,12): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(159,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(162,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(162,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(163,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(163,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(164,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(164,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(166,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(166,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(167,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(167,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(168,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(168,17): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(170,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(170,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(171,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(171,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(172,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(172,25): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. -tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(174,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. +tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(174,13): error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(175,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(175,18): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeticOperatorWithUndefinedValueAndInvalidOperands.ts(176,13): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -694,7 +694,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti // operator & var r8a1 = undefined & a; ~~~~~~~~~~~~~ -!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. +!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. var r8a2 = undefined & b; ~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -708,7 +708,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti var r8b1 = a & undefined; ~~~~~~~~~~~~~ -!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. +!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. var r8b2 = b & undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -722,7 +722,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti var r8c1 = undefined & true; ~~~~~~~~~~~~~~~~ -!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. +!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. var r8c2 = undefined & ''; ~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -736,7 +736,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti var r8d1 = true & undefined; ~~~~~~~~~~~~~~~~ -!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using && instead. +!!! error TS2447: The '&' operator is not allowed for boolean types. Consider using '&&' instead. var r8d2 = '' & undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -751,7 +751,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti // operator ^ var r9a1 = undefined ^ a; ~~~~~~~~~~~~~ -!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. +!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. var r9a2 = undefined ^ b; ~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -765,7 +765,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti var r9b1 = a ^ undefined; ~~~~~~~~~~~~~ -!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. +!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. var r9b2 = b ^ undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -779,7 +779,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti var r9c1 = undefined ^ true; ~~~~~~~~~~~~~~~~ -!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. +!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. var r9c2 = undefined ^ ''; ~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -793,7 +793,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti var r9d1 = true ^ undefined; ~~~~~~~~~~~~~~~~ -!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. +!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. var r9d2 = '' ^ undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -808,7 +808,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti // operator | var r10a1 = undefined | a; ~~~~~~~~~~~~~ -!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. +!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. var r10a2 = undefined | b; ~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -822,7 +822,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti var r10b1 = a | undefined; ~~~~~~~~~~~~~ -!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. +!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. var r10b2 = b | undefined; ~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -836,7 +836,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti var r10c1 = undefined | true; ~~~~~~~~~~~~~~~~ -!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. +!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. var r10c2 = undefined | ''; ~~~~~~~~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. @@ -850,7 +850,7 @@ tests/cases/conformance/expressions/binaryOperators/arithmeticOperator/arithmeti var r10d1 = true | undefined; ~~~~~~~~~~~~~~~~ -!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using || instead. +!!! error TS2447: The '|' operator is not allowed for boolean types. Consider using '||' instead. var r10d2 = '' | undefined; ~~ !!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. diff --git a/tests/baselines/reference/bitwiseCompoundAssignmentOperators.errors.txt b/tests/baselines/reference/bitwiseCompoundAssignmentOperators.errors.txt new file mode 100644 index 00000000000..1cd51984682 --- /dev/null +++ b/tests/baselines/reference/bitwiseCompoundAssignmentOperators.errors.txt @@ -0,0 +1,59 @@ +tests/cases/compiler/bitwiseCompoundAssignmentOperators.ts(3,1): error TS2447: The '^=' operator is not allowed for boolean types. Consider using '!==' instead. +tests/cases/compiler/bitwiseCompoundAssignmentOperators.ts(7,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/compiler/bitwiseCompoundAssignmentOperators.ts(9,6): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/compiler/bitwiseCompoundAssignmentOperators.ts(14,1): error TS2447: The '&=' operator is not allowed for boolean types. Consider using '&&' instead. +tests/cases/compiler/bitwiseCompoundAssignmentOperators.ts(18,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/compiler/bitwiseCompoundAssignmentOperators.ts(20,6): error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. +tests/cases/compiler/bitwiseCompoundAssignmentOperators.ts(24,1): error TS2447: The '|=' operator is not allowed for boolean types. Consider using '||' instead. +tests/cases/compiler/bitwiseCompoundAssignmentOperators.ts(28,1): error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + + +==== tests/cases/compiler/bitwiseCompoundAssignmentOperators.ts (8 errors) ==== + var a = true; + var b = 1; + a ^= a; + ~~~~~~ +!!! error TS2447: The '^=' operator is not allowed for boolean types. Consider using '!==' instead. + a = true; + b ^= b; + b = 1; + a ^= b; + ~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + a = true; + b ^= a; + ~ +!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + b = 1; + + var c = false; + var d = 2; + c &= c; + ~~~~~~ +!!! error TS2447: The '&=' operator is not allowed for boolean types. Consider using '&&' instead. + c = false; + d &= d; + d = 2; + c &= d; + ~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + c = false; + d &= c; + ~ +!!! error TS2363: The right-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + + var e = true; + var f = 0; + e |= e; + ~~~~~~ +!!! error TS2447: The '|=' operator is not allowed for boolean types. Consider using '||' instead. + e = true; + f |= f; + f = 0; + e |= f; + ~ +!!! error TS2362: The left-hand side of an arithmetic operation must be of type 'any', 'number' or an enum type. + e = true; + f |= f; + + \ No newline at end of file diff --git a/tests/baselines/reference/bitwiseCompoundAssignmentOperators.js b/tests/baselines/reference/bitwiseCompoundAssignmentOperators.js new file mode 100644 index 00000000000..e9bfeabb965 --- /dev/null +++ b/tests/baselines/reference/bitwiseCompoundAssignmentOperators.js @@ -0,0 +1,63 @@ +//// [bitwiseCompoundAssignmentOperators.ts] +var a = true; +var b = 1; +a ^= a; +a = true; +b ^= b; +b = 1; +a ^= b; +a = true; +b ^= a; +b = 1; + +var c = false; +var d = 2; +c &= c; +c = false; +d &= d; +d = 2; +c &= d; +c = false; +d &= c; + +var e = true; +var f = 0; +e |= e; +e = true; +f |= f; +f = 0; +e |= f; +e = true; +f |= f; + + + +//// [bitwiseCompoundAssignmentOperators.js] +var a = true; +var b = 1; +a ^= a; +a = true; +b ^= b; +b = 1; +a ^= b; +a = true; +b ^= a; +b = 1; +var c = false; +var d = 2; +c &= c; +c = false; +d &= d; +d = 2; +c &= d; +c = false; +d &= c; +var e = true; +var f = 0; +e |= e; +e = true; +f |= f; +f = 0; +e |= f; +e = true; +f |= f; diff --git a/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt b/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt index ab82d01a819..0e91d11b280 100644 --- a/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt +++ b/tests/baselines/reference/constructorWithIncompleteTypeAnnotation.errors.txt @@ -72,7 +72,7 @@ tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(89,23): error TS tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(108,24): error TS2365: Operator '+' cannot be applied to types 'number' and 'boolean'. tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(159,31): error TS2304: Cannot find name 'Property'. tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(166,13): error TS2365: Operator '+=' cannot be applied to types 'number' and 'void'. -tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(180,40): error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. +tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(180,40): error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(213,16): error TS2304: Cannot find name 'bool'. tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(218,29): error TS2304: Cannot find name 'yield'. tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(223,23): error TS2304: Cannot find name 'bool'. @@ -370,7 +370,7 @@ tests/cases/compiler/constructorWithIncompleteTypeAnnotation.ts(259,37): error T i = i + i - i * i / i % i & i | i ^ i;/*+ - * / % & | ^*/ var b = true && false || true ^ false;/*& | ^*/ ~~~~~~~~~~~~ -!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using !== instead. +!!! error TS2447: The '^' operator is not allowed for boolean types. Consider using '!==' instead. b = !b;/*!*/ i = ~i;/*~i*/ b = i < (i - 1) && (i + 1) > i;/*< && >*/ diff --git a/tests/cases/compiler/bitwiseCompoundAssignmentOperators.ts b/tests/cases/compiler/bitwiseCompoundAssignmentOperators.ts new file mode 100644 index 00000000000..29f10cbf38e --- /dev/null +++ b/tests/cases/compiler/bitwiseCompoundAssignmentOperators.ts @@ -0,0 +1,31 @@ +var a = true; +var b = 1; +a ^= a; +a = true; +b ^= b; +b = 1; +a ^= b; +a = true; +b ^= a; +b = 1; + +var c = false; +var d = 2; +c &= c; +c = false; +d &= d; +d = 2; +c &= d; +c = false; +d &= c; + +var e = true; +var f = 0; +e |= e; +e = true; +f |= f; +f = 0; +e |= f; +e = true; +f |= f; + From 739885381771db522d6af162f7703cc93970e0bd Mon Sep 17 00:00:00 2001 From: Chris Bubernak Date: Sat, 4 Oct 2014 11:25:16 -0700 Subject: [PATCH 38/38] fixed spelling mistake --- src/compiler/checker.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/compiler/checker.ts b/src/compiler/checker.ts index d93df28b20b..8915606f235 100644 --- a/src/compiler/checker.ts +++ b/src/compiler/checker.ts @@ -5031,7 +5031,7 @@ module ts { error(node, Diagnostics.The_0_operator_is_not_allowed_for_boolean_types_Consider_using_1_instead, tokenToString(node.operator), tokenToString(suggestedOperator)); } else { - // otherwise just check each operand seperately and report errors as normal + // otherwise just check each operand separately and report errors as normal var leftOk = checkArithmeticOperandType(node.left, leftType, Diagnostics.The_left_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type); var rightOk = checkArithmeticOperandType(node.right, rightType, Diagnostics.The_right_hand_side_of_an_arithmetic_operation_must_be_of_type_any_number_or_an_enum_type); if (leftOk && rightOk) {