Skip to content

Commit b6e686e

Browse files
committed
Emit static Effect schema declarations
1 parent 7964e22 commit b6e686e

4 files changed

Lines changed: 582 additions & 2 deletions

File tree

src/compiler/checker.ts

Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51218,6 +51218,116 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
5121851218
return nodeBuilder.serializeTypeForExpression(expr, enclosingDeclaration, flags | NodeBuilderFlags.MultilineObjectLiterals, internalFlags, tracker);
5121951219
}
5122051220

51221+
function createTypeOfTypeNode(typeNodeIn: TypeNode, enclosingDeclaration: Node, flags: NodeBuilderFlags, internalFlags: InternalNodeBuilderFlags, tracker: SymbolTracker) {
51222+
const typeNode = getParseTreeNode(typeNodeIn, isTypeNode) || typeNodeIn;
51223+
if (!typeNode) {
51224+
return factory.createToken(SyntaxKind.AnyKeyword) as KeywordTypeNode;
51225+
}
51226+
return nodeBuilder.typeToTypeNode(getTypeFromTypeNode(typeNode), enclosingDeclaration, flags | NodeBuilderFlags.MultilineObjectLiterals, internalFlags, tracker);
51227+
}
51228+
51229+
function createTypeLiteralOfTypeNode(typeNodeIn: TypeNode, enclosingDeclaration: Node, flags: NodeBuilderFlags, internalFlags: InternalNodeBuilderFlags, tracker: SymbolTracker) {
51230+
const typeNode = getParseTreeNode(typeNodeIn, isTypeNode) || typeNodeIn;
51231+
if (!typeNode) return;
51232+
return createTypeLiteralOfType(getTypeFromTypeNode(typeNode), enclosingDeclaration, flags, internalFlags, tracker);
51233+
}
51234+
51235+
function createTypeLiteralOfClassDeclaration(declarationIn: ClassDeclaration, enclosingDeclaration: Node, flags: NodeBuilderFlags, internalFlags: InternalNodeBuilderFlags, tracker: SymbolTracker) {
51236+
const declaration = getParseTreeNode(declarationIn, isClassDeclaration) || declarationIn;
51237+
if (!declaration) return;
51238+
const schemaType = getTypeOfClassSchemaProperty(declaration, "Type");
51239+
if (schemaType) {
51240+
return createTypeLiteralOfType(schemaType, enclosingDeclaration, flags, internalFlags, tracker);
51241+
}
51242+
const symbol = getSymbolOfDeclaration(declaration);
51243+
if (!symbol) return;
51244+
return createTypeLiteralOfType(getDeclaredTypeOfSymbol(symbol), enclosingDeclaration, flags, internalFlags, tracker);
51245+
}
51246+
51247+
function createMakeTypeOfClassDeclaration(declarationIn: ClassDeclaration, enclosingDeclaration: Node, flags: NodeBuilderFlags, internalFlags: InternalNodeBuilderFlags, tracker: SymbolTracker) {
51248+
const declaration = getParseTreeNode(declarationIn, isClassDeclaration) || declarationIn;
51249+
if (!declaration) return;
51250+
const makeType = getTypeOfClassSchemaProperty(declaration, "~type.make.in");
51251+
const typeType = getTypeOfClassSchemaProperty(declaration, "Type");
51252+
if (!makeType || !typeType) return;
51253+
return createMakeTypeOfTypes(makeType, typeType, enclosingDeclaration, flags, internalFlags, tracker);
51254+
}
51255+
51256+
function createTypeOfClassStaticProperty(declarationIn: ClassDeclaration, propertyName: string, enclosingDeclaration: Node, flags: NodeBuilderFlags, internalFlags: InternalNodeBuilderFlags, tracker: SymbolTracker) {
51257+
const declaration = getParseTreeNode(declarationIn, isClassDeclaration) || declarationIn;
51258+
if (!declaration) return;
51259+
const propertyType = getTypeOfClassSchemaProperty(declaration, propertyName) || getTypeOfClassStaticProperty(declaration, propertyName);
51260+
if (!propertyType) return;
51261+
return nodeBuilder.typeToTypeNode(propertyType, enclosingDeclaration, flags | NodeBuilderFlags.MultilineObjectLiterals | NodeBuilderFlags.UseFullyQualifiedType, internalFlags, tracker);
51262+
}
51263+
51264+
function getTypeOfClassSchemaProperty(declaration: ClassDeclaration, propertyName: string) {
51265+
const schemaExpression = getClassSchemaExpression(declaration);
51266+
if (!schemaExpression) return;
51267+
const schemaType = getTypeOfExpression(schemaExpression);
51268+
const property = getPropertyOfType(schemaType, escapeLeadingUnderscores(propertyName));
51269+
return property && getTypeOfSymbolAtLocation(property, schemaExpression);
51270+
}
51271+
51272+
function getClassSchemaExpression(declaration: ClassDeclaration): Expression | undefined {
51273+
const heritageClause = declaration.heritageClauses?.[0];
51274+
const heritageType = heritageClause?.types[0];
51275+
const expression = heritageType?.expression;
51276+
return expression && isCallExpression(expression) && expression.arguments.length > 0 ? expression.arguments[0] : undefined;
51277+
}
51278+
51279+
function getTypeOfClassStaticProperty(declaration: ClassDeclaration, propertyName: string) {
51280+
const symbol = getSymbolOfDeclaration(declaration);
51281+
if (!symbol) return;
51282+
const staticType = getTypeOfSymbol(symbol);
51283+
const property = getPropertyOfType(staticType, escapeLeadingUnderscores(propertyName));
51284+
return property && getTypeOfSymbolAtLocation(property, declaration);
51285+
}
51286+
51287+
function createTypeLiteralOfType(type: Type, enclosingDeclaration: Node, flags: NodeBuilderFlags, internalFlags: InternalNodeBuilderFlags, tracker: SymbolTracker) {
51288+
const members = map(getPropertiesOfType(type), property => {
51289+
const name = unescapeLeadingUnderscores(property.escapedName);
51290+
const propertyType = getTypeOfSymbol(property);
51291+
const propertyTypeNode = nodeBuilder.typeToTypeNode(propertyType, enclosingDeclaration, flags | NodeBuilderFlags.MultilineObjectLiterals | NodeBuilderFlags.UseFullyQualifiedType, internalFlags, tracker)
51292+
|| factory.createKeywordTypeNode(SyntaxKind.AnyKeyword);
51293+
return factory.createPropertySignature(
51294+
[factory.createModifier(SyntaxKind.ReadonlyKeyword)],
51295+
isIdentifierText(name, ScriptTarget.ESNext) ? factory.createIdentifier(name) : factory.createStringLiteral(name),
51296+
property.flags & SymbolFlags.Optional ? factory.createToken(SyntaxKind.QuestionToken) : undefined,
51297+
propertyTypeNode,
51298+
);
51299+
});
51300+
return factory.createTypeLiteralNode(members);
51301+
}
51302+
51303+
function createMakeTypeOfTypes(makeType: Type, typeType: Type, enclosingDeclaration: Node, flags: NodeBuilderFlags, internalFlags: InternalNodeBuilderFlags, tracker: SymbolTracker) {
51304+
const isVoidish = (type: Type) => !!(type.flags & (TypeFlags.Void | TypeFlags.Undefined));
51305+
const makeTypes = makeType.flags & TypeFlags.Union ? (makeType as UnionType).types : undefined;
51306+
const hasVoid = !!makeTypes?.some(isVoidish);
51307+
const objectMakeType = makeTypes
51308+
? makeTypes.find(type => getPropertiesOfType(type).length > 0) || makeType
51309+
: makeType;
51310+
const makeProperties = getPropertiesOfType(objectMakeType);
51311+
if (!makeProperties.length) {
51312+
return nodeBuilder.typeToTypeNode(makeType, enclosingDeclaration, flags | NodeBuilderFlags.MultilineObjectLiterals | NodeBuilderFlags.UseFullyQualifiedType, internalFlags, tracker);
51313+
}
51314+
const typeProperties = new Map(getPropertiesOfType(typeType).map(property => [property.escapedName, property]));
51315+
const literal = factory.createTypeLiteralNode(map(makeProperties, property => {
51316+
const name = unescapeLeadingUnderscores(property.escapedName);
51317+
const source = typeProperties.get(property.escapedName) || property;
51318+
const propertyType = getTypeOfSymbol(source);
51319+
const propertyTypeNode = nodeBuilder.typeToTypeNode(propertyType, enclosingDeclaration, flags | NodeBuilderFlags.MultilineObjectLiterals | NodeBuilderFlags.UseFullyQualifiedType, internalFlags, tracker)
51320+
|| factory.createKeywordTypeNode(SyntaxKind.AnyKeyword);
51321+
return factory.createPropertySignature(
51322+
[factory.createModifier(SyntaxKind.ReadonlyKeyword)],
51323+
isIdentifierText(name, ScriptTarget.ESNext) ? factory.createIdentifier(name) : factory.createStringLiteral(name),
51324+
property.flags & SymbolFlags.Optional ? factory.createToken(SyntaxKind.QuestionToken) : undefined,
51325+
propertyTypeNode,
51326+
);
51327+
}));
51328+
return hasVoid ? factory.createUnionTypeNode([literal, factory.createKeywordTypeNode(SyntaxKind.VoidKeyword)]) : literal;
51329+
}
51330+
5122151331
function hasGlobalName(name: string): boolean {
5122251332
return globals.has(escapeLeadingUnderscores(name));
5122351333
}
@@ -51408,6 +51518,11 @@ export function createTypeChecker(host: TypeCheckerHost): TypeChecker {
5140851518
createTypeOfDeclaration,
5140951519
createReturnTypeOfSignatureDeclaration,
5141051520
createTypeOfExpression,
51521+
createTypeOfTypeNode,
51522+
createTypeLiteralOfTypeNode,
51523+
createTypeLiteralOfClassDeclaration,
51524+
createMakeTypeOfClassDeclaration,
51525+
createTypeOfClassStaticProperty,
5141151526
createLiteralConstValue,
5141251527
isSymbolAccessible,
5141351528
isEntityNameVisible,

src/compiler/emitter.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1165,6 +1165,11 @@ export const notImplementedResolver: EmitResolver = {
11651165
createTypeOfDeclaration: notImplemented,
11661166
createReturnTypeOfSignatureDeclaration: notImplemented,
11671167
createTypeOfExpression: notImplemented,
1168+
createTypeOfTypeNode: notImplemented,
1169+
createTypeLiteralOfTypeNode: notImplemented,
1170+
createTypeLiteralOfClassDeclaration: notImplemented,
1171+
createMakeTypeOfClassDeclaration: notImplemented,
1172+
createTypeOfClassStaticProperty: notImplemented,
11681173
createLiteralConstValue: notImplemented,
11691174
isSymbolAccessible: notImplemented,
11701175
isEntityNameVisible: notImplemented,

0 commit comments

Comments
 (0)