Skip to content
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

[ID-Prep] PR5 - Preserve type nodes from function like expression in declaration emit #57678

41 changes: 35 additions & 6 deletions src/compiler/checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6329,8 +6329,25 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {

const firstIdentifier = getFirstIdentifier(entityName);
const symbol = resolveName(enclosingDeclaration, firstIdentifier.escapedText, meaning, /*nameNotFoundMessage*/ undefined, /*nameArg*/ undefined, /*isUse*/ false);
if (symbol && symbol.flags & SymbolFlags.TypeParameter && meaning & SymbolFlags.Type) {
return { accessibility: SymbolAccessibility.Accessible };
if (symbol) {
if (symbol.flags & SymbolFlags.TypeParameter && meaning & SymbolFlags.Type) {
return { accessibility: SymbolAccessibility.Accessible };
}

// Parameters or binding elements from parameters are always visible in their enclosing function declarations
Copy link
Contributor Author

Choose a reason for hiding this comment

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

The checker complained about the parameter name not being accessible (since arrow functions are not themselves marked as visible by determineIfDeclarationIsVisible.

if (symbol.flags & SymbolFlags.FunctionScopedVariable && meaning & SymbolFlags.Value) {
let declaration: Node | undefined = symbol.valueDeclaration;
while (declaration) {
if (declaration.kind === SyntaxKind.Parameter) break;
if (declaration.kind === SyntaxKind.BindingElement) {
declaration = declaration.parent.parent;
}
break;
}
if (declaration?.kind === SyntaxKind.Parameter) {
return { accessibility: SymbolAccessibility.Accessible };
}
}
}
if (!symbol && isThisIdentifier(firstIdentifier) && isSymbolAccessible(getSymbolOfDeclaration(getThisContainer(firstIdentifier, /*includeArrowFunctions*/ false, /*includeClassComputedPropertyName*/ false)), firstIdentifier, meaning, /*shouldComputeAliasesToMakeVisible*/ false).accessibility === SymbolAccessibility.Accessible) {
return { accessibility: SymbolAccessibility.Accessible };
Expand Down Expand Up @@ -48160,13 +48177,25 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
hasSyntacticModifier(parameter, ModifierFlags.ParameterPropertyModifier);
}

function isExpandoFunctionDeclaration(node: Declaration): boolean {
const declaration = getParseTreeNode(node, isFunctionDeclaration);
function isExpandoFunctionDeclaration(node: FunctionDeclaration | VariableDeclaration): boolean {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Both function and variable declarations will now be tested. We can't reliably determine the type for an expando functions variable from just it's declaration so we fall back on the type checker.

const declaration = getParseTreeNode(node, isDeclaration);
if (!declaration) {
return false;
}
const symbol = getSymbolOfDeclaration(declaration);
if (!symbol || !(symbol.flags & SymbolFlags.Function)) {
let symbol: Symbol;
if (isVariableDeclaration(declaration)) {
if (declaration.type || !isVarConstLike(declaration)) {
return false;
}
if (!(declaration.initializer && isFunctionExpressionOrArrowFunction(declaration.initializer))) {
return false;
}
symbol = getSymbolOfDeclaration(declaration.initializer);
}
else {
symbol = getSymbolOfDeclaration(declaration);
}
if (!symbol || !(symbol.flags & SymbolFlags.Function | SymbolFlags.Variable)) {
return false;
}
return !!forEachEntry(getExportsOfSymbol(symbol), p => p.flags & SymbolFlags.Value && isExpandoPropertyDeclaration(p.valueDeclaration));
Expand Down
Loading
Loading