Fix crash pulling on global types before they're initialized (#46471)
* Add failing test * Dumb fix * Compute error message info more lazily * One more laziness
This commit is contained in:
parent
6b6665e6ae
commit
3519af0bab
|
@ -3275,21 +3275,40 @@ namespace ts {
|
|||
const namespaceName = getFullyQualifiedName(namespace);
|
||||
const declarationName = declarationNameToString(right);
|
||||
const suggestionForNonexistentModule = getSuggestedSymbolForNonexistentModule(right, namespace);
|
||||
const exportedTypeSymbol = getMergedSymbol(getSymbol(getExportsOfSymbol(namespace), right.escapedText, SymbolFlags.Type));
|
||||
const containingQualifiedName = isQualifiedName(name) && getContainingQualifiedNameNode(name);
|
||||
const canSuggestTypeof = containingQualifiedName && !isTypeOfExpression(containingQualifiedName.parent) && tryGetQualifiedNameAsValue(containingQualifiedName);
|
||||
if (suggestionForNonexistentModule) {
|
||||
error(right, Diagnostics._0_has_no_exported_member_named_1_Did_you_mean_2, namespaceName, declarationName, symbolToString(suggestionForNonexistentModule));
|
||||
return undefined;
|
||||
}
|
||||
else if (canSuggestTypeof) {
|
||||
error(containingQualifiedName, Diagnostics._0_refers_to_a_value_but_is_being_used_as_a_type_here_Did_you_mean_typeof_0, entityNameToString(containingQualifiedName));
|
||||
|
||||
const containingQualifiedName = isQualifiedName(name) && getContainingQualifiedNameNode(name);
|
||||
const canSuggestTypeof = globalObjectType // <-- can't pull on types if global types aren't initialized yet
|
||||
&& (meaning & SymbolFlags.Type)
|
||||
&& containingQualifiedName
|
||||
&& !isTypeOfExpression(containingQualifiedName.parent)
|
||||
&& tryGetQualifiedNameAsValue(containingQualifiedName);
|
||||
if (canSuggestTypeof) {
|
||||
error(
|
||||
containingQualifiedName,
|
||||
Diagnostics._0_refers_to_a_value_but_is_being_used_as_a_type_here_Did_you_mean_typeof_0,
|
||||
entityNameToString(containingQualifiedName)
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
else if (meaning & SymbolFlags.Namespace && exportedTypeSymbol && isQualifiedName(name.parent)) {
|
||||
error(name.parent.right, Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1, symbolToString(exportedTypeSymbol), unescapeLeadingUnderscores(name.parent.right.escapedText));
|
||||
}
|
||||
else {
|
||||
error(right, Diagnostics.Namespace_0_has_no_exported_member_1, namespaceName, declarationName);
|
||||
|
||||
if (meaning & SymbolFlags.Namespace && isQualifiedName(name.parent)) {
|
||||
const exportedTypeSymbol = getMergedSymbol(getSymbol(getExportsOfSymbol(namespace), right.escapedText, SymbolFlags.Type));
|
||||
if (exportedTypeSymbol) {
|
||||
error(
|
||||
name.parent.right,
|
||||
Diagnostics.Cannot_access_0_1_because_0_is_a_type_but_not_a_namespace_Did_you_mean_to_retrieve_the_type_of_the_property_1_in_0_with_0_1,
|
||||
symbolToString(exportedTypeSymbol),
|
||||
unescapeLeadingUnderscores(name.parent.right.escapedText)
|
||||
);
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
error(right, Diagnostics.Namespace_0_has_no_exported_member_1, namespaceName, declarationName);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
|
15
tests/baselines/reference/importEqualsError45874.errors.txt
Normal file
15
tests/baselines/reference/importEqualsError45874.errors.txt
Normal file
|
@ -0,0 +1,15 @@
|
|||
/globals.ts(5,22): error TS2694: Namespace 'globals' has no exported member 'toString'.
|
||||
|
||||
|
||||
==== /globals.ts (1 errors) ====
|
||||
namespace globals {
|
||||
export type Foo = {};
|
||||
export const Bar = {};
|
||||
}
|
||||
import Foo = globals.toString.Blah;
|
||||
~~~~~~~~
|
||||
!!! error TS2694: Namespace 'globals' has no exported member 'toString'.
|
||||
|
||||
==== /index.ts (0 errors) ====
|
||||
const Foo = {};
|
||||
|
21
tests/baselines/reference/importEqualsError45874.js
Normal file
21
tests/baselines/reference/importEqualsError45874.js
Normal file
|
@ -0,0 +1,21 @@
|
|||
//// [tests/cases/compiler/importEqualsError45874.ts] ////
|
||||
|
||||
//// [globals.ts]
|
||||
namespace globals {
|
||||
export type Foo = {};
|
||||
export const Bar = {};
|
||||
}
|
||||
import Foo = globals.toString.Blah;
|
||||
|
||||
//// [index.ts]
|
||||
const Foo = {};
|
||||
|
||||
|
||||
//// [globals.js]
|
||||
var globals;
|
||||
(function (globals) {
|
||||
globals.Bar = {};
|
||||
})(globals || (globals = {}));
|
||||
var Foo = globals.toString.Blah;
|
||||
//// [index.js]
|
||||
var Foo = {};
|
18
tests/baselines/reference/importEqualsError45874.symbols
Normal file
18
tests/baselines/reference/importEqualsError45874.symbols
Normal file
|
@ -0,0 +1,18 @@
|
|||
=== /globals.ts ===
|
||||
namespace globals {
|
||||
>globals : Symbol(globals, Decl(globals.ts, 0, 0))
|
||||
|
||||
export type Foo = {};
|
||||
>Foo : Symbol(Foo, Decl(globals.ts, 0, 19))
|
||||
|
||||
export const Bar = {};
|
||||
>Bar : Symbol(Bar, Decl(globals.ts, 2, 14))
|
||||
}
|
||||
import Foo = globals.toString.Blah;
|
||||
>Foo : Symbol(Foo, Decl(globals.ts, 3, 1))
|
||||
>globals : Symbol(globals, Decl(globals.ts, 0, 0))
|
||||
|
||||
=== /index.ts ===
|
||||
const Foo = {};
|
||||
>Foo : Symbol(Foo, Decl(index.ts, 0, 5))
|
||||
|
22
tests/baselines/reference/importEqualsError45874.types
Normal file
22
tests/baselines/reference/importEqualsError45874.types
Normal file
|
@ -0,0 +1,22 @@
|
|||
=== /globals.ts ===
|
||||
namespace globals {
|
||||
>globals : typeof globals
|
||||
|
||||
export type Foo = {};
|
||||
>Foo : Foo
|
||||
|
||||
export const Bar = {};
|
||||
>Bar : {}
|
||||
>{} : {}
|
||||
}
|
||||
import Foo = globals.toString.Blah;
|
||||
>Foo : any
|
||||
>globals : typeof globals
|
||||
>toString : any
|
||||
>Blah : any
|
||||
|
||||
=== /index.ts ===
|
||||
const Foo = {};
|
||||
>Foo : {}
|
||||
>{} : {}
|
||||
|
9
tests/cases/compiler/importEqualsError45874.ts
Normal file
9
tests/cases/compiler/importEqualsError45874.ts
Normal file
|
@ -0,0 +1,9 @@
|
|||
// @Filename: /globals.ts
|
||||
namespace globals {
|
||||
export type Foo = {};
|
||||
export const Bar = {};
|
||||
}
|
||||
import Foo = globals.toString.Blah;
|
||||
|
||||
// @Filename: /index.ts
|
||||
const Foo = {};
|
Loading…
Reference in a new issue