aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDaniel Gavin <danielgavin5@hotmail.com>2022-02-15 17:35:22 +0100
committerDaniel Gavin <danielgavin5@hotmail.com>2022-02-15 17:35:22 +0100
commit63d0bd412a8817445d6dc18e79d5d54c94caf401 (patch)
tree90032a710b80fe211b0cc9bd46cbc27cd5dbf6ae /src
parentefe15efabd1b718f89c869ac9c1a6dbd680a8bc0 (diff)
parent1d4c3bd57e6d5c7f8472f3e0b825bb38739e5ecc (diff)
Merge branch 'master' into refractor-analysis
Diffstat (limited to 'src')
-rw-r--r--src/analysis/analysis.odin2
-rw-r--r--src/odin/printer/printer.odin4
-rw-r--r--src/odin/printer/visit.odin177
-rw-r--r--src/server/completion.odin1
-rw-r--r--src/server/semantic_tokens.odin2
-rw-r--r--src/server/types.odin4
6 files changed, 150 insertions, 40 deletions
diff --git a/src/analysis/analysis.odin b/src/analysis/analysis.odin
index 9ca6270..34e8ac1 100644
--- a/src/analysis/analysis.odin
+++ b/src/analysis/analysis.odin
@@ -292,6 +292,8 @@ resolve_type_comp_literal :: proc(ast_context: ^AstContext, position_context: ^D
if position_context.comp_lit == current_comp_lit {
return current_symbol, current_comp_lit, true;
+ } else if current_comp_lit == nil {
+ return {}, nil, false
}
if current_comp_lit == nil {
diff --git a/src/odin/printer/printer.odin b/src/odin/printer/printer.odin
index cedf3a2..88c1c41 100644
--- a/src/odin/printer/printer.odin
+++ b/src/odin/printer/printer.odin
@@ -153,8 +153,8 @@ print :: proc(p: ^Printer, file: ^ast.File) -> string {
build_disabled_lines_info(p)
- p.source_position.line = 1;
- p.source_position.column = 1;
+ p.source_position.line = 1
+ p.source_position.column = 1
p.document = move_line(p, file.pkg_token.pos);
p.document = cons(p.document, cons_with_nopl(text(file.pkg_token.text), text(file.pkg_name)))
diff --git a/src/odin/printer/visit.odin b/src/odin/printer/visit.odin
index 7e0eb91..84a6b9c 100644
--- a/src/odin/printer/visit.odin
+++ b/src/odin/printer/visit.odin
@@ -96,7 +96,7 @@ move_line_limit :: proc(p: ^Printer, pos: tokenizer.Pos, limit: int) -> (^Docume
}
@(private)
-visit_comment :: proc(p: ^Printer, comment: tokenizer.Token, end_newline := true) -> (int, ^Document) {
+visit_comment :: proc(p: ^Printer, comment: tokenizer.Token) -> (int, ^Document) {
document := empty()
if len(comment.text) == 0 {
return 0, document
@@ -139,7 +139,7 @@ visit_comment :: proc(p: ^Printer, comment: tokenizer.Token, end_newline := true
}
@(private)
-visit_comments :: proc(p: ^Printer, pos: tokenizer.Pos, end_newline := true) -> (^Document, int) {
+visit_comments :: proc(p: ^Printer, pos: tokenizer.Pos) -> (^Document, int) {
document := empty()
lines := 0
@@ -147,7 +147,7 @@ visit_comments :: proc(p: ^Printer, pos: tokenizer.Pos, end_newline := true) ->
comment_group := p.comments[p.latest_comment_index]
for comment, i in comment_group.list {
- newlined, tmp_document := visit_comment(p, comment, end_newline)
+ newlined, tmp_document := visit_comment(p, comment)
lines += newlined
document = cons(document, tmp_document)
}
@@ -338,6 +338,8 @@ visit_exprs :: proc(p: ^Printer, list: []^ast.Expr, options := List_Options{}, c
for expr, i in list {
+ p.source_position = expr.pos
+
if .Enforce_Newline in options {
document = cons(document, .Group in options ? group(visit_expr(p, expr, called_from, options)) : visit_expr(p, expr, called_from, options))
} else if .Glue in options {
@@ -351,8 +353,11 @@ visit_exprs :: proc(p: ^Printer, list: []^ast.Expr, options := List_Options{}, c
}
if (i != len(list) - 1 && .Enforce_Newline in options) {
- comment, ok := visit_comments(p, list[i+1].pos, false)
+ comment, ok := visit_comments(p, list[i+1].pos)
document = cons(document, cons(comment, newline(1)))
+ } else if .Enforce_Newline in options {
+ comment, ok := visit_comments(p, list[i].end)
+ document = cons(document, comment)
}
}
@@ -360,16 +365,24 @@ visit_exprs :: proc(p: ^Printer, list: []^ast.Expr, options := List_Options{}, c
}
@(private)
-visit_enum_exprs :: proc(p: ^Printer, list: []^ast.Expr, options := List_Options{}) -> ^Document {
- if len(list) == 0 {
+visit_enum_exprs :: proc(p: ^Printer, enum_type: ast.Enum_Type, options := List_Options{}) -> ^Document {
+ if len(enum_type.fields) == 0 {
return empty()
}
document := empty()
- for expr, i in list {
+ for expr, i in enum_type.fields {
+ if i == 0 && .Enforce_Newline in options {
+ comment, ok := visit_comments(p, enum_type.fields[i].pos)
+ if _, is_nil := comment.(Document_Nil); !is_nil {
+ comment = cons(comment, newline(1))
+ }
+ document = cons(comment, document)
+ }
+
if (.Enforce_Newline in options) {
- alignment := get_possible_enum_alignment(p, list)
+ alignment := get_possible_enum_alignment(p, enum_type.fields)
if value, ok := expr.derived.(ast.Field_Value); ok && alignment > 0 {
document = cons(document, cons_with_nopl(visit_expr(p, value.field), cons_with_nopl(cons(repeat_space(alignment - get_node_length(value.field)), text_position(p, "=", value.sep)), visit_expr(p, value.value))))
@@ -380,13 +393,16 @@ visit_enum_exprs :: proc(p: ^Printer, list: []^ast.Expr, options := List_Options
document = group(cons_with_opl(document, visit_expr(p, expr, .Generic, options)))
}
- if (i != len(list) - 1 || .Trailing in options) && .Add_Comma in options {
+ if (i != len(enum_type.fields) - 1 || .Trailing in options) && .Add_Comma in options {
document = cons(document, text(","))
}
- if (i != len(list) - 1 && .Enforce_Newline in options) {
- comment, ok := visit_comments(p, list[i+1].pos, false)
+ if (i != len(enum_type.fields) - 1 && .Enforce_Newline in options) {
+ comment, ok := visit_comments(p, enum_type.fields[i+1].pos)
document = cons(document, cons(comment, newline(1)))
+ } else if .Enforce_Newline in options {
+ comment, ok := visit_comments(p, enum_type.end)
+ document = cons(document, comment)
}
}
@@ -394,16 +410,69 @@ visit_enum_exprs :: proc(p: ^Printer, list: []^ast.Expr, options := List_Options
}
@(private)
-visit_comp_lit_exprs :: proc(p: ^Printer, list: []^ast.Expr, options := List_Options{}) -> ^Document {
- if len(list) == 0 {
+visit_union_exprs :: proc(p: ^Printer, union_type: ast.Union_Type, options := List_Options{}) -> ^Document {
+ if len(union_type.variants) == 0 {
return empty()
}
document := empty()
- for expr, i in list {
+ for expr, i in union_type.variants {
+ if i == 0 && .Enforce_Newline in options {
+ comment, ok := visit_comments(p, union_type.variants[i].pos)
+ if _, is_nil := comment.(Document_Nil); !is_nil {
+ comment = cons(comment, newline(1))
+ }
+ document = cons(comment, document)
+ }
+
+ if (.Enforce_Newline in options) {
+ alignment := get_possible_enum_alignment(p, union_type.variants)
+
+ if value, ok := expr.derived.(ast.Field_Value); ok && alignment > 0 {
+ document = cons(document, cons_with_nopl(visit_expr(p, value.field), cons_with_nopl(cons(repeat_space(alignment - get_node_length(value.field)), text_position(p, "=", value.sep)), visit_expr(p, value.value))))
+ } else {
+ document = group(cons(document, visit_expr(p, expr, .Generic, options)))
+ }
+ } else {
+ document = group(cons_with_opl(document, visit_expr(p, expr, .Generic, options)))
+ }
+
+ if (i != len(union_type.variants) - 1 || .Trailing in options) && .Add_Comma in options {
+ document = cons(document, text(","))
+ }
+
+ if (i != len(union_type.variants) - 1 && .Enforce_Newline in options) {
+ comment, ok := visit_comments(p, union_type.variants[i+1].pos)
+ document = cons(document, cons(comment, newline(1)))
+ } else if .Enforce_Newline in options {
+ comment, ok := visit_comments(p, union_type.end)
+ document = cons(document, comment)
+ }
+ }
+
+ return document
+}
+
+@(private)
+visit_comp_lit_exprs :: proc(p: ^Printer, comp_lit: ast.Comp_Lit, options := List_Options{}) -> ^Document {
+ if len(comp_lit.elems) == 0 {
+ return empty()
+ }
+
+ document := empty()
+
+ for expr, i in comp_lit.elems {
+ if i == 0 && .Enforce_Newline in options {
+ comment, ok := visit_comments(p, comp_lit.elems[i].pos)
+ if _, is_nil := comment.(Document_Nil); !is_nil {
+ comment = cons(comment, newline(1))
+ }
+ document = cons(comment, document)
+ }
+
if (.Enforce_Newline in options) {
- alignment := get_possible_comp_lit_alignment(p, list)
+ alignment := get_possible_comp_lit_alignment(p, comp_lit.elems)
if value, ok := expr.derived.(ast.Field_Value); ok && alignment > 0 {
document = cons(document, cons_with_nopl(visit_expr(p, value.field), cons_with_nopl(cons(repeat_space(alignment - get_node_length(value.field)), text_position(p, "=", value.sep)), visit_expr(p, value.value))))
} else {
@@ -413,13 +482,16 @@ visit_comp_lit_exprs :: proc(p: ^Printer, list: []^ast.Expr, options := List_Opt
document = group(cons_with_nopl(document, visit_expr(p, expr, .Generic, options)))
}
- if (i != len(list) - 1 || .Trailing in options) && .Add_Comma in options {
+ if (i != len(comp_lit.elems) - 1 || .Trailing in options) && .Add_Comma in options {
document = cons(document, text(","))
}
- if (i != len(list) - 1 && .Enforce_Newline in options) {
- comment, ok := visit_comments(p, list[i+1].pos, false)
+ if (i != len(comp_lit.elems) - 1 && .Enforce_Newline in options) {
+ comment, ok := visit_comments(p, comp_lit.elems[i+1].pos)
document = cons(document, cons(comment, newline(1)))
+ } else if .Enforce_Newline in options {
+ comment, ok := visit_comments(p, comp_lit.end)
+ document = cons(document, comment)
}
}
@@ -502,7 +574,7 @@ visit_stmt :: proc(p: ^Printer, stmt: ^ast.Stmt, block_type: Block_Type = .Gener
set_source_position(p, v.pos)
block := visit_block_stmts(p, v.stmts, len(v.stmts) > 1)
- comment_end, _ := visit_comments(p, tokenizer.Pos {line = v.end.line, offset = v.end.offset}, false)
+ comment_end, _ := visit_comments(p, tokenizer.Pos {line = v.end.line, offset = v.end.offset})
if block_type == .Switch_Stmt && !p.config.indent_cases {
document = cons(document, cons(block, comment_end))
@@ -783,6 +855,18 @@ should_align_comp_lit :: proc(p: ^Printer, comp_lit: ast.Comp_Lit) -> bool {
}
@(private)
+contains_comments_in_range :: proc(p: ^Printer, pos: tokenizer.Pos, end: tokenizer.Pos) -> bool {
+ for i := p.latest_comment_index; i < len(p.comments); i += 1 {
+ for c in p.comments[i].list {
+ if pos.offset <= c.pos.offset && c.pos.offset <= end.offset {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+@(private)
should_align_assignment_stmt :: proc(p: ^Printer, stmt: ast.Assign_Stmt) -> bool {
if len(stmt.rhs) == 0 {
return false
@@ -950,8 +1034,10 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
} else {
document = cons_with_opl(document, visit_begin_brace(p, v.pos, .Generic))
set_source_position(p, v.variants[0].pos)
- document = cons(document, nest(p.indentation_count, cons(newline_position(p, 1, v.variants[0].pos), visit_exprs(p, v.variants, {.Add_Comma, .Trailing, .Enforce_Newline}))))
- document = cons(document, visit_end_brace(p, v.end, 1))
+ document = cons(document, nest(p.indentation_count, cons(newline_position(p, 1, v.pos), visit_union_exprs(p, v, {.Add_Comma, .Trailing, .Enforce_Newline}))))
+ set_source_position(p, v.end)
+
+ document = cons(document, cons(newline(1), text_position(p, "}", v.end)))
}
return document
case Enum_Type:
@@ -967,8 +1053,10 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
} else {
document = cons(document, cons(break_with_space(), visit_begin_brace(p, v.pos, .Generic)))
set_source_position(p, v.fields[0].pos)
- document = cons(document, nest(p.indentation_count, cons(newline_position(p, 1, v.fields[0].pos), visit_enum_exprs(p, v.fields, {.Add_Comma, .Trailing, .Enforce_Newline}))))
- document = cons(document, visit_end_brace(p, v.end, 1))
+ document = cons(document, nest(p.indentation_count, cons(newline_position(p, 1, v.open), visit_enum_exprs(p, v, {.Add_Comma, .Trailing, .Enforce_Newline}))))
+ set_source_position(p, v.end)
+
+ document = cons(document, cons(newline(1), text_position(p, "}", v.end)))
}
set_source_position(p, v.end)
@@ -1001,16 +1089,16 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
document = cons(document, cons(break_with_space(), visit_begin_brace(p, v.pos, .Generic)))
set_source_position(p, v.fields.pos)
+ document = cons(document, nest(p.indentation_count, cons(newline_position(p, 1, v.fields.open), visit_field_list(p, v.fields, {.Add_Comma, .Trailing, .Enforce_Newline}))))
+ set_source_position(p, v.fields.end)
- document = cons(document, nest(p.indentation_count, cons(newline_position(p, 1, v.fields.pos), visit_field_list(p, v.fields, {.Add_Comma, .Trailing, .Enforce_Newline}))))
- document = cons(document, visit_end_brace(p, v.end, 1))
+ document = cons(document, cons(newline(1), text_position(p, "}", v.end)))
}
set_source_position(p, v.end)
return document
case Proc_Lit:
document := empty()
-
switch v.inlining {
case .None:
case .Inline:
@@ -1019,7 +1107,7 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
document = cons(document, text("#force_no_inline"))
}
- document = cons(document, visit_proc_type(p, v.type^))
+ document = cons_with_nopl(document, visit_proc_type(p, v.type^))
document = cons_with_nopl(document, push_where_clauses(p, v.where_clauses))
if v.body != nil {
@@ -1082,11 +1170,14 @@ visit_expr :: proc(p: ^Printer, expr: ^ast.Expr, called_from: Expr_Called_Type =
}
//If we call from the value declartion, we want it to be nicely newlined and aligned
- if should_align_comp_lit(p, v) && (called_from == .Value_Decl || called_from == .Assignment_Stmt) && len(v.elems) != 0 {
+ if (should_align_comp_lit(p, v) || contains_comments_in_range(p, v.pos, v.end)) && (called_from == .Value_Decl || called_from == .Assignment_Stmt) && len(v.elems) != 0 {
document = cons_with_opl(document, visit_begin_brace(p, v.pos, .Generic))
- set_source_position(p, v.elems[0].pos)
- document = cons(document, nest(p.indentation_count, cons(newline_position(p, 1, v.elems[0].pos), visit_comp_lit_exprs(p, v.elems, {.Add_Comma, .Trailing, .Enforce_Newline}))))
- document = cons(document, visit_end_brace(p, v.end, 1))
+
+ set_source_position(p, v.open)
+ document = cons(document, nest(p.indentation_count, cons(newline_position(p, 1, v.elems[0].pos), visit_comp_lit_exprs(p, v, {.Add_Comma, .Trailing, .Enforce_Newline}))))
+ set_source_position(p, v.end)
+
+ document = cons(document, cons(newline(1), text_position(p, "}", v.end)))
} else {
document = cons(document, text("{"))
document = cons(document, nest(p.indentation_count, cons(break_with(""), visit_exprs(p, v.elems, {.Add_Comma, .Group}))))
@@ -1198,6 +1289,10 @@ visit_block_stmts :: proc(p: ^Printer, stmts: []^ast.Stmt, split := false) -> ^D
document := empty()
for stmt, i in stmts {
+ last_index := max(0, i-1);
+ if stmts[last_index].end.line == stmt.pos.line && i != 0 {
+ document = cons(document, break_with(";"));
+ }
document = cons(document, group(visit_stmt(p, stmt, .Generic, false, true)))
}
@@ -1222,11 +1317,18 @@ visit_field_list :: proc(p: ^Printer, list: ^ast.Field_List, options := List_Opt
}
for field, i in list.list {
-
align := empty()
p.source_position = field.pos
+ if i == 0 && .Enforce_Newline in options {
+ comment, ok := visit_comments(p, list.list[i].pos)
+ if _, is_nil := comment.(Document_Nil); !is_nil {
+ comment = cons(comment, newline(1))
+ }
+ document = cons(comment, document)
+ }
+
if .Using in field.flags {
document = cons(document, cons(text("using"), break_with_no_newline()))
}
@@ -1273,9 +1375,12 @@ visit_field_list :: proc(p: ^Printer, list: ^ast.Field_List, options := List_Opt
}
if i != len(list.list) - 1 && .Enforce_Newline in options {
- comment, ok := visit_comments(p, list.list[i+1].pos, false)
+ comment, ok := visit_comments(p, list.list[i+1].pos)
document = cons(document, cons(comment, newline(1)))
- }
+ } else {
+ comment, ok := visit_comments(p, list.end)
+ document = cons(document, comment)
+ }
}
return document
}
@@ -1324,6 +1429,10 @@ visit_proc_type :: proc(p: ^Printer, proc_type: ast.Proc_Type) -> ^Document {
} else {
document = cons(document, group(nest(p.indentation_count, cons(break_with(" "), group(visit_signature_list(p, proc_type.results))))))
}
+ } else if proc_type.diverging {
+ document = cons_with_nopl(document, text("-"))
+ document = cons(document, text(">"))
+ document = cons_with_nopl(document, text("!"))
}
return document
diff --git a/src/server/completion.odin b/src/server/completion.odin
index 6b24d9d..59df7a3 100644
--- a/src/server/completion.odin
+++ b/src/server/completion.odin
@@ -1029,7 +1029,6 @@ get_identifier_completion :: proc(ast_context: ^analysis.AstContext, position_co
} else {
item := CompletionItem {
label = result.name,
- insertTextFormat = .PlainText,
documentation = result.doc,
};
diff --git a/src/server/semantic_tokens.odin b/src/server/semantic_tokens.odin
index 389d34c..c0a117f 100644
--- a/src/server/semantic_tokens.odin
+++ b/src/server/semantic_tokens.odin
@@ -472,7 +472,7 @@ visit_enum_fields :: proc(node: ast.Enum_Type, builder: ^SemanticTokenBuilder, a
write_semantic_node(builder, field, ast_context.file.src, .EnumMember, .None);
}
else if f, ok := field.derived.(Field_Value); ok {
- if ident, ok := f.field.derived.(Ident); ok {
+ if _, ok := f.field.derived.(Ident); ok {
write_semantic_node(builder, f.field, ast_context.file.src, .EnumMember, .None);
}
visit(f.value, builder, ast_context);
diff --git a/src/server/types.odin b/src/server/types.odin
index c3147e9..8521108 100644
--- a/src/server/types.odin
+++ b/src/server/types.odin
@@ -268,8 +268,8 @@ CompletionItem :: struct {
kind: CompletionItemKind,
detail: string,
documentation: string,
- insertTextFormat: InsertTextFormat,
- insertText: string,
+ insertTextFormat: Maybe(InsertTextFormat),
+ insertText: Maybe(string),
additionalTextEdits: []TextEdit,
tags: []CompletionItemTag,
deprecated: bool,