@mistlog/typetype
Version:
A programming language designed for typescript type generation
276 lines (275 loc) • 11.9 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.ContextType = exports.MappedTypeExpression = exports.IndexType = exports.KeyOfType = exports.ReadonlyArray = exports.ReadonlyTuple = exports.OperatorType = exports.IntersectionType = exports.UnionType = exports.InferType = exports.ParamList = exports.TypeExpressionList = exports.TypeCallExpression = exports.ConditionalTypeExpression = exports.TypeArrowFunctionExpression = exports.ParenthesizedType = exports.TypeExpression = void 0;
const react_peg_1 = require("react-peg");
const common_1 = require("../common");
const basic_1 = require("../basic");
const statement_1 = require("../statement");
const function_1 = require("../function");
function TypeExpression() {
return (react_peg_1.ReactPeg.createChunk("or", null,
react_peg_1.ReactPeg.createChunk(ContextType, null),
react_peg_1.ReactPeg.createChunk(ParenthesizedType, null),
react_peg_1.ReactPeg.createChunk(function_1.FunctionType, null),
react_peg_1.ReactPeg.createChunk(OperatorType, null),
react_peg_1.ReactPeg.createChunk(IndexType, null),
react_peg_1.ReactPeg.createChunk(UnionType, null),
react_peg_1.ReactPeg.createChunk(IntersectionType, null),
react_peg_1.ReactPeg.createChunk(ConditionalTypeExpression, null),
react_peg_1.ReactPeg.createChunk(MappedTypeExpression, null),
react_peg_1.ReactPeg.createChunk(TypeCallExpression, null),
react_peg_1.ReactPeg.createChunk(basic_1.BasicType, null),
react_peg_1.ReactPeg.createChunk(InferType, null),
react_peg_1.ReactPeg.createChunk(basic_1.TypeReference, null)));
}
exports.TypeExpression = TypeExpression;
function ParenthesizedType() {
const action = ({ param }) => {
return {
kind: "ParenthesizedType",
param
};
};
return (react_peg_1.ReactPeg.createChunk("pattern", { action: action },
common_1.Text("("),
react_peg_1.ReactPeg.createChunk(TypeExpression, { label: "param" }),
common_1.Text(")")));
}
exports.ParenthesizedType = ParenthesizedType;
/**
* TODO: add more expressions? use block statement?
*/
function TypeArrowFunctionExpression() {
const action = ({ params, body }) => {
return {
kind: "TypeArrowFunctionExpression",
params,
body
};
};
return (react_peg_1.ReactPeg.createChunk("pattern", { action: action },
common_1.Text("("),
react_peg_1.ReactPeg.createChunk(ParamList, { label: "params" }),
common_1.Text(")"),
common_1.Text("=>"),
react_peg_1.ReactPeg.createChunk(TypeExpression, { label: "body" })));
}
exports.TypeArrowFunctionExpression = TypeArrowFunctionExpression;
function ConditionalTypeExpression() {
const action = ({ statement }) => {
return {
kind: "ConditionalTypeExpression",
body: statement
};
};
return (react_peg_1.ReactPeg.createChunk("pattern", { action: action },
common_1.Text("^{"),
react_peg_1.ReactPeg.createChunk(statement_1.TypeIfStatement, { label: "statement" }),
common_1.Text("}")));
}
exports.ConditionalTypeExpression = ConditionalTypeExpression;
function TypeCallExpression() {
const action = ({ callee, params }) => {
return {
kind: "TypeCallExpression",
callee,
params
};
};
return (react_peg_1.ReactPeg.createChunk("pattern", { action: action },
react_peg_1.ReactPeg.createChunk(common_1._, null),
react_peg_1.ReactPeg.createChunk(basic_1.TypeReference, { label: "callee" }),
common_1.Text("<"),
react_peg_1.ReactPeg.createChunk(ParamList, { label: "params" }),
common_1.Text(">"),
react_peg_1.ReactPeg.createChunk(common_1._, null)));
}
exports.TypeCallExpression = TypeCallExpression;
function TypeExpressionList() {
return (react_peg_1.ReactPeg.createChunk("pattern", { action: ({ head, tail }) => head ? [head, ...tail] : [] },
react_peg_1.ReactPeg.createChunk("opt", { label: "head" },
react_peg_1.ReactPeg.createChunk("or", null,
react_peg_1.ReactPeg.createChunk(TypeExpression, null),
react_peg_1.ReactPeg.createChunk(basic_1.RestType, null))),
react_peg_1.ReactPeg.createChunk("repeat", { type: "*", label: "tail" },
react_peg_1.ReactPeg.createChunk("pattern", { action: ({ param }) => param },
common_1.Text(","),
react_peg_1.ReactPeg.createChunk("or", { label: "param" },
react_peg_1.ReactPeg.createChunk(basic_1.RestType, null),
react_peg_1.ReactPeg.createChunk(TypeExpression, null))))));
}
exports.TypeExpressionList = TypeExpressionList;
function ParamList() {
const action = ({ head, tail }) => head ? [head, ...tail] : [];
const actionReturnParam = ({ param, constraint, _default }) => {
const _param = param;
if (constraint) {
_param.constraint = constraint;
}
if (_default) {
_param.default = _default;
}
return _param;
};
const paramWithConstraint = () => {
return (react_peg_1.ReactPeg.createChunk("list", null,
react_peg_1.ReactPeg.createChunk(TypeExpression, { label: "param" }),
react_peg_1.ReactPeg.createChunk("opt", { label: "constraint" },
react_peg_1.ReactPeg.createChunk("pattern", { action: ({ expression }) => expression },
common_1.Text("extends"),
react_peg_1.ReactPeg.createChunk(TypeExpression, { label: "expression" }))),
react_peg_1.ReactPeg.createChunk("opt", { label: "_default" },
react_peg_1.ReactPeg.createChunk("pattern", { action: ({ expression }) => expression },
common_1.Text("="),
react_peg_1.ReactPeg.createChunk(TypeExpression, { label: "expression" })))));
};
return (react_peg_1.ReactPeg.createChunk("pattern", { action: action },
react_peg_1.ReactPeg.createChunk("opt", { label: "head" },
react_peg_1.ReactPeg.createChunk("pattern", { action: actionReturnParam }, paramWithConstraint())),
react_peg_1.ReactPeg.createChunk("repeat", { type: "*", label: "tail" },
react_peg_1.ReactPeg.createChunk("pattern", { action: actionReturnParam },
common_1.Text(","),
paramWithConstraint()))));
}
exports.ParamList = ParamList;
function InferType() {
const action = ({ typeName }) => {
return {
kind: "InferType",
typeName
};
};
return (react_peg_1.ReactPeg.createChunk("pattern", { action: action },
common_1.Text("infer"),
react_peg_1.ReactPeg.createChunk(basic_1.Identifier, { label: "typeName" })));
}
exports.InferType = InferType;
function UnionType() {
const action = ({ types }) => {
return {
kind: "UnionType",
types
};
};
return (react_peg_1.ReactPeg.createChunk("pattern", { action: action },
react_peg_1.ReactPeg.createChunk("or", null,
common_1.Text("|"),
common_1.Text("union")),
common_1.Text("["),
react_peg_1.ReactPeg.createChunk(TypeExpressionList, { label: "types" }),
common_1.Text("]")));
}
exports.UnionType = UnionType;
function IntersectionType() {
const action = ({ types }) => {
return {
kind: "IntersectionType",
types
};
};
/** An intersection type combines multiple types into one */
return (react_peg_1.ReactPeg.createChunk("pattern", { action: action },
react_peg_1.ReactPeg.createChunk("or", null,
common_1.Text("&"),
common_1.Text("combine")),
common_1.Text("["),
react_peg_1.ReactPeg.createChunk(TypeExpressionList, { label: "types" }),
common_1.Text("]")));
}
exports.IntersectionType = IntersectionType;
function OperatorType() {
return (react_peg_1.ReactPeg.createChunk("or", null,
react_peg_1.ReactPeg.createChunk(KeyOfType, null),
react_peg_1.ReactPeg.createChunk(ReadonlyArray, null),
react_peg_1.ReactPeg.createChunk(ReadonlyTuple, null)));
}
exports.OperatorType = OperatorType;
function ReadonlyTuple() {
const action = ({ operand }) => {
return {
kind: "ReadonlyTuple",
operand
};
};
return (react_peg_1.ReactPeg.createChunk("pattern", { action: action },
common_1.Text("readonly"),
react_peg_1.ReactPeg.createChunk(basic_1.TupleType, { label: "operand" })));
}
exports.ReadonlyTuple = ReadonlyTuple;
function ReadonlyArray() {
const action = ({ operand }) => {
return {
kind: "ReadonlyArray",
operand
};
};
return (react_peg_1.ReactPeg.createChunk("pattern", { action: action },
common_1.Text("readonly"),
react_peg_1.ReactPeg.createChunk(basic_1.ArrayType, { label: "operand" })));
}
exports.ReadonlyArray = ReadonlyArray;
function KeyOfType() {
const action = ({ operand }) => {
return {
kind: "KeyOfType",
operand
};
};
return (react_peg_1.ReactPeg.createChunk("pattern", { action: action },
common_1.Text("keyof"),
react_peg_1.ReactPeg.createChunk(TypeExpression, { label: "operand" })));
}
exports.KeyOfType = KeyOfType;
function IndexTypeHead() {
const typeExpression = TypeExpression();
typeExpression.children = typeExpression.children.filter((child) => child.rule !== IndexType);
return typeExpression;
}
function IndexType() {
const action = ({ head, members }) => {
return {
kind: "IndexType",
head,
members
};
};
return (react_peg_1.ReactPeg.createChunk("pattern", { action: action },
react_peg_1.ReactPeg.createChunk(IndexTypeHead, { label: "head" }),
react_peg_1.ReactPeg.createChunk("repeat", { type: "+", label: "members" },
react_peg_1.ReactPeg.createChunk("pattern", { action: ({ indexType }) => indexType },
common_1.Text("["),
react_peg_1.ReactPeg.createChunk(TypeExpression, { label: "indexType" }),
common_1.Text("]")))));
}
exports.IndexType = IndexType;
function MappedTypeExpression() {
const action = ({ statement }) => {
return {
kind: "MappedTypeExpression",
body: statement
};
};
return (react_peg_1.ReactPeg.createChunk("pattern", { action: action },
common_1.Text("^{"),
react_peg_1.ReactPeg.createChunk(statement_1.TypeForInStatement, { label: "statement" }),
common_1.Text("}")));
}
exports.MappedTypeExpression = MappedTypeExpression;
function ContextType() {
const action = ({ context, source, globalContext }) => {
const ast = {
kind: "ContextType",
body: {
context,
source
}
};
return globalContext.resolveContextType ? globalContext.resolveContextType(ast) : ast;
};
return (react_peg_1.ReactPeg.createChunk("pattern", { action: action },
common_1.Text("```"),
react_peg_1.ReactPeg.createChunk(basic_1.String, { label: "context" }),
react_peg_1.ReactPeg.createChunk(basic_1.Source, { label: "source" }),
common_1.Text("```")));
}
exports.ContextType = ContextType;