diff options
| author | Daniel Gavin <danielgavin5@hotmail.com> | 2022-02-15 17:35:22 +0100 |
|---|---|---|
| committer | Daniel Gavin <danielgavin5@hotmail.com> | 2022-02-15 17:35:22 +0100 |
| commit | 63d0bd412a8817445d6dc18e79d5d54c94caf401 (patch) | |
| tree | 90032a710b80fe211b0cc9bd46cbc27cd5dbf6ae /src | |
| parent | efe15efabd1b718f89c869ac9c1a6dbd680a8bc0 (diff) | |
| parent | 1d4c3bd57e6d5c7f8472f3e0b825bb38739e5ecc (diff) | |
Merge branch 'master' into refractor-analysis
Diffstat (limited to 'src')
| -rw-r--r-- | src/analysis/analysis.odin | 2 | ||||
| -rw-r--r-- | src/odin/printer/printer.odin | 4 | ||||
| -rw-r--r-- | src/odin/printer/visit.odin | 177 | ||||
| -rw-r--r-- | src/server/completion.odin | 1 | ||||
| -rw-r--r-- | src/server/semantic_tokens.odin | 2 | ||||
| -rw-r--r-- | src/server/types.odin | 4 |
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, |