Skip to content

Related error spans on "used before declared" error messages #25359

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Jul 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 26 additions & 7 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1655,14 +1655,25 @@ namespace ts {
if (declaration === undefined) return Debug.fail("Declaration to checkResolvedBlockScopedVariable is undefined");

if (!(declaration.flags & NodeFlags.Ambient) && !isBlockScopedNameDeclaredBeforeUse(declaration, errorLocation)) {
let diagnosticMessage;
const declarationName = declarationNameToString(getNameOfDeclaration(declaration));
if (result.flags & SymbolFlags.BlockScopedVariable) {
error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, declarationNameToString(getNameOfDeclaration(declaration)));
diagnosticMessage = error(errorLocation, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, declarationName);
}
else if (result.flags & SymbolFlags.Class) {
error(errorLocation, Diagnostics.Class_0_used_before_its_declaration, declarationNameToString(getNameOfDeclaration(declaration)));
diagnosticMessage = error(errorLocation, Diagnostics.Class_0_used_before_its_declaration, declarationName);
}
else if (result.flags & SymbolFlags.RegularEnum) {
error(errorLocation, Diagnostics.Enum_0_used_before_its_declaration, declarationNameToString(getNameOfDeclaration(declaration)));
diagnosticMessage = error(errorLocation, Diagnostics.Enum_0_used_before_its_declaration, declarationName);
}
else {
Debug.assert(!!(result.flags & SymbolFlags.ConstEnum));
}

if (diagnosticMessage) {
addRelatedInfo(diagnosticMessage,
createDiagnosticForNode(declaration, Diagnostics._0_was_declared_here, declarationName)
);
}
}
}
Expand Down Expand Up @@ -17460,16 +17471,24 @@ namespace ts {
return;
}

let diagnosticMessage;
const declarationName = idText(right);
if (isInPropertyInitializer(node) &&
!isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right)
&& !isPropertyDeclaredInAncestorClass(prop)) {
error(right, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, idText(right));
diagnosticMessage = error(right, Diagnostics.Block_scoped_variable_0_used_before_its_declaration, declarationName);
}
else if (valueDeclaration.kind === SyntaxKind.ClassDeclaration &&
node.parent.kind !== SyntaxKind.TypeReference &&
!(valueDeclaration.flags & NodeFlags.Ambient) &&
!isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right)) {
error(right, Diagnostics.Class_0_used_before_its_declaration, idText(right));
diagnosticMessage = error(right, Diagnostics.Class_0_used_before_its_declaration, declarationName);
}

if (diagnosticMessage) {
addRelatedInfo(diagnosticMessage,
createDiagnosticForNode(valueDeclaration, Diagnostics._0_was_declared_here, declarationName)
);
}
}

Expand Down Expand Up @@ -19083,8 +19102,8 @@ namespace ts {
if (importNode && !isImportCall(importNode)) {
const sigs = getSignaturesOfType(getTypeOfSymbol(getSymbolLinks(apparentType.symbol).target!), kind);
if (!sigs || !sigs.length) return;
diagnostic.relatedInformation = diagnostic.relatedInformation || [];
diagnostic.relatedInformation.push(createDiagnosticForNode(importNode, Diagnostics.Type_originates_at_this_import_A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime_Consider_using_a_default_import_or_import_require_here_instead));
Debug.assert(!diagnostic.relatedInformation);
diagnostic.relatedInformation = [createDiagnosticForNode(importNode, Diagnostics.Type_originates_at_this_import_A_namespace_style_import_cannot_be_called_or_constructed_and_will_cause_a_failure_at_runtime_Consider_using_a_default_import_or_import_require_here_instead)];
Copy link
Member

@weswigham weswigham Jul 2, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we're going to update this, we should probably just update it to use addRelatedInfo. This can actually potentially stack with the related info provided by #25140, after all, since they're for the same (assignability) diagnostics.

}
}

Expand Down
4 changes: 4 additions & 0 deletions src/compiler/diagnosticMessages.json
Original file line number Diff line number Diff line change
Expand Up @@ -2397,6 +2397,10 @@
"category": "Error",
"code": 2727
},
"'{0}' was declared here.": {
"category": "Error",
"code": 2728
},

