[vala/wip/printer: 1/2] WIP parser: Create bi-directional list of source-references for source-file
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/wip/printer: 1/2] WIP parser: Create bi-directional list of source-references for source-file
- Date: Thu, 9 Apr 2020 18:35:54 +0000 (UTC)
commit e86114d26133f5b62702cb3bece20ae84f84c24a
Author: Rico Tzschichholz <ricotz ubuntu com>
Date: Thu Apr 9 20:35:23 2020 +0200
WIP parser: Create bi-directional list of source-references for source-file
Add first/last source-reference to SourceFile as starting point and
prev/next source-reference to SourceReference to walk through the created
syntax-tree.
vala/valaparser.vala | 91 ++++++++++++++++++++++++++++++++++++++++---
vala/valasourcefile.vala | 10 +++++
vala/valasourcereference.vala | 10 +++++
3 files changed, 106 insertions(+), 5 deletions(-)
---
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index 48818a293..cd96f4595 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -39,6 +39,8 @@ public class Vala.Parser : CodeVisitor {
Comment comment;
+ weak SourceReference? previous_reference;
+
const int BUFFER_SIZE = 32;
static List<TypeParameter> _empty_type_parameter_list;
@@ -179,6 +181,32 @@ public class Vala.Parser : CodeVisitor {
return new SourceReference (scanner.source_file, token.begin, token.end);
}
+ void link_src (CodeNode node, SourceReference? insert_at = null) {
+ unowned SourceReference src = node.source_reference;
+ assert (src != null);
+
+ // FIXME never ever
+ if (src == previous_reference) {
+ return;
+ }
+
+ if (previous_reference != insert_at && insert_at != null) {
+ unowned SourceReference? next = insert_at.next;
+ insert_at.next = src;
+ src.prev = insert_at;
+ src.next = next;
+ return;
+ }
+
+ if (previous_reference == null) {
+ src.file.first = src;
+ } else {
+ previous_reference.next = src;
+ src.prev = previous_reference;
+ }
+ previous_reference = src;
+ }
+
void rollback (SourceLocation location) {
while (tokens[index].begin.pos != location.pos) {
index = (index - 1 + BUFFER_SIZE) % BUFFER_SIZE;
@@ -359,6 +387,7 @@ public class Vala.Parser : CodeVisitor {
scanner = new Scanner (source_file);
parse_file_comments ();
+ previous_reference = null;
index = -1;
size = 0;
@@ -378,6 +407,10 @@ public class Vala.Parser : CodeVisitor {
report_parse_error (e);
}
+ if (previous_reference != null) {
+ source_file.last = previous_reference;
+ }
+
scanner = null;
if (!has_global_context) {
context = null;
@@ -639,6 +672,8 @@ public class Vala.Parser : CodeVisitor {
Expression expr;
+ unowned SourceReference? current_reference = previous_reference;
+
switch (current ()) {
case TokenType.TRUE:
case TokenType.FALSE:
@@ -718,6 +753,8 @@ public class Vala.Parser : CodeVisitor {
}
}
+ link_src (expr, current_reference);
+
return expr;
}
@@ -1562,6 +1599,7 @@ public class Vala.Parser : CodeVisitor {
try {
Statement stmt = null;
bool is_decl = false;
+ unowned SourceReference? current_reference = previous_reference;
comment = scanner.pop_comment ();
switch (current ()) {
@@ -1644,6 +1682,7 @@ public class Vala.Parser : CodeVisitor {
}
if (!is_decl) {
+ link_src (stmt, current_reference);
block.add_statement (stmt);
}
} catch (ParseError e) {
@@ -1748,15 +1787,19 @@ public class Vala.Parser : CodeVisitor {
Block parse_embedded_statement (string statement_name, bool accept_empty_body = true) throws
ParseError {
if (current () == TokenType.OPEN_BRACE) {
var block = parse_block ();
+ link_src (block);
return block;
}
comment = scanner.pop_comment ();
var block = new Block (get_src (get_location ()));
+ link_src (block);
try {
+ unowned SourceReference? current_reference = previous_reference;
var stmt = parse_embedded_statement_without_block (statement_name, accept_empty_body);
+ link_src (stmt, current_reference);
block.add_statement (stmt);
} catch (ParseError e) {
if (context.keep_going) {
@@ -1817,6 +1860,7 @@ public class Vala.Parser : CodeVisitor {
var begin = get_location ();
expect (TokenType.OPEN_BRACE);
var block = new Block (get_src (begin));
+ link_src (block);
parse_statements (block);
if (!accept (TokenType.CLOSE_BRACE)) {
// only report error if it's not a secondary error
@@ -1864,14 +1908,18 @@ public class Vala.Parser : CodeVisitor {
expect (TokenType.ASSIGN);
var tuple = parse_expression ();
var tuple_local = new LocalVariable (null, CodeNode.get_temp_name (), tuple,
get_src (begin));
- block.add_statement (new DeclarationStatement (tuple_local,
tuple_local.source_reference));
+ var tuple_stmt = new DeclarationStatement (tuple_local,
tuple_local.source_reference);
+ link_src (tuple_stmt);
+ block.add_statement (tuple_stmt);
for (int i = 0; i < identifiers.length; i++) {
var temp_access = new MemberAccess.simple (tuple_local.name,
tuple_local.source_reference);
var ea = new ElementAccess (temp_access,
tuple_local.source_reference);
ea.append_index (new IntegerLiteral (i.to_string ()));
var local = new LocalVariable (null, identifiers[i], ea,
tuple_local.source_reference);
- block.add_statement (new DeclarationStatement (local,
local.source_reference));
+ var stmt = new DeclarationStatement (local, local.source_reference);
+ link_src (stmt);
+ block.add_statement (stmt);
}
continue;
@@ -1887,8 +1935,11 @@ public class Vala.Parser : CodeVisitor {
if (variable_type != null) {
type_copy = variable_type.copy ();
}
+ unowned SourceReference? current_reference = previous_reference;
var local = parse_local_variable (type_copy);
- block.add_statement (new DeclarationStatement (local, get_src (begin)));
+ var stmt = new DeclarationStatement (local, get_src (begin));
+ link_src (stmt, current_reference);
+ block.add_statement (stmt);
} while (accept (TokenType.COMMA));
expect (TokenType.SEMICOLON);
}
@@ -1926,8 +1977,11 @@ public class Vala.Parser : CodeVisitor {
}
DataType type_copy = constant_type.copy ();
+ unowned SourceReference? current_reference = previous_reference;
var local = parse_local_constant (type_copy);
- block.add_statement (new DeclarationStatement (local, get_src (begin)));
+ var stmt = new DeclarationStatement (local, get_src (begin));
+ link_src (stmt, current_reference);
+ block.add_statement (stmt);
block.add_local_constant (local);
local.active = false;
} while (accept (TokenType.COMMA));
@@ -2089,6 +2143,7 @@ public class Vala.Parser : CodeVisitor {
stmt.add_iterator (iter);
}
if (block != null) {
+ link_src (stmt);
block.add_statement (stmt);
return block;
} else {
@@ -2319,6 +2374,7 @@ public class Vala.Parser : CodeVisitor {
method.access = SymbolAccessibility.PUBLIC;
method.binding = MemberBinding.STATIC;
method.body = new Block (get_src (begin));
+ link_src (method.body);
parse_statements (method.body);
if (current () != TokenType.EOF) {
Report.error (get_current_src (), "expected end of file");
@@ -2577,6 +2633,7 @@ public class Vala.Parser : CodeVisitor {
expect (TokenType.NAMESPACE);
var sym = parse_symbol_name ();
var ns = new Namespace (sym.name, get_src (begin));
+ link_src (ns);
if (comment != null) {
ns.add_comment (comment);
comment = null;
@@ -2616,6 +2673,7 @@ public class Vala.Parser : CodeVisitor {
var begin = get_location ();
var sym = parse_symbol_name ();
var ns_ref = new UsingDirective (sym, get_src (begin));
+ link_src (ns_ref);
scanner.source_file.add_using_directive (ns_ref);
ns.add_using_directive (ns_ref);
} while (accept (TokenType.COMMA));
@@ -2638,6 +2696,7 @@ public class Vala.Parser : CodeVisitor {
}
var cl = new Class (sym.name, get_src (begin), comment);
+ link_src (cl);
cl.access = access;
if (ModifierFlags.ABSTRACT in flags) {
cl.is_abstract = true;
@@ -2689,6 +2748,7 @@ public class Vala.Parser : CodeVisitor {
}
var c = new Constant (id, type, null, get_src (begin), comment);
+ link_src (c);
c.access = access;
if (ModifierFlags.EXTERN in flags) {
c.is_extern = true;
@@ -2723,6 +2783,7 @@ public class Vala.Parser : CodeVisitor {
type = parse_inline_array_type (type);
var f = new Field (id, type, null, get_src (begin), comment);
+ link_src (f);
f.access = access;
set_attributes (f, attrs);
@@ -2796,6 +2857,7 @@ public class Vala.Parser : CodeVisitor {
var sym = parse_symbol_name ();
var type_param_list = parse_type_parameter_list ();
var method = new Method (sym.name, type, get_src (begin), comment);
+ link_src (method);
if (sym.inner != null) {
method.base_interface_type = new UnresolvedType.from_symbol (sym.inner,
sym.inner.source_reference);
}
@@ -2888,6 +2950,7 @@ public class Vala.Parser : CodeVisitor {
var type = parse_type (true, true);
string id = parse_identifier ();
var prop = new Property (id, type, null, null, get_src (begin), comment);
+ link_src (prop);
prop.access = access;
set_attributes (prop, attrs);
if (ModifierFlags.STATIC in flags && ModifierFlags.CLASS in flags) {
@@ -2935,6 +2998,7 @@ public class Vala.Parser : CodeVisitor {
}
expect (TokenType.ASSIGN);
prop.initializer = parse_expression ();
+ link_src (prop.initializer);
expect (TokenType.SEMICOLON);
} else {
comment = scanner.pop_comment ();
@@ -2964,6 +3028,7 @@ public class Vala.Parser : CodeVisitor {
prop.external = false;
}
prop.get_accessor = new PropertyAccessor (true, false, false,
value_type, block, get_src (accessor_begin), comment);
+ link_src (prop.get_accessor);
set_attributes (prop.get_accessor, accessor_attrs);
prop.get_accessor.access = accessor_access;
} else {
@@ -2986,6 +3051,7 @@ public class Vala.Parser : CodeVisitor {
prop.external = false;
}
prop.set_accessor = new PropertyAccessor (false, writable,
_construct, value_type, block, get_src (accessor_begin), comment);
+ link_src (prop.set_accessor);
set_attributes (prop.set_accessor, accessor_attrs);
prop.set_accessor.access = accessor_access;
}
@@ -3004,6 +3070,7 @@ public class Vala.Parser : CodeVisitor {
var type = parse_type (true, false);
string id = parse_identifier ();
var sig = new Signal (id, type, get_src (begin), comment);
+ link_src (sig);
sig.access = access;
set_attributes (sig, attrs);
if (ModifierFlags.STATIC in flags) {
@@ -3040,6 +3107,7 @@ public class Vala.Parser : CodeVisitor {
throw new ParseError.SYNTAX ("`new' modifier not allowed on constructor");
}
var c = new Constructor (get_src (begin));
+ link_src (c);
if (ModifierFlags.STATIC in flags && ModifierFlags.CLASS in flags) {
Report.error (c.source_reference, "only one of `static' or `class' may be specified");
} else if (ModifierFlags.STATIC in flags) {
@@ -3063,6 +3131,7 @@ public class Vala.Parser : CodeVisitor {
throw new ParseError.SYNTAX ("`new' modifier not allowed on destructor");
}
var d = new Destructor (get_src (begin));
+ link_src (d);
if (identifier != parent.name) {
Report.error (d.source_reference, "destructor and parent symbol name do not match");
}
@@ -3090,6 +3159,7 @@ public class Vala.Parser : CodeVisitor {
base_type = parse_type (true, false);
}
var st = new Struct (sym.name, get_src (begin), comment);
+ link_src (st);
st.access = access;
if (ModifierFlags.EXTERN in flags) {
st.is_extern = true;
@@ -3133,6 +3203,7 @@ public class Vala.Parser : CodeVisitor {
} while (accept (TokenType.COMMA));
}
var iface = new Interface (sym.name, get_src (begin), comment);
+ link_src (iface);
iface.access = access;
if (ModifierFlags.EXTERN in flags) {
iface.is_extern = true;
@@ -3168,6 +3239,7 @@ public class Vala.Parser : CodeVisitor {
expect (TokenType.ENUM);
var sym = parse_symbol_name ();
var en = new Enum (sym.name, get_src (begin), comment);
+ link_src (en);
en.access = access;
if (ModifierFlags.EXTERN in flags) {
en.is_extern = true;
@@ -3201,6 +3273,7 @@ public class Vala.Parser : CodeVisitor {
}
var ev = new EnumValue (id, value, get_src (value_begin), comment);
+ link_src (ev);
ev.access = SymbolAccessibility.PUBLIC;
set_attributes (ev, value_attrs);
en.add_value (ev);
@@ -3235,6 +3308,7 @@ public class Vala.Parser : CodeVisitor {
expect (TokenType.ERRORDOMAIN);
var sym = parse_symbol_name ();
var ed = new ErrorDomain (sym.name, get_src (begin), comment);
+ link_src (ed);
ed.access = access;
if (ModifierFlags.EXTERN in flags) {
ed.is_extern = true;
@@ -3263,6 +3337,7 @@ public class Vala.Parser : CodeVisitor {
}
var ec = new ErrorCode (id, get_src (code_begin), comment);
+ link_src (ec);
set_attributes (ec, code_attrs);
if (accept (TokenType.ASSIGN)) {
ec.value = parse_expression ();
@@ -3388,7 +3463,9 @@ public class Vala.Parser : CodeVisitor {
var begin = get_location ();
if (accept (TokenType.ELLIPSIS)) {
// varargs
- return new Parameter.with_ellipsis (get_src (begin));
+ var param = new Parameter.with_ellipsis (get_src (begin));
+ link_src (param);
+ return param;
}
bool params_array = accept (TokenType.PARAMS);
var direction = ParameterDirection.IN;
@@ -3414,6 +3491,7 @@ public class Vala.Parser : CodeVisitor {
type = parse_inline_array_type (type);
var param = new Parameter (id, type, get_src (begin));
+ link_src (param);
set_attributes (param, attrs);
param.direction = direction;
param.params_array = params_array;
@@ -3437,6 +3515,7 @@ public class Vala.Parser : CodeVisitor {
} else {
method = new CreationMethod (sym.inner.name, sym.name, get_src (begin), comment);
}
+ link_src (method);
if (ModifierFlags.EXTERN in flags) {
method.is_extern = true;
}
@@ -3493,6 +3572,7 @@ public class Vala.Parser : CodeVisitor {
var sym = parse_symbol_name ();
var type_param_list = parse_type_parameter_list ();
var d = new Delegate (sym.name, type, get_src (begin), comment);
+ link_src (d);
d.access = access;
set_attributes (d, attrs);
if (ModifierFlags.STATIC in flags) {
@@ -3637,6 +3717,7 @@ public class Vala.Parser : CodeVisitor {
List<DataType> type_arg_list = parse_type_argument_list (false);
expr = new MemberAccess (expr != null ? expr : base_expr, id, get_src (begin));
+ link_src (expr);
expr.qualified = qualified;
if (type_arg_list != null) {
foreach (DataType type_arg in type_arg_list) {
diff --git a/vala/valasourcefile.vala b/vala/valasourcefile.vala
index 2e270a06c..22d7263b4 100644
--- a/vala/valasourcefile.vala
+++ b/vala/valasourcefile.vala
@@ -88,6 +88,16 @@ public class Vala.SourceFile {
*/
public SourceFileType file_type { get; set; }
+ /**
+ * The first source reference.
+ */
+ public weak SourceReference? first { get; set; }
+
+ /**
+ * The last source reference.
+ */
+ public weak SourceReference? last { get; set; }
+
/**
* Specifies whether this file came from the command line directly.
*/
diff --git a/vala/valasourcereference.vala b/vala/valasourcereference.vala
index be79e197e..9fb4e01e3 100644
--- a/vala/valasourcereference.vala
+++ b/vala/valasourcereference.vala
@@ -46,6 +46,16 @@ public class Vala.SourceReference {
*/
public SourceLocation end { get; set; }
+ /**
+ * The previous source reference.
+ */
+ public weak SourceReference? prev { get; set; }
+
+ /**
+ * The next source reference.
+ */
+ public weak SourceReference? next { get; set; }
+
public List<UsingDirective> using_directives { get; private set; }
/**
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]