aboutsummaryrefslogtreecommitdiff
path: root/src/common
diff options
context:
space:
mode:
authorDamian Tarnawski <gthetarnav@gmail.com>2024-08-30 14:20:45 +0200
committerDamian Tarnawski <gthetarnav@gmail.com>2024-08-30 14:20:45 +0200
commitc69f4208fd916cf5d81d2d6f48612030a1c459aa (patch)
tree75e1f7e9424619d5a56e22eee4d057c1c12be136 /src/common
parentbd60025df3b54c22a8bcb5745b98a30f88162ddd (diff)
Use a new file tag parser
Diffstat (limited to 'src/common')
-rw-r--r--src/common/ast.odin192
1 files changed, 84 insertions, 108 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)
}
}
}