"Import declaration '{0}' is using private name '{1}'.": {
"category": "Error",
Expand Down
1 change: 1 addition & 0 deletions tests/baselines/reference/ES5For-of17.errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ tests/cases/conformance/statements/for-ofStatements/ES5For-of17.ts(3,20): error
for (let v of [v]) {
~
!!! error TS2448: Block-scoped variable 'v' used before its declaration.
!!! related TS2728 tests/cases/conformance/statements/for-ofStatements/ES5For-of17.ts:3:14: 'v' was declared here.
var x = v;
v++;
}
Expand Down
1 change: 1 addition & 0 deletions tests/baselines/reference/ES5For-of20.errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ tests/cases/conformance/statements/for-ofStatements/ES5For-of20.ts(4,15): error
for (let v of [v]) {
~
!!! error TS2448: Block-scoped variable 'v' used before its declaration.
!!! related TS2728 tests/cases/conformance/statements/for-ofStatements/ES5For-of20.ts:3:14: 'v' was declared here.
const v;
~
!!! error TS1155: 'const' declarations must be initialized.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ tests/cases/conformance/internalModules/DeclarationMerging/simple.ts(2,31): erro
export var Instance = new A();
~
!!! error TS2449: Class 'A' used before its declaration.
!!! related TS2728 tests/cases/conformance/internalModules/DeclarationMerging/simple.ts:6:7: 'A' was declared here.
}

// duplicate identifier
Expand Down
1 change: 1 addition & 0 deletions tests/baselines/reference/api/tsserverlibrary.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5418,6 +5418,7 @@ declare namespace ts {
Class_name_cannot_be_Object_when_targeting_ES5_with_module_0: DiagnosticMessage;
Cannot_find_lib_definition_for_0: DiagnosticMessage;
Cannot_find_lib_definition_for_0_Did_you_mean_1: DiagnosticMessage;
_0_was_declared_here: DiagnosticMessage;
Import_declaration_0_is_using_private_name_1: DiagnosticMessage;
Type_parameter_0_of_exported_class_has_or_is_using_private_name_1: DiagnosticMessage;
Type_parameter_0_of_exported_interface_has_or_is_using_private_name_1: DiagnosticMessage;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,16 @@ tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts(8,7): error TS2448: Bloc
for (let {[a]: a} of [{ }]) continue;
~
!!! error TS2448: Block-scoped variable 'a' used before its declaration.
!!! related TS2728 tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts:2:16: 'a' was declared here.

// 2:
for (let {[a]: a} = { }; false; ) continue;
~
!!! error TS2448: Block-scoped variable 'a' used before its declaration.
!!! related TS2728 tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts:5:16: 'a' was declared here.

// 3:
let {[b]: b} = { };
~
!!! error TS2448: Block-scoped variable 'b' used before its declaration.
!!! error TS2448: Block-scoped variable 'b' used before its declaration.
!!! related TS2728 tests/cases/compiler/blockScopedBindingUsedBeforeDef.ts:8:11: 'b' was declared here.
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts(100,12): error TS2448:
let a = x;
~
!!! error TS2448: Block-scoped variable 'x' used before its declaration.
!!! related TS2728 tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts:3:9: 'x' was declared here.
let x;
}

Expand Down Expand Up @@ -67,6 +68,7 @@ tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts(100,12): error TS2448:
static a = x;
~
!!! error TS2448: Block-scoped variable 'x' used before its declaration.
!!! related TS2728 tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts:60:9: 'x' was declared here.
}
let x;
}
Expand All @@ -76,6 +78,7 @@ tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts(100,12): error TS2448:
static a = x;
~
!!! error TS2448: Block-scoped variable 'x' used before its declaration.
!!! related TS2728 tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts:67:9: 'x' was declared here.
}
let x;
}
Expand Down Expand Up @@ -113,6 +116,7 @@ tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts(100,12): error TS2448:
a: x
~
!!! error TS2448: Block-scoped variable 'x' used before its declaration.
!!! related TS2728 tests/cases/compiler/blockScopedVariablesUseBeforeDef.ts:102:9: 'x' was declared here.
}
let x
}
1 change: 1 addition & 0 deletions tests/baselines/reference/circularImportAlias.errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ tests/cases/conformance/internalModules/importDeclarations/circularImportAlias.t
export class D extends a.C {
~
!!! error TS2449: Class 'C' used before its declaration.
!!! related TS2728 tests/cases/conformance/internalModules/importDeclarations/circularImportAlias.ts:11:18: 'C' was declared here.
id: number;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbst
var x : any = C;
~
!!! error TS2449: Class 'C' used before its declaration.
!!! related TS2728 tests/cases/conformance/classes/classDeclarations/classAbstractKeyword/classAbstractInstantiations2.ts:26:7: 'C' was declared here.
new x; // okay -- undefined behavior at runtime

class C extends B { } // error -- not declared abstract
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,18 @@ tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts(8,6):
static readonly [A.p1] = 0;
~
!!! error TS2449: Class 'A' used before its declaration.
!!! related TS2728 tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts:1:7: 'A' was declared here.
static [A.p2]() { return 0 };
~
!!! error TS2449: Class 'A' used before its declaration.
!!! related TS2728 tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts:1:7: 'A' was declared here.
[A.p1]() { }
~
!!! error TS2449: Class 'A' used before its declaration.
!!! related TS2728 tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts:1:7: 'A' was declared here.
[A.p2] = 0
~
!!! error TS2449: Class 'A' used before its declaration.
!!! related TS2728 tests/cases/compiler/classDeclarationShouldBeOutOfScopeInComputedNames.ts:1:7: 'A' was declared here.
}

Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/cla
!!! error TS2506: 'C' is referenced directly or indirectly in its own base expression.
~
!!! error TS2449: Class 'E' used before its declaration.
!!! related TS2728 tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly.ts:5:7: 'E' was declared here.

