UNPKG

@mistlog/typetype

Version:

A programming language designed for typescript type generation

276 lines (275 loc) 11.9 kB
"use strict"; 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;