typegenerator

This commit is contained in:
Jarred Sumner
2022-02-27 01:53:34 -08:00
parent a6901fdac1
commit 7576caa54a
5 changed files with 147 additions and 97 deletions

View File

@@ -443,8 +443,14 @@ fn hasTypeScript(comptime Type: type) bool {
}
fn getTypeScript(comptime Type: type, value: Type) d.ts.or_decl {
if (comptime !@hasDecl(Type, "ts") and !@hasField(Type, "ts")) {
return d.ts.or_decl{
.ts = .{ .name = @typeName(Type) },
};
}
if (comptime hasTypeScriptField(Type)) {
if (@TypeOf(Type.ts) == d.ts.decl) {
if (@TypeOf(value.ts) == d.ts.decl) {
return d.ts.or_decl{ .decl = value };
} else {
return d.ts.or_decl{ .ts = value.ts };
@@ -795,7 +801,7 @@ pub const d = struct {
comptime var buf: string = "";
comptime brk: {
var splitter = std.mem.split(str, "\n");
var splitter = std.mem.split(u8, str, "\n");
const first = splitter.next() orelse break :brk;
const second = splitter.next() orelse {
@@ -1113,13 +1119,14 @@ pub fn NewClass(
switch (@typeInfo(Func)) {
.Struct => {
var total: usize = 1;
if (hasTypeScript(Func)) {
if (std.meta.trait.isIndexable(@TypeOf(func.ts))) {
count += func.ts.len;
} else {
count += 1;
total = func.ts.len;
}
}
count += total;
},
else => continue,
}
@@ -1128,38 +1135,44 @@ pub fn NewClass(
var funcs = std.mem.zeroes([count]d.ts);
class.functions = std.mem.span(&funcs);
var func_i: usize = 0;
@setEvalBranchQuota(99999);
inline for (function_name_literals) |_, i| {
const func = @field(staticFunctions, function_names[i]);
const Func = @TypeOf(func);
switch (@typeInfo(Func)) {
.Struct => {
if (hasTypeScript(Func)) {
var ts_functions: []const d.ts = &[_]d.ts{};
var ts_functions: []const d.ts = &[_]d.ts{};
if (hasTypeScript(Func)) {
if (std.meta.trait.isIndexable(@TypeOf(func.ts))) {
ts_functions = std.mem.span(func.ts);
} else {
var funcs1 = std.mem.zeroes([1]d.ts);
funcs1[0] = func.ts;
ts_functions = std.mem.span(&funcs1);
}
}
if (ts_functions.len == 0 and hasTypeScript(Func)) {
var funcs1 = std.mem.zeroes([1]d.ts);
funcs1[0] = func.ts;
ts_functions = std.mem.span(&funcs1);
} else {
var funcs1 = std.mem.zeroes([1]d.ts);
funcs1[0] = .{ .name = function_names[i] };
ts_functions = std.mem.span(&funcs1);
}
for (ts_functions) |ts_function_| {
var ts_function = ts_function_;
if (ts_function.name.len == 0) {
ts_function.name = function_names[i];
}
for (ts_functions) |ts_function_| {
var ts_function = ts_function_;
if (ts_function.name.len == 0) {
ts_function.name = function_names[i];
}
if (ts_function.read_only == null) {
ts_function.read_only = class.read_only;
}
class.functions[func_i] = ts_function;
func_i += 1;
if (ts_function.read_only == null) {
ts_function.read_only = class.read_only;
}
class.functions[func_i] = ts_function;
func_i += 1;
}
},
else => continue,
@@ -1253,9 +1266,17 @@ pub fn NewClass(
decl.module = typescriptModuleDeclaration();
},
.class => {
decl.class = typescriptClassDeclaration();
decl.class = typescriptClassDeclaration(decl.class);
},
.empty => {
decl = d.ts.decl{
.class = typescriptClassDeclaration(
d.ts.class{
.name = options.name,
},
),
};
},
.empty => {},
};
return decl;
@@ -1297,8 +1318,8 @@ pub fn NewClass(
}
// This should only be run at comptime
pub fn typescriptClassDeclaration() d.ts.class {
comptime var class = options.ts.class;
pub fn typescriptClassDeclaration(comptime original: d.ts.class) d.ts.class {
comptime var class = original;
comptime {
if (class.name.len == 0) {
@@ -1317,13 +1338,14 @@ pub fn NewClass(
switch (@typeInfo(Func)) {
.Struct => {
var total: usize = 1;
if (hasTypeScript(Func)) {
if (std.meta.trait.isIndexable(@TypeOf(func.ts))) {
count += func.ts.len;
} else {
count += 1;
total = func.ts.len;
}
}
count += total;
},
else => continue,
}
@@ -1339,35 +1361,41 @@ pub fn NewClass(
switch (@typeInfo(Func)) {
.Struct => {
if (hasTypeScript(Func)) {
var ts_functions: []const d.ts = &[_]d.ts{};
var ts_functions: []const d.ts = &[_]d.ts{};
if (hasTypeScript(Func)) {
if (std.meta.trait.isIndexable(@TypeOf(func.ts))) {
ts_functions = std.mem.span(func.ts);
} else {
var funcs1 = std.mem.zeroes([1]d.ts);
funcs1[0] = func.ts;
ts_functions = std.mem.span(&funcs1);
}
}
if (ts_functions.len == 0 and hasTypeScript(Func)) {
var funcs1 = std.mem.zeroes([1]d.ts);
funcs1[0] = func.ts;
ts_functions = std.mem.span(&funcs1);
} else {
var funcs1 = std.mem.zeroes([1]d.ts);
funcs1[0] = .{ .name = function_names[i] };
ts_functions = std.mem.span(&funcs1);
}
for (ts_functions) |ts_function_| {
var ts_function = ts_function_;
if (ts_function.name.len == 0) {
ts_function.name = function_names[i];
}
for (ts_functions) |ts_function_| {
var ts_function = ts_function_;
if (ts_function.name.len == 0) {
ts_function.name = function_names[i];
}
if (class.interface and strings.eqlComptime(ts_function.name, "constructor")) {
ts_function.name = "new";
}
if (ts_function.read_only == null) {
ts_function.read_only = class.read_only;
}
class.functions[func_i] = ts_function;
func_i += 1;
if (class.interface and strings.eqlComptime(ts_function.name, "constructor")) {
ts_function.name = "new";
}
if (ts_function.read_only == null) {
ts_function.read_only = class.read_only;
}
class.functions[func_i] = ts_function;
func_i += 1;
}
},
else => continue,
@@ -1376,14 +1404,7 @@ pub fn NewClass(
}
if (property_names.len > 0) {
var count: usize = 0;
inline for (property_names) |_, i| {
const field = @field(properties, property_names[i]);
if (hasTypeScript(@TypeOf(field))) {
count += 1;
}
}
var count: usize = property_names.len;
var props = std.mem.zeroes([count]d.ts);
class.properties = std.mem.span(&props);
@@ -1392,24 +1413,26 @@ pub fn NewClass(
inline for (property_names) |property_name, i| {
const field = @field(properties, property_names[i]);
var ts_field: d.ts = .{};
if (hasTypeScript(@TypeOf(field))) {
var ts_field: d.ts = field.ts;
if (ts_field.name.len == 0) {
ts_field.name = property_name;
}
if (ts_field.read_only == null) {
if (hasReadOnly(@TypeOf(field))) {
ts_field.read_only = field.ro;
} else {
ts_field.read_only = class.read_only;
}
}
class.properties[property_i] = ts_field;
property_i += 1;
ts_field = field.ts;
}
if (ts_field.name.len == 0) {
ts_field.name = property_name;
}
if (ts_field.read_only == null) {
if (hasReadOnly(@TypeOf(field))) {
ts_field.read_only = field.ro;
} else {
ts_field.read_only = class.read_only;
}
}
class.properties[property_i] = ts_field;
property_i += 1;
}
}
}

View File

@@ -3190,10 +3190,11 @@ pub const BuildError = struct {
pub const Class = NewClass(
BuildError,
.{
.name = "BuildError",
.read_only = true,
},
.{ .name = "BuildError", .read_only = true, .ts = .{
.class = .{
.name = "BuildError",
},
} },
.{},
.{
.@"message" = .{

View File

@@ -7,6 +7,7 @@ const Maybe = JSC.Node.Maybe;
const Encoding = JSC.Node.Encoding;
const FeatureFlags = @import("../../../global.zig").FeatureFlags;
const Args = JSC.Node.NodeFS.Arguments;
const d = JSC.d;
const NodeFSFunction = fn (
*JSC.Node.NodeFS,
@@ -138,7 +139,7 @@ fn call(comptime Function: NodeFSFunctionEnum) NodeFSFunction {
pub const NodeFSBindings = JSC.NewClass(
JSC.Node.NodeFS,
.{ .name = "fs" },
.{ .name = "fs", .ts = .{ .module = .{ .path = "fs" } } },
.{
.access = .{

View File

@@ -40,6 +40,7 @@ const VirtualMachine = @import("../javascript.zig").VirtualMachine;
const Task = @import("../javascript.zig").Task;
const Fs = @import("../../../fs.zig");
const is_bindgen: bool = std.meta.globalOption("bindgen", bool) orelse false;
fn notImplementedFn(_: *anyopaque, ctx: js.JSContextRef, _: js.JSObjectRef, _: js.JSObjectRef, _: []const js.JSValueRef, exception: js.ExceptionRef) js.JSValueRef {
JSError(getAllocator(ctx), "Not implemented yet!", .{}, ctx, exception);
@@ -660,6 +661,7 @@ pub const TestScope = struct {
pub fn run(
this: *TestScope,
) Result {
if (comptime is_bindgen) return undefined;
var vm = VirtualMachine.vm;
defer {
js.JSValueUnprotect(vm.global.ref(), this.callback);
@@ -799,6 +801,7 @@ pub const DescribeScope = struct {
}
pub fn run(this: *DescribeScope, thisObject: js.JSObjectRef, ctx: js.JSContextRef, callback: js.JSObjectRef, exception: js.ExceptionRef) js.JSObjectRef {
if (comptime is_bindgen) return undefined;
js.JSValueProtect(ctx, callback);
defer js.JSValueUnprotect(ctx, callback);
var original_active = active;
@@ -881,6 +884,7 @@ pub const DescribeScope = struct {
// }
pub fn runCallbacks(this: *DescribeScope, ctx: js.JSContextRef, callbacks: std.ArrayListUnmanaged(js.JSObjectRef), exception: js.ExceptionRef) bool {
if (comptime is_bindgen) return undefined;
var i: usize = 0;
while (i < callbacks.items.len) : (i += 1) {
var callback = callbacks.items[i];

View File

@@ -1,8 +1,6 @@
const d = @import("./base.zig").d;
const std = @import("std");
const Api = @import("../../api/schema.zig").Api;
const Router = @import("./api/router.zig");
const JavaScript = @import("./javascript.zig");
const builtin = @import("builtin");
const io = std.io;
const fs = std.fs;
@@ -14,18 +12,39 @@ const mem = std.mem;
const testing = std.testing;
const Allocator = std.mem.Allocator;
const resolve_path = @import("../../resolver/resolve_path.zig");
const JSC = @import("../../jsc.zig");
const _global = @import("../../global.zig");
const string = _global.string;
const strings = _global.strings;
const default_allocator = _global.default_allocator;
const modules = [_]d.ts.decl{
Router.Class.typescriptDeclaration(),
};
const hidden_globals = [_]d.ts.decl{
FetchEvent.Class.typescriptDeclaration(),
};
const global = JavaScript.GlobalObject.GlobalClass.typescriptDeclaration();
pub const bindgen = true;
pub fn main() anyerror!void {
const modules = comptime [_]d.ts.decl{
JSC.Node.NodeFSBindings.typescriptDeclaration(),
};
const hidden_globals = comptime [_]d.ts.decl{
JSC.WebCore.FetchEvent.Class.typescriptDeclaration(),
};
const globals = comptime [_]d.ts.decl{
Router.Instance.typescriptDeclaration(),
JSC.Bun.Class.typescriptDeclaration(),
JSC.BuildError.Class.typescriptDeclaration(),
JSC.ResolveError.Class.typescriptDeclaration(),
JSC.WebCore.Response.Class.typescriptDeclaration(),
JSC.WebCore.Headers.Class.typescriptDeclaration(),
JSC.EventListenerMixin.addEventListener(JSC.VirtualMachine).typescriptDeclaration(),
JSC.WebCore.Fetch.Class.typescriptDeclaration(),
JSC.Performance.Class.typescriptDeclaration(),
JSC.Crypto.Class.typescriptDeclaration(),
JSC.WebCore.TextEncoder.Class.typescriptDeclaration(),
JSC.WebCore.TextDecoder.Class.typescriptDeclaration(),
JSC.API.Transpiler.Class.typescriptDeclaration(),
};
var allocator = default_allocator;
var argv = std.mem.span(std.os.argv);
var dest = [_]string{ std.mem.span(argv[argv.len - 2]), std.mem.span(argv[argv.len - 1]) };
@@ -53,7 +72,9 @@ pub fn main() anyerror!void {
\\
\\
);
try global_file.writeAll(comptime d.ts.class.Printer.printDecl(global, 0));
inline for (globals) |global| {
try global_file.writeAll(comptime d.ts.class.Printer.printDecl(global, 0));
}
var module_file = try dir.createFile("modules.d.ts", .{});
try module_file.writeAll(
@@ -78,7 +99,7 @@ pub fn main() anyerror!void {
inline for (modules) |decl| {
comptime var module: d.ts.module = decl.module;
const basepath = comptime module.path["bun.js/".len..];
const basepath = comptime module.path;
if (std.fs.path.dirname(basepath)) |dirname| {
try dir.makePath(dirname);
}