Fix getting completion details for meta properties (#45031)

* Fix getting completion details for meta properties.

* Move inside the worker.

* Move ImportMeta handling to completions.ts

* Fix property type name for new.target.

* Use symbols for ImportMeta completions.

* Accept baselines.

* Revert lib change.

* Revert needless parser change.

* Missed these reverts.

* Remove now unused `isMetaPropertyExpression`

* Move up meta property keyword check to be done in `getSymbolAtLocation` and `getTypeOfNode`

* Call `checkNewTargetMetaProperty` directly and handle when it's an error type.

* Make meta property expression types synthetic.

* Make event.target and import.meta properties readonly

* Add a test for go to definition (I think?)

* Copy built-in types/values test for go to definition.

* Add tests for go to definition when not a module.

* Fix "go to definition" for new.target
This commit is contained in:
David Sherret
2021-08-04 12:41:04 -04:00
committed by GitHub
parent 318930b9e3
commit 03dff41c9f
20 changed files with 235 additions and 8 deletions

View File

@@ -921,6 +921,7 @@ namespace ts {
let deferredGlobalAsyncGeneratorType: GenericType;
let deferredGlobalTemplateStringsArrayType: ObjectType;
let deferredGlobalImportMetaType: ObjectType;
let deferredGlobalImportMetaExpressionType: ObjectType;
let deferredGlobalExtractSymbol: Symbol;
let deferredGlobalOmitSymbol: Symbol;
let deferredGlobalBigIntType: ObjectType;
@@ -13324,6 +13325,24 @@ namespace ts {
return deferredGlobalImportMetaType || (deferredGlobalImportMetaType = getGlobalType("ImportMeta" as __String, /*arity*/ 0, /*reportErrors*/ true)) || emptyObjectType;
}
function getGlobalImportMetaExpressionType() {
if (!deferredGlobalImportMetaExpressionType) {
// Create a synthetic type `ImportMetaExpression { meta: MetaProperty }`
const symbol = createSymbol(SymbolFlags.None, "ImportMetaExpression" as __String);
const importMetaType = getGlobalImportMetaType();
const metaPropertySymbol = createSymbol(SymbolFlags.Property, "meta" as __String, CheckFlags.Readonly);
metaPropertySymbol.parent = symbol;
metaPropertySymbol.type = importMetaType;
const members = createSymbolTable([metaPropertySymbol]);
symbol.members = members;
deferredGlobalImportMetaExpressionType = createAnonymousType(symbol, members, emptyArray, emptyArray, emptyArray);
}
return deferredGlobalImportMetaExpressionType;
}
function getGlobalESSymbolConstructorSymbol(reportErrors: boolean) {
return deferredGlobalESSymbolConstructorSymbol || (deferredGlobalESSymbolConstructorSymbol = getGlobalValueSymbol("Symbol" as __String, reportErrors));
}
@@ -30465,6 +30484,18 @@ namespace ts {
return Debug.assertNever(node.keywordToken);
}
function checkMetaPropertyKeyword(node: MetaProperty): Type {
switch (node.keywordToken) {
case SyntaxKind.ImportKeyword:
return getGlobalImportMetaExpressionType();
case SyntaxKind.NewKeyword:
const type = checkNewTargetMetaProperty(node);
return type === errorType ? errorType : createNewTargetExpressionType(type);
default:
Debug.assertNever(node.keywordToken);
}
}
function checkNewTargetMetaProperty(node: MetaProperty) {
const container = getNewTargetContainer(node);
if (!container) {
@@ -30487,7 +30518,6 @@ namespace ts {
}
const file = getSourceFileOfNode(node);
Debug.assert(!!(file.flags & NodeFlags.PossiblyContainsImportMeta), "Containing file is missing import meta node flag.");
Debug.assert(!!file.externalModuleIndicator, "Containing file should be a module.");
return node.name.escapedText === "meta" ? getGlobalImportMetaType() : errorType;
}
@@ -30849,6 +30879,19 @@ namespace ts {
return promiseType;
}
function createNewTargetExpressionType(targetType: Type): Type {
// Create a synthetic type `NewTargetExpression { target: TargetType; }`
const symbol = createSymbol(SymbolFlags.None, "NewTargetExpression" as __String);
const targetPropertySymbol = createSymbol(SymbolFlags.Property, "target" as __String, CheckFlags.Readonly);
targetPropertySymbol.parent = symbol;
targetPropertySymbol.type = targetType;
const members = createSymbolTable([targetPropertySymbol]);
symbol.members = members;
return createAnonymousType(symbol, members, emptyArray, emptyArray, emptyArray);
}
function getReturnTypeFromBody(func: FunctionLikeDeclaration, checkMode?: CheckMode): Type {
if (!func.body) {
return errorType;
@@ -39784,6 +39827,16 @@ namespace ts {
return propertyDeclaration;
}
}
else if (isMetaProperty(parent)) {
const parentType = getTypeOfNode(parent);
const propertyDeclaration = getPropertyOfType(parentType, (node as Identifier).escapedText);
if (propertyDeclaration) {
return propertyDeclaration;
}
if (parent.keywordToken === SyntaxKind.NewKeyword) {
return checkNewTargetMetaProperty(parent).symbol;
}
}
}
switch (node.kind) {
@@ -39858,6 +39911,12 @@ namespace ts {
case SyntaxKind.ExportKeyword:
return isExportAssignment(node.parent) ? Debug.checkDefined(node.parent.symbol) : undefined;
case SyntaxKind.ImportKeyword:
case SyntaxKind.NewKeyword:
return isMetaProperty(node.parent) ? checkMetaPropertyKeyword(node.parent).symbol : undefined;
case SyntaxKind.MetaProperty:
return checkExpression(node as Expression).symbol;
default:
return undefined;
}
@@ -39957,6 +40016,10 @@ namespace ts {
}
}
if (isMetaProperty(node.parent) && node.parent.keywordToken === node.kind) {
return checkMetaPropertyKeyword(node.parent);
}
return errorType;
}