Remove getAllAccessorDeclarations from the EmitResolver (#57993)

This commit is contained in:
Wesley Wigham 2024-03-28 20:45:47 -07:00 committed by GitHub
parent 97dc5f0dd9
commit a73ca902ea
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 65 additions and 34 deletions

View File

@ -235,7 +235,6 @@ import {
GenericType,
GetAccessorDeclaration,
getAliasDeclarationFromName,
getAllAccessorDeclarations,
getAllJSDocTags,
getAllowSyntheticDefaultImports,
getAncestor,
@ -8507,7 +8506,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
function getDeclarationWithTypeAnnotation(symbol: Symbol, enclosingDeclaration: Node | undefined) {
return symbol.declarations && find(symbol.declarations, s => !!getEffectiveTypeAnnotationNode(s) && (!enclosingDeclaration || !!findAncestor(s, n => n === enclosingDeclaration)));
return symbol.declarations && find(symbol.declarations, s => !!getNonlocalEffectiveTypeAnnotationNode(s) && (!enclosingDeclaration || !!findAncestor(s, n => n === enclosingDeclaration)));
}
function existingTypeNodeIsNotReferenceOrIsReferenceWithCompatibleTypeArgumentCount(existing: TypeNode, type: Type) {
@ -8530,7 +8529,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const declWithExistingAnnotation = getDeclarationWithTypeAnnotation(symbol, getEnclosingDeclarationIgnoringFakeScope(enclosingDeclaration));
if (declWithExistingAnnotation && !isFunctionLikeDeclaration(declWithExistingAnnotation) && !isGetAccessorDeclaration(declWithExistingAnnotation)) {
// try to reuse the existing annotation
const existing = getEffectiveTypeAnnotationNode(declWithExistingAnnotation)!;
const existing = getNonlocalEffectiveTypeAnnotationNode(declWithExistingAnnotation)!;
const result = tryReuseExistingTypeNode(context, existing, type, declWithExistingAnnotation, addUndefined, includePrivateSymbol, bundled);
if (result) {
return result;
@ -8583,7 +8582,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
const typePredicate = getTypePredicateOfSignature(signature);
const type = getReturnTypeOfSignature(signature);
if (!isErrorType(type) && context.enclosingDeclaration) {
const annotation = signature.declaration && getEffectiveReturnTypeNode(signature.declaration);
const annotation = signature.declaration && getNonlocalEffectiveReturnTypeAnnotationNode(signature.declaration);
const enclosingDeclarationIgnoringFakeScope = getEnclosingDeclarationIgnoringFakeScope(context.enclosingDeclaration);
if (!!findAncestor(annotation, n => n === enclosingDeclarationIgnoringFakeScope) && annotation) {
const annotated = getTypeFromTypeNode(annotation);
@ -48696,6 +48695,22 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
return isFunctionLike(declaration) || isExportAssignment(declaration) || isVariableLike(declaration);
}
function getAllAccessorDeclarationsForDeclaration(accessor: AccessorDeclaration): AllAccessorDeclarations {
accessor = getParseTreeNode(accessor, isGetOrSetAccessorDeclaration)!; // TODO: GH#18217
const otherKind = accessor.kind === SyntaxKind.SetAccessor ? SyntaxKind.GetAccessor : SyntaxKind.SetAccessor;
const otherAccessor = getDeclarationOfKind<AccessorDeclaration>(getSymbolOfDeclaration(accessor), otherKind);
const firstAccessor = otherAccessor && (otherAccessor.pos < accessor.pos) ? otherAccessor : accessor;
const secondAccessor = otherAccessor && (otherAccessor.pos < accessor.pos) ? accessor : otherAccessor;
const setAccessor = accessor.kind === SyntaxKind.SetAccessor ? accessor : otherAccessor as SetAccessorDeclaration;
const getAccessor = accessor.kind === SyntaxKind.GetAccessor ? accessor : otherAccessor as GetAccessorDeclaration;
return {
firstAccessor,
secondAccessor,
setAccessor,
getAccessor,
};
}
function getPossibleTypeNodeReuseExpression(declaration: DeclarationWithPotentialInnerNodeReuse) {
return isFunctionLike(declaration) && !isSetAccessor(declaration)
? getSingleReturnExpression(declaration)
@ -48704,7 +48719,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
: !!(declaration as HasInitializer).initializer
? (declaration as HasInitializer & typeof declaration).initializer
: isParameter(declaration) && isSetAccessor(declaration.parent)
? getSingleReturnExpression(getAllAccessorDeclarations(getSymbolOfDeclaration(declaration.parent)?.declarations, declaration.parent).getAccessor)
? getSingleReturnExpression(getAllAccessorDeclarationsForDeclaration(declaration.parent).getAccessor)
: undefined;
}
@ -48894,6 +48909,37 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
function getNonlocalEffectiveTypeAnnotationNode(node: Node) {
const direct = getEffectiveTypeAnnotationNode(node);
if (direct) {
return direct;
}
if (node.kind === SyntaxKind.Parameter && node.parent.kind === SyntaxKind.SetAccessor) {
const other = getAllAccessorDeclarationsForDeclaration(node.parent as SetAccessorDeclaration).getAccessor;
if (other) {
return getEffectiveReturnTypeNode(other);
}
}
return undefined;
}
function getNonlocalEffectiveReturnTypeAnnotationNode(node: SignatureDeclaration | JSDocSignature) {
const direct = getEffectiveReturnTypeNode(node);
if (direct) {
return direct;
}
if (node.kind === SyntaxKind.GetAccessor) {
const other = getAllAccessorDeclarationsForDeclaration(node).setAccessor;
if (other) {
const param = getSetAccessorValueParameter(other);
if (param) {
return getEffectiveTypeAnnotationNode(param);
}
}
}
return undefined;
}
function createResolver(): EmitResolver {
return {
getReferencedExportContainer,
@ -48949,21 +48995,6 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
},
getJsxFactoryEntity,
getJsxFragmentFactoryEntity,
getAllAccessorDeclarations(accessor: AccessorDeclaration): AllAccessorDeclarations {
accessor = getParseTreeNode(accessor, isGetOrSetAccessorDeclaration)!; // TODO: GH#18217
const otherKind = accessor.kind === SyntaxKind.SetAccessor ? SyntaxKind.GetAccessor : SyntaxKind.SetAccessor;
const otherAccessor = getDeclarationOfKind<AccessorDeclaration>(getSymbolOfDeclaration(accessor), otherKind);
const firstAccessor = otherAccessor && (otherAccessor.pos < accessor.pos) ? otherAccessor : accessor;
const secondAccessor = otherAccessor && (otherAccessor.pos < accessor.pos) ? accessor : otherAccessor;
const setAccessor = accessor.kind === SyntaxKind.SetAccessor ? accessor : otherAccessor as SetAccessorDeclaration;
const getAccessor = accessor.kind === SyntaxKind.GetAccessor ? accessor : otherAccessor as GetAccessorDeclaration;
return {
firstAccessor,
secondAccessor,
setAccessor,
getAccessor,
};
},
isBindingCapturedByNode: (node, decl) => {
const parseNode = getParseTreeNode(node);
const parseDecl = getParseTreeNode(decl);
@ -49280,7 +49311,7 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
}
}
else if (legacyDecorators && (node.kind === SyntaxKind.GetAccessor || node.kind === SyntaxKind.SetAccessor)) {
const accessors = getAllAccessorDeclarations((node.parent as ClassDeclaration).members, node as AccessorDeclaration);
const accessors = getAllAccessorDeclarationsForDeclaration(node as AccessorDeclaration);
if (hasDecorators(accessors.firstAccessor) && node === accessors.secondAccessor) {
return grammarErrorOnFirstToken(node, Diagnostics.Decorators_cannot_be_applied_to_multiple_get_Slashset_accessors_of_the_same_name);
}

View File

@ -1112,7 +1112,6 @@ export const notImplementedResolver: EmitResolver = {
isLiteralConstDeclaration: notImplemented,
getJsxFactoryEntity: notImplemented,
getJsxFragmentFactoryEntity: notImplemented,
getAllAccessorDeclarations: notImplemented,
isBindingCapturedByNode: notImplemented,
getDeclarationStatementsForSourceFile: notImplemented,
isImportRequiredByAugmentation: notImplemented,

View File

@ -50,6 +50,7 @@ import {
FunctionTypeNode,
GeneratedIdentifierFlags,
GetAccessorDeclaration,
getAllAccessorDeclarations,
getCommentRange,
getDirectoryPath,
getEffectiveBaseTypeNode,
@ -119,6 +120,7 @@ import {
isMethodSignature,
isModifier,
isModuleDeclaration,
isObjectLiteralExpression,
isOmittedExpression,
isPrivateIdentifier,
isSemicolonClassElement,
@ -728,7 +730,7 @@ export function transformDeclarations(context: TransformationContext) {
if (!isPrivate) {
const valueParameter = getSetAccessorValueParameter(input);
if (valueParameter) {
const accessorType = getTypeAnnotationFromAllAccessorDeclarations(input, resolver.getAllAccessorDeclarations(input));
const accessorType = getTypeAnnotationFromAllAccessorDeclarations(input, getAllAccessorDeclarations(isObjectLiteralExpression(input.parent) ? input.parent.properties : input.parent.members, input));
newValueParameter = ensureParameter(valueParameter, /*modifierMask*/ undefined, accessorType);
}
}
@ -1037,7 +1039,7 @@ export function transformDeclarations(context: TransformationContext) {
if (isPrivateIdentifier(input.name)) {
return cleanup(/*returnValue*/ undefined);
}
const accessorType = getTypeAnnotationFromAllAccessorDeclarations(input, resolver.getAllAccessorDeclarations(input));
const accessorType = getTypeAnnotationFromAllAccessorDeclarations(input, getAllAccessorDeclarations(isObjectLiteralExpression(input.parent) ? input.parent.properties : input.parent.members, input));
return cleanup(factory.updateGetAccessorDeclaration(
input,
ensureModifiers(input),

View File

@ -1122,7 +1122,7 @@ export function transformTypeScript(context: TransformationContext) {
if (typeSerializer) {
let decorators: Decorator[] | undefined;
if (shouldAddTypeMetadata(node)) {
const typeMetadata = emitHelpers().createMetadataHelper("design:type", typeSerializer.serializeTypeOfNode({ currentLexicalScope, currentNameScope: container }, node));
const typeMetadata = emitHelpers().createMetadataHelper("design:type", typeSerializer.serializeTypeOfNode({ currentLexicalScope, currentNameScope: container }, node, container));
decorators = append(decorators, factory.createDecorator(typeMetadata));
}
if (shouldAddParamTypesMetadata(node)) {
@ -1141,7 +1141,7 @@ export function transformTypeScript(context: TransformationContext) {
if (typeSerializer) {
let properties: ObjectLiteralElementLike[] | undefined;
if (shouldAddTypeMetadata(node)) {
const typeProperty = factory.createPropertyAssignment("type", factory.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, factory.createToken(SyntaxKind.EqualsGreaterThanToken), typeSerializer.serializeTypeOfNode({ currentLexicalScope, currentNameScope: container }, node)));
const typeProperty = factory.createPropertyAssignment("type", factory.createArrowFunction(/*modifiers*/ undefined, /*typeParameters*/ undefined, [], /*type*/ undefined, factory.createToken(SyntaxKind.EqualsGreaterThanToken), typeSerializer.serializeTypeOfNode({ currentLexicalScope, currentNameScope: container }, node, container)));
properties = append(properties, typeProperty);
}
if (shouldAddParamTypesMetadata(node)) {

View File

@ -115,7 +115,7 @@ export interface RuntimeTypeSerializer {
* Serializes the type of a node for use with decorator type metadata.
* @param node The node that should have its type serialized.
*/
serializeTypeOfNode(serializerContext: RuntimeTypeSerializerContext, node: PropertyDeclaration | ParameterDeclaration | AccessorDeclaration | ClassLikeDeclaration | MethodDeclaration): Expression;
serializeTypeOfNode(serializerContext: RuntimeTypeSerializerContext, node: PropertyDeclaration | ParameterDeclaration | AccessorDeclaration | ClassLikeDeclaration | MethodDeclaration, container: ClassLikeDeclaration): Expression;
/**
* Serializes the types of the parameters of a node for use with decorator type metadata.
* @param node The node that should have its parameter types serialized.
@ -145,7 +145,7 @@ export function createRuntimeTypeSerializer(context: TransformationContext): Run
return {
serializeTypeNode: (serializerContext, node) => setSerializerContextAnd(serializerContext, serializeTypeNode, node),
serializeTypeOfNode: (serializerContext, node) => setSerializerContextAnd(serializerContext, serializeTypeOfNode, node),
serializeTypeOfNode: (serializerContext, node, container) => setSerializerContextAnd(serializerContext, serializeTypeOfNode, node, container),
serializeParameterTypesOfNode: (serializerContext, node, container) => setSerializerContextAnd(serializerContext, serializeParameterTypesOfNode, node, container),
serializeReturnTypeOfNode: (serializerContext, node) => setSerializerContextAnd(serializerContext, serializeReturnTypeOfNode, node),
};
@ -166,8 +166,8 @@ export function createRuntimeTypeSerializer(context: TransformationContext): Run
return result;
}
function getAccessorTypeNode(node: AccessorDeclaration) {
const accessors = resolver.getAllAccessorDeclarations(node);
function getAccessorTypeNode(node: AccessorDeclaration, container: ClassLikeDeclaration) {
const accessors = getAllAccessorDeclarations(container.members, node);
return accessors.setAccessor && getSetAccessorTypeAnnotationNode(accessors.setAccessor)
|| accessors.getAccessor && getEffectiveReturnTypeNode(accessors.getAccessor);
}
@ -176,14 +176,14 @@ export function createRuntimeTypeSerializer(context: TransformationContext): Run
* Serializes the type of a node for use with decorator type metadata.
* @param node The node that should have its type serialized.
*/
function serializeTypeOfNode(node: PropertyDeclaration | ParameterDeclaration | AccessorDeclaration | ClassLikeDeclaration | MethodDeclaration): SerializedTypeNode {
function serializeTypeOfNode(node: PropertyDeclaration | ParameterDeclaration | AccessorDeclaration | ClassLikeDeclaration | MethodDeclaration, container: ClassLikeDeclaration): SerializedTypeNode {
switch (node.kind) {
case SyntaxKind.PropertyDeclaration:
case SyntaxKind.Parameter:
return serializeTypeNode(node.type);
case SyntaxKind.SetAccessor:
case SyntaxKind.GetAccessor:
return serializeTypeNode(getAccessorTypeNode(node));
return serializeTypeNode(getAccessorTypeNode(node, container));
case SyntaxKind.ClassDeclaration:
case SyntaxKind.ClassExpression:
case SyntaxKind.MethodDeclaration:
@ -217,7 +217,7 @@ export function createRuntimeTypeSerializer(context: TransformationContext): Run
expressions.push(serializeTypeNode(getRestParameterElementType(parameter.type)));
}
else {
expressions.push(serializeTypeOfNode(parameter));
expressions.push(serializeTypeOfNode(parameter, container));
}
}
}

View File

@ -5635,7 +5635,6 @@ export interface EmitResolver {
isLiteralConstDeclaration(node: VariableDeclaration | PropertyDeclaration | PropertySignature | ParameterDeclaration): boolean;
getJsxFactoryEntity(location?: Node): EntityName | undefined;
getJsxFragmentFactoryEntity(location?: Node): EntityName | undefined;
getAllAccessorDeclarations(declaration: AccessorDeclaration): AllAccessorDeclarations;
isBindingCapturedByNode(node: Node, decl: VariableDeclaration | BindingElement): boolean;
getDeclarationStatementsForSourceFile(node: SourceFile, flags: NodeBuilderFlags, tracker: SymbolTracker, bundled?: boolean): Statement[] | undefined;
isImportRequiredByAugmentation(decl: ImportDeclaration): boolean;