-
Notifications
You must be signed in to change notification settings - Fork 13.1k
Fix crash pulling on global types before they're initialized #46471
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
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -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)); | ||
| } | ||
| 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)); | ||
|
|
||
| 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 { | ||
| 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; | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 = {}; | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 = {}; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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)) | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 : {} | ||
| >{} : {} | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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 = {}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So the original change also added this. This means that while we're doing symbol merging, we're asking for the merged symbol. Is this also a problem?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nope.