From 1bb7e2f4e5dbfe7e234e46883381399aa445f829 Mon Sep 17 00:00:00 2001 From: Ron Buckton Date: Fri, 5 Apr 2024 16:30:45 -0400 Subject: [PATCH] Define concrete fields for known inputs --- src/compiler/objectConstructors.ts | 108 +++++++++++++++++++---------- src/services/services.ts | 3 + 2 files changed, 74 insertions(+), 37 deletions(-) diff --git a/src/compiler/objectConstructors.ts b/src/compiler/objectConstructors.ts index e45e390487c..bdec56609c2 100644 --- a/src/compiler/objectConstructors.ts +++ b/src/compiler/objectConstructors.ts @@ -44,39 +44,37 @@ import { /** @internal */ export class SymbolObject implements Symbol { - declare flags: SymbolFlags; - declare escapedName: __String; - declare declarations?: Declaration[] | undefined; - declare valueDeclaration?: Declaration | undefined; - declare members?: SymbolTable | undefined; - declare exports?: SymbolTable | undefined; - declare globalExports?: SymbolTable | undefined; - declare id: number; - declare mergeId: number; - declare parent?: Symbol | undefined; - declare exportSymbol?: Symbol | undefined; - declare constEnumOnlyModule: boolean | undefined; - declare isReferenced?: SymbolFlags | undefined; + flags: SymbolFlags = 0; + escapedName: __String = "" as __String; + declarations: Declaration[] | undefined = undefined; + valueDeclaration: Declaration | undefined = undefined; + id = 0; + mergeId = 0; + parent: Symbol | undefined = undefined; + members: SymbolTable | undefined = undefined; + exports: SymbolTable | undefined = undefined; + exportSymbol: Symbol | undefined = undefined; + constEnumOnlyModule: boolean | undefined = undefined; + isReferenced: SymbolFlags | undefined = undefined; + lastAssignmentPos: number | undefined = undefined; + links: SymbolLinks | undefined = undefined; // used by TransientSymbol + + // TODO: Review these for polymorphism: declare isReplaceableByMethod?: boolean | undefined; - declare lastAssignmentPos?: number | undefined; declare assignmentDeclarationMembers?: Map | undefined; - declare links?: SymbolLinks; + declare globalExports?: SymbolTable | undefined; + + // TODO: Added by services, review for migration/polymorphism: + // documentationComment?: SymbolDisplayPart[]; + // tags?: JSDocTagInfo[]; // same + // contextualGetAccessorDocumentationComment?: SymbolDisplayPart[]; + // contextualSetAccessorDocumentationComment?: SymbolDisplayPart[]; + // contextualGetAccessorTags?: JSDocTagInfo[]; + // contextualSetAccessorTags?: JSDocTagInfo[]; constructor(flags: SymbolFlags, name: __String) { this.flags = flags; this.escapedName = name; - this.declarations = undefined; - this.valueDeclaration = undefined; - this.id = 0; - this.mergeId = 0; - this.parent = undefined; - this.members = undefined; - this.exports = undefined; - this.exportSymbol = undefined; - this.constEnumOnlyModule = undefined; - this.isReferenced = undefined; - this.lastAssignmentPos = undefined; - this.links = undefined; // used by TransientSymbol } getFlags(): SymbolFlags { @@ -118,9 +116,11 @@ export class SymbolObject implements Symbol { /** @internal */ export class TypeObject implements Type { - declare flags: TypeFlags; + flags: TypeFlags; + checker: TypeChecker; + + // TODO: Review for polymorphism declare id: number; - declare checker: TypeChecker; declare symbol: Symbol; declare pattern?: DestructuringPattern | undefined; declare aliasSymbol?: Symbol | undefined; @@ -132,7 +132,6 @@ export class TypeObject implements Type { declare widened?: Type | undefined; constructor(checker: TypeChecker, flags: TypeFlags) { - // TODO: stabilize map this.flags = flags; this.checker = checker; } @@ -140,45 +139,59 @@ export class TypeObject implements Type { getFlags(): TypeFlags { return this.flags; } + getSymbol(): Symbol | undefined { return this.symbol; } + getProperties(): Symbol[] { return this.checker.getPropertiesOfType(this); } + getProperty(propertyName: string): Symbol | undefined { return this.checker.getPropertyOfType(this, propertyName); } + getApparentProperties(): Symbol[] { return this.checker.getAugmentedPropertiesOfType(this); } + getCallSignatures(): readonly Signature[] { return this.checker.getSignaturesOfType(this, SignatureKind.Call); } + getConstructSignatures(): readonly Signature[] { return this.checker.getSignaturesOfType(this, SignatureKind.Construct); } + getStringIndexType(): Type | undefined { return this.checker.getIndexTypeOfType(this, IndexKind.String); } + getNumberIndexType(): Type | undefined { return this.checker.getIndexTypeOfType(this, IndexKind.Number); } + getBaseTypes(): BaseType[] | undefined { return this.isClassOrInterface() ? this.checker.getBaseTypes(this) : undefined; } + isNullableType(): boolean { return this.checker.isNullableType(this); } + getNonNullableType(): Type { return this.checker.getNonNullableType(this); } + getNonOptionalType(): Type { return this.checker.getNonOptionalType(this); } + getConstraint(): Type | undefined { return this.checker.getBaseConstraintOfType(this); } + getDefault(): Type | undefined { return this.checker.getDefaultFromTypeParameter(this); } @@ -186,33 +199,43 @@ export class TypeObject implements Type { isUnion(): this is UnionType { return !!(this.flags & TypeFlags.Union); } + isIntersection(): this is IntersectionType { return !!(this.flags & TypeFlags.Intersection); } + isUnionOrIntersection(): this is UnionOrIntersectionType { return !!(this.flags & TypeFlags.UnionOrIntersection); } + isLiteral(): this is LiteralType { return !!(this.flags & (TypeFlags.StringLiteral | TypeFlags.NumberLiteral | TypeFlags.BigIntLiteral)); } + isStringLiteral(): this is StringLiteralType { return !!(this.flags & TypeFlags.StringLiteral); } + isNumberLiteral(): this is NumberLiteralType { return !!(this.flags & TypeFlags.NumberLiteral); } + isTypeParameter(): this is TypeParameter { return !!(this.flags & TypeFlags.TypeParameter); } + isClassOrInterface(): this is InterfaceType { return !!(getObjectFlags(this) & ObjectFlags.ClassOrInterface); } + isClass(): this is InterfaceType { return !!(getObjectFlags(this) & ObjectFlags.Class); } + isIndexType(): this is IndexType { return isIndexType(this); } + /** * This polyfills `referenceType.typeArguments` for API consumers */ @@ -226,8 +249,10 @@ export class TypeObject implements Type { /** @internal */ export class SignatureObject implements Signature { - declare flags: SignatureFlags; - declare checker: TypeChecker; + flags: SignatureFlags; + checker: TypeChecker; + + // TODO: Review for polymorphism: declare declaration?: JSDocSignature | SignatureDeclaration | undefined; declare typeParameters?: readonly TypeParameter[] | undefined; declare parameters: readonly Symbol[]; @@ -247,6 +272,10 @@ export class SignatureObject implements Signature { declare isolatedSignatureType?: ObjectType | undefined; declare instantiations?: Map | undefined; + // TODO: Added by services, review for migration/polymorhpism: + // documentationComment?: SymbolDisplayPart[]; + // jsDocTags?: JSDocTagInfo[]; // same + constructor(checker: TypeChecker, flags: SignatureFlags) { // TODO: stabilize map this.flags = flags; @@ -256,15 +285,19 @@ export class SignatureObject implements Signature { getDeclaration(): JSDocSignature | SignatureDeclaration { return this.declaration ?? Debug.fail(); } + getTypeParameters(): readonly TypeParameter[] | undefined { return this.typeParameters; } + getParameters(): readonly Symbol[] { return this.parameters; } + getReturnType(): Type { return this.checker.getReturnTypeOfSignature(this); } + getTypeParameterAtPosition(pos: number): Type { const type = this.checker.getParameterType(this, pos); if (isIndexType(type) && isThisTypeParameter(type.type)) { @@ -287,13 +320,14 @@ export class SignatureObject implements Signature { /** @internal */ export class SourceMapSourceObject implements SourceMapSource { - declare fileName: string; - declare text: string; - declare skipTrivia: ((pos: number) => number); + fileName: string; + text: string; + skipTrivia: ((pos: number) => number); + + // TODO: Review for polymorphism: declare lineMap: readonly number[]; constructor(fileName: string, text: string, skipTrivia: (pos: number) => number = identity) { - // TODO: stabilize map this.fileName = fileName; this.text = text; this.skipTrivia = skipTrivia; @@ -306,4 +340,4 @@ export class SourceMapSourceObject implements SourceMapSource { function isIndexType(type: Type): type is IndexType { return !!(type.flags & TypeFlags.Index); -} \ No newline at end of file +} diff --git a/src/services/services.ts b/src/services/services.ts index 5b681d8cc57..9585c843dc5 100644 --- a/src/services/services.ts +++ b/src/services/services.ts @@ -282,6 +282,7 @@ import * as classifier2020 from "./classifier2020"; /** The version of the language service API */ export const servicesVersion = "0.8"; +// TODO: Move SymbolInternals to compiler // Patch Symbol for use with services. interface SymbolInternals { // Undefined is used to indicate the value has not been computed. If, after computing, the @@ -363,6 +364,8 @@ ObjectConstructors.SymbolObject.prototype.getContextualJsDocTags = function (thi return this.getJsDocTags(checker); }; +// TODO: Move SignatureInternals to compiler + interface SignatureInternals { // Undefined is used to indicate the value has not been computed. If, after computing, the // symbol has no doc comment, then the empty array will be returned.