Add missing MetaProperty stuffs

Add missing parts in the binder and the checker to enable CFA +
narrowing of `import.meta` values.

Fixes #41468
This commit is contained in:
Eli Barzilay
2021-02-18 18:32:17 -05:00
parent 87d10eb055
commit d495957065
13 changed files with 179 additions and 9 deletions

View File

@@ -882,11 +882,11 @@ namespace ts {
}
function isNarrowableReference(expr: Expression): boolean {
return expr.kind === SyntaxKind.Identifier || expr.kind === SyntaxKind.PrivateIdentifier || expr.kind === SyntaxKind.ThisKeyword || expr.kind === SyntaxKind.SuperKeyword ||
(isPropertyAccessExpression(expr) || isNonNullExpression(expr) || isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression) ||
isBinaryExpression(expr) && expr.operatorToken.kind === SyntaxKind.CommaToken && isNarrowableReference(expr.right) ||
isElementAccessExpression(expr) && isStringOrNumericLiteralLike(expr.argumentExpression) && isNarrowableReference(expr.expression) ||
isAssignmentExpression(expr) && isNarrowableReference(expr.left);
return isDottedName(expr)
|| (isPropertyAccessExpression(expr) || isNonNullExpression(expr) || isParenthesizedExpression(expr)) && isNarrowableReference(expr.expression)
|| isBinaryExpression(expr) && expr.operatorToken.kind === SyntaxKind.CommaToken && isNarrowableReference(expr.right)
|| isElementAccessExpression(expr) && isStringOrNumericLiteralLike(expr.argumentExpression) && isNarrowableReference(expr.expression)
|| isAssignmentExpression(expr) && isNarrowableReference(expr.left);
}
function containsNarrowableReference(expr: Expression): boolean {
@@ -1369,7 +1369,7 @@ namespace ts {
// is potentially an assertion and is therefore included in the control flow.
if (node.kind === SyntaxKind.CallExpression) {
const call = <CallExpression>node;
if (isDottedName(call.expression) && call.expression.kind !== SyntaxKind.SuperKeyword) {
if (call.expression.kind !== SyntaxKind.SuperKeyword && isDottedName(call.expression)) {
currentFlow = createFlowCall(currentFlow, call);
}
}
@@ -2542,6 +2542,7 @@ namespace ts {
node.flowNode = currentFlow;
}
break;
case SyntaxKind.MetaProperty:
case SyntaxKind.SuperKeyword:
node.flowNode = currentFlow;
break;

View File

@@ -21320,6 +21320,12 @@ namespace ts {
(isBinaryExpression(target) && target.operatorToken.kind === SyntaxKind.CommaToken && isMatchingReference(source, target.right));
}
switch (source.kind) {
case SyntaxKind.MetaProperty:
return target.kind === SyntaxKind.MetaProperty
&& (source as MetaProperty).keywordToken === SyntaxKind.ImportKeyword
&& (target as MetaProperty).keywordToken === SyntaxKind.ImportKeyword
&& (source as MetaProperty).name.escapedText === "meta"
&& (target as MetaProperty).name.escapedText === "meta";
case SyntaxKind.Identifier:
case SyntaxKind.PrivateIdentifier:
return target.kind === SyntaxKind.Identifier && getResolvedSymbol(<Identifier>source) === getResolvedSymbol(<Identifier>target) ||

View File

@@ -4836,9 +4836,12 @@ namespace ts {
}
export function isDottedName(node: Expression): boolean {
return node.kind === SyntaxKind.Identifier || node.kind === SyntaxKind.ThisKeyword || node.kind === SyntaxKind.SuperKeyword ||
node.kind === SyntaxKind.PropertyAccessExpression && isDottedName((<PropertyAccessExpression>node).expression) ||
node.kind === SyntaxKind.ParenthesizedExpression && isDottedName((<ParenthesizedExpression>node).expression);
return node.kind === SyntaxKind.Identifier
|| node.kind === SyntaxKind.ThisKeyword
|| node.kind === SyntaxKind.SuperKeyword
|| node.kind === SyntaxKind.MetaProperty
|| node.kind === SyntaxKind.PropertyAccessExpression && isDottedName((<PropertyAccessExpression>node).expression)
|| node.kind === SyntaxKind.ParenthesizedExpression && isDottedName((<ParenthesizedExpression>node).expression);
}
export function isPropertyAccessEntityNameExpression(node: Node): node is PropertyAccessEntityNameExpression {