// This file is part of the Luau programming language and is licensed under MIT License; see LICENSE.txt for details #include "Luau/BuiltinDefinitions.h" namespace Luau { static const std::string kBuiltinDefinitionBaseSrc = R"BUILTIN_SRC( @checked declare function require(target: any): any @checked declare function getfenv(target: any): { [string]: any } declare _G: any declare _VERSION: string declare function gcinfo(): number declare function print(...: T...) declare function type(value: T): string declare function typeof(value: T): string -- `assert` has a magic function attached that will give more detailed type information declare function assert(value: T, errorMessage: string?): T declare function error(message: T, level: number?): never declare function tostring(value: T): string declare function tonumber(value: T, radix: number?): number? declare function rawequal(a: T1, b: T2): boolean declare function rawget(tab: {[K]: V}, k: K): V declare function rawset(tab: {[K]: V}, k: K, v: V): {[K]: V} declare function rawlen(obj: {[K]: V} | string): number declare function setfenv(target: number | (T...) -> R..., env: {[string]: any}): ((T...) -> R...)? declare function ipairs(tab: {V}): (({V}, number) -> (number?, V), {V}, number) declare function pcall(f: (A...) -> R..., ...: A...): (boolean, R...) -- FIXME: The actual type of `xpcall` is: -- (f: (A...) -> R1..., err: (E) -> R2..., A...) -> (true, R1...) | (false, R2...) -- Since we can't represent the return value, we use (boolean, R1...). declare function xpcall(f: (A...) -> R1..., err: (E) -> R2..., ...: A...): (boolean, R1...) -- `select` has a magic function attached to provide more detailed type information declare function select(i: string | number, ...: A...): ...any -- FIXME: This type is not entirely correct - `loadstring` returns a function or -- (nil, string). declare function loadstring(src: string, chunkname: string?): (((A...) -> any)?, string?) @checked declare function newproxy(mt: boolean?): any -- Cannot use `typeof` here because it will produce a polytype when we expect a monotype. declare function unpack(tab: {V}, i: number?, j: number?): ...V )BUILTIN_SRC"; static const std::string kBuiltinDefinitionBit32Src = R"BUILTIN_SRC( declare bit32: { band: @checked (...number) -> number, bor: @checked (...number) -> number, bxor: @checked (...number) -> number, btest: @checked (number, ...number) -> boolean, rrotate: @checked (x: number, disp: number) -> number, lrotate: @checked (x: number, disp: number) -> number, lshift: @checked (x: number, disp: number) -> number, arshift: @checked (x: number, disp: number) -> number, rshift: @checked (x: number, disp: number) -> number, bnot: @checked (x: number) -> number, extract: @checked (n: number, field: number, width: number?) -> number, replace: @checked (n: number, v: number, field: number, width: number?) -> number, countlz: @checked (n: number) -> number, countrz: @checked (n: number) -> number, byteswap: @checked (n: number) -> number, } )BUILTIN_SRC"; static const std::string kBuiltinDefinitionMathSrc = R"BUILTIN_SRC( declare math: { frexp: @checked (n: number) -> (number, number), ldexp: @checked (s: number, e: number) -> number, fmod: @checked (x: number, y: number) -> number, modf: @checked (n: number) -> (number, number), pow: @checked (x: number, y: number) -> number, exp: @checked (n: number) -> number, ceil: @checked (n: number) -> number, floor: @checked (n: number) -> number, abs: @checked (n: number) -> number, sqrt: @checked (n: number) -> number, log: @checked (n: number, base: number?) -> number, log10: @checked (n: number) -> number, rad: @checked (n: number) -> number, deg: @checked (n: number) -> number, sin: @checked (n: number) -> number, cos: @checked (n: number) -> number, tan: @checked (n: number) -> number, sinh: @checked (n: number) -> number, cosh: @checked (n: number) -> number, tanh: @checked (n: number) -> number, atan: @checked (n: number) -> number, acos: @checked (n: number) -> number, asin: @checked (n: number) -> number, atan2: @checked (y: number, x: number) -> number, min: @checked (number, ...number) -> number, max: @checked (number, ...number) -> number, pi: number, huge: number, randomseed: @checked (seed: number) -> (), random: @checked (number?, number?) -> number, sign: @checked (n: number) -> number, clamp: @checked (n: number, min: number, max: number) -> number, noise: @checked (x: number, y: number?, z: number?) -> number, round: @checked (n: number) -> number, map: @checked (x: number, inmin: number, inmax: number, outmin: number, outmax: number) -> number, lerp: @checked (a: number, b: number, t: number) -> number, } )BUILTIN_SRC"; static const std::string kBuiltinDefinitionOsSrc = R"BUILTIN_SRC( type DateTypeArg = { year: number, month: number, day: number, hour: number?, min: number?, sec: number?, isdst: boolean?, } type DateTypeResult = { year: number, month: number, wday: number, yday: number, day: number, hour: number, min: number, sec: number, isdst: boolean, } declare os: { time: (time: DateTypeArg?) -> number, date: ((formatString: "*t" | "!*t", time: number?) -> DateTypeResult) & ((formatString: string?, time: number?) -> string), difftime: (t2: DateTypeResult | number, t1: DateTypeResult | number) -> number, clock: () -> number, } )BUILTIN_SRC"; static const std::string kBuiltinDefinitionCoroutineSrc = R"BUILTIN_SRC( declare coroutine: { create: (f: (A...) -> R...) -> thread, resume: (co: thread, A...) -> (boolean, R...), running: () -> thread, status: @checked (co: thread) -> "dead" | "running" | "normal" | "suspended", wrap: (f: (A...) -> R...) -> ((A...) -> R...), yield: (A...) -> R..., isyieldable: () -> boolean, close: @checked (co: thread) -> (boolean, any) } )BUILTIN_SRC"; static const std::string kBuiltinDefinitionTableSrc = R"BUILTIN_SRC( declare table: { concat: (t: {V}, sep: string?, i: number?, j: number?) -> string, insert: ((t: {V}, value: V) -> ()) & ((t: {V}, pos: number, value: V) -> ()), maxn: (t: {V}) -> number, remove: (t: {V}, number?) -> V?, sort: (t: {V}, comp: ((V, V) -> boolean)?) -> (), create: (count: number, value: V?) -> {V}, find: (haystack: {V}, needle: V, init: number?) -> number?, unpack: (list: {V}, i: number?, j: number?) -> ...V, pack: (...V) -> { n: number, [number]: V }, getn: (t: {V}) -> number, foreach: (t: {[K]: V}, f: (K, V) -> ()) -> (), foreachi: ({V}, (number, V) -> ()) -> (), move: (src: {V}, a: number, b: number, t: number, dst: {V}?) -> {V}, clear: (table: {[K]: V}) -> (), isfrozen: (t: {[K]: V}) -> boolean, } )BUILTIN_SRC"; static const std::string kBuiltinDefinitionDebugSrc = R"BUILTIN_SRC( declare debug: { info: ((thread: thread, level: number, options: string) -> ...any) & ((level: number, options: string) -> ...any) & ((func: (A...) -> R1..., options: string) -> ...any), traceback: ((message: string?, level: number?) -> string) & ((thread: thread, message: string?, level: number?) -> string), } )BUILTIN_SRC"; static const std::string kBuiltinDefinitionUtf8Src = R"BUILTIN_SRC( declare utf8: { char: @checked (...number) -> string, charpattern: string, codes: @checked (str: string) -> ((string, number) -> (number, number), string, number), codepoint: @checked (str: string, i: number?, j: number?) -> ...number, len: @checked (s: string, i: number?, j: number?) -> (number?, number?), offset: @checked (s: string, n: number?, i: number?) -> number, } )BUILTIN_SRC"; static const std::string kBuiltinDefinitionBufferSrc = R"BUILTIN_SRC( --- Buffer API declare buffer: { create: @checked (size: number) -> buffer, fromstring: @checked (str: string) -> buffer, tostring: @checked (b: buffer) -> string, len: @checked (b: buffer) -> number, copy: @checked (target: buffer, targetOffset: number, source: buffer, sourceOffset: number?, count: number?) -> (), fill: @checked (b: buffer, offset: number, value: number, count: number?) -> (), readi8: @checked (b: buffer, offset: number) -> number, readu8: @checked (b: buffer, offset: number) -> number, readi16: @checked (b: buffer, offset: number) -> number, readu16: @checked (b: buffer, offset: number) -> number, readi32: @checked (b: buffer, offset: number) -> number, readu32: @checked (b: buffer, offset: number) -> number, readf32: @checked (b: buffer, offset: number) -> number, readf64: @checked (b: buffer, offset: number) -> number, writei8: @checked (b: buffer, offset: number, value: number) -> (), writeu8: @checked (b: buffer, offset: number, value: number) -> (), writei16: @checked (b: buffer, offset: number, value: number) -> (), writeu16: @checked (b: buffer, offset: number, value: number) -> (), writei32: @checked (b: buffer, offset: number, value: number) -> (), writeu32: @checked (b: buffer, offset: number, value: number) -> (), writef32: @checked (b: buffer, offset: number, value: number) -> (), writef64: @checked (b: buffer, offset: number, value: number) -> (), readstring: @checked (b: buffer, offset: number, count: number) -> string, writestring: @checked (b: buffer, offset: number, value: string, count: number?) -> (), readbits: @checked (b: buffer, bitOffset: number, bitCount: number) -> number, writebits: @checked (b: buffer, bitOffset: number, bitCount: number, value: number) -> (), } )BUILTIN_SRC"; static const std::string kBuiltinDefinitionVectorSrc = R"BUILTIN_SRC( -- While vector would have been better represented as a built-in primitive type, type solver class handling covers most of the properties declare class vector x: number y: number z: number end declare vector: { create: @checked (x: number, y: number, z: number?) -> vector, magnitude: @checked (vec: vector) -> number, normalize: @checked (vec: vector) -> vector, cross: @checked (vec1: vector, vec2: vector) -> vector, dot: @checked (vec1: vector, vec2: vector) -> number, angle: @checked (vec1: vector, vec2: vector, axis: vector?) -> number, floor: @checked (vec: vector) -> vector, ceil: @checked (vec: vector) -> vector, abs: @checked (vec: vector) -> vector, sign: @checked (vec: vector) -> vector, clamp: @checked (vec: vector, min: vector, max: vector) -> vector, max: @checked (vector, ...vector) -> vector, min: @checked (vector, ...vector) -> vector, zero: vector, one: vector, } )BUILTIN_SRC"; std::string getBuiltinDefinitionSource() { std::string result = kBuiltinDefinitionBaseSrc; result += kBuiltinDefinitionBit32Src; result += kBuiltinDefinitionMathSrc; result += kBuiltinDefinitionOsSrc; result += kBuiltinDefinitionCoroutineSrc; result += kBuiltinDefinitionTableSrc; result += kBuiltinDefinitionDebugSrc; result += kBuiltinDefinitionUtf8Src; result += kBuiltinDefinitionBufferSrc; result += kBuiltinDefinitionVectorSrc; return result; } // TODO: split into separate tagged unions when the new solver can appropriately handle that. static const std::string kBuiltinDefinitionTypesSrc = R"BUILTIN_SRC( export type type = { tag: "nil" | "unknown" | "never" | "any" | "boolean" | "number" | "string" | "buffer" | "thread" | "singleton" | "negation" | "union" | "intesection" | "table" | "function" | "class" | "generic", is: (self: type, arg: string) -> boolean, -- for singleton type value: (self: type) -> (string | boolean | nil), -- for negation type inner: (self: type) -> type, -- for union and intersection types components: (self: type) -> {type}, -- for table type setproperty: (self: type, key: type, value: type?) -> (), setreadproperty: (self: type, key: type, value: type?) -> (), setwriteproperty: (self: type, key: type, value: type?) -> (), readproperty: (self: type, key: type) -> type?, writeproperty: (self: type, key: type) -> type?, properties: (self: type) -> { [type]: { read: type?, write: type? } }, setindexer: (self: type, index: type, result: type) -> (), setreadindexer: (self: type, index: type, result: type) -> (), setwriteindexer: (self: type, index: type, result: type) -> (), indexer: (self: type) -> { index: type, readresult: type, writeresult: type }?, readindexer: (self: type) -> { index: type, result: type }?, writeindexer: (self: type) -> { index: type, result: type }?, setmetatable: (self: type, arg: type) -> (), metatable: (self: type) -> type?, -- for function type setparameters: (self: type, head: {type}?, tail: type?) -> (), parameters: (self: type) -> { head: {type}?, tail: type? }, setreturns: (self: type, head: {type}?, tail: type? ) -> (), returns: (self: type) -> { head: {type}?, tail: type? }, setgenerics: (self: type, {type}?) -> (), generics: (self: type) -> {type}, -- for class type -- 'properties', 'metatable', 'indexer', 'readindexer' and 'writeindexer' are shared with table type readparent: (self: type) -> type?, writeparent: (self: type) -> type?, -- for generic type name: (self: type) -> string?, ispack: (self: type) -> boolean, } declare types: { unknown: type, never: type, any: type, boolean: type, number: type, string: type, thread: type, buffer: type, singleton: @checked (arg: string | boolean | nil) -> type, generic: @checked (name: string, ispack: boolean?) -> type, negationof: @checked (arg: type) -> type, unionof: @checked (...type) -> type, intersectionof: @checked (...type) -> type, newtable: @checked (props: {[type]: type} | {[type]: { read: type, write: type } } | nil, indexer: { index: type, readresult: type, writeresult: type }?, metatable: type?) -> type, newfunction: @checked (parameters: { head: {type}?, tail: type? }?, returns: { head: {type}?, tail: type? }?, generics: {type}?) -> type, copy: @checked (arg: type) -> type, } )BUILTIN_SRC"; std::string getTypeFunctionDefinitionSource() { return kBuiltinDefinitionTypesSrc; } } // namespace Luau