aboutsummaryrefslogtreecommitdiff
path: root/src/server
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2020-11-13 10:24:01 +0100
committerDanielGavin <danielgavin5@hotmail.com>2020-11-13 10:24:01 +0100
commit79fdfe53119ac01cb1a1d06609c79aabcac7b946 (patch)
tree5209df3c8197285396f249896d7a2cbb341e1524 /src/server
parent1c7fed2a7dd524a24b54a60a0aefe5b7093a9310 (diff)
start working on handling fields in indexed structs
Diffstat (limited to 'src/server')
-rw-r--r--src/server/analysis.odin152
-rw-r--r--src/server/documents.odin105
-rw-r--r--src/server/requests.odin24
3 files changed, 129 insertions, 152 deletions
diff --git a/src/server/analysis.odin b/src/server/analysis.odin
index 8994812..1bef7f4 100644
--- a/src/server/analysis.odin
+++ b/src/server/analysis.odin
@@ -35,14 +35,17 @@ AstContext :: struct {
globals: map [string] ^ast.Expr,
file: ast.File,
allocator: mem.Allocator,
+ imports: [] Package,
+ foreign_package: bool,
};
-make_ast_context :: proc(file: ast.File, allocator := context.temp_allocator) -> AstContext {
+make_ast_context :: proc(file: ast.File, imports: [] Package, allocator := context.temp_allocator) -> AstContext {
ast_context := AstContext {
locals = make(map [string] ^ast.Expr, 0, allocator),
globals = make(map [string] ^ast.Expr, 0, allocator),
file = file,
+ imports = imports,
};
return ast_context;
@@ -60,7 +63,7 @@ resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr, expec
case Ident:
return resolve_type_identifier(ast_context, v, expect_identifier);
case Call_Expr:
- return resolve_type_identifier(ast_context, v.expr.derived.(Ident));
+ return resolve_type_expression(ast_context, v.expr);
case Selector_Expr:
if selector, ok := resolve_type_expression(ast_context, v.expr); ok {
@@ -72,6 +75,17 @@ resolve_type_expression :: proc(ast_context: ^AstContext, node: ^ast.Expr, expec
return resolve_type_expression(ast_context, s.types[i], false);
}
}
+ case index.SymbolPackageValue:
+ //TODO(Daniel, when we go into a package we are no longer in our project and cannot look at globals and locals)
+ if v.field != nil {
+ //ast_context.foreign_package = true;
+ return index.lookup(v.field.name, selector.scope);
+ }
+
+ else {
+ return index.Symbol {}, false;
+ }
+
}
}
@@ -93,7 +107,9 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident, expec
using ast;
- if local, ok := ast_context.locals[node.name]; ok {
+ log.info(node.name);
+
+ if local, ok := ast_context.locals[node.name]; !ast_context.foreign_package && ok {
switch v in local.derived {
case Ident:
@@ -102,13 +118,25 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident, expec
return make_symbol_struct_from_ast(ast_context, v), !expect_identifier;
case Proc_Lit:
return make_symbol_procedure_from_ast(ast_context, v, node.name), !expect_identifier;
- case:
+ case Selector_Expr:
+
+ if ident, ok := v.expr.derived.(Ident); ok {
+
+ if selector, ok := resolve_type_identifier(ast_context, ident); ok {
+
+ if value, ok := selector.value.(index.SymbolPackageValue); ok {
+ return index.lookup(v.field.name, selector.scope);
+ }
+
+ }
+
+ }
+
return index.Symbol {}, false;
}
-
}
- else if global, ok := ast_context.globals[node.name]; ok {
+ else if global, ok := ast_context.globals[node.name]; !ast_context.foreign_package && ok {
switch v in global.derived {
case Ident:
@@ -117,7 +145,19 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident, expec
return make_symbol_struct_from_ast(ast_context, v), !expect_identifier;
case Proc_Lit:
return make_symbol_procedure_from_ast(ast_context, v, node.name), !expect_identifier;
- case:
+ case Selector_Expr:
+ if ident, ok := v.expr.derived.(Ident); ok {
+
+ if selector, ok := resolve_type_identifier(ast_context, ident); ok {
+
+ if value, ok := selector.value.(index.SymbolPackageValue); ok {
+ return index.lookup(v.field.name, selector.scope);
+ }
+
+ }
+
+ }
+
return index.Symbol {}, false;
}
@@ -130,20 +170,34 @@ resolve_type_identifier :: proc(ast_context: ^AstContext, node: ast.Ident, expec
type = .Keyword,
};
- return symbol, !expect_identifier;
+ return symbol, true;
}
//imports - probably have this higher to check imports befure everything else
else {
- for imp in ast_context.file.imports {
+ for imp in ast_context.imports {
+
+ if strings.compare(imp.base, node.name) == 0 {
- log.info(imp);
+ symbol := index.Symbol {
+ type = .Package,
+ scope = imp.name,
+ value = index.SymbolPackageValue {
+ }
+ };
+
+ return symbol, true;
+ }
}
- //TODO(daniel, index can be used on identifiers if using is in the function scope)
+ //last option is to check the index
+
+
+
+ //TODO(daniel, index can be used on identifiers if using is in the function scope)
}
return index.Symbol {}, false;
@@ -207,16 +261,6 @@ make_symbol_struct_from_ast :: proc(ast_context: ^AstContext, v: ast.Struct_Type
return symbol;
}
-make_symbol_package_from_ast :: proc(ast_context: ^AstContext, v: ast.Import_Decl) -> index.Symbol {
-
- symbol := index.Symbol {
- range = common.get_token_range(v, ast_context.file.src),
- type = .Struct,
- };
-
- return symbol;
-}
-
get_globals :: proc(file: ast.File, ast_context: ^AstContext) {
for decl in file.decls {
@@ -285,7 +329,7 @@ get_definition_location :: proc(document: ^Document, position: common.Position)
location: common.Location;
- ast_context := make_ast_context(document.ast);
+ ast_context := make_ast_context(document.ast, document.imports);
uri: string;
@@ -341,6 +385,15 @@ get_definition_location :: proc(document: ^Document, position: common.Position)
location.range = common.get_token_range(v.types[i]^, document.ast.src);
}
}
+ case index.SymbolPackageValue:
+ if symbol, ok := index.lookup(field, selector.scope); ok {
+ log.info(symbol);
+ location.range = symbol.range;
+ uri = symbol.uri;
+ }
+ else {
+ return location, false;
+ }
}
if !ok {
@@ -371,7 +424,7 @@ get_completion_list :: proc(document: ^Document, position: common.Position) -> (
list: CompletionList;
- ast_context := make_ast_context(document.ast);
+ ast_context := make_ast_context(document.ast, document.imports);
position_context, ok := get_document_position_context(document, position, .Completion);
@@ -395,16 +448,17 @@ get_completion_list :: proc(document: ^Document, position: common.Position) -> (
return list, true;
}
- /*
+
field: string;
- switch v in position_context.field.derived {
- case ast.Ident:
- field = v.name;
- case:
- return list, true;
+ if position_context.field != nil {
+
+ switch v in position_context.field.derived {
+ case ast.Ident:
+ field = v.name;
+ }
+
}
- */
switch v in selector.value {
case index.SymbolStructValue:
@@ -418,18 +472,32 @@ get_completion_list :: proc(document: ^Document, position: common.Position) -> (
else {
log.errorf("Failed to resolve field: %v", name);
+ return list, true;
}
}
list.isIncomplete = false;
- }
+ case index.SymbolPackageValue:
+
+ if field != "" {
+
+ if searched, ok := index.fuzzy_search(selector.name, {selector.scope}); ok {
+
+ for search in searched {
+ append(&symbols, search);
+ }
+
+ }
- //symbols, ok = index.fuzzy_search(field, {selector});
+ else {
+ return list, true;
+ }
- //if !ok {
- // return list, false;
- //}
+ }
+
+ list.isIncomplete = true;
+ }
}
@@ -453,7 +521,7 @@ get_signature_information :: proc(document: ^Document, position: common.Position
signature_help: SignatureHelp;
- ast_context := make_ast_context(document.ast);
+ ast_context := make_ast_context(document.ast, document.imports);
position_context, ok := get_document_position_context(document, position, .SignatureHelp);
@@ -474,17 +542,13 @@ get_signature_information :: proc(document: ^Document, position: common.Position
call: index.Symbol;
call, ok = resolve_type_expression(&ast_context, position_context.call);
- //log.info(call);
-
- signature_help.signatures = [] SignatureInformation {
+ log.info(call);
- SignatureInformation {
- label = strings.concatenate({call.name, call.signature}, context.temp_allocator),
- },
-
- };
+ signature_information := make([] SignatureInformation, 1, context.temp_allocator);
+ signature_information[0].label = strings.concatenate({call.name, call.signature}, context.temp_allocator);
+ signature_help.signatures = signature_information;
return signature_help, true;
}
diff --git a/src/server/documents.odin b/src/server/documents.odin
index 7759616..a626ec3 100644
--- a/src/server/documents.odin
+++ b/src/server/documents.odin
@@ -21,7 +21,8 @@ ParserError :: struct {
Package :: struct {
- documents: [dynamic]^Document,
+ name: string, //the entire absolute path to the directory
+ base: string,
};
Document :: struct {
@@ -31,13 +32,11 @@ Document :: struct {
client_owned: bool,
diagnosed_errors: bool,
ast: ast.File,
- package_name: string,
- imports: [] string,
+ imports: [] Package,
};
DocumentStorage :: struct {
documents: map [string] Document,
- packages: map [string] Package,
};
document_storage: DocumentStorage;
@@ -59,32 +58,6 @@ document_get :: proc(uri_string: string) -> ^Document {
You usually always need the documents that are loaded in core files, your own files, etc.)
*/
-/*
- Server opens a new document with text from filesystem
-*/
-document_new :: proc(path: string, config: ^common.Config) -> common.Error {
-
- text, ok := os.read_entire_file(path);
-
- uri := common.create_uri(path);
-
- if !ok {
- log.error("Failed to parse uri");
- return .ParseError;
- }
-
- document := Document {
- uri = uri,
- text = transmute([] u8)text,
- client_owned = false,
- used_text = len(text),
- };
-
-
- document_storage.documents[path] = document;
-
- return .None;
-}
/*
Client opens a document with transferred text
@@ -108,14 +81,6 @@ document_open :: proc(uri_string: string, text: string, config: ^common.Config,
return .InvalidRequest;
}
- if document.text != nil {
- delete(document.text);
- }
-
- if len(document.uri.uri) > 0 {
- common.delete_uri(document.uri);
- }
-
document.uri = uri;
document.client_owned = true;
document.text = transmute([] u8)text;
@@ -255,9 +220,13 @@ document_close :: proc(uri_string: string) -> common.Error {
document.client_owned = false;
+ common.free_ast_file(document.ast);
+
+ common.delete_uri(document.uri);
+
delete(document.text);
- common.free_ast_file(document.ast);
+ document.used_text = 0;
return .None;
@@ -337,34 +306,6 @@ document_refresh :: proc(document: ^Document, config: ^common.Config, writer: ^W
return .None;
}
-document_load_package :: proc(package_directory: string, config: ^common.Config) -> common.Error {
-
- fd, err := os.open(package_directory);
-
- if err != 0 {
- return .ParseError;
- }
-
- files: []os.File_Info;
- files, err = os.read_dir(fd, 100, context.temp_allocator);
-
- for file in files {
-
- //if we have never encountered the document
- if _, ok := document_storage.documents[file.fullpath]; !ok {
-
- if doc_err := document_new(file.fullpath, config); doc_err != .None {
- return doc_err;
- }
-
- }
-
- }
-
- return .None;
-}
-
-
current_errors: [dynamic] ParserError;
parser_error_handler :: proc(pos: tokenizer.Pos, msg: string, args: ..any) {
@@ -395,31 +336,24 @@ parse_document :: proc(document: ^Document, config: ^common.Config) -> ([] Parse
parser.parse_file(&p, &document.ast);
- /*
- fmt.println();
- fmt.println();
-
- for decl in document.ast.decls {
- common.print_ast(decl, 0, document.ast.src);
- }
+ if document.imports != nil {
- fmt.println();
- fmt.println();
- */
+ for p in document.imports {
+ delete(p.name);
+ }
- /*
- 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;
+
+ document.imports = make([]Package, len(document.ast.imports));
for imp, index in document.ast.imports {
//collection specified
if i := strings.index(imp.fullpath, ":"); i != -1 {
+ //Note(Daniel, assuming absolute path atm, but that will change)
+
collection := imp.fullpath[1:i];
p := imp.fullpath[i+1:len(imp.fullpath)-1];
@@ -429,7 +363,8 @@ parse_document :: proc(document: ^Document, config: ^common.Config) -> ([] Parse
continue;
}
- document.imports[index] = path.join(dir, p);
+ document.imports[index].name = path.join(dir, p);
+ document.imports[index].base = path.base(document.imports[index].name, false);
}
@@ -437,8 +372,10 @@ parse_document :: proc(document: ^Document, config: ^common.Config) -> ([] Parse
else {
}
+
}
- */
+
+ //fmt.println(document.imports);
return current_errors[:], true;
}
diff --git a/src/server/requests.odin b/src/server/requests.odin
index b5391e1..e5cf22b 100644
--- a/src/server/requests.odin
+++ b/src/server/requests.odin
@@ -373,28 +373,6 @@ request_signature_help :: proc(params: json.Value, id: RequestId, config: ^commo
return .InternalError;
}
- /*
- parameters := [] ParameterInformation {
- {
- label = {0, 4},
- },
- };
-
-
- signatures := [] SignatureInformation {
- {
- label = "test",
- parameters = parameters,
- },
- };
-
- help := SignatureHelp {
- activeSignature = 0,
- activeParameter = 0,
- signatures = signatures,
- };
- */
-
help: SignatureHelp;
help, ok = get_signature_information(document, signature_params.position);
@@ -405,8 +383,6 @@ request_signature_help :: proc(params: json.Value, id: RequestId, config: ^commo
send_response(response, writer);
- //log.info(help);
-
return .None;
}