diff options
| author | DanielGavin <danielgavin5@hotmail.com> | 2020-11-13 10:24:01 +0100 |
|---|---|---|
| committer | DanielGavin <danielgavin5@hotmail.com> | 2020-11-13 10:24:01 +0100 |
| commit | 79fdfe53119ac01cb1a1d06609c79aabcac7b946 (patch) | |
| tree | 5209df3c8197285396f249896d7a2cbb341e1524 /src/server | |
| parent | 1c7fed2a7dd524a24b54a60a0aefe5b7093a9310 (diff) | |
start working on handling fields in indexed structs
Diffstat (limited to 'src/server')
| -rw-r--r-- | src/server/analysis.odin | 152 | ||||
| -rw-r--r-- | src/server/documents.odin | 105 | ||||
| -rw-r--r-- | src/server/requests.odin | 24 |
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; } |