[vala] Support using directives inside namespaces
- From: Jürg Billeter <juergbi src gnome org>
- To: svn-commits-list gnome org
- Cc:
- Subject: [vala] Support using directives inside namespaces
- Date: Sat, 26 Sep 2009 12:47:17 +0000 (UTC)
commit 8ca6708517e07c3d9a25c9352b0b26792ed49e6c
Author: Jürg Billeter <j bitron ch>
Date: Sat Sep 26 00:38:08 2009 +0200
Support using directives inside namespaces
compiler/valacompiler.vala | 8 +++++-
vala/valagenieparser.vala | 1 +
vala/valamemberaccess.vala | 6 ++--
vala/valanamespace.vala | 20 ++++++++++++++++-
vala/valaparser.vala | 22 ++++++++++++++++--
vala/valasourcefile.vala | 48 ++++++----------------------------------
vala/valasourcereference.vala | 7 ++++-
vala/valasymbolresolver.vala | 20 +++++++---------
8 files changed, 70 insertions(+), 62 deletions(-)
---
diff --git a/compiler/valacompiler.vala b/compiler/valacompiler.vala
index e1cf96b..4f8e31f 100644
--- a/compiler/valacompiler.vala
+++ b/compiler/valacompiler.vala
@@ -273,10 +273,14 @@ class Vala.Compiler {
if (context.profile == Profile.POSIX) {
// import the Posix namespace by default (namespace of backend-specific standard library)
- source_file.add_using_directive (new UsingDirective (new UnresolvedSymbol (null, "Posix", null)));
+ var ns_ref = new UsingDirective (new UnresolvedSymbol (null, "Posix", null));
+ source_file.add_using_directive (ns_ref);
+ context.root.add_using_directive (ns_ref);
} else if (context.profile == Profile.GOBJECT) {
// import the GLib namespace by default (namespace of backend-specific standard library)
- source_file.add_using_directive (new UsingDirective (new UnresolvedSymbol (null, "GLib", null)));
+ var ns_ref = new UsingDirective (new UnresolvedSymbol (null, "GLib", null));
+ source_file.add_using_directive (ns_ref);
+ context.root.add_using_directive (ns_ref);
}
context.add_source_file (source_file);
diff --git a/vala/valagenieparser.vala b/vala/valagenieparser.vala
index 32edf6b..9aa9652 100644
--- a/vala/valagenieparser.vala
+++ b/vala/valagenieparser.vala
@@ -2402,6 +2402,7 @@ public class Vala.Genie.Parser : CodeVisitor {
var ns_ref = new UsingDirective (sym, get_src (begin));
scanner.source_file.add_using_directive (ns_ref);
+ context.root.add_using_directive (ns_ref);
}
void parse_using_directives () throws ParseError {
diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala
index 8833d80..af6ca6b 100644
--- a/vala/valamemberaccess.vala
+++ b/vala/valamemberaccess.vala
@@ -254,11 +254,11 @@ public class Vala.MemberAccess : Expression {
sym = sym.parent_symbol;
}
- if (symbol_reference == null) {
- foreach (UsingDirective ns in analyzer.current_source_file.get_using_directives ()) {
+ if (symbol_reference == null && source_reference != null) {
+ foreach (UsingDirective ns in source_reference.using_directives) {
var local_sym = ns.namespace_symbol.scope.lookup (member_name);
if (local_sym != null) {
- if (symbol_reference != null) {
+ if (symbol_reference != null && symbol_reference != local_sym) {
error = true;
Report.error (source_reference, "`%s' is an ambiguous reference between `%s' and `%s'".printf (member_name, symbol_reference.get_full_name (), local_sym.get_full_name ()));
return false;
diff --git a/vala/valanamespace.vala b/vala/valanamespace.vala
index b7e16aa..aebac89 100644
--- a/vala/valanamespace.vala
+++ b/vala/valanamespace.vala
@@ -46,6 +46,8 @@ public class Vala.Namespace : Symbol {
private Gee.List<Namespace> namespaces = new ArrayList<Namespace> ();
+ private Gee.List<UsingDirective> using_directives = new ArrayList<UsingDirective> ();
+
/**
* Creates a new namespace.
*
@@ -57,7 +59,16 @@ public class Vala.Namespace : Symbol {
base (name, source_reference);
access = SymbolAccessibility.PUBLIC;
}
-
+
+ /**
+ * Adds a new using directive with the specified namespace.
+ *
+ * @param ns reference to namespace
+ */
+ public void add_using_directive (UsingDirective ns) {
+ using_directives.add (ns);
+ }
+
public void add_comment (Comment comment) {
comments.add (comment);
}
@@ -84,6 +95,9 @@ public class Vala.Namespace : Symbol {
old_ns.source_reference = ns.source_reference;
}
+ foreach (var using_directive in ns.using_directives) {
+ old_ns.add_using_directive (using_directive);
+ }
foreach (Namespace sub_ns in ns.get_namespaces ()) {
old_ns.add_namespace (sub_ns);
}
@@ -392,6 +406,10 @@ public class Vala.Namespace : Symbol {
}
public override void accept_children (CodeVisitor visitor) {
+ foreach (UsingDirective ns_ref in using_directives) {
+ ns_ref.accept (visitor);
+ }
+
foreach (Namespace ns in namespaces) {
ns.accept (visitor);
}
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index 962ff4c..e9add95 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -310,7 +310,7 @@ public class Vala.Parser : CodeVisitor {
try {
- parse_using_directives ();
+ parse_using_directives (context.root);
parse_declarations (context.root, true);
} catch (ParseError e) {
// already reported
@@ -1964,7 +1964,22 @@ public class Vala.Parser : CodeVisitor {
}
set_attributes (ns, attrs);
- parse_declarations (ns);
+
+ expect (TokenType.OPEN_BRACE);
+
+ var old_using_directives = scanner.source_file.current_using_directives;
+ parse_using_directives (ns);
+
+ parse_declarations (ns, true);
+
+ scanner.source_file.current_using_directives = old_using_directives;
+
+ if (!accept (TokenType.CLOSE_BRACE)) {
+ // only report error if it's not a secondary error
+ if (context.report.get_errors () == 0) {
+ Report.error (get_current_src (), "expected `}'");
+ }
+ }
Namespace result = ns;
while (sym.inner != null) {
@@ -2015,13 +2030,14 @@ public class Vala.Parser : CodeVisitor {
scanner.source_file.add_node (sym);
}
- void parse_using_directives () throws ParseError {
+ void parse_using_directives (Namespace ns) throws ParseError {
while (accept (TokenType.USING)) {
do {
var begin = get_location ();
var sym = parse_symbol_name ();
var ns_ref = new UsingDirective (sym, get_src (begin));
scanner.source_file.add_using_directive (ns_ref);
+ ns.add_using_directive (ns_ref);
} while (accept (TokenType.COMMA));
expect (TokenType.SEMICOLON);
}
diff --git a/vala/valasourcefile.vala b/vala/valasourcefile.vala
index ee3d281..ab6d570 100644
--- a/vala/valasourcefile.vala
+++ b/vala/valasourcefile.vala
@@ -53,7 +53,7 @@ public class Vala.SourceFile {
private ArrayList<Comment> comments = new ArrayList<Comment> ();
- private Gee.List<UsingDirective> using_directives = new ArrayList<UsingDirective> ();
+ public Gee.List<UsingDirective> current_using_directives { get; set; default = new ArrayList<UsingDirective> (); }
private Gee.List<CodeNode> nodes = new ArrayList<CodeNode> ();
@@ -102,45 +102,17 @@ public class Vala.SourceFile {
* @param ns reference to namespace
*/
public void add_using_directive (UsingDirective ns) {
- foreach (UsingDirective using_directive in using_directives) {
- if (same_symbol (using_directive.namespace_symbol, ns.namespace_symbol)) {
- // ignore duplicates
- return;
- }
- }
- using_directives.add (ns);
- }
-
- public void clear_using_directives () {
- using_directives.clear ();
- }
-
- bool same_symbol (Symbol? sym1, Symbol? sym2) {
- if (sym1 == sym2) {
- return true;
- }
-
- var unresolved_symbol1 = sym1 as UnresolvedSymbol;
- var unresolved_symbol2 = sym2 as UnresolvedSymbol;
- if (unresolved_symbol1 != null && unresolved_symbol2 != null) {
- if (same_symbol (unresolved_symbol1.inner, unresolved_symbol2.inner)) {
- return (unresolved_symbol1.name == unresolved_symbol2.name);
- }
+ // do not modify current_using_directives, it should be considered immutable
+ // for correct symbol resolving
+ var old_using_directives = current_using_directives;
+ current_using_directives = new ArrayList<UsingDirective> ();
+ foreach (var using_directive in old_using_directives) {
+ current_using_directives.add (using_directive);
}
-
- return false;
+ current_using_directives.add (ns);
}
/**
- * Returns a copy of the list of using directives.
- *
- * @return using directive list
- */
- public Gee.List<UsingDirective> get_using_directives () {
- return new ReadOnlyList<UsingDirective> (using_directives);
- }
-
- /**
* Adds the specified code node to this source file.
*
* @param node a code node
@@ -167,10 +139,6 @@ public class Vala.SourceFile {
}
public void accept_children (CodeVisitor visitor) {
- foreach (UsingDirective ns_ref in using_directives) {
- ns_ref.accept (visitor);
- }
-
foreach (CodeNode node in nodes) {
node.accept (visitor);
}
diff --git a/vala/valasourcereference.vala b/vala/valasourcereference.vala
index 4afe4d8..7675977 100644
--- a/vala/valasourcereference.vala
+++ b/vala/valasourcereference.vala
@@ -1,6 +1,6 @@
/* valasourcereference.vala
*
- * Copyright (C) 2006-2008 Jürg Billeter
+ * Copyright (C) 2006-2009 Jürg Billeter
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -50,7 +50,9 @@ public class Vala.SourceReference {
* The last column number of the referenced source code.
*/
public int last_column { get; set; }
-
+
+ public Gee.List<UsingDirective> using_directives { get; private set; }
+
/**
* Creates a new source reference.
*
@@ -67,6 +69,7 @@ public class Vala.SourceReference {
first_column = _first_column;
last_line = _last_line;
last_column = _last_column;
+ using_directives = file.current_using_directives;
}
/**
diff --git a/vala/valasymbolresolver.vala b/vala/valasymbolresolver.vala
index 24612f1..213bd53 100644
--- a/vala/valasymbolresolver.vala
+++ b/vala/valasymbolresolver.vala
@@ -31,7 +31,6 @@ using Gee;
public class Vala.SymbolResolver : CodeVisitor {
Symbol root_symbol;
Scope current_scope;
- Gee.List<UsingDirective> current_using_directives;
/**
* Resolve symbol names in the specified code context.
@@ -40,18 +39,17 @@ public class Vala.SymbolResolver : CodeVisitor {
*/
public void resolve (CodeContext context) {
root_symbol = context.root;
- current_scope = root_symbol.scope;
- context.accept (this);
+ context.root.accept (this);
}
- public override void visit_source_file (SourceFile file) {
- current_using_directives = file.get_using_directives ();
- current_scope = root_symbol.scope;
+ public override void visit_namespace (Namespace ns) {
+ var old_scope = current_scope;
+ current_scope = ns.scope;
- file.accept_children (this);
+ ns.accept_children (this);
- current_using_directives = null;
+ current_scope = old_scope;
}
public override void visit_class (Class cl) {
@@ -220,8 +218,8 @@ public class Vala.SymbolResolver : CodeVisitor {
scope = scope.parent_scope;
}
- if (sym == null) {
- foreach (UsingDirective ns in current_using_directives) {
+ if (sym == null && unresolved_symbol.source_reference != null) {
+ foreach (UsingDirective ns in unresolved_symbol.source_reference.using_directives) {
if (ns.error || ns.namespace_symbol is UnresolvedSymbol) {
continue;
}
@@ -234,7 +232,7 @@ public class Vala.SymbolResolver : CodeVisitor {
}
if (local_sym != null) {
- if (sym != null) {
+ if (sym != null && sym != local_sym) {
unresolved_symbol.error = true;
Report.error (unresolved_symbol.source_reference, "`%s' is an ambiguous reference between `%s' and `%s'".printf (unresolved_symbol.name, sym.get_full_name (), local_sym.get_full_name ()));
return null;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]