add master data, add data selection

This commit is contained in:
SuperAuguste 2020-05-07 11:29:40 -04:00
parent f80dc1d35c
commit 1725278be1
6 changed files with 361 additions and 14 deletions

View File

@ -1,7 +1,8 @@
const std = @import("std"); const std = @import("std");
const builtin = @import("builtin"); const builtin = @import("builtin");
// const build_options = @import("build_options");
pub fn build(b: *std.build.Builder) void { pub fn build(b: *std.build.Builder) !void {
// Standard target options allows the person running `zig build` to choose // Standard target options allows the person running `zig build` to choose
// what target to build for. Here we do not override the defaults, which // what target to build for. Here we do not override the defaults, which
// means any target is allowed, and the default is native. Other options // means any target is allowed, and the default is native. Other options
@ -14,7 +15,13 @@ pub fn build(b: *std.build.Builder) void {
const exe = b.addExecutable("zls", "src/main.zig"); const exe = b.addExecutable("zls", "src/main.zig");
exe.addPackagePath("data", "src/data/0.6.0.zig"); const data_version = try std.mem.concat(b.allocator, u8, &[3][]const u8{"\"", b.option([]const u8, "data_version", "The data version - either 0.6.0 or master.") orelse "0.6.0", "\""});
defer b.allocator.free(data_version);
exe.addBuildOption(
[]const u8,
"data_version",
data_version,
);
exe.addBuildOption( exe.addBuildOption(
bool, bool,

View File

@ -1,4 +1,4 @@
/// THIS FILE CONTAINS DATA FROM THE 0.6.0 DOCUMENTATION /// data from 0.6.0 documentation
/// Builtin functions /// Builtin functions
pub const builtins = [_][]const u8{ pub const builtins = [_][]const u8{

View File

@ -52,3 +52,20 @@ return document.querySelector("#" + _.innerText.slice(1)).nextElementSibling.inn
return document.querySelector("#" + _.innerText.slice(1)).nextElementSibling.nextElementSibling.innerText; return document.querySelector("#" + _.innerText.slice(1)).nextElementSibling.nextElementSibling.innerText;
}).map(_ => JSON.stringify(_)).join(",\n"); }).map(_ => JSON.stringify(_)).join(",\n");
``` ```
## All together now
```js
`/// Builtin functions
pub const builtins = [_][]const u8{` + [...document.querySelector("#toc-Builtin-Functions").parentElement.lastElementChild.children].map(_ => {const code = document.querySelector("#" + _.innerText.slice(1)).nextElementSibling.children[0].innerText; var l = (code.lastIndexOf(") ") == -1 ? code.length : code.lastIndexOf(") ")) + 1; var p = code.slice(0, l); var name = p.slice(0, p.indexOf("("));var body = p.slice(p.indexOf("(") + 1, -1);if (body.trim().length === 0) return `${name}()`; var nb = ""; let depth = 0; let vi = 2; let i = 0; let skip = false; for (const c of body) {if (skip) {skip = false;if (c === " ") {i++; continue;};};if (c === "(") depth++;else if (c === ")") depth--;if (c === "," && depth == 0) {nb += `}, \${${vi}:`;vi++;skip = true;} else if (i === body.length - 1) {nb += c;nb += "}";} else nb += c;i++;};return `${name}(\${1:${nb})`;}).map(_ => JSON.stringify(_)).join(",\n") + `};
/// Builtin function details
pub const builtin_details = [_][]const u8{` + [...document.querySelector("#toc-Builtin-Functions").parentElement.lastElementChild.children].map(_ => {
return document.querySelector("#" + _.innerText.slice(1)).nextElementSibling.innerText;
}).map(_ => JSON.stringify(_)).join(",\n") + `};
/// Builtin function docs
pub const builtin_docs = [_][]const u8{` + [...document.querySelector("#toc-Builtin-Functions").parentElement.lastElementChild.children].map(_ => {
return document.querySelector("#" + _.innerText.slice(1)).nextElementSibling.nextElementSibling.innerText;
}).map(_ => JSON.stringify(_)).join(",\n") + `};
`
```

304
src/data/master.zig Normal file
View File

@ -0,0 +1,304 @@
/// data from master documentation
/// Builtin functions
pub const builtins = [_][]const u8{"@addWithOverflow(${1:comptime T: type}, ${2:a: T}, ${3:b: T}, ${4:result: *T})",
"@alignCast(${1:comptime alignment: u29}, ${2:ptr: var})",
"@alignOf(${1:comptime T: type})",
"@as(${1:comptime T: type}, ${2:expression})",
"@asyncCall(${1:frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8}, ${2:result_ptr}, ${3:function_ptr}, ${4:args: ...})",
"@atomicLoad(${1:comptime T: type}, ${2:ptr: *const T}, ${3:comptime ordering: builtin.AtomicOrder})",
"@atomicRmw(${1:comptime T: type}, ${2:ptr: *T}, ${3:comptime op: builtin.AtomicRmwOp}, ${4:operand: T}, ${5:comptime ordering: builtin.AtomicOrder})",
"@atomicStore(${1:comptime T: type}, ${2:ptr: *T}, ${3:value: T}, ${4:comptime ordering: builtin.AtomicOrder})",
"@bitCast(${1:comptime DestType: type}, ${2:value: var})",
"@bitOffsetOf(${1:comptime T: type}, ${2:comptime field_name: []const u8})",
"@boolToInt(${1:value: bool})",
"@bitSizeOf(${1:comptime T: type})",
"@breakpoint()",
"@mulAdd(${1:comptime T: type}, ${2:a: T}, ${3:b: T}, ${4:c: T})",
"@byteSwap(${1:comptime T: type}, ${2:operand: T})",
"@bitReverse(${1:comptime T: type}, ${2:integer: T})",
"@byteOffsetOf(${1:comptime T: type}, ${2:comptime field_name: []const u8})",
"@call(${1:options: std.builtin.CallOptions}, ${2:function: var}, ${3:args: var})",
"@cDefine(${1:comptime name: []u8}, ${2:value})",
"@cImport(${1:expression})",
"@cInclude(${1:comptime path: []u8})",
"@clz(${1:comptime T: type}, ${2:integer: T})",
"@cmpxchgStrong(${1:comptime T: type}, ${2:ptr: *T}, ${3:expected_value: T}, ${4:new_value: T}, ${5:success_order: AtomicOrder}, ${6:fail_order: AtomicOrder})",
"@cmpxchgWeak(${1:comptime T: type}, ${2:ptr: *T}, ${3:expected_value: T}, ${4:new_value: T}, ${5:success_order: AtomicOrder}, ${6:fail_order: AtomicOrder})",
"@compileError(${1:comptime msg: []u8})",
"@compileLog(${1:args: ...})",
"@ctz(${1:comptime T: type}, ${2:integer: T})",
"@cUndef(${1:comptime name: []u8})",
"@divExact(${1:numerator: T}, ${2:denominator: T})",
"@divFloor(${1:numerator: T}, ${2:denominator: T})",
"@divTrunc(${1:numerator: T}, ${2:denominator: T})",
"@embedFile(${1:comptime path: []const u8})",
"@enumToInt(${1:enum_or_tagged_union: var})",
"@errorName(${1:err: anyerror})",
"@errorReturnTrace()",
"@errorToInt(${1:err: var) std.meta.IntType(false}, ${2:@sizeOf(anyerror})",
"@errSetCast(${1:comptime T: DestType}, ${2:value: var})",
"@export(${1:target: var}, ${2:comptime options: std.builtin.ExportOptions})",
"@fence(${1:order: AtomicOrder})",
"@field(${1:lhs: var}, ${2:comptime field_name: []const u8})",
"@fieldParentPtr(${1:comptime ParentType: type}, ${2:comptime field_name: []const u8}, ${3:\n field_ptr: *T})",
"@floatCast(${1:comptime DestType: type}, ${2:value: var})",
"@floatToInt(${1:comptime DestType: type}, ${2:float: var})",
"@frame()",
"@Frame(${1:func: var})",
"@frameAddress()",
"@frameSize()",
"@hasDecl(${1:comptime Container: type}, ${2:comptime name: []const u8})",
"@hasField(${1:comptime Container: type}, ${2:comptime name: []const u8})",
"@import(${1:comptime path: []u8})",
"@intCast(${1:comptime DestType: type}, ${2:int: var})",
"@intToEnum(${1:comptime DestType: type}, ${2:int_value: @TagType(DestType)})",
"@intToError(${1:value: std.meta.IntType(false, @sizeOf(anyerror) * 8)})",
"@intToFloat(${1:comptime DestType: type}, ${2:int: var})",
"@intToPtr(${1:comptime DestType: type}, ${2:address: usize})",
"@memcpy(${1:noalias dest: [*]u8}, ${2:noalias source: [*]const u8}, ${3:byte_count: usize})",
"@memset(${1:dest: [*]u8}, ${2:c: u8}, ${3:byte_count: usize})",
"@mod(${1:numerator: T}, ${2:denominator: T})",
"@mulWithOverflow(${1:comptime T: type}, ${2:a: T}, ${3:b: T}, ${4:result: *T})",
"@panic(${1:message: []const u8})",
"@popCount(${1:comptime T: type}, ${2:integer: T})",
"@ptrCast(${1:comptime DestType: type}, ${2:value: var})",
"@ptrToInt(${1:value: var})",
"@rem(${1:numerator: T}, ${2:denominator: T})",
"@returnAddress()",
"@setAlignStack(${1:comptime alignment: u29})",
"@setCold(${1:is_cold: bool})",
"@setEvalBranchQuota(${1:new_quota: usize})",
"@setFloatMode(${1:mode: @import(\"builtin\").FloatMode})",
"@setRuntimeSafety(${1:safety_on: bool})",
"@shlExact(${1:value: T}, ${2:shift_amt: Log2T})",
"@shlWithOverflow(${1:comptime T: type}, ${2:a: T}, ${3:shift_amt: Log2T}, ${4:result: *T})",
"@shrExact(${1:value: T}, ${2:shift_amt: Log2T})",
"@shuffle(${1:comptime E: type}, ${2:a: std.meta.Vector(a_len, E)}, ${3:b: std.meta.Vector(b_len, E)}, ${4:comptime mask: std.meta.Vector(mask_len, i32)})",
"@sizeOf(${1:comptime T: type})",
"@splat(${1:comptime len: u32}, ${2:scalar: var})",
"@sqrt(${1:value: var})",
"@sin(${1:value: var})",
"@cos(${1:value: var})",
"@exp(${1:value: var})",
"@exp2(${1:value: var})",
"@log(${1:value: var})",
"@log2(${1:value: var})",
"@log10(${1:value: var})",
"@fabs(${1:value: var})",
"@floor(${1:value: var})",
"@ceil(${1:value: var})",
"@trunc(${1:value: var})",
"@round(${1:value: var})",
"@subWithOverflow(${1:comptime T: type}, ${2:a: T}, ${3:b: T}, ${4:result: *T})",
"@tagName(${1:value: var})",
"@TagType(${1:T: type})",
"@This()",
"@truncate(${1:comptime T: type}, ${2:integer: var})",
"@Type(${1:comptime info: @import(\"builtin\").TypeInfo})",
"@typeInfo(${1:comptime T: type})",
"@typeName(${1:T: type})",
"@TypeOf(${1:...})",
"@unionInit(${1:comptime Union: type}, ${2:comptime active_field_name: []const u8}, ${3:init_expr})"};
/// Builtin function details
pub const builtin_details = [_][]const u8{"@addWithOverflow(comptime T: type, a: T, b: T, result: *T) bool",
"@alignCast(comptime alignment: u29, ptr: var) var",
"@alignOf(comptime T: type) comptime_int",
"@as(comptime T: type, expression) T",
"@asyncCall(frame_buffer: []align(@alignOf(@Frame(anyAsyncFunction))) u8, result_ptr, function_ptr, args: ...) anyframe->T",
"@atomicLoad(comptime T: type, ptr: *const T, comptime ordering: builtin.AtomicOrder) T",
"@atomicRmw(comptime T: type, ptr: *T, comptime op: builtin.AtomicRmwOp, operand: T, comptime ordering: builtin.AtomicOrder) T",
"@atomicStore(comptime T: type, ptr: *T, value: T, comptime ordering: builtin.AtomicOrder) void",
"@bitCast(comptime DestType: type, value: var) DestType",
"@bitOffsetOf(comptime T: type, comptime field_name: []const u8) comptime_int",
"@boolToInt(value: bool) u1",
"@bitSizeOf(comptime T: type) comptime_int",
"@breakpoint()",
"@mulAdd(comptime T: type, a: T, b: T, c: T) T",
"@byteSwap(comptime T: type, operand: T) T",
"@bitReverse(comptime T: type, integer: T) T",
"@byteOffsetOf(comptime T: type, comptime field_name: []const u8) comptime_int",
"@call(options: std.builtin.CallOptions, function: var, args: var) var",
"@cDefine(comptime name: []u8, value)",
"@cImport(expression) type",
"@cInclude(comptime path: []u8)",
"@clz(comptime T: type, integer: T)",
"@cmpxchgStrong(comptime T: type, ptr: *T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T",
"@cmpxchgWeak(comptime T: type, ptr: *T, expected_value: T, new_value: T, success_order: AtomicOrder, fail_order: AtomicOrder) ?T",
"@compileError(comptime msg: []u8)",
"@compileLog(args: ...)",
"@ctz(comptime T: type, integer: T)",
"@cUndef(comptime name: []u8)",
"@divExact(numerator: T, denominator: T) T",
"@divFloor(numerator: T, denominator: T) T",
"@divTrunc(numerator: T, denominator: T) T",
"@embedFile(comptime path: []const u8) *const [X:0]u8",
"@enumToInt(enum_or_tagged_union: var) var",
"@errorName(err: anyerror) []const u8",
"@errorReturnTrace() ?*builtin.StackTrace",
"@errorToInt(err: var) std.meta.IntType(false, @sizeOf(anyerror) * 8)",
"@errSetCast(comptime T: DestType, value: var) DestType",
"@export(target: var, comptime options: std.builtin.ExportOptions) void",
"@fence(order: AtomicOrder)",
"@field(lhs: var, comptime field_name: []const u8) (field)",
"@fieldParentPtr(comptime ParentType: type, comptime field_name: []const u8,\n field_ptr: *T) *ParentType",
"@floatCast(comptime DestType: type, value: var) DestType",
"@floatToInt(comptime DestType: type, float: var) DestType",
"@frame() *@Frame(func)",
"@Frame(func: var) type",
"@frameAddress() usize",
"@frameSize() usize",
"@hasDecl(comptime Container: type, comptime name: []const u8) bool",
"@hasField(comptime Container: type, comptime name: []const u8) bool",
"@import(comptime path: []u8) type",
"@intCast(comptime DestType: type, int: var) DestType",
"@intToEnum(comptime DestType: type, int_value: @TagType(DestType)) DestType",
"@intToError(value: std.meta.IntType(false, @sizeOf(anyerror) * 8)) anyerror",
"@intToFloat(comptime DestType: type, int: var) DestType",
"@intToPtr(comptime DestType: type, address: usize) DestType",
"@memcpy(noalias dest: [*]u8, noalias source: [*]const u8, byte_count: usize)",
"@memset(dest: [*]u8, c: u8, byte_count: usize)",
"@mod(numerator: T, denominator: T) T",
"@mulWithOverflow(comptime T: type, a: T, b: T, result: *T) bool",
"@panic(message: []const u8) noreturn",
"@popCount(comptime T: type, integer: T)",
"@ptrCast(comptime DestType: type, value: var) DestType",
"@ptrToInt(value: var) usize",
"@rem(numerator: T, denominator: T) T",
"@returnAddress() usize",
"@setAlignStack(comptime alignment: u29)",
"@setCold(is_cold: bool)",
"@setEvalBranchQuota(new_quota: usize)",
"@setFloatMode(mode: @import(\"builtin\").FloatMode)",
"@setRuntimeSafety(safety_on: bool)",
"@shlExact(value: T, shift_amt: Log2T) T",
"@shlWithOverflow(comptime T: type, a: T, shift_amt: Log2T, result: *T) bool",
"@shrExact(value: T, shift_amt: Log2T) T",
"@shuffle(comptime E: type, a: std.meta.Vector(a_len, E), b: std.meta.Vector(b_len, E), comptime mask: std.meta.Vector(mask_len, i32)) std.meta.Vector(mask_len, E)",
"@sizeOf(comptime T: type) comptime_int",
"@splat(comptime len: u32, scalar: var) std.meta.Vector(len, @TypeOf(scalar))",
"@sqrt(value: var) @TypeOf(value)",
"@sin(value: var) @TypeOf(value)",
"@cos(value: var) @TypeOf(value)",
"@exp(value: var) @TypeOf(value)",
"@exp2(value: var) @TypeOf(value)",
"@log(value: var) @TypeOf(value)",
"@log2(value: var) @TypeOf(value)",
"@log10(value: var) @TypeOf(value)",
"@fabs(value: var) @TypeOf(value)",
"@floor(value: var) @TypeOf(value)",
"@ceil(value: var) @TypeOf(value)",
"@trunc(value: var) @TypeOf(value)",
"@round(value: var) @TypeOf(value)",
"@subWithOverflow(comptime T: type, a: T, b: T, result: *T) bool",
"@tagName(value: var) []const u8",
"@TagType(T: type) type",
"@This() type",
"@truncate(comptime T: type, integer: var) T",
"@Type(comptime info: @import(\"builtin\").TypeInfo) type",
"@typeInfo(comptime T: type) @import(\"std\").builtin.TypeInfo",
"@typeName(T: type) [N]u8",
"@TypeOf(...) type",
"@unionInit(comptime Union: type, comptime active_field_name: []const u8, init_expr) Union"};
/// Builtin function docs
pub const builtin_docs = [_][]const u8{"Performs result.* = a + b. If overflow or underflow occurs, stores the overflowed bits in result and returns true. If no overflow or underflow occurs, returns false.",
"ptr can be *T, fn(), ?*T, ?fn(), or []T. It returns the same type as ptr except with the alignment adjusted to the new value.",
"This function returns the number of bytes that this type should be aligned to for the current target to match the C ABI. When the child type of a pointer has this alignment, the alignment can be omitted from the type.",
"Performs Type Coercion. This cast is allowed when the conversion is unambiguous and safe, and is the preferred way to convert between types, whenever possible.",
"@asyncCall performs an async call on a function pointer, which may or may not be an async function.",
"This builtin function atomically dereferences a pointer and returns the value.",
"This builtin function atomically modifies memory and then returns the previous value.",
"This builtin function atomically stores a value.",
"Converts a value of one type to another type.",
"Returns the bit offset of a field relative to its containing struct.",
"Converts true to u1(1) and false to u1(0).",
"This function returns the number of bits it takes to store T in memory. The result is a target-specific compile time constant.",
"This function inserts a platform-specific debug trap instruction which causes debuggers to break there.",
"Fused multiply add, similar to (a * b) + c, except only rounds once, and is thus more accurate.",
"T must be an integer type with bit count evenly divisible by 8.",
"T accepts any integer type.",
"Returns the byte offset of a field relative to its containing struct.",
"Calls a function, in the same way that invoking an expression with parentheses does:",
"This function can only occur inside @cImport.",
"This function parses C code and imports the functions, types, variables, and compatible macro definitions into a new empty struct type, and then returns that type.",
"This function can only occur inside @cImport.",
"This function counts the number of most-significant (leading in a big-Endian sense) zeroes in integer.",
"This function performs a strong atomic compare exchange operation. It's the equivalent of this code, except atomic:",
"This function performs a weak atomic compare exchange operation. It's the equivalent of this code, except atomic:",
"This function, when semantically analyzed, causes a compile error with the message msg.",
"This function prints the arguments passed to it at compile-time.",
"This function counts the number of least-significant (trailing in a big-Endian sense) zeroes in integer.",
"This function can only occur inside @cImport.",
"Exact division. Caller guarantees denominator != 0 and @divTrunc(numerator, denominator) * denominator == numerator.",
"Floored division. Rounds toward negative infinity. For unsigned integers it is the same as numerator / denominator. Caller guarantees denominator != 0 and !(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1).",
"Truncated division. Rounds toward zero. For unsigned integers it is the same as numerator / denominator. Caller guarantees denominator != 0 and !(@typeInfo(T) == .Int and T.is_signed and numerator == std.math.minInt(T) and denominator == -1).",
"This function returns a compile time constant pointer to null-terminated, fixed-size array with length equal to the byte count of the file given by path. The contents of the array are the contents of the file. This is equivalent to a string literal with the file contents.",
"Converts an enumeration value into its integer tag type. When a tagged union is passed, the tag value is used as the enumeration value.",
"This function returns the string representation of an error. The string representation of error.OutOfMem is \"OutOfMem\".",
"If the binary is built with error return tracing, and this function is invoked in a function that calls a function with an error or error union return type, returns a stack trace object. Otherwise returns `null`.",
"Supports the following types:",
"Converts an error value from one error set to another error set. Attempting to convert an error which is not in the destination error set results in safety-protected Undefined Behavior.",
"Creates a symbol in the output object file.",
"The fence function is used to introduce happens-before edges between operations.",
"Performs field access by a compile-time string.",
"Given a pointer to a field, returns the base pointer of a struct.",
"Convert from one float type to another. This cast is safe, but may cause the numeric value to lose precision.",
"Converts the integer part of a floating point number to the destination type.",
"This function returns a pointer to the frame for a given function. This type can be coerced to anyframe->T and to anyframe, where T is the return type of the function in scope.",
"This function returns the frame type of a function. This works for Async Functions as well as any function without a specific calling convention.",
"This function returns the base pointer of the current stack frame.",
"This is the same as @sizeOf(@Frame(func)), where func may be runtime-known.",
"Returns whether or not a struct, enum, or union has a declaration matching name.",
"Returns whether the field name of a struct, union, or enum exists.",
"This function finds a zig file corresponding to path and adds it to the build, if it is not already added.",
"Converts an integer to another integer while keeping the same numerical value. Attempting to convert a number which is out of range of the destination type results in safety-protected Undefined Behavior.",
"Converts an integer into an enum value.",
"Converts from the integer representation of an error into The Global Error Set type.",
"Converts an integer to the closest floating point representation. To convert the other way, use @floatToInt. This cast is always safe.",
"Converts an integer to a pointer. To convert the other way, use @ptrToInt.",
"This function copies bytes from one region of memory to another. dest and source are both pointers and must not overlap.",
"This function sets a region of memory to c. dest is a pointer.",
"Modulus division. For unsigned integers this is the same as numerator % denominator. Caller guarantees denominator > 0.",
"Performs result.* = a * b. If overflow or underflow occurs, stores the overflowed bits in result and returns true. If no overflow or underflow occurs, returns false.",
"Invokes the panic handler function. By default the panic handler function calls the public panic function exposed in the root source file, or if there is not one specified, the std.builtin.default_panic function from std/builtin.zig.",
"Counts the number of bits set in an integer.",
"Converts a pointer of one type to a pointer of another type.",
"Converts value to a usize which is the address of the pointer. value can be one of these types:",
"Remainder division. For unsigned integers this is the same as numerator % denominator. Caller guarantees denominator > 0.",
"This function returns the address of the next machine code instruction that will be executed when the current function returns.",
"Ensures that a function will have a stack alignment of at least alignment bytes.",
"Tells the optimizer that a function is rarely called.",
"Changes the maximum number of backwards branches that compile-time code execution can use before giving up and making a compile error.",
"Sets the floating point mode of the current scope. Possible values are:",
"Sets whether runtime safety checks are enabled for the scope that contains the function call.",
"Performs the left shift operation (<<). Caller guarantees that the shift will not shift any 1 bits out.",
"Performs result.* = a << b. If overflow or underflow occurs, stores the overflowed bits in result and returns true. If no overflow or underflow occurs, returns false.",
"Performs the right shift operation (>>). Caller guarantees that the shift will not shift any 1 bits out.",
"Constructs a new vector by selecting elements from a and b based on mask.",
"This function returns the number of bytes it takes to store T in memory. The result is a target-specific compile time constant.",
"Produces a vector of length len where each element is the value scalar:",
"Performs the square root of a floating point number. Uses a dedicated hardware instruction when available.",
"Sine trigometric function on a floating point number. Uses a dedicated hardware instruction when available.",
"Cosine trigometric function on a floating point number. Uses a dedicated hardware instruction when available.",
"Base-e exponential function on a floating point number. Uses a dedicated hardware instruction when available.",
"Base-2 exponential function on a floating point number. Uses a dedicated hardware instruction when available.",
"Returns the natural logarithm of a floating point number. Uses a dedicated hardware instruction when available.",
"Returns the logarithm to the base 2 of a floating point number. Uses a dedicated hardware instruction when available.",
"Returns the logarithm to the base 10 of a floating point number. Uses a dedicated hardware instruction when available.",
"Returns the absolute value of a floating point number. Uses a dedicated hardware instruction when available.",
"Returns the largest integral value not greater than the given floating point number. Uses a dedicated hardware instruction when available.",
"Returns the largest integral value not less than the given floating point number. Uses a dedicated hardware instruction when available.",
"Rounds the given floating point number to an integer, towards zero. Uses a dedicated hardware instruction when available.",
"Rounds the given floating point number to an integer, away from zero. Uses a dedicated hardware instruction when available.",
"Performs result.* = a - b. If overflow or underflow occurs, stores the overflowed bits in result and returns true. If no overflow or underflow occurs, returns false.",
"Converts an enum value or union value to a slice of bytes representing the name.",
"For an enum, returns the integer type that is used to store the enumeration value.",
"Returns the innermost struct or union that this function call is inside. This can be useful for an anonymous struct that needs to refer to itself:",
"This function truncates bits from an integer type, resulting in a smaller or same-sized integer type.",
"This function is the inverse of @typeInfo. It reifies type information into a type.",
"Provides type reflection.",
"This function returns the string representation of a type, as an array. It is equivalent to a string literal of the type name.",
"@TypeOf is a special builtin function that takes any (nonzero) number of expressions as parameters and returns the type of the result, using Peer Type Resolution.",
"This is the same thing as union initialization syntax, except that the field name is a comptime-known value rather than an identifier token."};

View File

@ -1,6 +1,8 @@
const std = @import("std"); const std = @import("std");
const build_options = @import("build_options");
const Uri = @import("uri.zig"); const Uri = @import("uri.zig");
const data = @import("data"); const data = @import("data/" ++ build_options.data_version ++ ".zig");
const types = @import("types.zig"); const types = @import("types.zig");
const analysis = @import("analysis.zig"); const analysis = @import("analysis.zig");
@ -77,7 +79,14 @@ pub fn openDocument(uri: []const u8, text: []const u8) !void {
}); });
} }
pub fn publishDiagnostics(document: types.TextDocument) !void { pub fn cacheSane(document: *types.TextDocument) !void {
if (document.sane_text) |old_sane| {
allocator.free(old_sane);
}
document.sane_text = try std.mem.dupe(allocator, u8, document.text);
}
pub fn publishDiagnostics(document: *types.TextDocument) !void {
const tree = try std.zig.parse(allocator, document.text); const tree = try std.zig.parse(allocator, document.text);
defer tree.deinit(); defer tree.deinit();
@ -117,6 +126,7 @@ pub fn publishDiagnostics(document: types.TextDocument) !void {
}); });
} }
} else { } else {
try cacheSane(document);
var decls = tree.root_node.decls.iterator(0); var decls = tree.root_node.decls.iterator(0);
while (decls.next()) |decl_ptr| { while (decls.next()) |decl_ptr| {
var decl = decl_ptr.*; var decl = decl_ptr.*;
@ -161,12 +171,19 @@ pub fn publishDiagnostics(document: types.TextDocument) !void {
}); });
} }
pub fn completeGlobal(id: i64, document: types.TextDocument) !void { pub fn completeGlobal(id: i64, document: *types.TextDocument) !void {
// The tree uses its own arena, so we just pass our main allocator. // The tree uses its own arena, so we just pass our main allocator.
const tree = try std.zig.parse(allocator, document.text); var tree = try std.zig.parse(allocator, document.text);
defer tree.deinit();
if (tree.errors.len > 0) return try respondGeneric(id, no_completions_response); if (tree.errors.len > 0) {
if (document.sane_text) |sane_text| {
tree.deinit();
tree = try std.zig.parse(allocator, sane_text);
} else return try respondGeneric(id, no_completions_response);
}
else {try cacheSane(document);}
defer tree.deinit();
// We use a local arena allocator to deallocate all temporary data without iterating // We use a local arena allocator to deallocate all temporary data without iterating
var arena = std.heap.ArenaAllocator.init(allocator); var arena = std.heap.ArenaAllocator.init(allocator);
@ -284,14 +301,13 @@ pub fn processJsonRpc(json: []const u8) !void {
const text = document.getValue("text").?.String; const text = document.getValue("text").?.String;
try openDocument(uri, text); try openDocument(uri, text);
try publishDiagnostics(documents.getValue(uri).?); try publishDiagnostics(&(documents.get(uri).?.value));
} else if (std.mem.eql(u8, method, "textDocument/didChange")) { } else if (std.mem.eql(u8, method, "textDocument/didChange")) {
const text_document = params.getValue("textDocument").?.Object; const text_document = params.getValue("textDocument").?.Object;
const uri = text_document.getValue("uri").?.String; const uri = text_document.getValue("uri").?.String;
var document = &(documents.get(uri).?.value); var document = &(documents.get(uri).?.value);
const content_changes = params.getValue("contentChanges").?.Array; const content_changes = params.getValue("contentChanges").?.Array;
// const text = content_changes.items[0].Object.getValue("text").?.String
for (content_changes.items) |change| { for (content_changes.items) |change| {
if (change.Object.getValue("range")) |range| { if (change.Object.getValue("range")) |range| {
@ -316,7 +332,7 @@ pub fn processJsonRpc(json: []const u8) !void {
} }
} }
try publishDiagnostics(document.*); try publishDiagnostics(document);
} else if (std.mem.eql(u8, method, "textDocument/didSave")) { } else if (std.mem.eql(u8, method, "textDocument/didSave")) {
// noop // noop
} else if (std.mem.eql(u8, method, "textDocument/didClose")) { } else if (std.mem.eql(u8, method, "textDocument/didClose")) {
@ -331,7 +347,7 @@ pub fn processJsonRpc(json: []const u8) !void {
const uri = text_document.getValue("uri").?.String; const uri = text_document.getValue("uri").?.String;
const position = params.getValue("position").?.Object; const position = params.getValue("position").?.Object;
const document = documents.getValue(uri).?; var document = &(documents.get(uri).?.value);
const pos = types.Position{ const pos = types.Position{
.line = position.getValue("line").?.Integer, .line = position.getValue("line").?.Integer,
.character = position.getValue("character").?.Integer - 1, .character = position.getValue("character").?.Integer - 1,
@ -379,7 +395,7 @@ pub fn processJsonRpc(json: []const u8) !void {
} }
} }
const use_leak_count_alloc = @import("build_options").leak_detection; const use_leak_count_alloc = build_options.leak_detection;
var leak_alloc_global: std.testing.LeakCountAllocator = undefined; var leak_alloc_global: std.testing.LeakCountAllocator = undefined;
// We can now use if(leak_count_alloc) |alloc| { ... } as a comptime check. // We can now use if(leak_count_alloc) |alloc| { ... } as a comptime check.
@ -394,6 +410,7 @@ pub fn main() anyerror!void {
if (use_leak_count_alloc) { if (use_leak_count_alloc) {
// Initialize the leak counting allocator. // Initialize the leak counting allocator.
std.debug.warn("Counting memory leaks...\n", .{});
leak_alloc_global = std.testing.LeakCountAllocator.init(allocator); leak_alloc_global = std.testing.LeakCountAllocator.init(allocator);
allocator = &leak_alloc_global.allocator; allocator = &leak_alloc_global.allocator;
} }

View File

@ -137,6 +137,8 @@ pub const PublishDiagnosticsParams = struct {
pub const TextDocument = struct { pub const TextDocument = struct {
uri: DocumentUri, uri: DocumentUri,
text: String, text: String,
sane_text: ?String = "",
// tree: ?*std.zig.ast.Tree = null,
pub fn positionToIndex(self: *const TextDocument, position: Position) !usize { pub fn positionToIndex(self: *const TextDocument, position: Position) !usize {
var split_iterator = std.mem.split(self.text, "\n"); var split_iterator = std.mem.split(self.text, "\n");