src/TypeSpec.hack (127 lines of code) (raw):

/* * Copyright (c) 2016, Fred Emmott * Copyright (c) 2017-present, Facebook, Inc. * All rights reserved. * * This source code is licensed under the MIT license found in the * LICENSE file in the root directory of this source tree. * */ namespace Facebook\TypeSpec; abstract class TypeSpec<+T> { private ?Trace $trace = null; abstract public function coerceType(mixed $value): T; abstract public function assertType(mixed $value): T; abstract public function toString(): string; public function isOptional(): bool { return false; } final protected function getTrace(): Trace { return $this->trace ?? new Trace(); } final protected function withTrace(Trace $trace): TypeSpec<T> { $new = clone $this; $new->trace = $trace; return $new; } } function arraykey(): TypeSpec<arraykey> { return new __Private\ArrayKeySpec(); } function bool(): TypeSpec<bool> { return new __Private\BoolSpec(); } function classname<T>(classname<T> $what): TypeSpec<classname<T>> { return new __Private\ClassnameSpec($what); } function constmap<Tk as arraykey, Tv>( TypeSpec<Tk> $tsk, TypeSpec<Tv> $tsv, ): TypeSpec<\ConstMap<Tk, Tv>> { return new __Private\MapSpec(\ConstMap::class, $tsk, $tsv); } function constset<Tv as arraykey>(TypeSpec<Tv> $tsv): TypeSpec<\ConstSet<Tv>> { return new __Private\SetSpec(\ConstSet::class, $tsv); } function constvector<Tv>(TypeSpec<Tv> $inner): TypeSpec<\ConstVector<Tv>> { return new __Private\VectorSpec(\ConstVector::class, $inner); } function darray<Tk as arraykey, Tv>( TypeSpec<Tk> $tsk, TypeSpec<Tv> $tsv, ): TypeSpec<darray<Tk, Tv>> { return new __Private\DarraySpec($tsk, $tsv); } function dict<Tk as arraykey, Tv>( TypeSpec<Tk> $tsk, TypeSpec<Tv> $tsv, ): TypeSpec<dict<Tk, Tv>> { return new __Private\DictSpec($tsk, $tsv); } function enum<T as arraykey>(\HH\enumname<T> $what): TypeSpec<T> { return new __Private\EnumSpec($what); } function float(): TypeSpec<float> { return new __Private\FloatSpec(); } function instance_of<T>(classname<T> $what): TypeSpec<T> { return new __Private\InstanceOfSpec($what); } function int(): TypeSpec<int> { return new __Private\IntSpec(); } function immmap<Tk as arraykey, Tv>( TypeSpec<Tk> $tsk, TypeSpec<Tv> $tsv, ): TypeSpec<ImmMap<Tk, Tv>> { return new __Private\MapSpec(ImmMap::class, $tsk, $tsv); } function immset<Tv as arraykey>(TypeSpec<Tv> $tsv): TypeSpec<ImmSet<Tv>> { return new __Private\SetSpec(ImmSet::class, $tsv); } function immvector<Tv>(TypeSpec<Tv> $inner): TypeSpec<ImmVector<Tv>> { return new __Private\VectorSpec(ImmVector::class, $inner); } function keyset<Tk as arraykey>(TypeSpec<Tk> $inner): TypeSpec<keyset<Tk>> { return new __Private\KeysetSpec($inner); } function map<Tk as arraykey, Tv>( TypeSpec<Tk> $tsk, TypeSpec<Tv> $tsv, ): TypeSpec<Map<Tk, Tv>> { return new __Private\MapSpec(Map::class, $tsk, $tsv); } function mixed(): TypeSpec<mixed> { return new __Private\MixedSpec(); } function nonnull(): TypeSpec<nonnull> { return new __Private\NonNullSpec(); } function null(): TypeSpec<null> { return new __Private\NullSpec(); } function nullable<T>(TypeSpec<T> $inner): TypeSpec<?T> { return new __Private\NullableSpec($inner); } function num(): TypeSpec<num> { return new __Private\NumSpec(); } function resource(?string $kind = null): TypeSpec<resource> { return new __Private\ResourceSpec($kind); } function set<Tv as arraykey>(TypeSpec<Tv> $tsv): TypeSpec<Set<Tv>> { return new __Private\SetSpec(Set::class, $tsv); } function string(): TypeSpec<string> { return new __Private\StringSpec(); } function varray<Tv>(TypeSpec<Tv> $tsv): TypeSpec<varray<Tv>> { return new __Private\VarraySpec($tsv); } function vec<Tv>(TypeSpec<Tv> $inner): TypeSpec<vec<Tv>> { return new __Private\VecSpec($inner); } function vector<Tv>(TypeSpec<Tv> $inner): TypeSpec<Vector<Tv>> { return new __Private\VectorSpec(Vector::class, $inner); } function varray_or_darray<Tv>( TypeSpec<Tv> $inner, ): TypeSpec<varray_or_darray<Tv>> { return new __Private\VArrayOrDArraySpec($inner); } function of<reify T>(): TypeSpec<T> { return __Private\from_type_structure( \HH\ReifiedGenerics\get_type_structure<T>(), ); }