aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
Diffstat (limited to 'src/server')
-rw-r--r--src/server/analysis.odin13
-rw-r--r--src/server/completion.odin81
-rw-r--r--src/server/documentation.odin259
-rw-r--r--src/server/hover.odin14
-rw-r--r--src/server/position_context.odin3
5 files changed, 193 insertions, 177 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 4fc69c4..2c7f4f4 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -1400,7 +1400,18 @@ resolve_call_directive :: proc(ast_context: ^AstContext, call: ^ast.Call_Expr) -
ident.name = "int"
return resolve_type_identifier(ast_context, ident^)
case "load_directory":
- return lookup("Load_Directory_File", indexer.runtime_package, call.pos.file)
+ pkg := new_type(ast.Ident, call.pos, call.end, ast_context.allocator)
+ pkg.name = "runtime"
+ field := new_type(ast.Ident, call.pos, call.end, ast_context.allocator)
+ field.name = "Load_Directory_File"
+ selector := new_type(ast.Selector_Expr, call.pos, call.end, ast_context.allocator)
+ selector.expr = pkg
+ selector.field = field
+ value := SymbolSliceValue{
+ expr = selector
+ }
+ symbol := Symbol{name = "#load_directory", pkg = ast_context.current_package, value = value}
+ return symbol, true
}
return {}, false
diff --git a/src/server/completion.odin b/src/server/completion.odin
index 0324b23..6663be9 100644
--- a/src/server/completion.odin
+++ b/src/server/completion.odin
@@ -560,80 +560,25 @@ get_attribute_completion :: proc(
}
-DIRECTIVE_NAME_LIST :: []string {
- // basic directives
- "file",
- "directory",
- "line",
- "procedure",
- "caller_location",
- "reverse",
- // call directives
- "location",
- "caller_expression",
- "exists",
- "load",
- "load_directory",
- "load_hash",
- "hash",
- "assert",
- "panic",
- "defined",
- "config",
- /* type helper */
- "type",
- /* struct type */
- "packed",
- "raw_union",
- "align",
- "all_or_none",
- /* union type */
- "no_nil",
- "shared_nil",
- /* array type */
- "simd",
- "soa",
- "sparse",
- /* ptr type */
- "relative",
- /* field flags */
- "no_alias",
- "c_vararg",
- "const",
- "any_int",
- "subtype",
- "by_ptr",
- "no_broadcast",
- "no_capture",
- /* swich flags */
- "partial",
- /* block flags */
- "bounds_check",
- "no_bounds_check",
- "type_assert",
- "no_type_assert",
- /* proc inlining */
- "force_inline",
- "force_no_inline",
- /* return values flags */
- "optional_ok",
- "optional_allocator_error",
-}
-
completion_items_directives: []CompletionResult
@(init)
_init_completion_items_directives :: proc "contextless" () {
context = runtime.default_context()
- completion_items_directives = slice.mapper(DIRECTIVE_NAME_LIST, proc(name: string) -> CompletionResult {
- return CompletionResult {
- completion_item = CompletionItem {
- detail = strings.concatenate({"#", name}) or_else name,
- label = name,
- kind = .Constant,
+ directives := make([dynamic]CompletionResult, 0, len(directive_docs), allocator = context.allocator)
+ for name, doc in directive_docs {
+ documentation := MarkupContent {
+ kind = "markdown",
+ value = doc,
+ }
+ append(
+ &directives,
+ CompletionResult {
+ completion_item = CompletionItem{label = name, kind = .Constant, documentation = documentation},
},
- }
- })
+ )
+ }
+ completion_items_directives = directives[:]
}
get_directive_completion :: proc(
diff --git a/src/server/documentation.odin b/src/server/documentation.odin
index 0069ac4..2fe8842 100644
--- a/src/server/documentation.odin
+++ b/src/server/documentation.odin
@@ -6,113 +6,6 @@ import "core:odin/ast"
import path "core:path/slashpath"
import "core:strings"
-// Docs taken from https://pkg.odin-lang.org/base/builtin
-keywords_docs: map[string]string = {
- "typeid" = "```odin\ntypeid :: typeid\n```\n`typeid` is a unique identifier for an Odin type at runtime. It can be mapped to relevant type information through `type_info_of`.",
- "string" = "```odin\nstring :: string\n```\n`string` is the set of all strings of 8-bit bytes, conventionally but not necessarily representing UTF-8 encoding text. A `string` may be empty but not `nil`. Elements of `string` type are immutable and indexable.",
- "string16" = "",
- "cstring" = "```odin\ncstring :: cstring\n```\n`cstring` is the set of all strings of 8-bit bytes terminated with a NUL (0) byte, conventionally but not necessarily representing UTF-8 encoding text. A `cstring` may be empty or `nil`. Elements of `cstring` type are immutable but not indexable.",
- "cstring16" = "",
- "int" = "```odin\nint :: int\n```\n`int` is a signed integer type that is at least 32 bits in size. It is a distinct type, however, and not an alias for say, `i32`.",
- "uint" = "```odin\nuint :: uint\n```\n`uint` is an unsigned integer type that is at least 32 bits in size. It is a distinct type, however, and not an alias for say, `u32`.",
- "u8" = "```odin\nu8 :: u8\n```\n`u8` is the set of all unsigned 8-bit integers. Range 0 through 255.",
- "i8" = "```odin\ni8 :: i8\n```\n`i8` is the set of all signed 8-bit integers. Range -128 through 127.",
- "u16" = "```odin\nu16 :: u16\n```\n`u16` is the set of all unsigned 16-bit integers with native endianness. Range 0 through 65535.",
- "i16" = "```odin\ni16 :: i16\n```\n`i16` is the set of all signed 16-bit integers with native endianness. Range -32768 through 32767.",
- "u32" = "```odin\nu32 :: u32\n```\n`u32` is the set of all unsigned 32-bit integers with native endianness. Range 0 through 4294967295.",
- "i32" = "```odin\ni32 :: i32\n```\n`i32` is the set of all signed 32-bit integers with native endianness. Range -2147483648 through 2147483647.",
- "u64" = "```odin\nu64 :: u64\n```\n`u64` is the set of all unsigned 64-bit integers with native endianness. Range 0 through 18446744073709551615.",
- "i64" = "```odin\ni64 :: i64\n```\n`i64` is the set of all signed 64-bit integers with native endianness. Range -9223372036854775808 through 9223372036854775807.",
- "u128" = "```odin\nu128 :: u128\n```\n`u128` is the set of all unsigned 128-bit integers with native endianness. Range 0 through 340282366920938463463374607431768211455.",
- "i128" = "```odin\ni128 :: i128\n```\n`i128` is the set of all signed 128-bit integers with native endianness. Range -170141183460469231731687303715884105728 through 170141183460469231731687303715884105727.",
- "f16" = "```odin\nf16 :: f16\n```\n`f16` is the set of all IEEE-754 16-bit floating-point numbers with native endianness.",
- "f32" = "```odin\nf32 :: f32\n```\n`f32` is the set of all IEEE-754 32-bit floating-point numbers with native endianness.",
- "f64" = "```odin\nf64 :: f64\n```\n`f64` is the set of all IEEE-754 64-bit floating-point numbers with native endianness.",
- "bool" = "```odin\nbool :: bool\n```\n`bool` is the set of boolean values, `false` and `true`. This is distinct to `b8`. `bool` has a size of 1 byte (8 bits).",
- "any" = "```odin\nany :: any\n```\n`any` is reference any data type at runtime. Internally it contains a pointer to the underlying data and its relevant `typeid`. This is a very useful construct in order to have a runtime type safe printing procedure.\n\nNote: The `any` value is only valid for as long as the underlying data is still valid. Passing a literal to an `any` will allocate the literal in the current stack frame.\n\nNote: It is highly recommend that you do not use this unless you know what you are doing. Its primary use is for printing procedures.",
- "b8" = "```odin\nb8 :: b8\n```\n`b8` is the set of boolean values, `false` and `true`. This is distinct to `bool`. `b8` has a size of 1 byte (8 bits).",
- "b16" = "```odin\nb16 :: b16\n```\n`b16` is the set of boolean values, `false` and `true`. `b16` has a size of 2 bytes (16 bits).",
- "b32" = "```odin\nb32 :: b32\n```\n`b32` is the set of boolean values, `false` and `true`. `b32` has a size of 4 bytes (32 bits).",
- "b64" = "```odin\nb64 :: b64\n```\n`b64` is the set of boolean values, `false` and `true`. `b64` has a size of 8 bytes (64 bits).",
- "true" = "```odin\ntrue :: 0 == 0 // untyped boolean\n```",
- "false" = "```odin\nfalse :: 0 != 0 // untyped boolean\n```",
- "nil" = "```odin\nnil :: ... // untyped nil \n```\n`nil` is a predeclared identifier representing the zero value for a pointer, multi-pointer, enum, bit_set, slice, dynamic array, map, procedure, any, typeid, cstring, union, #soa array, #soa pointer, #relative type.",
- "byte" = "```odin\nbyte :: u8\n```\n`byte` is an alias for `u8` and is equivalent to `u8` in all ways. It is used as a convention to distinguish values from 8-bit unsigned integer values.",
- "rune" = "```odin\nrune :: rune\n```\n`rune` is the set of all Unicode code points. It is internally the same as i32 but distinct.",
- "f16be" = "```odin\nf16be :: f16be\n```\n`f16be` is the set of all IEEE-754 16-bit floating-point numbers with big endianness.",
- "f16le" = "```odin\nf16le :: f16le\n```\n`f16le` is the set of all IEEE-754 16-bit floating-point numbers with little endianness.",
- "f32be" = "```odin\nf32be :: f32be\n```\n`f32be` is the set of all IEEE-754 32-bit floating-point numbers with big endianness.",
- "f32le" = "```odin\nf32le :: f32le\n```\n`f32le` is the set of all IEEE-754 32-bit floating-point numbers with little endianness.",
- "f64be" = "```odin\nf64be :: f64be\n```\n`f64be` is the set of all IEEE-754 64-bit floating-point numbers with big endianness.",
- "f64le" = "```odin\nf64le :: f64le\n```\n`f64le` is the set of all IEEE-754 64-bit floating-point numbers with little endianness.",
- "i16be" = "```odin\ni16be :: i16be\n```\n`i16be` is the set of all signed 16-bit integers with big endianness. Range -32768 through 32767.",
- "i16le" = "```odin\ni16le :: i16le\n```\n`i16le` is the set of all signed 16-bit integers with little endianness. Range -32768 through 32767.",
- "i32be" = "```odin\ni32be :: i32be\n```\n`i32be` is the set of all signed 32-bit integers with big endianness. Range -2147483648 through 2147483647.",
- "i32le" = "```odin\ni32le :: i32le\n```\n`i32le` is the set of all signed 32-bit integers with little endianness. Range -2147483648 through 2147483647.",
- "i64be" = "```odin\ni64be :: i64be\n```\n`i64be` is the set of all signed 64-bit integers with big endianness. Range -9223372036854775808 through 9223372036854775807.",
- "i64le" = "```odin\ni64le :: i64le\n```\n`i64le` is the set of all signed 64-bit integers with little endianness. Range -9223372036854775808 through 9223372036854775807.",
- "u16be" = "```odin\nu16be :: u16be\n```\n`u16be` is the set of all unsigned 16-bit integers with big endianness. Range 0 through 65535.",
- "u16le" = "```odin\nu16le :: u16le\n```\n`u16le` is the set of all unsigned 16-bit integers with little endianness. Range 0 through 65535.",
- "u32be" = "```odin\nu32be :: u32be\n```\n`u32be` is the set of all unsigned 32-bit integers with big endianness. Range 0 through 4294967295.",
- "u32le" = "```odin\nu32le :: u32le\n```\n`u32le` is the set of all unsigned 32-bit integers with little endianness. Range 0 through 4294967295.",
- "u64be" = "```odin\nu64be :: u64be\n```\n`u64be` is the set of all unsigned 64-bit integers with big endianness. Range 0 through 18446744073709551615.",
- "u64le" = "```odin\nu64le :: u64le\n```\n`u64le` is the set of all unsigned 64-bit integers with little endianness. Range 0 through 18446744073709551615.",
- "i128be" = "```odin\ni128be :: i128be\n```\n`i128be` is the set of all signed 128-bit integers with big endianness. Range -170141183460469231731687303715884105728 through 170141183460469231731687303715884105727.",
- "i128le" = "```odin\ni128le :: i128le\n```\n`i128le` is the set of all signed 128-bit integers with little endianness. Range -170141183460469231731687303715884105728 through 170141183460469231731687303715884105727.",
- "u128be" = "```odin\nu128be :: u128be\n```\n`u128be` is the set of all unsigned 128-bit integers with big endianness. Range 0 through 340282366920938463463374607431768211455.",
- "u128le" = "```odin\nu128le :: u128le\n```\n`u128le` is the set of all unsigned 128-bit integers with little endianness. Range 0 through 340282366920938463463374607431768211455.",
- "complex32" = "```odin\ncomplex32 :: complex32\n```\n`complex32` is the set of all complex numbers with `f16` real and imaginary parts.",
- "complex64" = "```odin\ncomplex64 :: complex64\n```\n`complex64` is the set of all complex numbers with `f32` real and imaginary parts.",
- "complex128" = "```odin\ncomplex128 :: complex128\n```\n`complex128` is the set of all complex numbers with `f64` real and imaginary parts.",
- "quaternion64" = "```odin\nquaternion64 :: quaternion64\n```\n`quaternion64` is the set of all complex numbers with `f16` real and imaginary (i, j, & k) parts.",
- "quaternion128" = "```odin\nquaternion128 :: quaternion128\n```\n`quaternion128` is the set of all complex numbers with `f32` real and imaginary (i, j, & k) parts.",
- "quaternion256" = "```odin\nquaternion256 :: quaternion256\n```\n`quaternion256` is the set of all complex numbers with `f64` real and imaginary (i, j, & k) parts.",
- "uintptr" = "```odin\nuintptr :: uintptr\n```\n`uintptr` is an unsigned integer type that is large enough to hold the bit pattern of any pointer.",
- "rawptr" = "```odin\nrawptr :: rawptr\n```\n`rawptr` is a pointer to an arbitrary type. It is equivalent to void * in C.",
- // taken from https://github.com/odin-lang/Odin/wiki/Keywords-and-Operators
- "asm" = "",
- "auto_cast" = "```odin\nauto_cast v```\nAutomatically casts an expression `v` to the destination’s type if possible.",
- "bit_field" = "",
- "bit_set" = "",
- "break" = "",
- "case" = "",
- "cast" = "```odin\ncast(T)v\n```\nConverts the value `v` to the type `T`.",
- "const" = "",
- "context" = "```odin\nruntime.context: Context\n```\nThe context variable is local to each scope. It is copy-on-write and is implicitly passed by pointer to any procedure call in that scope (if the procedure has the Odin calling convention).",
- "continue" = "",
- "defer" = "",
- "distinct" = "```odin\ndistinct T\n```\nCreate a new type with the same underlying semantics as `T`",
- "do" = "",
- "dynamic" = "",
- "else" = "",
- "enum" = "",
- "fallthrough" = "",
- "for" = "",
- "foreign" = "",
- "if" = "",
- "import" = "",
- "in" = "",
- "inline" = "",
- "map" = "",
- "not_in" = "",
- "or_break" = "",
- "or_continue" = "",
- "or_else" = "",
- "or_return" = "",
- "opaque" = "",
- "package" = "",
- "proc" = "",
- "return" = "",
- "struct" = "",
- "switch" = "",
- "transmute" = "```odin\ntransmute(T)v\n```\nBitwise cast between 2 types of the same size.",
- "typeid" = "",
- "union" = "",
- "using" = "",
- "when" = "",
- "where" = "",
-}
-
// Adds signature and docs information to the provided symbol
// This should only be used for a symbol created with the temp allocator
build_documentation :: proc(ast_context: ^AstContext, symbol: ^Symbol, short_signature := true) {
@@ -1006,3 +899,155 @@ write_symbol_type_information :: proc(sb: ^strings.Builder, ast_context: ^AstCon
}
return true
}
+
+// Docs taken from https://pkg.odin-lang.org/base/builtin
+keywords_docs: map[string]string = {
+ "typeid" = "```odin\ntypeid :: typeid\n```\n`typeid` is a unique identifier for an Odin type at runtime. It can be mapped to relevant type information through `type_info_of`.",
+ "string" = "```odin\nstring :: string\n```\n`string` is the set of all strings of 8-bit bytes, conventionally but not necessarily representing UTF-8 encoding text. A `string` may be empty but not `nil`. Elements of `string` type are immutable and indexable.",
+ "string16" = "",
+ "cstring" = "```odin\ncstring :: cstring\n```\n`cstring` is the set of all strings of 8-bit bytes terminated with a NUL (0) byte, conventionally but not necessarily representing UTF-8 encoding text. A `cstring` may be empty or `nil`. Elements of `cstring` type are immutable but not indexable.",
+ "cstring16" = "",
+ "int" = "```odin\nint :: int\n```\n`int` is a signed integer type that is at least 32 bits in size. It is a distinct type, however, and not an alias for say, `i32`.",
+ "uint" = "```odin\nuint :: uint\n```\n`uint` is an unsigned integer type that is at least 32 bits in size. It is a distinct type, however, and not an alias for say, `u32`.",
+ "u8" = "```odin\nu8 :: u8\n```\n`u8` is the set of all unsigned 8-bit integers. Range 0 through 255.",
+ "i8" = "```odin\ni8 :: i8\n```\n`i8` is the set of all signed 8-bit integers. Range -128 through 127.",
+ "u16" = "```odin\nu16 :: u16\n```\n`u16` is the set of all unsigned 16-bit integers with native endianness. Range 0 through 65535.",
+ "i16" = "```odin\ni16 :: i16\n```\n`i16` is the set of all signed 16-bit integers with native endianness. Range -32768 through 32767.",
+ "u32" = "```odin\nu32 :: u32\n```\n`u32` is the set of all unsigned 32-bit integers with native endianness. Range 0 through 4294967295.",
+ "i32" = "```odin\ni32 :: i32\n```\n`i32` is the set of all signed 32-bit integers with native endianness. Range -2147483648 through 2147483647.",
+ "u64" = "```odin\nu64 :: u64\n```\n`u64` is the set of all unsigned 64-bit integers with native endianness. Range 0 through 18446744073709551615.",
+ "i64" = "```odin\ni64 :: i64\n```\n`i64` is the set of all signed 64-bit integers with native endianness. Range -9223372036854775808 through 9223372036854775807.",
+ "u128" = "```odin\nu128 :: u128\n```\n`u128` is the set of all unsigned 128-bit integers with native endianness. Range 0 through 340282366920938463463374607431768211455.",
+ "i128" = "```odin\ni128 :: i128\n```\n`i128` is the set of all signed 128-bit integers with native endianness. Range -170141183460469231731687303715884105728 through 170141183460469231731687303715884105727.",
+ "f16" = "```odin\nf16 :: f16\n```\n`f16` is the set of all IEEE-754 16-bit floating-point numbers with native endianness.",
+ "f32" = "```odin\nf32 :: f32\n```\n`f32` is the set of all IEEE-754 32-bit floating-point numbers with native endianness.",
+ "f64" = "```odin\nf64 :: f64\n```\n`f64` is the set of all IEEE-754 64-bit floating-point numbers with native endianness.",
+ "bool" = "```odin\nbool :: bool\n```\n`bool` is the set of boolean values, `false` and `true`. This is distinct to `b8`. `bool` has a size of 1 byte (8 bits).",
+ "any" = "```odin\nany :: any\n```\n`any` is reference any data type at runtime. Internally it contains a pointer to the underlying data and its relevant `typeid`. This is a very useful construct in order to have a runtime type safe printing procedure.\n\nNote: The `any` value is only valid for as long as the underlying data is still valid. Passing a literal to an `any` will allocate the literal in the current stack frame.\n\nNote: It is highly recommend that you do not use this unless you know what you are doing. Its primary use is for printing procedures.",
+ "b8" = "```odin\nb8 :: b8\n```\n`b8` is the set of boolean values, `false` and `true`. This is distinct to `bool`. `b8` has a size of 1 byte (8 bits).",
+ "b16" = "```odin\nb16 :: b16\n```\n`b16` is the set of boolean values, `false` and `true`. `b16` has a size of 2 bytes (16 bits).",
+ "b32" = "```odin\nb32 :: b32\n```\n`b32` is the set of boolean values, `false` and `true`. `b32` has a size of 4 bytes (32 bits).",
+ "b64" = "```odin\nb64 :: b64\n```\n`b64` is the set of boolean values, `false` and `true`. `b64` has a size of 8 bytes (64 bits).",
+ "true" = "```odin\ntrue :: 0 == 0 // untyped boolean\n```",
+ "false" = "```odin\nfalse :: 0 != 0 // untyped boolean\n```",
+ "nil" = "```odin\nnil :: ... // untyped nil \n```\n`nil` is a predeclared identifier representing the zero value for a pointer, multi-pointer, enum, bit_set, slice, dynamic array, map, procedure, any, typeid, cstring, union, #soa array, #soa pointer, #relative type.",
+ "byte" = "```odin\nbyte :: u8\n```\n`byte` is an alias for `u8` and is equivalent to `u8` in all ways. It is used as a convention to distinguish values from 8-bit unsigned integer values.",
+ "rune" = "```odin\nrune :: rune\n```\n`rune` is the set of all Unicode code points. It is internally the same as i32 but distinct.",
+ "f16be" = "```odin\nf16be :: f16be\n```\n`f16be` is the set of all IEEE-754 16-bit floating-point numbers with big endianness.",
+ "f16le" = "```odin\nf16le :: f16le\n```\n`f16le` is the set of all IEEE-754 16-bit floating-point numbers with little endianness.",
+ "f32be" = "```odin\nf32be :: f32be\n```\n`f32be` is the set of all IEEE-754 32-bit floating-point numbers with big endianness.",
+ "f32le" = "```odin\nf32le :: f32le\n```\n`f32le` is the set of all IEEE-754 32-bit floating-point numbers with little endianness.",
+ "f64be" = "```odin\nf64be :: f64be\n```\n`f64be` is the set of all IEEE-754 64-bit floating-point numbers with big endianness.",
+ "f64le" = "```odin\nf64le :: f64le\n```\n`f64le` is the set of all IEEE-754 64-bit floating-point numbers with little endianness.",
+ "i16be" = "```odin\ni16be :: i16be\n```\n`i16be` is the set of all signed 16-bit integers with big endianness. Range -32768 through 32767.",
+ "i16le" = "```odin\ni16le :: i16le\n```\n`i16le` is the set of all signed 16-bit integers with little endianness. Range -32768 through 32767.",
+ "i32be" = "```odin\ni32be :: i32be\n```\n`i32be` is the set of all signed 32-bit integers with big endianness. Range -2147483648 through 2147483647.",
+ "i32le" = "```odin\ni32le :: i32le\n```\n`i32le` is the set of all signed 32-bit integers with little endianness. Range -2147483648 through 2147483647.",
+ "i64be" = "```odin\ni64be :: i64be\n```\n`i64be` is the set of all signed 64-bit integers with big endianness. Range -9223372036854775808 through 9223372036854775807.",
+ "i64le" = "```odin\ni64le :: i64le\n```\n`i64le` is the set of all signed 64-bit integers with little endianness. Range -9223372036854775808 through 9223372036854775807.",
+ "u16be" = "```odin\nu16be :: u16be\n```\n`u16be` is the set of all unsigned 16-bit integers with big endianness. Range 0 through 65535.",
+ "u16le" = "```odin\nu16le :: u16le\n```\n`u16le` is the set of all unsigned 16-bit integers with little endianness. Range 0 through 65535.",
+ "u32be" = "```odin\nu32be :: u32be\n```\n`u32be` is the set of all unsigned 32-bit integers with big endianness. Range 0 through 4294967295.",
+ "u32le" = "```odin\nu32le :: u32le\n```\n`u32le` is the set of all unsigned 32-bit integers with little endianness. Range 0 through 4294967295.",
+ "u64be" = "```odin\nu64be :: u64be\n```\n`u64be` is the set of all unsigned 64-bit integers with big endianness. Range 0 through 18446744073709551615.",
+ "u64le" = "```odin\nu64le :: u64le\n```\n`u64le` is the set of all unsigned 64-bit integers with little endianness. Range 0 through 18446744073709551615.",
+ "i128be" = "```odin\ni128be :: i128be\n```\n`i128be` is the set of all signed 128-bit integers with big endianness. Range -170141183460469231731687303715884105728 through 170141183460469231731687303715884105727.",
+ "i128le" = "```odin\ni128le :: i128le\n```\n`i128le` is the set of all signed 128-bit integers with little endianness. Range -170141183460469231731687303715884105728 through 170141183460469231731687303715884105727.",
+ "u128be" = "```odin\nu128be :: u128be\n```\n`u128be` is the set of all unsigned 128-bit integers with big endianness. Range 0 through 340282366920938463463374607431768211455.",
+ "u128le" = "```odin\nu128le :: u128le\n```\n`u128le` is the set of all unsigned 128-bit integers with little endianness. Range 0 through 340282366920938463463374607431768211455.",
+ "complex32" = "```odin\ncomplex32 :: complex32\n```\n`complex32` is the set of all complex numbers with `f16` real and imaginary parts.",
+ "complex64" = "```odin\ncomplex64 :: complex64\n```\n`complex64` is the set of all complex numbers with `f32` real and imaginary parts.",
+ "complex128" = "```odin\ncomplex128 :: complex128\n```\n`complex128` is the set of all complex numbers with `f64` real and imaginary parts.",
+ "quaternion64" = "```odin\nquaternion64 :: quaternion64\n```\n`quaternion64` is the set of all complex numbers with `f16` real and imaginary (i, j, & k) parts.",
+ "quaternion128" = "```odin\nquaternion128 :: quaternion128\n```\n`quaternion128` is the set of all complex numbers with `f32` real and imaginary (i, j, & k) parts.",
+ "quaternion256" = "```odin\nquaternion256 :: quaternion256\n```\n`quaternion256` is the set of all complex numbers with `f64` real and imaginary (i, j, & k) parts.",
+ "uintptr" = "```odin\nuintptr :: uintptr\n```\n`uintptr` is an unsigned integer type that is large enough to hold the bit pattern of any pointer.",
+ "rawptr" = "```odin\nrawptr :: rawptr\n```\n`rawptr` is a pointer to an arbitrary type. It is equivalent to void * in C.",
+ // taken from https://github.com/odin-lang/Odin/wiki/Keywords-and-Operators
+ "asm" = "",
+ "auto_cast" = "```odin\nauto_cast v```\nAutomatically casts an expression `v` to the destination’s type if possible.",
+ "bit_field" = "",
+ "bit_set" = "",
+ "break" = "",
+ "case" = "",
+ "cast" = "```odin\ncast(T)v\n```\nConverts the value `v` to the type `T`.",
+ "const" = "",
+ "context" = "```odin\nruntime.context: Context\n```\nThe context variable is local to each scope. It is copy-on-write and is implicitly passed by pointer to any procedure call in that scope (if the procedure has the Odin calling convention).",
+ "continue" = "",
+ "defer" = "",
+ "distinct" = "```odin\ndistinct T\n```\nCreate a new type with the same underlying semantics as `T`",
+ "do" = "",
+ "dynamic" = "",
+ "else" = "",
+ "enum" = "",
+ "fallthrough" = "",
+ "for" = "",
+ "foreign" = "",
+ "if" = "",
+ "import" = "",
+ "in" = "",
+ "inline" = "",
+ "map" = "",
+ "not_in" = "",
+ "or_break" = "",
+ "or_continue" = "",
+ "or_else" = "",
+ "or_return" = "",
+ "opaque" = "",
+ "package" = "",
+ "proc" = "",
+ "return" = "",
+ "struct" = "",
+ "switch" = "",
+ "transmute" = "```odin\ntransmute(T)v\n```\nBitwise cast between 2 types of the same size.",
+ "typeid" = "",
+ "union" = "",
+ "using" = "",
+ "when" = "",
+ "where" = "",
+}
+
+directive_docs : map[string]string = {
+ // Record memory layout
+ "packed" = "```odin\n#packed\n```\n\nThis tag can be applied to a struct. Removes padding between fields that’s normally inserted to ensure all fields meet their type’s alignment requirements. Fields remain in source order.\n\nThis is useful where the structure is unlikely to be correctly aligned (the insertion rules for padding assume it is), or if the space-savings are more important or useful than the access speed of the fields.\n\nAccessing a field in a packed struct may require copying the field out of the struct into a temporary location, or using a machine instruction that doesn’t assume the pointer address is correctly aligned, in order to be performant or avoid crashing on some systems. (See `intrinsics.unaligned_load`.)",
+ "raw_union" = "```odin\n#raw_union\n```\n\nThis tag can be applied to a `struct`. Struct’s fields will share the same memory space which serves the same functionality as `union`s in C language. Useful when writing bindings especially.",
+ "align" = "```odin\n#align\n```\n\nThis tag can be applied to a `struct` or `union`. When `#align` is passed an integer `N` (as in `#align N`), it specifies that the `struct` will be aligned to `N` bytes. The `struct`’s fields will remain in source-order.",
+ "no_nil" = "```odin\n#align\n```\n\nThis tag can be applied to a union to not allow `nil` values.",
+ // Control statements
+ "partial" = "```odin\n#partial\n```\n\nBy default all `case`s of an `enum` or `union` have to be covered in a `switch` statement. The reason for this requirement is because it makes accidental bugs less likely. However, the `#partial` tag allows you to not have to write out cases that you don’t need to handle.\n\nThe `#partial` directive can also be used to initialize an enumerated array.",
+ // Procedure parameters
+ "no_alias" = "```odin\n#no_alias\n```\n\nThis tag can be applied to a procedure parameter that is a pointer. This is a hint to the compiler that this parameter will not alias other parameters. This is equivalent to C’s `__restrict`.",
+ "any_int" = "```odin\n#any_int\n```\n\n`#any_int` enables implicit casts to a procedure’s integer type at the call site. A parameter with `#any_int` must be an integer.",
+ "caller_location" = "```odin\n#caller_location\n```\n\n`#caller_location` sets a parameter’s default value to the location of the code calling the procedure. The location value has the type `runtime.Source_Code_Location`. `#caller_location` may only be used as a default value for procedure parameters.",
+ "caller_expression" = "```odin\n#caller_expression\n// or\n#caller_expression(<count>)\n```\n\n`#caller_expression` gives a procedure the entire call expression or the expression used to create a parameter. `#caller_expression` may only be used as a default value for procedure parameters.",
+ "c_vararg" = "```odin\n#c_vararg\n```\n\nUsed to interface with vararg functions in foreign procedures.",
+ "by_ptr" = "```odin\n#by_ptr\n```\n\nUsed to interface with const reference parameters in foreign procedures. The parameter is passed by pointer internally.",
+ "optional_ok" = "```odin\n#optional_ok\n```\n\nAllows skipping the last return parameter, which needs to be a `bool`.",
+ "optional_allocator_error" = "```odin\n#optional_allocator_error\n```\n\nAllows skipping the last return parameter, which needs to be a runtime.Allocator_Error",
+ // Expressions
+ "type" = "```odin\n#type\n```\n\nThis tag doesn’t serve a functional purpose in the compiler, this is for telling someone reading the code that the expression is a type. The main case is for showing that a procedure signature without a body is a type and not just missing its body.",
+ "sparse" = "```odin\n#sparse\n```\n\nThis directive may be used to create a sparse enumerated array. This is necessary when the enumerated values are not contiguous.",
+ "force_inline" = "```odin\n#force_inline\n```\n\nSpecify whether a procedure literal or call will be forced to inline (`#force_inline`) or forced to never inline `#force_no_inline`. This is not an suggestion to the compiler. If the compiler cannot inline the procedure, it will (currently) silently ignore the directive.\n\nThis is enabled all optization levels except `-o:none` which has all inlining disabled.",
+ "force_no_inline" = "```odin\n#force_no_inline\n```\n\nSpecify whether a procedure literal or call will be forced to inline (`#force_inline`) or forced to never inline `#force_no_inline`. This is not an suggestion to the compiler. If the compiler cannot inline the procedure, it will (currently) silently ignore the directive.\n\nThis is enabled all optization levels except `-o:none` which has all inlining disabled.",
+ // Statements
+ "bounds_check" = "```odin\n#bounds_check\n```\n\nThe `#bounds_check` and `#no_bounds_check` flags control Odin’s built-in bounds checking of arrays and slices. Any statement, block, or function with one of these flags will have their bounds checking turned on or off, depending on the flag provided.\n\nBy default, the Odin compiler has bounds checking enabled program-wide where applicable, and it may be turned off by passing the -no-bounds-check build flag.",
+ "no_bounds_check" = "```odin\n#no_bounds_check\n```\n\nThe `#bounds_check` and `#no_bounds_check` flags control Odin’s built-in bounds checking of arrays and slices. Any statement, block, or function with one of these flags will have their bounds checking turned on or off, depending on the flag provided.\n\nBy default, the Odin compiler has bounds checking enabled program-wide where applicable, and it may be turned off by passing the -no-bounds-check build flag.",
+ "type_assert" = "```odin\n#type_assert\n```\n\n`#no_type_assert` will bypass the underlying call to `runtime.type_assertion_check` when placed at the head of a statement or block which would normally do a type assert, such as the resolution of a `union` or an `any` into its true type. `#type_assert` will re-enable type assertions, if they were turned off in an outer scope.\n\nBy default, the Odin compiler has type assertions enabled program-wide where applicable, and they may be turned off by passing the `-no-type-assert` build flag. Note that `-disable-assert` does not also turn off type assertions; `-no-type-assert` must be passed explicitly.",
+ "no_type_assert" = "```odin\n#no_type_assert\n```\n\n`#no_type_assert` will bypass the underlying call to `runtime.type_assertion_check` when placed at the head of a statement or block which would normally do a type assert, such as the resolution of a `union` or an `any` into its true type. `#type_assert` will re-enable type assertions, if they were turned off in an outer scope.\n\nBy default, the Odin compiler has type assertions enabled program-wide where applicable, and they may be turned off by passing the `-no-type-assert` build flag. Note that `-disable-assert` does not also turn off type assertions; `-no-type-assert` must be passed explicitly.",
+ // Built-in
+ "assert" = "```odin\n#assert\n```\n\nUnlike `assert`, `#assert` runs at compile-time. `#assert` breaks compilation if the given bool expression is false, and thus #assert is useful for catching bugs before they ever even reach run-time. It also has no run-time cost.",
+ "panic" = "```odin\n#panic(<string>)\n```\n\nPanic runs at compile-time. It is functionally equivalent to an `#assert` with a `false` condition, but `#panic` has an error message string parameter.",
+ "config" = "```odin\n#config(<identifier>, default)\n```\n\nChecks if an identifier is defined through the command line, or gives a default value instead.\n\nValues can be set with the `-define:NAME=VALUE` command line flag.",
+ "defined" = "```odin\n#defined\n```\n\nChecks if an identifier is defined. This may only be used within a procedure’s body.",
+ "file" = "```odin\n#file\n```\n\nReturn the current file path.",
+ "directory" = "```odin\n#directory\n```\n\nReturn the current directory.",
+ "line" = "```odin\n#line\n```\n\nReturn the current line number.",
+ "procedure" = "```odin\n#procedure\n```\n\nReturn the current procedure name.",
+ "exists" = "```odin\n#exists(<string-path>)\n```\n\nReturns `true` or `false` if the file at the given path exists. If the path is relative, it is accessed relative to the Odin source file that references it.",
+ "branch_location" = "```odin\n#branch_location\n```\n\nWhen used within a `defer` statement, this directive returns a `runtime.Source_Code_Location` of the point at which the control flow triggered execution of the `defer`. This may be a `return` statement or the end of a scope.",
+ "location" = "```odin\n#location()\n// or\n#location(<entity>)\n```\n\nReturns a `runtime.Source_Code_Location`. Can be called with no parameters for current location, or with a parameter for the location of the variable/proc declaration.",
+ "load" = "```odin\n#load(<string-path>)\n//or\n#load(<string-path>, <type>)\n```\n\nReturns a `[]u8` of the file contents at compile time. This means that the loaded data is baked into your program. Optionally, you can provide a type name as second argument; interpreting the data as being of that type.\n\n`#load` also works with `or_else` to provide default content when the file wasn’t found",
+ "hash" = "```odin\n#hash(<string-text>, <string-hash>)\n```\n\nReturns a constant integer of the hash of a string literal at compile time.\n\nAvailable hashes:\n\n- adler32\n- crc32\n- crc64\n- fnv32\n- fnv64\n- fnv32a\n- fnv64a\n- murmur32\n- murmur64",
+ "load_hash" = "```odin\n#load_hash(<string-path>, <string-hash>)\n```\n\nReturns a constant integer of the hash of a file’s contents at compile time..\n\nAvailable hashes:\n\n- adler32\n- crc32\n- crc64\n- fnv32\n- fnv64\n- fnv32a\n- fnv64a\n- murmur32\n- murmur64",
+ "load_directory" = "```odin\n#load_directory(<string-path>)\n```\n\nLoads all files within a directory, at compile time. All the data of those files will be baked into your program. Returns `[]runtime.Load_Directory_File`.",
+}
diff --git a/src/server/hover.odin b/src/server/hover.odin
index 20651e4..ca791ef 100644
--- a/src/server/hover.odin
+++ b/src/server/hover.odin
@@ -66,6 +66,15 @@ get_hover_information :: proc(document: ^Document, position: common.Position) ->
}
}
+ if position_context.directive != nil && position_in_node(position_context.directive, position_context.position) {
+ if str, ok := directive_docs[position_context.directive.name]; ok {
+ hover.contents.kind = "markdown"
+ hover.contents.value = str
+ hover.range = common.get_token_range(position_context.directive, ast_context.file.src)
+ return hover, true, true
+ }
+ }
+
if position_context.identifier != nil {
if ident, ok := position_context.identifier.derived.(^ast.Ident); ok {
if str, ok := keywords_docs[ident.name]; ok {
@@ -323,7 +332,10 @@ get_hover_information :: proc(document: ^Document, position: common.Position) ->
}
}
- if resolved, ok := resolve_symbol_return(&ast_context, lookup(ident.name, selector.pkg, ast_context.fullpath)); ok {
+ if resolved, ok := resolve_symbol_return(
+ &ast_context,
+ lookup(ident.name, selector.pkg, ast_context.fullpath),
+ ); ok {
build_documentation(&ast_context, &resolved, false)
resolved.name = ident.name
diff --git a/src/server/position_context.odin b/src/server/position_context.odin
index 2792194..602d9a1 100644
--- a/src/server/position_context.odin
+++ b/src/server/position_context.odin
@@ -61,6 +61,7 @@ DocumentPositionContext :: struct {
import_stmt: ^ast.Import_Decl,
type_cast: ^ast.Type_Cast,
call_commas: []int,
+ directive: ^ast.Basic_Directive,
}
@@ -881,6 +882,8 @@ get_document_position_node :: proc(node: ^ast.Node, position_context: ^DocumentP
get_document_position(n.name, position_context)
get_document_position(n.type, position_context)
get_document_position(n.bit_size, position_context)
+ case ^Basic_Directive:
+ position_context.directive = n
case:
}
}