[vala/switch-to-gir] girparser: Parse vala types in the metadata
- From: Luca Bruno <lucabru src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/switch-to-gir] girparser: Parse vala types in the metadata
- Date: Wed, 25 Aug 2010 10:23:26 +0000 (UTC)
commit f5e1e3443ca0977b23ee04ebd738cf70e5ca8e29
Author: Luca Bruno <lethalman88 gmail com>
Date: Wed Aug 25 12:00:10 2010 +0200
girparser: Parse vala types in the metadata
vala/valagirparser.vala | 207 +++++++++++++++++++++++++++++++++++++++-------
1 files changed, 175 insertions(+), 32 deletions(-)
---
diff --git a/vala/valagirparser.vala b/vala/valagirparser.vala
index 565d4b6..f728bb8 100644
--- a/vala/valagirparser.vala
+++ b/vala/valagirparser.vala
@@ -32,20 +32,31 @@ public class Vala.GirParser : CodeVisitor {
SIGNAL
}
- enum Argument {
- HIDDEN;
+ enum ArgumentType {
+ HIDDEN,
+ TYPE;
- public static Argument? from_string (string name) {
- var enum_class = (EnumClass) typeof(Argument).class_ref ();
+ public static ArgumentType? from_string (string name) {
+ var enum_class = (EnumClass) typeof(ArgumentType).class_ref ();
unowned GLib.EnumValue? enum_value = enum_class.get_value_by_nick (name);
if (enum_value != null) {
- Argument value = (Argument) enum_value.value;
+ ArgumentType value = (ArgumentType) enum_value.value;
return value;
}
return null;
}
}
+ class Argument {
+ public Expression expression;
+ public SourceLocation source_location;
+
+ public Argument (Expression expression, SourceLocation source_location) {
+ this.expression = expression;
+ this.source_location = source_location;
+ }
+ }
+
class Metadata {
private static Metadata _empty = new Metadata ("");
public static Metadata empty {
@@ -54,18 +65,21 @@ public class Vala.GirParser : CodeVisitor {
}
}
- public SourceReference source_reference;
public string pattern;
public PatternSpec pattern_spec;
public MetadataType type;
+ public MetadataParser parser;
+ public SourceReference source_reference;
+
public bool used = false;
- public Vala.Map<Argument,CodeNode> args = new HashMap<Argument,CodeNode> ();
+ public Vala.Map<ArgumentType,Argument> args = new HashMap<ArgumentType,Argument> ();
public ArrayList<Metadata> children = new ArrayList<Metadata> ();
- public Metadata (string pattern, MetadataType type = MetadataType.GENERIC, SourceReference? source_reference = null) {
+ public Metadata (string pattern, MetadataType type = MetadataType.GENERIC, MetadataParser? parser = null, SourceReference? source_reference = null) {
this.pattern = pattern;
this.pattern_spec = new PatternSpec (pattern);
this.type = type;
+ this.parser = parser;
this.source_reference = source_reference;
}
@@ -82,16 +96,24 @@ public class Vala.GirParser : CodeVisitor {
return Metadata.empty;
}
- public void add_argument (Argument key, CodeNode value) {
+ public void add_argument (ArgumentType key, Argument value) {
args.set (key, value);
}
- public bool has_argument (Argument key) {
+ public bool has_argument (ArgumentType key) {
return args.contains (key);
}
- public string? get_string (Argument arg) {
- var lit = args.get (arg) as StringLiteral;
+ public Expression? get_expression (ArgumentType arg) {
+ var val = args.get (arg);
+ if (val != null) {
+ return val.expression;
+ }
+ return null;
+ }
+
+ public string? get_string (ArgumentType arg) {
+ var lit = get_expression (arg) as StringLiteral;
if (lit != null) {
return lit.eval ();
}
@@ -99,8 +121,8 @@ public class Vala.GirParser : CodeVisitor {
return null;
}
- public int get_integer (Argument arg) {
- var lit = args.get (arg) as IntegerLiteral;
+ public int get_integer (ArgumentType arg) {
+ var lit = get_expression (arg) as IntegerLiteral;
if (lit != null) {
return lit.value.to_int ();
}
@@ -108,20 +130,20 @@ public class Vala.GirParser : CodeVisitor {
return 0;
}
- public double get_double (Argument arg) {
- var name = args.get (arg);
- if (name is RealLiteral) {
- var lit = (RealLiteral) name;
+ public double get_double (ArgumentType arg) {
+ var expr = get_expression (arg);
+ if (expr is RealLiteral) {
+ var lit = (RealLiteral) expr;
return lit.value.to_double ();
- } else if (name is IntegerLiteral) {
- var lit = (IntegerLiteral) name;
+ } else if (expr is IntegerLiteral) {
+ var lit = (IntegerLiteral) expr;
return lit.value.to_int ();
}
return 0;
}
- public bool get_bool (Argument arg) {
- var lit = args.get (arg) as BooleanLiteral;
+ public bool get_bool (ArgumentType arg) {
+ var lit = get_expression (arg) as BooleanLiteral;
if (lit != null) {
return lit.value;
}
@@ -129,8 +151,15 @@ public class Vala.GirParser : CodeVisitor {
return false;
}
- public DataType get_data_type (Argument arg) {
- return args.get (arg) as DataType;
+ public DataType? get_data_type (ArgumentType arg, bool owned_by_default) {
+ var type_arg = args.get (arg);
+ if (type_arg != null && type_arg.expression is StringLiteral) {
+ var location = SourceLocation (type_arg.source_location.pos + 1, type_arg.source_location.line, type_arg.source_location.column + 1);
+ parser.seek (location);
+ var type = parser.parse_type (owned_by_default);
+ return type;
+ }
+ return null;
}
}
@@ -158,6 +187,10 @@ public class Vala.GirParser : CodeVisitor {
return new SourceReference (scanner.source_file, begin.line, begin.column, end.line, end.column);
}
+ SourceReference get_src (SourceLocation begin) {
+ return new SourceReference (scanner.source_file, begin.line, begin.column, end.line, end.column);
+ }
+
public Metadata parse_metadata (SourceFile metadata_file) {
scanner = new Scanner (metadata_file);
next ();
@@ -169,6 +202,70 @@ public class Vala.GirParser : CodeVisitor {
return tree;
}
+ public DataType? parse_type (bool owned_by_default) {
+ // sync with valaparser.vala
+ var begin = this.begin;
+
+ if (accept (TokenType.VOID)) {
+ DataType type = new VoidType (get_src (begin));
+ while (accept (TokenType.STAR)) {
+ type = new PointerType (type);
+ }
+ return type;
+ }
+
+ bool value_owned = owned_by_default;
+
+ if (owned_by_default && accept (TokenType.UNOWNED)) {
+ value_owned = false;
+ } else if (!owned_by_default) {
+ value_owned = accept (TokenType.OWNED);
+ }
+
+ var sym = parse_symbol_name ();
+ if (sym == null) {
+ return null;
+ }
+ List<DataType> type_arg_list = parse_type_argument_list ();
+
+ DataType type = new UnresolvedType.from_symbol (sym, get_src (begin));
+ if (type_arg_list != null) {
+ foreach (DataType type_arg in type_arg_list) {
+ type.add_type_argument (type_arg);
+ }
+ }
+
+ while (accept (TokenType.STAR)) {
+ type = new PointerType (type, get_src (begin));
+ }
+
+ if (!(type is PointerType)) {
+ type.nullable = accept (TokenType.INTERR);
+ }
+
+ while (accept (TokenType.OPEN_BRACKET)) {
+ if (current != TokenType.CLOSE_BRACKET) {
+ Report.error (get_current_src (), "expected `]'");
+ return null;
+ }
+
+ type.value_owned = true;
+
+ var array_type = new ArrayType (type, 0, get_src (begin));
+ array_type.nullable = accept (TokenType.INTERR);
+
+ type = array_type;
+ }
+
+ type.value_owned = value_owned;
+ return type;
+ }
+
+ public void seek (SourceLocation location) {
+ scanner.seek (location);
+ next ();
+ }
+
TokenType next () {
current = scanner.read_token (out begin, out end);
return current;
@@ -178,6 +275,14 @@ public class Vala.GirParser : CodeVisitor {
return ((string) begin.pos).ndup ((end.pos - begin.pos));
}
+ inline bool accept (TokenType type) {
+ if (current == type) {
+ next ();
+ return true;
+ }
+ return false;
+ }
+
MetadataType? parse_metadata_access () {
switch (current) {
case TokenType.DOT:
@@ -211,7 +316,7 @@ public class Vala.GirParser : CodeVisitor {
return null;
}
- metadata = new Metadata (get_string (), type, get_current_src ());
+ metadata = new Metadata (get_string (), type, this, get_current_src ());
if (parent_metadata == null) {
Report.error (get_current_src (), "cannot determinate parent namespace");
return null;
@@ -236,7 +341,7 @@ public class Vala.GirParser : CodeVisitor {
Report.error (get_current_src (), "expected identifier");
return null;
}
- var child = new Metadata (get_string (), type, get_current_src ());
+ var child = new Metadata (get_string (), type, this, get_current_src ());
metadata.add_child (child);
metadata = child;
}
@@ -268,6 +373,37 @@ public class Vala.GirParser : CodeVisitor {
}
}
+ UnresolvedSymbol? parse_symbol_name () {
+ // sync with valaparser.vala
+ var begin = this.begin;
+ UnresolvedSymbol sym = null;
+ do {
+ if (current != TokenType.IDENTIFIER) {
+ Report.error (get_current_src (), "expected identifier");
+ return null;
+ }
+ string name = get_string ();
+ sym = new UnresolvedSymbol (sym, name, get_src (begin));
+ } while (accept (TokenType.DOT));
+ return sym;
+ }
+
+ List<DataType>? parse_type_argument_list () {
+ if (accept (TokenType.OP_LT)) {
+ var list = new ArrayList<DataType> ();
+ do {
+ var type = parse_type (true);
+ list.add (type);
+ } while (accept (TokenType.COMMA));
+ if (current != TokenType.OP_GT) {
+ Report.error (get_current_src (), "expected `>'");
+ return null;
+ }
+ return list;
+ }
+ return null;
+ }
+
bool parse_args (Metadata metadata) {
var old_end = end;
if (current != TokenType.IDENTIFIER) {
@@ -281,7 +417,7 @@ public class Vala.GirParser : CodeVisitor {
break;
}
- var id = Argument.from_string (get_string ());
+ var id = ArgumentType.from_string (get_string ());
if (id == null) {
Report.error (get_current_src (), "unknown argument");
return false;
@@ -297,8 +433,7 @@ public class Vala.GirParser : CodeVisitor {
if (expr == null) {
return false;
}
-
- metadata.add_argument (id, expr);
+ metadata.add_argument (id, new Argument (expr, begin));
} while (current == TokenType.IDENTIFIER);
return true;
@@ -461,7 +596,7 @@ public class Vala.GirParser : CodeVisitor {
return false;
}
var new_metadata = get_metadata_from_element ();
- if (new_metadata.has_argument (Argument.HIDDEN) && new_metadata.get_bool (Argument.HIDDEN)) {
+ if (new_metadata.has_argument (ArgumentType.HIDDEN) && new_metadata.get_bool (ArgumentType.HIDDEN)) {
return false;
}
@@ -475,6 +610,14 @@ public class Vala.GirParser : CodeVisitor {
metadata_stack.remove_at (metadata_stack.size - 1);
}
+ DataType? element_get_type (string attribute_name, bool owned_by_default) {
+ var type = metadata.get_data_type (ArgumentType.TYPE, owned_by_default);
+ if (type == null) {
+ type = parse_type_from_gir_name (reader.get_attribute ("target"));
+ }
+ return type;
+ }
+
void parse_repository () {
start_element ("repository");
next ();
@@ -671,7 +814,7 @@ public class Vala.GirParser : CodeVisitor {
var alias = new Alias ();
alias.source_reference = get_current_src ();
alias.name = reader.get_attribute ("name");
- alias.base_type = parse_type_from_gir_name (reader.get_attribute ("target"));
+ alias.base_type = element_get_type ("target", true);
alias.parent_namespace = current_namespace;
next ();
end_element ("alias");
@@ -953,7 +1096,7 @@ public class Vala.GirParser : CodeVisitor {
return type;
}
- DataType parse_type_from_gir_name (string type_name) {
+ DataType? parse_type_from_gir_name (string type_name) {
DataType type;
if (type_name == "none") {
type = new VoidType (get_current_src ());
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]