Skip to content

Commit

Permalink
Remove markers from declaration files
Browse files Browse the repository at this point in the history
  • Loading branch information
GoogleFeud committed Dec 10, 2024
1 parent 118d113 commit d31ddbd
Show file tree
Hide file tree
Showing 3 changed files with 58 additions and 15 deletions.
4 changes: 2 additions & 2 deletions src/gen/validators/genValidator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -127,8 +127,8 @@ export function genValidator(transformer: Transformer, type: ts.Type | undefined
if (!keyType) continue;
const valueType = genValidator(transformer, info.type, "", undefined, objValidator);
if (valueType) {
if (keyType.getBaseType() === TypeDataKinds.String) (objValidator.typeData as ObjectTypeData).stringIndexInfo = [keyType, valueType];
else if (keyType.getBaseType() === TypeDataKinds.Number) (objValidator.typeData as ObjectTypeData).numberIndexInfo = [keyType, valueType];
if (keyType.getBaseTypeKind() === TypeDataKinds.String) (objValidator.typeData as ObjectTypeData).stringIndexInfo = [keyType, valueType];
else if (keyType.getBaseTypeKind() === TypeDataKinds.Number) (objValidator.typeData as ObjectTypeData).numberIndexInfo = [keyType, valueType];
}
}
return objValidator;
Expand Down
11 changes: 10 additions & 1 deletion src/gen/validators/validator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -380,11 +380,20 @@ export class Validator {
return this.children.reduce((prev, current) => prev + current.weigh(), sum);
}

getBaseType(): TypeDataKinds {
getBaseTypeKind(): TypeDataKinds {
if (this.typeData.kind === TypeDataKinds.Check && this.children.length) return this.children[0]!.typeData.kind;
return this.typeData.kind;
}

getBaseType() : ts.Type | undefined {
switch(this.typeData.kind) {
case TypeDataKinds.Check:
return this.children[0]?._original;
default:
return this._original;
}
}

/**
* Whether the validator is in it's simplest form - no children, extra checks, etc.
*/
Expand Down
58 changes: 46 additions & 12 deletions src/transformer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export class Transformer {
toBeResolved: Map<ts.SignatureDeclaration, ToBeResolved[]>;
validatedDecls: Map<ts.Declaration, ts.FunctionLikeDeclaration>;
symbolsToImport: SymbolImportInfo;
private boundDeclarationVisitor = this.declarationVisitor.bind(this);
constructor(program: ts.Program, ctx: ts.TransformationContext, config: TsRuntimeChecksConfig, toBeResolved = new Map(), validatedDecls = new Map()) {
this.checker = program.getTypeChecker();
this.program = program;
Expand All @@ -52,12 +53,12 @@ export class Transformer {
};
}

extend(program: ts.Program, ctx: ts.TransformationContext) : Transformer {
extend(program: ts.Program, ctx: ts.TransformationContext): Transformer {
return new Transformer(program, ctx, this.config, this.toBeResolved);
}

run(node: ts.SourceFile): ts.SourceFile {
if (node.isDeclarationFile) return node;
if (node.isDeclarationFile) return ts.visitEachChild(node, this.boundDeclarationVisitor, this.ctx);
const children = this.visitEach(node.statements);
const allChildren = [...this.symbolsToImport.importStatements, ...children];
this.symbolsToImport = {identifierMap: new Map(), importStatements: []};
Expand Down Expand Up @@ -238,10 +239,9 @@ export class Transformer {
const markerName = this.getPropType(type, "marker");
if (!markerName || !markerName.isStringLiteral()) return;
marker = Markers[markerName.value] as MarkerFn;
const params = this.getPropType(type, "marker_params");
if (!params || !this.checker.isTupleType(params)) return;
markerParams = this.checker.getTypeArguments(params as ts.TypeReference) as ts.Type[];
if (!markerParams.length) markerParams = node.typeArguments?.map(arg => this.checker.getTypeAtLocation(arg)) || [];
const params = this.getMarkerParams(node, type);
if (!params) return;
markerParams = params;
} else {
// TODO: For now we only have one marker so setting the params is straightforward
// Change this when adding new markers
Expand All @@ -261,18 +261,20 @@ export class Transformer {
];
}

getMarkerParams(node: ts.TypeReferenceNode, type: ts.Type): ts.Type[] | undefined {
const params = this.getPropType(type, "marker_params");
if (!params || !this.checker.isTupleType(params)) return;
let markerParams = this.checker.getTypeArguments(params as ts.TypeReference) as ts.Type[];
if (!markerParams.length) markerParams = node.typeArguments?.map(arg => this.checker.getTypeAtLocation(arg)) || [];
return markerParams;
}

getPropType(type: ts.Type, prop: string): ts.Type | undefined {
const propSym = type.getProperty(`__$${prop}`);
if (!propSym || !propSym.valueDeclaration) return;
return this.checker.getNonNullableType(this.checker.getTypeOfSymbolAtLocation(propSym, propSym.valueDeclaration));
}

resolveActualType(t: ts.Type): ts.Type | undefined {
const prop = t.getProperty("__$marker");
if (!prop || !prop.valueDeclaration) return;
return this.checker.getNonNullableType(this.checker.getTypeOfSymbolAtLocation(prop, prop.valueDeclaration));
}

typeValueToNode(t: ts.Type, firstOnly?: true, exprReplacements?: Record<string, ts.Expression>): ts.Expression;
typeValueToNode(t: ts.Type, firstOnly?: boolean, exprReplacements?: Record<string, ts.Expression>): ts.Expression | Array<ts.Expression> {
if (t.isStringLiteral()) return ts.factory.createStringLiteral(t.value);
Expand Down Expand Up @@ -350,4 +352,36 @@ export class Transformer {
}
return refs;
}

declarationVisitor(node: ts.Node): ts.Node | undefined {
const typeOfNode = this.checker.getTypeAtLocation(node);
if (ts.isTypeReferenceNode(node)) {
const markerName = this.getPropType(typeOfNode, "marker");
if (markerName) {
const params = this.getMarkerParams(node, typeOfNode);
if (!params || !params[0]) return node;
return this.checker.typeToTypeNode(params[0], undefined, undefined);
}
const utilityMarker = this.getPropType(typeOfNode, "name");
if (utilityMarker && utilityMarker.isStringLiteral()) {
if (utilityMarker.value === "Check") {
const validator = genValidator(this, typeOfNode, "");
if (!validator || !validator.children[0]) return;
return this.checker.typeToTypeNode(validator.getBaseType()!, undefined, undefined);
} else if (utilityMarker.value === "NoCheck") {
return node.typeArguments?.[0];
} else return;
}
} else if (typeOfNode.isUnion() && ts.isTypeNode(node)) {
const validator = genValidator(this, typeOfNode, "");
if (!validator) return node;
return ts.factory.createUnionTypeNode(
validator.children
.map(child => child.getBaseType())
.filter(t => t)
.map(baseType => this.checker.typeToTypeNode(baseType!, undefined, undefined)!)
);
}
return ts.visitEachChild(node, this.boundDeclarationVisitor, this.ctx);
}
}

0 comments on commit d31ddbd

Please sign in to comment.