diff options
| author | DanielGavin <danielgavin5@hotmail.com> | 2024-09-22 11:23:40 +0200 |
|---|---|---|
| committer | DanielGavin <danielgavin5@hotmail.com> | 2024-09-22 11:23:40 +0200 |
| commit | 23bd4b328139a2d8197316867dc29c8ca2368136 (patch) | |
| tree | dbfa17a349890df8ef26dfd1046f58a3916f019b /src | |
| parent | 0d1d4d86f2f210c071e6a5f26cca65d5763f2c84 (diff) | |
| parent | e23ddd2c6ce457b40d6bf73a8f9c4005a9eee857 (diff) | |
Merge branch 'master' of https://github.com/DanielGavin/ols
Diffstat (limited to 'src')
| -rw-r--r-- | src/common/ast.odin | 192 | ||||
| -rw-r--r-- | src/odin/printer/printer.odin | 11 | ||||
| -rw-r--r-- | src/odin/printer/visit.odin | 15 | ||||
| -rw-r--r-- | src/server/collector.odin | 4 |
4 files changed, 108 insertions, 114 deletions
diff --git a/src/common/ast.odin b/src/common/ast.odin index dbc5647..3fde304 100644 --- a/src/common/ast.odin +++ b/src/common/ast.odin @@ -4,6 +4,7 @@ import "core:fmt" import "core:log" import "core:mem" import "core:odin/ast" +import "core:odin/parser" import path "core:path/slashpath" import "core:strings" @@ -69,16 +70,15 @@ keyword_map: map[string]bool = { } GlobalExpr :: struct { - name: string, - name_expr: ^ast.Expr, - expr: ^ast.Expr, - mutable: bool, - docs: ^ast.Comment_Group, - attributes: []^ast.Attribute, - deprecated: bool, - file_private: bool, - package_private: bool, - builtin: bool, + name: string, + name_expr: ^ast.Expr, + expr: ^ast.Expr, + mutable: bool, + docs: ^ast.Comment_Group, + attributes: []^ast.Attribute, + deprecated: bool, + private: parser.Private_Flag, + builtin: bool, } get_attribute_objc_type :: proc(attributes: []^ast.Attribute) -> ^ast.Expr { @@ -240,116 +240,92 @@ is_expr_basic_lit :: proc(expr: ^ast.Expr) -> bool { return ok } -collect_value_decl :: proc(exprs: ^[dynamic]GlobalExpr, file: ast.File, stmt: ^ast.Node, skip_private: bool) { - if value_decl, ok := stmt.derived.(^ast.Value_Decl); ok { - is_deprecated := false - is_private_file := false - is_private_pkg := false - is_builtin := false - - for attribute in value_decl.attributes { - for elem in attribute.elems { - if value, ok := elem.derived.(^ast.Field_Value); ok { - if ident, ok := value.field.derived.(^ast.Ident); ok { - switch ident.name { - case "private": - if val, ok := value.value.derived.(^ast.Basic_Lit); ok { - switch val.tok.text { - case "\"file\"": - is_private_file = true - case "package": - is_private_pkg = true - } - } else { - is_private_pkg = true - } - } - } - } else if ident, ok := elem.derived.(^ast.Ident); ok { - switch ident.name { - case "deprecated": - is_deprecated = true - case "builtin": - is_builtin = true - case "private": - is_private_pkg = true - } - } - } - } +collect_value_decl :: proc( + exprs: ^[dynamic]GlobalExpr, + file: ast.File, + file_tags: parser.File_Tags, + stmt: ^ast.Node, + skip_private: bool, +) { + value_decl, is_value_decl := stmt.derived.(^ast.Value_Decl) - if is_private_file && skip_private { - return - } + if !is_value_decl { + return + } - // If a private status is not explicitly set with an attribute above the declaration - // check the file comment. - if !is_private_file && !is_private_pkg && file.docs != nil { - for comment in file.docs.list { - txt := comment.text - if strings.has_prefix(txt, "//+private") { - txt = strings.trim_prefix(txt, "//+private") - is_private_pkg = true - - if strings.has_prefix(txt, " ") { - txt = strings.trim_space(txt) - if txt == "file" { - is_private_file = true - } + global_expr := GlobalExpr{ + mutable = value_decl.is_mutable, + docs = value_decl.docs, + attributes = value_decl.attributes[:], + private = file_tags.private, + } + + for attribute in value_decl.attributes { + for elem in attribute.elems { + ident: ^ast.Ident + value: ast.Any_Node + + #partial switch v in elem.derived { + case ^ast.Field_Value: + ident = v.field.derived.(^ast.Ident) or_continue + value = v.value.derived + case ^ast.Ident: + ident = v + case: + continue + } + + switch ident.name { + case "deprecated": + global_expr.deprecated = true + case "builtin": + global_expr.builtin = true + case "private": + if val, ok := value.(^ast.Basic_Lit); ok { + switch val.tok.text { + case "\"file\"": + global_expr.private = .File + case "\"package\"": + global_expr.private = .Package } - } else if strings.has_prefix(txt, "//+build ignore") { - is_private_pkg = true - is_private_file = true + } else { + global_expr.private = .Package } } } + } - for name, i in value_decl.names { - str := get_ast_node_string(name, file.src) - - if value_decl.type != nil { - append( - exprs, - GlobalExpr { - name = str, - name_expr = name, - expr = value_decl.type, - mutable = value_decl.is_mutable, - docs = value_decl.docs, - attributes = value_decl.attributes[:], - deprecated = is_deprecated, - builtin = is_builtin, - package_private = is_private_pkg, - }, - ) - } else { - if len(value_decl.values) > i { - append( - exprs, - GlobalExpr { - name = str, - name_expr = name, - expr = value_decl.values[i], - mutable = value_decl.is_mutable, - docs = value_decl.docs, - attributes = value_decl.attributes[:], - deprecated = is_deprecated, - builtin = is_builtin, - package_private = is_private_pkg, - }, - ) - } - } + if file_tags.ignore { + global_expr.private = .File + } + + if skip_private && global_expr.private == .File { + return + } + + for name, i in value_decl.names { + global_expr.name = get_ast_node_string(name, file.src) + global_expr.name_expr = name + + if value_decl.type != nil { + global_expr.expr = value_decl.type + append(exprs, global_expr) + } else if len(value_decl.values) > i { + global_expr.expr = value_decl.values[i] + append(exprs, global_expr) } } } collect_globals :: proc(file: ast.File, skip_private := false) -> []GlobalExpr { exprs := make([dynamic]GlobalExpr, context.temp_allocator) + defer shrink(&exprs) + + file_tags := parser.parse_file_tags(file, context.temp_allocator) for decl in file.decls { if value_decl, ok := decl.derived.(^ast.Value_Decl); ok { - collect_value_decl(&exprs, file, decl, skip_private) + collect_value_decl(&exprs, file, file_tags, decl, skip_private) } else if when_decl, ok := decl.derived.(^ast.When_Stmt); ok { if when_decl.cond == nil { continue @@ -395,13 +371,13 @@ collect_globals :: proc(file: ast.File, skip_private := false) -> []GlobalExpr { if allowed { if block, ok := when_decl.body.derived.(^ast.Block_Stmt); ok { for stmt in block.stmts { - collect_value_decl(&exprs, file, stmt, skip_private) + collect_value_decl(&exprs, file, file_tags, stmt, skip_private) } } } else if ident.name != "ODIN_OS" && ident.name != "ODIN_ARCH" { if block, ok := when_decl.body.derived.(^ast.Block_Stmt); ok { for stmt in block.stmts { - collect_value_decl(&exprs, file, stmt, skip_private) + collect_value_decl(&exprs, file, file_tags, stmt, skip_private) } } } @@ -409,7 +385,7 @@ collect_globals :: proc(file: ast.File, skip_private := false) -> []GlobalExpr { } else { if block, ok := when_decl.body.derived.(^ast.Block_Stmt); ok { for stmt in block.stmts { - collect_value_decl(&exprs, file, stmt, skip_private) + collect_value_decl(&exprs, file, file_tags, stmt, skip_private) } } } @@ -420,7 +396,7 @@ collect_globals :: proc(file: ast.File, skip_private := false) -> []GlobalExpr { if block, ok := foreign_decl.body.derived.(^ast.Block_Stmt); ok { for stmt in block.stmts { - collect_value_decl(&exprs, file, stmt, skip_private) + collect_value_decl(&exprs, file, file_tags, stmt, skip_private) } } } diff --git a/src/odin/printer/printer.odin b/src/odin/printer/printer.odin index d3b3db6..559a4e3 100644 --- a/src/odin/printer/printer.odin +++ b/src/odin/printer/printer.odin @@ -252,6 +252,11 @@ print_file :: proc(p: ^Printer, file: ^ast.File) -> string { } } + // If the file ends with imports. + if import_group_start != nil { + print_sorted_imports(p, file.decls[import_group_start.?:]) + } + if len(p.comments) > 0 { infinite := p.comments[len(p.comments) - 1].end infinite.offset = 9999999 @@ -283,6 +288,12 @@ print_sorted_imports :: proc(p: ^Printer, decls: []^ast.Stmt) { decl.pos.line = start_line + i decl.end.line = start_line + i + imp := decl.derived.(^ast.Import_Decl) + for attr in imp.attributes { + attr.pos.line = start_line + i + attr.end.line = start_line + i + } + p.document = cons(p.document, visit_decl(p, cast(^ast.Decl)decl)) } } diff --git a/src/odin/printer/visit.odin b/src/odin/printer/visit.odin index 02e2867..869a4ac 100644 --- a/src/odin/printer/visit.odin +++ b/src/odin/printer/visit.odin @@ -265,12 +265,13 @@ visit_decl :: proc(p: ^Printer, decl: ^ast.Decl, called_in_stmt := false) -> ^Do return document case ^Import_Decl: - document := move_line(p, decl.pos) - + document := empty() if len(v.attributes) > 0 { document = cons(document, visit_attributes(p, &v.attributes, v.pos)) } + document = cons(document, move_line(p, decl.pos)) + if v.name.text != "" { document = cons( document, @@ -820,8 +821,8 @@ visit_attributes :: proc(p: ^Printer, attributes: ^[dynamic]^ast.Attribute, pos: //Ensure static is not forced newline, but until if the width is full if len(attributes) == 1 && len(attributes[0].elems) == 1 { - if ident, ok := attributes[0].elems[0].derived.(^ast.Ident); ok && ident.name == "static" { - document = cons(document, text("@"), text("("), visit_expr(p, attributes[0].elems[0]), text(")")) + if ident, ok := attributes[0].elems[0].derived.(^ast.Ident); ok && (ident.name == "static" || ident.name == "require") { + document = cons(document, text("@"), text("("), visit_expr(p, attributes[0].elems[0]), text(")"), break_with_no_newline()) set_source_position(p, pos) return document } @@ -848,6 +849,12 @@ visit_state_flags :: proc(p: ^Printer, flags: ast.Node_State_Flags) -> ^Document if .Bounds_Check in flags { return cons(text("#bounds_check"), break_with_no_newline()) } + if .No_Type_Assert in flags { + return cons(text("#no_type_assert"), break_with_no_newline()) + } + if .Type_Assert in flags { + return cons(text("#type_assert"), break_with_no_newline()) + } return empty() } diff --git a/src/server/collector.odin b/src/server/collector.odin index 26e4809..a9df6a6 100644 --- a/src/server/collector.odin +++ b/src/server/collector.odin @@ -644,11 +644,11 @@ collect_symbols :: proc(collection: ^SymbolCollection, file: ast.File, uri: stri symbol.flags |= {.Deprecated} } - if expr.file_private { + if expr.private == .File { symbol.flags |= {.PrivateFile} } - if expr.package_private { + if expr.private == .Package { symbol.flags |= {.PrivatePackage} } |