Skip to content

Commit 51a7455

Browse files
committed
Added support for adding constructor
1 parent 484465d commit 51a7455

File tree

4 files changed

+97
-10
lines changed

4 files changed

+97
-10
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
/* implementconstructoraction.vala
2+
*
3+
* Copyright 2022 JCWasmx86 <[email protected]>
4+
*
5+
* This file is free software; you can redistribute it and/or modify it
6+
* under the terms of the GNU Lesser General Public License as
7+
* published by the Free Software Foundation; either version 2.1 of the
8+
* License, or (at your option) any later version.
9+
*
10+
* This file is distributed in the hope that it will be useful, but
11+
* WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this program. If not, see <http://www.gnu.org/licenses/>.
17+
*
18+
* SPDX-License-Identifier: LGPL-2.1-or-later
19+
*/
20+
21+
using Lsp;
22+
using Gee;
23+
24+
class Vls.ImplementConstructorAction : CodeAction {
25+
public ImplementConstructorAction (Vala.ObjectCreationExpression oce, Vala.Symbol to_be_created) {
26+
var target_file = to_be_created.source_reference.file;
27+
var insertion_line = to_be_created.source_reference.end.line + 1;
28+
var sb = new StringBuilder ();
29+
var indent = to_be_created.source_reference.begin.column == 1 ? "" : "\t";
30+
sb.append (indent).append (indent).append ("public ").append (oce.member_name.to_string ()).append (" (");
31+
var args = oce.get_argument_list ();
32+
var idx = 0;
33+
for (var i = 0; i < args.size - 1; i++) {
34+
sb.append (args[i].value_type.to_string ()).append (" arg%d".printf (idx++)).append (", ");
35+
}
36+
if (args.size != 0)
37+
sb.append (args[args.size - 1].value_type.to_string ()).append (" arg%d".printf (idx));
38+
sb.append (") {}\n ");
39+
try {
40+
var target_uri = Filename.to_uri (target_file.filename);
41+
var target_document = new VersionedTextDocumentIdentifier () {
42+
uri = target_uri,
43+
version = 1
44+
};
45+
var workspace_edit = new WorkspaceEdit ();
46+
var document_edit = new TextDocumentEdit (target_document);
47+
var r = new Range.from_sourceref (
48+
new Vala.SourceReference (target_file,
49+
Vala.SourceLocation (null, insertion_line, 1),
50+
Vala.SourceLocation (null, insertion_line, 1)));
51+
var text_edit = new TextEdit (r);
52+
document_edit.edits.add (text_edit);
53+
workspace_edit.documentChanges = new Gee.ArrayList<TextDocumentEdit> ();
54+
workspace_edit.documentChanges.add (document_edit);
55+
this.edit = workspace_edit;
56+
this.title = "Add constructor";
57+
text_edit.newText = sb.str;
58+
} catch (ConvertError ce) {
59+
error ("Should not happen: %s", ce.message);
60+
}
61+
}
62+
}

src/codehelp/codeaction.vala

+33-9
Original file line numberDiff line numberDiff line change
@@ -23,13 +23,13 @@ using Vala;
2323

