aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2020-11-07 15:44:30 +0100
committerDanielGavin <danielgavin5@hotmail.com>2020-11-07 15:44:30 +0100
commit6ec424ed8d34cf8a5f51e277a20429741b33ee96 (patch)
tree6d0eed732e01d19effbae5cc525a9c2f6e28534f
parent3f1027bd4003cdb9fdc80665548181df2fb60810 (diff)
complete refractor of the project into packages
-rw-r--r--src/common/config.odin (renamed from src/config.odin)3
-rw-r--r--src/common/position.odin (renamed from src/position.odin)25
-rw-r--r--src/common/types.odin26
-rw-r--r--src/common/uri.odin (renamed from src/uri.odin)2
-rw-r--r--src/index/build.odin86
-rw-r--r--src/index/file_index.odin7
-rw-r--r--src/index/indexer.odin (renamed from src/index.odin)51
-rw-r--r--src/index/memory_index.odin29
-rw-r--r--src/index/symbol.odin66
-rw-r--r--src/main.odin27
-rw-r--r--src/server/analysis.odin (renamed from src/analysis.odin)33
-rw-r--r--src/server/documents.odin (renamed from src/documents.odin)79
-rw-r--r--src/server/log.odin (renamed from src/log.odin)2
-rw-r--r--src/server/reader.odin (renamed from src/reader.odin)4
-rw-r--r--src/server/requests.odin (renamed from src/requests.odin)32
-rw-r--r--src/server/response.odin (renamed from src/response.odin)2
-rw-r--r--src/server/types.odin (renamed from src/types.odin)55
-rw-r--r--src/server/unmarshal.odin (renamed from src/unmarshal.odin)2
-rw-r--r--src/server/workspace.odin1
-rw-r--r--src/server/writer.odin (renamed from src/writer.odin)2
-rw-r--r--src/workspace.odin1
-rw-r--r--tests/tests.odin18
22 files changed, 351 insertions, 202 deletions
diff --git a/src/config.odin b/src/common/config.odin
index b4df050..cdbe4fd 100644
--- a/src/config.odin
+++ b/src/common/config.odin
@@ -1,9 +1,10 @@
-package main
+package common
Config :: struct {
workspace_folders: [dynamic] WorkspaceFolder,
completion_support_md: bool,
hover_support_md: bool,
collections: map [string] string,
+ running: bool,
};
diff --git a/src/position.odin b/src/common/position.odin
index 3278f10..7eb4173 100644
--- a/src/position.odin
+++ b/src/common/position.odin
@@ -1,4 +1,4 @@
-package main
+package common
import "core:strings"
import "core:unicode/utf8"
@@ -9,6 +9,22 @@ import "core:odin/ast"
This file handles the conversion between utf-16 and utf-8 offsets in the text document
*/
+Position :: struct {
+ line: int,
+ character: int,
+};
+
+Range :: struct {
+ start: Position,
+ end: Position,
+};
+
+Location :: struct {
+ uri: string,
+ range: Range,
+};
+
+
AbsoluteRange :: struct {
start: int,
end: int,
@@ -59,12 +75,15 @@ get_token_range :: proc(node: ast.Node, document_text: [] u8) -> Range {
return index+1;
}
- offset := go_backwards_to_endline(node.pos.offset, document_text);
+ pos_offset := min(len(document_text)-1, node.pos.offset);
+ end_offset := min(len(document_text)-1, node.end.offset);
+
+ offset := go_backwards_to_endline(pos_offset, document_text);
range.start.line = node.pos.line-1;
range.start.character = get_character_offset_u8_to_u16(node.pos.column-1, document_text[offset:]);
- offset = go_backwards_to_endline(node.end.offset, document_text);
+ offset = go_backwards_to_endline(end_offset, document_text);
range.end.line = node.end.line-1;
range.end.character = get_character_offset_u8_to_u16(node.end.column-1, document_text[offset:]);
diff --git a/src/common/types.odin b/src/common/types.odin
new file mode 100644
index 0000000..08bd8c2
--- /dev/null
+++ b/src/common/types.odin
@@ -0,0 +1,26 @@
+package common
+
+
+Error :: enum {
+ None = 0,
+
+ // Defined by JSON RPC
+ ParseError = -32700,
+ InvalidRequest = -32600,
+ MethodNotFound = -32601,
+ InvalidParams = -32602,
+ InternalError = -32603,
+ serverErrorStart = -32099,
+ serverErrorEnd = -32000,
+ ServerNotInitialized = -32002,
+ UnknownErrorCode = -32001,
+
+ // Defined by the protocol.
+ RequestCancelled = -32800,
+ ContentModified = -32801,
+};
+
+WorkspaceFolder :: struct {
+ name: string,
+ uri: string,
+};
diff --git a/src/uri.odin b/src/common/uri.odin
index 8a59e4c..f8bee9e 100644
--- a/src/uri.odin
+++ b/src/common/uri.odin
@@ -1,4 +1,4 @@
-package main
+package common
import "core:mem"
import "core:strings"
diff --git a/src/index/build.odin b/src/index/build.odin
new file mode 100644
index 0000000..d52cbca
--- /dev/null
+++ b/src/index/build.odin
@@ -0,0 +1,86 @@
+package index
+
+import "core:path/filepath"
+import "core:os"
+import "core:fmt"
+import "core:odin/parser"
+import "core:odin/ast"
+import "core:odin/tokenizer"
+
+import "shared:common"
+
+/*
+ Not fully sure how to handle rebuilding, but one thing is for sure, dynamic indexing has to have a background thread
+ rebuilding every minute or less to fight against stale information
+ */
+
+
+//test version for static indexing
+
+symbol_collection: SymbolCollection;
+
+build_static_index :: proc(allocator := context.allocator, config: ^common.Config) {
+
+ //right now just collect the symbols from core
+
+ core_path := config.collections["core"];
+
+
+ symbol_collection = make_symbol_collection(allocator);
+
+ walk_static_index_build := proc(info: os.File_Info, in_err: os.Errno) -> (err: os.Errno, skip_dir: bool) {
+
+ if info.is_dir {
+ return 0, false;
+ }
+
+ //fmt.println(info.fullpath);
+
+ //bit worried about using temp allocator here since we might overwrite all our temp allocator budget
+ data, ok := os.read_entire_file(info.fullpath, context.allocator);
+
+ if !ok {
+ fmt.println("failed to read");
+ return 1, false;
+ }
+
+ p := parser.Parser {
+ err = no_error_handler,
+ warn = no_warning_handler,
+ };
+
+ file := ast.File {
+ fullpath = info.fullpath,
+ src = data,
+ };
+
+ parser.parse_file(&p, &file);
+
+ uri := common.create_uri(info.fullpath, context.temp_allocator);
+
+ collect_symbols(&symbol_collection, file, uri.uri);
+
+ delete(data);
+
+
+ return 0, false;
+ };
+
+ filepath.walk(core_path, walk_static_index_build);
+
+ indexer.static_index = make_memory_index(symbol_collection);
+}
+
+
+no_error_handler :: proc(pos: tokenizer.Pos, msg: string, args: ..any) {
+
+}
+
+no_warning_handler :: proc(pos: tokenizer.Pos, msg: string, args: ..any) {
+
+}
+
+
+
+
+
diff --git a/src/index/file_index.odin b/src/index/file_index.odin
new file mode 100644
index 0000000..fe787e5
--- /dev/null
+++ b/src/index/file_index.odin
@@ -0,0 +1,7 @@
+package index
+
+/*
+ This is indexer for static files operating on a file database to index symbols and files.
+
+ NOTE(Daniel, Let's be honest probably will not be made any time soon)
+ */ \ No newline at end of file
diff --git a/src/index.odin b/src/index/indexer.odin
index 7d2774f..46a2192 100644
--- a/src/index.odin
+++ b/src/index/indexer.odin
@@ -1,4 +1,4 @@
-package main
+package index
import "core:odin/ast"
import "core:fmt"
@@ -38,58 +38,17 @@ import "core:strings"
TODO(Daniel, Look into data structure for fuzzy searching)
*/
-BaseSymbol :: struct {
- range: Range,
- uri: ^Uri,
-};
-ProcedureSymbol :: struct {
- using symbolbase: BaseSymbol,
-};
-
-Symbol :: union {
- ProcedureSymbol,
-};
Indexer :: struct {
- symbol_table: map [string] Symbol,
+ static_index: MemoryIndex,
};
indexer: Indexer;
-index_document :: proc(document: ^Document) -> Error {
-
- for decl in document.ast.decls {
-
- if value_decl, ok := decl.derived.(ast.Value_Decl); ok {
-
- name := string(document.text[value_decl.names[0].pos.offset:value_decl.names[0].end.offset]);
-
- if len(value_decl.values) == 1 {
-
- if proc_lit, ok := value_decl.values[0].derived.(ast.Proc_Lit); ok {
- symbol: ProcedureSymbol;
-
- symbol.range = get_token_range(proc_lit, document.text);
- symbol.uri = &document.uri;
-
- indexer.symbol_table[strings.concatenate({document.package_name, name}, context.temp_allocator)] = symbol;
-
- //fmt.println(proc_lit.type);
-
- }
-
- }
-
- }
- }
-
- //fmt.println(indexer.symbol_table);
-
- return .None;
+lookup :: proc(id: string) -> (Symbol, bool) {
+ return memory_index_lookup(&indexer.static_index, id);
}
-indexer_get_symbol :: proc(id: string) -> (Symbol, bool) {
- return indexer.symbol_table[id];
-}
+//indexer_fuzzy_search :: proc(name: string, scope: [] string, )
diff --git a/src/index/memory_index.odin b/src/index/memory_index.odin
new file mode 100644
index 0000000..c5ce416
--- /dev/null
+++ b/src/index/memory_index.odin
@@ -0,0 +1,29 @@
+package index
+
+import "core:hash"
+
+/*
+ This is a in memory index designed for the dynamic indexing of symbols and files.
+ Designed for few files and should be fast at rebuilding.
+
+ Right now the implementation is quite naive.
+ */
+MemoryIndex :: struct {
+ collection: SymbolCollection,
+};
+
+
+make_memory_index :: proc(collection: SymbolCollection) -> MemoryIndex {
+
+ return MemoryIndex {
+ collection = collection,
+ };
+
+}
+
+memory_index_lookup :: proc(index: ^MemoryIndex, id: string) -> (Symbol, bool) {
+
+ hashed := hash.murmur64(transmute([]u8)id);
+
+ return index.collection.symbols[hashed];
+} \ No newline at end of file
diff --git a/src/index/symbol.odin b/src/index/symbol.odin
new file mode 100644
index 0000000..2cbd58c
--- /dev/null
+++ b/src/index/symbol.odin
@@ -0,0 +1,66 @@
+package index
+
+import "core:odin/ast"
+import "core:hash"
+import "core:strings"
+import "core:mem"
+
+import "shared:common"
+
+Symbol :: struct {
+ id: u64,
+ range: common.Range,
+ uri: string,
+};
+
+SymbolCollection :: struct {
+ allocator: mem.Allocator,
+ symbols: map[u64] Symbol,
+ unique_strings: map[u64] string,
+};
+
+make_symbol_collection :: proc(allocator := context.allocator) -> SymbolCollection {
+ return SymbolCollection {
+ allocator = allocator,
+ symbols = make(map[u64] Symbol, 16, allocator),
+ unique_strings = make(map[u64] string, 16, allocator),
+ };
+}
+
+collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: string) -> common.Error {
+
+ for decl in file.decls {
+
+ if value_decl, ok := decl.derived.(ast.Value_Decl); ok {
+
+ name := string(file.src[value_decl.names[0].pos.offset:value_decl.names[0].end.offset]);
+
+ if len(value_decl.values) == 1 {
+
+ if proc_lit, ok := value_decl.values[0].derived.(ast.Proc_Lit); ok {
+
+ symbol: Symbol;
+
+ symbol.range = common.get_token_range(proc_lit, file.src);
+
+ uri_id := hash.murmur64(transmute([]u8)uri);
+
+ if _, ok := collection.unique_strings[uri_id]; !ok {
+ collection.unique_strings[uri_id] = strings.clone(uri);
+ }
+
+ symbol.uri = collection.unique_strings[uri_id];
+
+ id := hash.murmur64(transmute([]u8)strings.concatenate({file.pkg_name, name}, context.temp_allocator));
+
+ collection.symbols[id] = symbol;
+
+ }
+
+ }
+
+ }
+ }
+
+ return .None;
+}
diff --git a/src/main.odin b/src/main.odin
index 382fd31..62c75f6 100644
--- a/src/main.odin
+++ b/src/main.odin
@@ -9,6 +9,10 @@ import "core:slice"
import "core:strconv"
import "core:encoding/json"
+import "shared:index"
+import "shared:server"
+import "shared:common"
+
running: bool;
os_read :: proc(handle: rawptr, data: [] byte) -> (int, int)
@@ -23,9 +27,9 @@ os_write :: proc(handle: rawptr, data: [] byte) -> (int, int)
//Note(Daniel, Should look into handling errors without crashing from parsing)
-run :: proc(reader: ^Reader, writer: ^Writer) {
+run :: proc(reader: ^server.Reader, writer: ^server.Writer) {
- config: Config;
+ config: common.Config;
//temporary collections being set manually, need to get client configuration set up.
config.collections = make(map [string] string);
@@ -34,11 +38,14 @@ run :: proc(reader: ^Reader, writer: ^Writer) {
log.info("Starting Odin Language Server");
- running = true;
+ index.build_static_index(context.allocator, &config);
+
+
+ config.running = true;
- for running {
+ for config.running {
- header, success := read_and_parse_header(reader);
+ header, success := server.read_and_parse_header(reader);
if(!success) {
log.error("Failed to read and parse header");
@@ -47,14 +54,14 @@ run :: proc(reader: ^Reader, writer: ^Writer) {
value: json.Value;
- value, success = read_and_parse_body(reader, header);
+ value, success = server.read_and_parse_body(reader, header);
if(!success) {
log.error("Failed to read and parse body");
return;
}
- success = handle_request(value, &config, writer);
+ success = server.handle_request(value, &config, writer);
if(!success) {
log.error("Unrecoverable handle request");
@@ -74,10 +81,10 @@ end :: proc() {
main :: proc() {
- reader := make_reader(os_read, cast(rawptr)os.stdin);
- writer := make_writer(os_write, cast(rawptr)os.stdout);
+ reader := server.make_reader(os_read, cast(rawptr)os.stdin);
+ writer := server.make_writer(os_write, cast(rawptr)os.stdout);
- context.logger = create_lsp_logger(&writer);
+ context.logger = server.create_lsp_logger(&writer);
run(&reader, &writer);
}
diff --git a/src/analysis.odin b/src/server/analysis.odin
index 23f18ae..e88532f 100644
--- a/src/analysis.odin
+++ b/src/server/analysis.odin
@@ -1,4 +1,4 @@
-package main
+package server
import "core:odin/parser"
import "core:odin/ast"
@@ -8,6 +8,10 @@ import "core:log"
import "core:strings"
import "core:path"
+import "shared:common"
+import "shared:index"
+
+
DocumentPositionContextDottedValue :: struct {
prefix: string,
@@ -37,14 +41,15 @@ tokenizer_error_handler :: proc(pos: tokenizer.Pos, msg: string, args: ..any) {
}
+
/*
Figure out what exactly is at the given position and whether it is in a function, struct, etc.
*/
-get_document_position_context :: proc(document: ^Document, position: Position) -> (DocumentPositionContext, bool) {
+get_document_position_context :: proc(document: ^Document, position: common.Position) -> (DocumentPositionContext, bool) {
position_context: DocumentPositionContext;
- absolute_position, ok := get_absolute_position(position, document.text);
+ absolute_position, ok := common.get_absolute_position(position, document.text);
if !ok {
return position_context, false;
@@ -86,9 +91,6 @@ get_document_position_context :: proc(document: ^Document, position: Position) -
}
- //fmt.println(current_token.text);
- //fmt.println();
-
if current_token.pos.offset+len(current_token.text) >= absolute_position {
break;
}
@@ -119,9 +121,12 @@ get_document_position_context :: proc(document: ^Document, position: Position) -
}
-get_definition_location :: proc(document: ^Document, position: Position) -> (Location, bool) {
+get_definition_location :: proc(document: ^Document, position: common.Position) -> (common.Location, bool) {
+
+
+ location: common.Location;
+
- location: Location;
position_context, ok := get_document_position_context(document, position);
@@ -129,11 +134,11 @@ get_definition_location :: proc(document: ^Document, position: Position) -> (Loc
return location, false;
}
- symbol: Symbol;
+ symbol: index.Symbol;
#partial switch v in position_context.value {
case DocumentPositionContextDottedValue:
- symbol, ok = indexer_get_symbol(strings.concatenate({v.prefix, v.postfix}, context.temp_allocator));
+ symbol, ok = index.lookup(strings.concatenate({v.prefix, v.postfix}, context.temp_allocator));
case:
return location, false;
}
@@ -144,11 +149,9 @@ get_definition_location :: proc(document: ^Document, position: Position) -> (Loc
return location, false;
}
- switch v in symbol {
- case ProcedureSymbol:
- location.range = v.range;
- location.uri = v.uri.uri;
- }
+ location.range = symbol.range;
+ location.uri = symbol.uri;
+
return location, true;
}
diff --git a/src/documents.odin b/src/server/documents.odin
index bda7c21..59eeadd 100644
--- a/src/documents.odin
+++ b/src/server/documents.odin
@@ -1,4 +1,4 @@
-package main
+package server
import "core:strings"
import "core:fmt"
@@ -9,6 +9,8 @@ import "core:odin/ast"
import "core:odin/tokenizer"
import "core:path"
+import "shared:common"
+
ParserError :: struct {
message: string,
line: int,
@@ -23,12 +25,11 @@ Package :: struct {
};
Document :: struct {
- uri: Uri,
+ uri: common.Uri,
text: [] u8,
used_text: int, //allow for the text to be reallocated with more data than needed
client_owned: bool,
diagnosed_errors: bool,
- indexed: bool,
ast: ast.File,
package_name: string,
imports: [] string,
@@ -44,7 +45,7 @@ document_storage: DocumentStorage;
document_get :: proc(uri_string: string) -> ^Document {
- uri, parsed_ok := parse_uri(uri_string, context.temp_allocator);
+ uri, parsed_ok := common.parse_uri(uri_string, context.temp_allocator);
if !parsed_ok {
return nil;
@@ -61,11 +62,11 @@ document_get :: proc(uri_string: string) -> ^Document {
/*
Server opens a new document with text from filesystem
*/
-document_new :: proc(path: string, config: ^Config) -> Error {
+document_new :: proc(path: string, config: ^common.Config) -> common.Error {
text, ok := os.read_entire_file(path);
- uri := create_uri(path);
+ uri := common.create_uri(path);
if !ok {
log.error("Failed to parse uri");
@@ -75,23 +76,12 @@ document_new :: proc(path: string, config: ^Config) -> Error {
document := Document {
uri = uri,
text = transmute([] u8)text,
- client_owned = true,
+ client_owned = false,
used_text = len(text),
};
- if err := document_refresh(&document, config, nil, false); err != .None {
- log.error("Failed to refresh new document");
- return err;
- }
-
- document_storage.documents[path] = document;
-
- if err := index_document(&document_storage.documents[path]); err != .None {
- log.error("Failed to index new document");
- return err;
- }
-
+ document_storage.documents[path] = document;
return .None;
}
@@ -100,9 +90,9 @@ document_new :: proc(path: string, config: ^Config) -> Error {
Client opens a document with transferred text
*/
-document_open :: proc(uri_string: string, text: string, config: ^Config, writer: ^Writer) -> Error {
+document_open :: proc(uri_string: string, text: string, config: ^common.Config, writer: ^Writer) -> common.Error {
- uri, parsed_ok := parse_uri(uri_string);
+ uri, parsed_ok := common.parse_uri(uri_string);
log.infof("document_open: %v", uri_string);
@@ -123,7 +113,7 @@ document_open :: proc(uri_string: string, text: string, config: ^Config, writer:
}
if len(document.uri.uri) > 0 {
- delete_uri(document.uri);
+ common.delete_uri(document.uri);
}
document.uri = uri;
@@ -164,9 +154,9 @@ document_open :: proc(uri_string: string, text: string, config: ^Config, writer:
/*
Function that applies changes to the given document through incremental syncronization
*/
-document_apply_changes :: proc(uri_string: string, changes: [dynamic] TextDocumentContentChangeEvent, config: ^Config, writer: ^Writer) -> Error {
+document_apply_changes :: proc(uri_string: string, changes: [dynamic] TextDocumentContentChangeEvent, config: ^common.Config, writer: ^Writer) -> common.Error {
- uri, parsed_ok := parse_uri(uri_string, context.temp_allocator);
+ uri, parsed_ok := common.parse_uri(uri_string, context.temp_allocator);
if !parsed_ok {
return .ParseError;
@@ -181,7 +171,7 @@ document_apply_changes :: proc(uri_string: string, changes: [dynamic] TextDocume
for change in changes {
- absolute_range, ok := get_absolute_range(change.range, document.text[:document.used_text]);
+ absolute_range, ok := common.get_absolute_range(change.range, document.text[:document.used_text]);
if !ok {
return .ParseError;
@@ -225,9 +215,9 @@ document_apply_changes :: proc(uri_string: string, changes: [dynamic] TextDocume
return document_refresh(document, config, writer, true);
}
-document_close :: proc(uri_string: string) -> Error {
+document_close :: proc(uri_string: string) -> common.Error {
- uri, parsed_ok := parse_uri(uri_string, context.temp_allocator);
+ uri, parsed_ok := common.parse_uri(uri_string, context.temp_allocator);
if !parsed_ok {
return .ParseError;
@@ -247,7 +237,7 @@ document_close :: proc(uri_string: string) -> Error {
-document_refresh :: proc(document: ^Document, config: ^Config, writer: ^Writer, parse_imports: bool) -> Error {
+document_refresh :: proc(document: ^Document, config: ^common.Config, writer: ^Writer, parse_imports: bool) -> common.Error {
errors, ok := parse_document(document, config);
@@ -267,12 +257,12 @@ document_refresh :: proc(document: ^Document, config: ^Config, writer: ^Writer,
for error, i in errors {
params.diagnostics[i] = Diagnostic {
- range = Range {
- start = Position {
+ range = common.Range {
+ start = common.Position {
line = error.line - 1,
character = 0,
},
- end = Position {
+ end = common.Position {
line = error.line,
character = 0,
},
@@ -316,27 +306,10 @@ document_refresh :: proc(document: ^Document, config: ^Config, writer: ^Writer,
}
- if parse_imports {
-
- /*
- go through the imports from this document and see if we need to load them into memory(not owned by client),
- and also refresh them if needed
- */
- for imp in document.imports {
-
- if err := document_load_package(imp, config); err != .None {
- return err;
- }
-
- }
-
- }
-
-
return .None;
}
-document_load_package :: proc(package_directory: string, config: ^Config) -> Error {
+document_load_package :: proc(package_directory: string, config: ^common.Config) -> common.Error {
fd, err := os.open(package_directory);
@@ -376,7 +349,7 @@ parser_warning_handler :: proc(pos: tokenizer.Pos, msg: string, args: ..any) {
}
-parse_document :: proc(document: ^Document, config: ^Config) -> ([] ParserError, bool) {
+parse_document :: proc(document: ^Document, config: ^common.Config) -> ([] ParserError, bool) {
p := parser.Parser {
err = parser_error_handler,
@@ -392,6 +365,11 @@ parse_document :: proc(document: ^Document, config: ^Config) -> ([] ParserError,
parser.parse_file(&p, &document.ast);
+ /*
+ if document.imports != nil {
+ delete(document.imports);
+ delete(document.package_name);
+ }
document.imports = make([]string, len(document.ast.imports));
document.package_name = document.ast.pkg_name;
@@ -418,6 +396,7 @@ parse_document :: proc(document: ^Document, config: ^Config) -> ([] ParserError,
}
}
+ */
return current_errors[:], true;
} \ No newline at end of file
diff --git a/src/log.odin b/src/server/log.odin
index 82a52a4..5ed007e 100644
--- a/src/log.odin
+++ b/src/server/log.odin
@@ -1,4 +1,4 @@
-package main
+package server
import "core:fmt";
import "core:strings";
diff --git a/src/reader.odin b/src/server/reader.odin
index 31019a5..f421d67 100644
--- a/src/reader.odin
+++ b/src/server/reader.odin
@@ -1,4 +1,4 @@
-package main
+package server
import "core:os"
import "core:mem"
@@ -46,7 +46,7 @@ read_until_delimiter :: proc(reader: ^Reader, delimiter: u8, builder: ^strings.B
}
}
- return true;
+ return true;
}
read_sized :: proc(reader: ^Reader, data: []u8) -> bool {
diff --git a/src/requests.odin b/src/server/requests.odin
index 182772a..cd8e734 100644
--- a/src/requests.odin
+++ b/src/server/requests.odin
@@ -1,4 +1,4 @@
-package main
+package server
import "core:fmt"
import "core:log"
@@ -9,6 +9,8 @@ import "core:slice"
import "core:strconv"
import "core:encoding/json"
+import "shared:common"
+
Header :: struct {
content_length: int,
@@ -129,7 +131,7 @@ read_and_parse_body :: proc(reader: ^Reader, header: Header) -> (json.Value, boo
}
-handle_request :: proc(request: json.Value, config: ^Config, writer: ^Writer) -> bool {
+handle_request :: proc(request: json.Value, config: ^common.Config, writer: ^Writer) -> bool {
root, ok := request.value.(json.Object);
@@ -156,7 +158,7 @@ handle_request :: proc(request: json.Value, config: ^Config, writer: ^Writer) ->
method := root["method"].value.(json.String);
- call_map : map [string] proc(json.Value, RequestId, ^Config, ^Writer) -> Error =
+ call_map : map [string] proc(json.Value, RequestId, ^common.Config, ^Writer) -> common.Error =
{"initialize" = request_initialize,
"initialized" = request_initialized,
"shutdown" = request_shutdown,
@@ -167,7 +169,7 @@ handle_request :: proc(request: json.Value, config: ^Config, writer: ^Writer) ->
"textDocument/didSave" = notification_did_save,
"textDocument/definition" = request_definition };
- fn: proc(json.Value, RequestId, ^Config, ^Writer) -> Error;
+ fn: proc(json.Value, RequestId, ^common.Config, ^Writer) -> common.Error;
fn, ok = call_map[method];
@@ -197,7 +199,7 @@ handle_request :: proc(request: json.Value, config: ^Config, writer: ^Writer) ->
return true;
}
-request_initialize :: proc(params: json.Value, id: RequestId, config: ^Config, writer: ^Writer) -> Error {
+request_initialize :: proc(params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
params_object, ok := params.value.(json.Object);
@@ -211,7 +213,7 @@ request_initialize :: proc(params: json.Value, id: RequestId, config: ^Config, w
return .ParseError;
}
- config.workspace_folders = make([dynamic]WorkspaceFolder);
+ config.workspace_folders = make([dynamic]common.WorkspaceFolder);
for s in initialize_params.workspaceFolders {
append_elem(&config.workspace_folders, s);
@@ -238,11 +240,11 @@ request_initialize :: proc(params: json.Value, id: RequestId, config: ^Config, w
return .None;
}
-request_initialized :: proc(params: json.Value, id: RequestId, config: ^Config, writer: ^Writer) -> Error {
+request_initialized :: proc(params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
return .None;
}
-request_shutdown :: proc(params: json.Value, id: RequestId, config: ^Config, writer: ^Writer) -> Error {
+request_shutdown :: proc(params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
response := make_response_message(
params = nil,
@@ -254,7 +256,7 @@ request_shutdown :: proc(params: json.Value, id: RequestId, config: ^Config, wri
return .None;
}
-request_definition :: proc(params: json.Value, id: RequestId, config: ^Config, writer: ^Writer) -> Error {
+request_definition :: proc(params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
params_object, ok := params.value.(json.Object);
@@ -293,12 +295,12 @@ request_definition :: proc(params: json.Value, id: RequestId, config: ^Config, w
return .None;
}
-notification_exit :: proc(params: json.Value, id: RequestId, config: ^Config, writer: ^Writer) -> Error {
- running = false;
+notification_exit :: proc(params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
+ config.running = false;
return .None;
}
-notification_did_open :: proc(params: json.Value, id: RequestId, config: ^Config, writer: ^Writer) -> Error {
+notification_did_open :: proc(params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
params_object, ok := params.value.(json.Object);
@@ -317,7 +319,7 @@ notification_did_open :: proc(params: json.Value, id: RequestId, config: ^Config
return document_open(open_params.textDocument.uri, open_params.textDocument.text, config, writer);
}
-notification_did_change :: proc(params: json.Value, id: RequestId, config: ^Config, writer: ^Writer) -> Error {
+notification_did_change :: proc(params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
params_object, ok := params.value.(json.Object);
@@ -336,7 +338,7 @@ notification_did_change :: proc(params: json.Value, id: RequestId, config: ^Conf
return .None;
}
-notification_did_close :: proc(params: json.Value, id: RequestId, config: ^Config, writer: ^Writer) -> Error {
+notification_did_close :: proc(params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
params_object, ok := params.value.(json.Object);
@@ -353,7 +355,7 @@ notification_did_close :: proc(params: json.Value, id: RequestId, config: ^Confi
return document_close(close_params.textDocument.uri);
}
-notification_did_save :: proc(params: json.Value, id: RequestId, config: ^Config, writer: ^Writer) -> Error {
+notification_did_save :: proc(params: json.Value, id: RequestId, config: ^common.Config, writer: ^Writer) -> common.Error {
diff --git a/src/response.odin b/src/server/response.odin
index b9249f4..bd7a77e 100644
--- a/src/response.odin
+++ b/src/server/response.odin
@@ -1,4 +1,4 @@
-package main
+package server
import "core:fmt"
diff --git a/src/types.odin b/src/server/types.odin
index f8964e5..262f464 100644
--- a/src/types.odin
+++ b/src/server/types.odin
@@ -1,7 +1,9 @@
-package main
+package server
import "core:encoding/json"
+import "shared:common"
+
/*
General types
*/
@@ -16,7 +18,7 @@ RequestId :: union {
ResponseParams :: union {
ResponseInitializeParams,
rawptr,
- Location,
+ common.Location,
};
ResponseMessage :: struct {
@@ -31,27 +33,8 @@ ResponseMessageError :: struct {
error: ResponseError,
};
-Error :: enum {
- None = 0,
-
- // Defined by JSON RPC
- ParseError = -32700,
- InvalidRequest = -32600,
- MethodNotFound = -32601,
- InvalidParams = -32602,
- InternalError = -32603,
- serverErrorStart = -32099,
- serverErrorEnd = -32000,
- ServerNotInitialized = -32002,
- UnknownErrorCode = -32001,
-
- // Defined by the protocol.
- RequestCancelled = -32800,
- ContentModified = -32801,
-};
-
ResponseError :: struct {
- code: Error,
+ code: common.Error,
message: string,
};
@@ -76,18 +59,13 @@ Notification :: struct {
params: NotificationParams
};
-WorkspaceFolder :: struct {
- name: string,
- uri: string,
-};
-
ResponseInitializeParams :: struct {
capabilities: ServerCapabilities,
};
RequestInitializeParams :: struct {
trace: string,
- workspaceFolders: [dynamic] WorkspaceFolder,
+ workspaceFolders: [dynamic] common.WorkspaceFolder,
capabilities: ClientCapabilities,
};
@@ -120,23 +98,8 @@ ClientCapabilities :: struct {
textDocument: TextDocumentClientCapabilities,
};
-Position :: struct {
- line: int,
- character: int,
-};
-
-Range :: struct {
- start: Position,
- end: Position,
-};
-
-Location :: struct {
- uri: string,
- range: Range,
-};
-
TextDocumentContentChangeEvent :: struct {
- range: Range,
+ range: common.Range,
text: string,
};
@@ -166,7 +129,7 @@ DiagnosticSeverity :: enum {
};
Diagnostic :: struct {
- range: Range,
+ range: common.Range,
severity: DiagnosticSeverity,
code: string,
message: string,
@@ -187,5 +150,5 @@ DidCloseTextDocumentParams :: struct {
TextDocumentPositionParams :: struct {
textDocument: TextDocumentIdentifier,
- position: Position,
+ position: common.Position,
}; \ No newline at end of file
diff --git a/src/unmarshal.odin b/src/server/unmarshal.odin
index 297bd89..e5ca619 100644
--- a/src/unmarshal.odin
+++ b/src/server/unmarshal.odin
@@ -1,4 +1,4 @@
-package main
+package server
import "core:encoding/json"
import "core:strings"
diff --git a/src/server/workspace.odin b/src/server/workspace.odin
new file mode 100644
index 0000000..abb4e43
--- /dev/null
+++ b/src/server/workspace.odin
@@ -0,0 +1 @@
+package server
diff --git a/src/writer.odin b/src/server/writer.odin
index ccb1762..3c82451 100644
--- a/src/writer.odin
+++ b/src/server/writer.odin
@@ -1,4 +1,4 @@
-package main
+package server
import "core:os"
import "core:mem"
diff --git a/src/workspace.odin b/src/workspace.odin
deleted file mode 100644
index 8b13789..0000000
--- a/src/workspace.odin
+++ /dev/null
@@ -1 +0,0 @@
-
diff --git a/tests/tests.odin b/tests/tests.odin
index 619fae4..ef7e4a5 100644
--- a/tests/tests.odin
+++ b/tests/tests.odin
@@ -6,7 +6,9 @@ import "core:fmt"
import "core:os"
import "core:strings"
+
import src "../src"
+import "shared:server"
/*
@@ -346,8 +348,8 @@ test_init_check_shutdown :: proc() -> bool {
data = transmute([]byte) strings.join({make_request(initialize_request), make_request(shutdown_request), make_request(exit_notification)}, "", context.allocator),
};
- reader := src.make_reader(test_read, &buffer);
- writer := src.make_writer(src.os_write, cast(rawptr)os.stdout);
+ reader := server.make_reader(test_read, &buffer);
+ writer := server.make_writer(src.os_write, cast(rawptr)os.stdout);
src.run(&reader, &writer);
@@ -447,10 +449,10 @@ test_open_and_change_notification :: proc() -> bool {
};
- reader := src.make_reader(test_read, &buffer);
- writer := src.make_writer(src.os_write, cast(rawptr)os.stdout);
+ reader := server.make_reader(test_read, &buffer);
+ writer := server.make_writer(src.os_write, cast(rawptr)os.stdout);
- context.logger = src.create_lsp_logger(&writer);
+ context.logger = server.create_lsp_logger(&writer);
src.run(&reader, &writer);
@@ -502,10 +504,10 @@ test_definition_request :: proc() -> bool {
};
- reader := src.make_reader(test_read, &buffer);
- writer := src.make_writer(src.os_write, cast(rawptr)os.stdout);
+ reader := server.make_reader(test_read, &buffer);
+ writer := server.make_writer(src.os_write, cast(rawptr)os.stdout);
- context.logger = src.create_lsp_logger(&writer);
+ context.logger = server.create_lsp_logger(&writer);
src.run(&reader, &writer);