Documentation
¶
Overview ¶
Package typesystem implements type-system with generics and structural subtyping. For convenience these structures have json tags (like `src` package). This is not clean architecture but it's very handy for LSP.
Index ¶
- Variables
- type Def
- type DefaultStringer
- type Expr
- type Helper
- func (h Helper) BaseDef(params ...Param) Def
- func (h Helper) BaseDefWithRecursionAllowed(params ...Param) Def
- func (h Helper) Def(body Expr, params ...Param) Def
- func (h Helper) Inst(ref string, args ...Expr) Expr
- func (h Helper) Param(name string, constr Expr) Param
- func (h Helper) ParamWithNoConstr(name string) Param
- func (h Helper) Struct(structure map[string]Expr) Expr
- func (h Helper) Trace(ss ...string) Trace
- func (h Helper) Union(els map[string]*Expr) Expr
- type InstExpr
- type LitExpr
- type LiteralType
- type Param
- type Resolver
- func (r Resolver) CheckArgsCompatibility(args []Expr, params []Param, scope Scope) error
- func (r Resolver) IsSubtypeOf(sub, sup Expr, scope Scope) error
- func (r Resolver) ResolveExpr(expr Expr, scope Scope) (Expr, error)
- func (r Resolver) ResolveExprWithFrame(expr Expr, frame map[string]Def, scope Scope) (Expr, error)
- func (r Resolver) ResolveExprsWithFrame(exprs []Expr, frame map[string]Def, scope Scope) ([]Expr, error)
- func (r Resolver) ResolveParams(params []Param, scope Scope) ([]Param, map[string]Def, error)
- type Scope
- type SubtypeChecker
- type Terminator
- type TerminatorParams
- type Trace
- type Validator
Constants ¶
This section is empty.
Variables ¶
var ( ErrInvalidExpr = errors.New("expression must be valid in order to be resolved") ErrScope = errors.New("can't get type def from scope by ref") ErrScopeUpdate = errors.New("scope update") ErrInstArgsCount = errors.New("wrong number of type arguments") ErrIncompatArg = errors.New("argument is not subtype of the parameter's contraint") ErrUnresolvedArg = errors.New("can't resolve argument") ErrConstr = errors.New("can't resolve constraint") ErrUnionUnresolvedEl = errors.New("can't resolve union element") ErrRecFieldUnresolved = errors.New("can't resolve struct field") ErrInvalidDef = errors.New("invalid definition") ErrTerminator = errors.New("recursion terminator") )
var ( ErrDiffKinds = errors.New("subtype and supertype must both be either literals or instances") ErrDiffRefs = errors.New("subtype instance must have same ref as supertype") ErrArgsCount = errors.New("subtype instance must have >= args than supertype") ErrArgNotSubtype = errors.New("subtype arg must be subtype of corresponding supertype arg") ErrStructLen = errors.New("subtype struct must contain >= fields than supertype") ErrStructField = errors.New("subtype struct field must be subtype of corresponding supertype field") ErrStructNoField = errors.New("subtype struct is missing field of supertype") ErrUnionArg = errors.New("subtype must be union") ErrUnionsLen = errors.New("subtype union must be <= supertype union") ErrUnions = errors.New("subtype union element must be subtype of supertype union") ErrDiffLitTypes = errors.New("subtype and supertype lits must be of the same type") )
var ( ErrDirectRecursion = errors.New("type definition's body must not be directly referenced to itself") ErrPrevDefNotFound = errors.New("prev def not found") ErrIndirectRecursion = errors.New("type definition's body must not be indirectly referenced to itself") ErrSwapRun = errors.New("couldn't do test run with swapped trace") ErrCounter = errors.New("recursive calls counter limit exceeded") )
var ( ErrExprMustBeInstOrLit = errors.New("expr must be ether literal or instantiation, not both and not neither") ErrParamDuplicate = errors.New("params must have unique names") ErrParams = errors.New("bad params") ErrUnionTag = errors.New("union tag must be non-empty") ErrUnionTagType = errors.New("union tag type must be valid") )
Functions ¶
This section is empty.
Types ¶
type Def ¶
type DefaultStringer ¶
type DefaultStringer string
func (DefaultStringer) String ¶
func (ds DefaultStringer) String() string
type Expr ¶
type Expr struct {
Lit *LitExpr `json:"lit,omitempty"`
Inst *InstExpr `json:"inst,omitempty"`
Meta core.Meta `json:"meta"` // This field must be ignored by the typesystem and only used outside
}
Instantiation or literal. Lit or Inst must be not nil, but not both
type Helper ¶
type Helper struct{}
Helper is just a namespace for helper functions to avoid conflicts with entity types. It's a stateless type and it's safe to share it between goroutines.
func (Helper) BaseDefWithRecursionAllowed ¶
any base type def (without body) that has type parameters allows recursion
func (Helper) ParamWithNoConstr ¶
type LitExpr ¶
type LitExpr struct {
Struct map[string]Expr `json:"struct,omitempty"`
Union map[string]*Expr `json:"union,omitempty"` // tag -> constraint
}
Literal expression. Only one field must be initialized
type LiteralType ¶
type LiteralType uint8
const ( EmptyLitType LiteralType = iota StructLitType UnionLitType )
type Resolver ¶
type Resolver struct {
// contains filtered or unexported fields
}
Resolver transforms expression it into a form where all references it contains points to resolved expressions.
func MustNewResolver ¶
func MustNewResolver(validator exprValidator, checker subtypeChecker, terminator recursionTerminator) Resolver
func (Resolver) CheckArgsCompatibility ¶
CheckArgsCompatibility resolves args and params and then checks their compatibility.
func (Resolver) IsSubtypeOf ¶
IsSubtypeOf resolves both `sub` and `sup` expressions and returns error if `sub` is not subtype of `sup`.
func (Resolver) ResolveExpr ¶
ResolveExpr resolves given expression using only global scope.
func (Resolver) ResolveExprWithFrame ¶
func (r Resolver) ResolveExprWithFrame( expr Expr, frame map[string]Def, scope Scope, ) (Expr, error)
ResolveExprWithFrame works like ResolveExpr but allows to pass local scope.
type SubtypeChecker ¶
type SubtypeChecker struct {
// contains filtered or unexported fields
}
func MustNewSubtypeChecker ¶
func MustNewSubtypeChecker(terminator recursionTerminator) SubtypeChecker
func (SubtypeChecker) Check ¶
func (s SubtypeChecker) Check( expr, constr Expr, params TerminatorParams, ) error
Check checks whether subtype is a subtype of supertype. Both subtype and supertype must be resolved. It also takes traces for those expressions and scope to handle recursive types.
type Terminator ¶
type Terminator struct{}
Terminator decides whether type resolution should continue expanding the current expression, stop at a valid recursive back-edge, or reject an invalid recursive definition.
func (Terminator) ShouldTerminate ¶
func (r Terminator) ShouldTerminate(cur Trace, scope Scope) (bool, error)
ShouldTerminate classifies the newest reference in a type-resolution trace. Its results have three meanings:
- false, nil: this is finite nesting; continue normal resolution;
- true, nil: this is a permitted recursive back-edge; keep the current type reference without expanding it again;
- false, err: the type contains invalid direct or indirect recursion.
For example, list<list<int>> returns false because both list occurrences are finite base-type instantiations. A recursive type such as `type Node struct { children list<Node> }` eventually returns true for the second Node because the path returns through list. In contrast, `type T T` returns ErrDirectRecursion because expanding T immediately produces T again.
type TerminatorParams ¶
type Trace ¶
type Trace struct {
// contains filtered or unexported fields
}
Trace records the type references visited during recursive type resolution. cur is the newest reference; prev links to the reference that led to it.
For example, while resolving the inner list in list<list<int>>, the trace is represented newest-first in memory as list -> list, while String prints it in source traversal order as [list, list].
type Validator ¶
type Validator struct{}
func (Validator) CheckParamUnique ¶
CheckParamUnique doesn't validate constraints, only ensures uniqueness
func (Validator) Validate ¶
Validate makes shallow validation of expr. It checks that it's inst or literal, not both and not neither; All insts are valid by default;
func (Validator) ValidateDef ¶
ValidateDef makes sure that type supports recursion only if it's base type and that parameters are valid