2424
namespace Vls.CodeActions {
2525
/**
26-
* Extracts a list of code actions for the given document and range.
26+
* Extracts a list of code actions for the given document and range using the AST and the diagnostics.
2727
*
2828
* @param file the current document
2929
* @param range the range to show code actions for
3030
* @param uri the document URI
3131
*/
32-
Collection<CodeAction> extract (Compilation compilation, TextDocument file, Range range, string uri) {
32+
Collection<CodeAction> generate_codeactions (Compilation compilation, TextDocument file, Range range, string uri, Reporter reporter) {
3333
// search for nodes containing the query range
3434
var finder = new NodeSearch (file, range.start, true, range.end);
3535
var code_actions = new ArrayList<CodeAction> ();
@@ -41,13 +41,14 @@ namespace Vls.CodeActions {
4141

4242
// add code actions
4343
foreach (CodeNode code_node in finder.result) {
44+
critical ("%s", code_node.type_name);
4445
if (code_node is IntegerLiteral) {
45-
var lit = (IntegerLiteral)code_node;
46+
var lit = (IntegerLiteral) code_node;
4647
var lit_range = new Range.from_sourceref (lit.source_reference);
4748
if (lit_range.contains (range.start) && lit_range.contains (range.end))
4849
code_actions.add (new BaseConverterAction (lit, document));
4950
} else if (code_node is Class) {
50-
var csym = (Class)code_node;
51+
var csym = (Class) code_node;
5152
var clsdef_range = compute_class_def_range (csym, class_ranges);
5253
var cls_range = new Range.from_sourceref (csym.source_reference);
5354
if (cls_range.contains (range.start) && cls_range.contains (range.end)) {
@@ -57,6 +58,29 @@ namespace Vls.CodeActions {
5758
code_actions.add (new ImplementMissingPrereqsAction (csym, missing.first, missing.second, clsdef_range.end, code_style, document));
5859
}
5960
}
61+
} else if (code_node is ObjectCreationExpression) {
62+
var oce = (ObjectCreationExpression) code_node;
63+
foreach (var diag in reporter.messages) {
64+
if (file.filename != diag.loc.file.filename)
65+
continue;
66+
if (!(oce.source_reference.contains (diag.loc.begin) || oce.source_reference.contains (diag.loc.end)))
67+
continue;
68+
if (diag.message.contains (" extra arguments for ")) {
69+
var to_be_created = oce.type_reference.symbol;
70+
if (!(to_be_created is Vala.Class)) {
71+
continue;
72+
}
73+
var constr = ((Vala.Class) to_be_created).constructor;
74+
if (constr != null) {
75+
continue;
76+
}
77+
var target_file = to_be_created.source_reference.file;
78+
// We can't just edit, e.g. some external vapi
79+
if (!compilation.get_project_files ().contains (target_file))
80+
continue;
81+
code_actions.add (new ImplementConstructorAction (oce, to_be_created));
82+
}
83+
}
6084
}
6185
}
6286

@@ -72,11 +96,11 @@ namespace Vls.CodeActions {
7296
// otherwise compute the result and cache it
7397
// csym.source_reference must be non-null otherwise NodeSearch wouldn't have found csym
7498
var pos = new Position.from_libvala (csym.source_reference.end);
75-
var offset = csym.source_reference.end.pos - (char *)csym.source_reference.file.content;
99+
var offset = csym.source_reference.end.pos - (char*) csym.source_reference.file.content;
76100
var dl = 0;
77101
var dc = 0;
78-
while (offset < csym.source_reference.file.content.length && csym.source_reference.file.content[(long)offset] != '{') {
79-
if (Util.is_newline (csym.source_reference.file.content[(long)offset])) {
102+
while (offset < csym.source_reference.file.content.length && csym.source_reference.file.content[(long) offset] != '{') {
103+
if (Util.is_newline (csym.source_reference.file.content[(long) offset])) {
80104
dl++;
81105
dc = 0;
82106
} else {
@@ -93,8 +117,8 @@ namespace Vls.CodeActions {
93117
if (member.source_reference == null)
94118
continue;
95119
range = range.union (new Range.from_sourceref (member.source_reference));
96-
if (member is Method && ((Method)member).body != null && ((Method)member).body.source_reference != null)
97-
range = range.union (new Range.from_sourceref (((Method)member).body.source_reference));
120+
if (member is Method && ((Method) member).body != null && ((Method) member).body.source_reference != null)
121+
range = range.union (new Range.from_sourceref (((Method) member).body.source_reference));
98122
}
99123
class_ranges[csym] = range;
100124
return range;

src/meson.build

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ vls_src = files([
44
'analysis/codestyleanalyzer.vala',
55
'analysis/symbolenumerator.vala',
66
'codeaction/baseconverteraction.vala',
7+
'codeaction/implementconstructoraction.vala',
78
'codeaction/implementmissingprereqsaction.vala',
89
'codehelp/callhierarchy.vala',
910
'codehelp/codeaction.vala',

src/server.vala

+1-1
Original file line numberDiff line numberDiff line change
@@ -1645,7 +1645,7 @@ class Vls.Server : Jsonrpc.Server {
16451645
var json_array = new Json.Array ();
16461646

16471647
Vala.CodeContext.push (compilation.code_context);
1648-
var code_actions = CodeActions.extract (compilation, (TextDocument) source_file, p.range, Uri.unescape_string (p.textDocument.uri));
1648+
var code_actions = CodeActions.generate_codeactions (compilation, (TextDocument) source_file, p.range, Uri.unescape_string (p.textDocument.uri), compilation.reporter);
16491649
foreach (var action in code_actions)
16501650
json_array.add_element (Json.gobject_serialize (action));
16511651
Vala.CodeContext.pop ();

0 commit comments

Comments
 (0)