aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDanielGavin <danielgavin5@hotmail.com>2024-09-22 11:23:40 +0200
committerDanielGavin <danielgavin5@hotmail.com>2024-09-22 11:23:40 +0200
commit23bd4b328139a2d8197316867dc29c8ca2368136 (patch)
treedbfa17a349890df8ef26dfd1046f58a3916f019b /src
parent0d1d4d86f2f210c071e6a5f26cca65d5763f2c84 (diff)
parente23ddd2c6ce457b40d6bf73a8f9c4005a9eee857 (diff)
Merge branch 'master' of https://github.com/DanielGavin/ols
Diffstat (limited to 'src')
-rw-r--r--src/common/ast.odin192
-rw-r--r--src/odin/printer/printer.odin11
-rw-r--r--src/odin/printer/visit.odin15
-rw-r--r--src/server/collector.odin4
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}
}