class D extends C { bar: string; }
~
Expand All @@ -28,6 +29,7 @@ tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/cla
!!! error TS2506: 'C2' is referenced directly or indirectly in its own base expression.
~~
!!! error TS2449: Class 'E2' used before its declaration.
!!! related TS2728 tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly.ts:11:7: 'E2' was declared here.

class D2<T> extends C2<T> { bar: T; }
~~
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/cla
!!! error TS2506: 'C' is referenced directly or indirectly in its own base expression.
~
!!! error TS2449: Class 'E' used before its declaration.
!!! related TS2728 tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly2.ts:9:18: 'E' was declared here.

module M {
export class D extends C { bar: string; }
Expand All @@ -34,6 +35,7 @@ tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/cla
!!! error TS2506: 'C2' is referenced directly or indirectly in its own base expression.
~~
!!! error TS2449: Class 'E2' used before its declaration.
!!! related TS2728 tests/cases/conformance/classes/classDeclarations/classHeritageSpecification/classExtendsItselfIndirectly2.ts:20:22: 'E2' was declared here.

module P {
export class D2<T> extends C2<T> { bar: T; }
Expand Down
1 change: 1 addition & 0 deletions tests/baselines/reference/classInheritence.errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ tests/cases/compiler/classInheritence.ts(2,7): error TS2506: 'A' is referenced d
class B extends A { }
~
!!! error TS2449: Class 'A' used before its declaration.
!!! related TS2728 tests/cases/compiler/classInheritence.ts:2:7: 'A' was declared here.
class A extends A { }
~
!!! error TS2506: 'A' is referenced directly or indirectly in its own base expression.
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,6 @@ tests/cases/compiler/classMergedWithInterfaceMultipleBasesNoError.ts(8,30): erro
readonly observer = this.handleIntersection;
~~~~~~~~~~~~~~~~~~
!!! error TS2448: Block-scoped variable 'handleIntersection' used before its declaration.
!!! related TS2728 tests/cases/compiler/classMergedWithInterfaceMultipleBasesNoError.ts:9:14: 'handleIntersection' was declared here.
readonly handleIntersection = () => { }
}
1 change: 1 addition & 0 deletions tests/baselines/reference/classOrder2.errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ tests/cases/compiler/classOrder2.ts(1,17): error TS2449: Class 'B' used before i
class A extends B {
~
!!! error TS2449: Class 'B' used before its declaration.
!!! related TS2728 tests/cases/compiler/classOrder2.ts:7:7: 'B' was declared here.

foo() { this.bar(); }

Expand Down
1 change: 1 addition & 0 deletions tests/baselines/reference/classSideInheritance2.errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ tests/cases/compiler/classSideInheritance2.ts(7,23): error TS2449: Class 'TextBa
class SubText extends TextBase {
~~~~~~~~
!!! error TS2449: Class 'TextBase' used before its declaration.
!!! related TS2728 tests/cases/compiler/classSideInheritance2.ts:14:7: 'TextBase' was declared here.

constructor(text: IText, span: TextSpan) {
super();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,21 @@ tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts(4,
static enumMember = Enum.A;
~~~~
!!! error TS2450: Enum 'Enum' used before its declaration.
!!! related TS2728 tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts:7:6: 'Enum' was declared here.
~
!!! error TS2448: Block-scoped variable 'A' used before its declaration.
!!! related TS2728 tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts:8:5: 'A' was declared here.
static objLiteralMember = ObjLiteral.A;
~~~~~~~~~~
!!! error TS2448: Block-scoped variable 'ObjLiteral' used before its declaration.
!!! related TS2728 tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts:11:7: 'ObjLiteral' was declared here.
~
!!! error TS2448: Block-scoped variable 'A' used before its declaration.
!!! related TS2728 tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts:12:5: 'A' was declared here.
static namespaceMember = Namespace.A;
~
!!! error TS2448: Block-scoped variable 'A' used before its declaration.
!!! related TS2728 tests/cases/compiler/classStaticInitializersUsePropertiesBeforeDeclaration.ts:16:16: 'A' was declared here.
}

enum Enum {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ tests/cases/compiler/complexClassRelationships.ts(2,23): error TS2449: Class 'Ba
class Derived extends Base {
~~~~
!!! error TS2449: Class 'Base' used before its declaration.
!!! related TS2728 tests/cases/compiler/complexClassRelationships.ts:13:7: 'Base' was declared here.
public static createEmpty(): Derived {
var item = new Derived();
return item;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@ tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticPr
get [C.staticProp]() {
~
!!! error TS2449: Class 'C' used before its declaration.
!!! related TS2728 tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticProperty.ts:1:7: 'C' was declared here.
return "hello";
}
set [C.staticProp](x: string) {
~
!!! error TS2449: Class 'C' used before its declaration.
!!! related TS2728 tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticProperty.ts:1:7: 'C' was declared here.
var y = x;
}
[C.staticProp]() { }
~
!!! error TS2449: Class 'C' used before its declaration.
!!! related TS2728 tests/cases/conformance/es6/computedProperties/computedPropertyNamesWithStaticProperty.ts:1:7: 'C' was declared here.
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ tests/cases/compiler/constDeclarations-useBeforeDefinition.ts(8,5): error TS2448
c1;
~~
!!! error TS2448: Block-scoped variable 'c1' used before its declaration.
!!! related TS2728 tests/cases/compiler/constDeclarations-useBeforeDefinition.ts:3:11: 'c1' was declared here.
const c1 = 0;
}

Expand All @@ -15,6 +16,7 @@ tests/cases/compiler/constDeclarations-useBeforeDefinition.ts(8,5): error TS2448
v1;
~~
!!! error TS2448: Block-scoped variable 'v1' used before its declaration.
!!! related TS2728 tests/cases/compiler/constDeclarations-useBeforeDefinition.ts:9:11: 'v1' was declared here.
const v1 = 0;
}

Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ tests/cases/compiler/file1.ts(1,1): error TS2448: Block-scoped variable 'c' used
c;
~
!!! error TS2448: Block-scoped variable 'c' used before its declaration.
!!! related TS2728 tests/cases/compiler/file2.ts:1:7: 'c' was declared here.

==== tests/cases/compiler/file2.ts (0 errors) ====
const c = 0;
1 change: 1 addition & 0 deletions tests/baselines/reference/derivedClasses.errors.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ tests/cases/compiler/derivedClasses.ts(1,19): error TS2449: Class 'Color' used b
class Red extends Color {
~~~~~
!!! error TS2449: Class 'Color' used before its declaration.
!!! related TS2728 tests/cases/compiler/derivedClasses.ts:8:7: 'Color' was declared here.
public shade() {
var getHue = () => { return this.hue(); };
return getHue() + " red";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@ tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAss
const [c, d = c, e = e] = [1]; // error for e = e
~
!!! error TS2448: Block-scoped variable 'e' used before its declaration.
!!! related TS2728 tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment3.ts:2:18: 'e' was declared here.
const [f, g = f, h = i, i = f] = [1]; // error for h = i
~
!!! error TS2448: Block-scoped variable 'i' used before its declaration.
!!! related TS2728 tests/cases/conformance/es6/destructuring/destructuringArrayBindingPatternAndAssignment3.ts:3:25: 'i' was declared here.

(function ([a, b = a]) { // ok
})([1]);
Expand Down
Loading