summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRico Tzschichholz <ricotz@ubuntu.com>2023-01-30 20:19:50 +0100
committerRico Tzschichholz <ricotz@ubuntu.com>2023-03-09 12:33:51 +0100
commit4c26e30c0a9b698d7909722abfe66a91239e4e5a (patch)
tree05551c4989137308988faded30a26be3560ef7b7
parentd5ecd13849a6a9126d3b90d16a3268f860800b41 (diff)
downloadvala-wip/attribute-expression.tar.gz
WIP vala: Use Vala.Expression as Vala.Attribute valueswip/attribute-expression
-rw-r--r--codegen/valagdbusclientmodule.vala18
-rw-r--r--codegen/valagdbusmodule.vala9
-rw-r--r--vala/valaattribute.vala67
-rw-r--r--vala/valaclass.vala2
-rw-r--r--vala/valacodenode.vala12
-rw-r--r--vala/valacodewriter.vala3
-rw-r--r--vala/valaconstant.vala2
-rw-r--r--vala/valadelegate.vala2
-rw-r--r--vala/valaenum.vala2
-rw-r--r--vala/valaenumvalue.vala2
-rw-r--r--vala/valaerrorcode.vala2
-rw-r--r--vala/valaerrordomain.vala2
-rw-r--r--vala/valafield.vala2
-rw-r--r--vala/valagenieparser.vala27
-rw-r--r--vala/valamethod.vala2
-rw-r--r--vala/valanamespace.vala2
-rw-r--r--vala/valaparameter.vala2
-rw-r--r--vala/valaparser.vala27
-rw-r--r--vala/valasignal.vala2
-rw-r--r--vala/valastruct.vala2
20 files changed, 106 insertions, 83 deletions
diff --git a/codegen/valagdbusclientmodule.vala b/codegen/valagdbusclientmodule.vala
index 697b08758..da715d2a5 100644
--- a/codegen/valagdbusclientmodule.vala
+++ b/codegen/valagdbusclientmodule.vala
@@ -29,17 +29,15 @@ public class Vala.GDBusClientModule : GDBusModule {
NO_REPLY
}
- public CCodeConstant get_dbus_timeout (Symbol symbol) {
- int timeout = -1;
-
+ public CCodeExpression get_dbus_timeout (Symbol symbol) {
var dbus = symbol.get_attribute ("DBus");
if (dbus != null && dbus.has_argument ("timeout")) {
- timeout = dbus.get_integer ("timeout");
+ return get_ccodenode (dbus.get_expression ("timeout"));
} else if (symbol.parent_symbol != null) {
return get_dbus_timeout (symbol.parent_symbol);
}
- return new CCodeConstant (timeout.to_string ());
+ return new CCodeConstant ("-1");
}
public override void generate_dynamic_method_wrapper (DynamicMethod method) {
@@ -53,7 +51,7 @@ public class Vala.GDBusClientModule : GDBusModule {
push_function (func);
if (method.dynamic_type.type_symbol == dbus_proxy_type) {
- generate_marshalling (method, CallType.SYNC, null, method.name, -1);
+ generate_marshalling (method, CallType.SYNC, null, method.name, null);
} else {
Report.error (method.source_reference, "dynamic methods are not supported for `%s'", method.dynamic_type.to_string ());
}
@@ -555,7 +553,7 @@ public class Vala.GDBusClientModule : GDBusModule {
cfile.add_function (cfunc);
}
- void generate_marshalling (Method m, CallType call_type, string? iface_name, string? method_name, int method_timeout) {
+ void generate_marshalling (Method m, CallType call_type, string? iface_name, string? method_name, CCodeExpression? method_timeout) {
var gdbusproxy = new CCodeCastExpression (new CCodeIdentifier ("self"), "GDBusProxy *");
var connection = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_proxy_get_connection"));
@@ -586,11 +584,11 @@ public class Vala.GDBusClientModule : GDBusModule {
object_path.add_argument (gdbusproxy);
CCodeExpression timeout;
- if (method_timeout <= 0) {
+ if (method_timeout == null) {
timeout = new CCodeFunctionCall (new CCodeIdentifier ("g_dbus_proxy_get_default_timeout"));
((CCodeFunctionCall) timeout).add_argument (gdbusproxy);
} else {
- timeout = new CCodeConstant ("%d".printf (method_timeout));
+ timeout = method_timeout;
}
// register errors
@@ -962,7 +960,7 @@ public class Vala.GDBusClientModule : GDBusModule {
push_function (function);
- generate_marshalling (m, CallType.FINISH, null, null, -1);
+ generate_marshalling (m, CallType.FINISH, null, null, null);
pop_function ();
diff --git a/codegen/valagdbusmodule.vala b/codegen/valagdbusmodule.vala
index 59ab1de8b..5e59b2369 100644
--- a/codegen/valagdbusmodule.vala
+++ b/codegen/valagdbusmodule.vala
@@ -34,8 +34,13 @@ public class Vala.GDBusModule : GVariantModule {
return Symbol.lower_case_to_camel_case (symbol.name);
}
- public static int get_dbus_timeout_for_member (Symbol symbol) {
- return symbol.get_attribute_integer ("DBus", "timeout", -1);
+ public CCodeExpression get_dbus_timeout_for_member (Symbol symbol) {
+ var dbus = symbol.get_attribute ("DBus");
+ if (dbus != null && dbus.has_argument ("timeout")) {
+ return get_ccodenode (dbus.get_expression ("timeout"));
+ }
+
+ return null; //new CCodeConstant ("-1");
}
public static bool is_dbus_visible (CodeNode node) {
diff --git a/vala/valaattribute.vala b/vala/valaattribute.vala
index 58a56ca5d..1538a731d 100644
--- a/vala/valaattribute.vala
+++ b/vala/valaattribute.vala
@@ -34,7 +34,7 @@ public class Vala.Attribute : CodeNode {
/**
* Contains all specified attribute arguments.
*/
- public Vala.Map<string,string> args { get; private set; }
+ public Vala.Map<string,Expression> args { get; private set; }
/**
* Creates a new attribute.
@@ -46,7 +46,7 @@ public class Vala.Attribute : CodeNode {
public Attribute (string name, SourceReference? source_reference = null) {
this.name = name;
this.source_reference = source_reference;
- this.args = new HashMap<string,string> (str_hash, str_equal);
+ this.args = new HashMap<string,Expression> (str_hash, str_equal);
if (!CodeContext.get ().deprecated) {
if (name == "Deprecated") {
@@ -63,7 +63,7 @@ public class Vala.Attribute : CodeNode {
* @param key argument name
* @param value argument value
*/
- public void add_argument (string key, string value) {
+ public void add_argument (string key, Expression value) {
args.set (key, value);
}
@@ -78,22 +78,37 @@ public class Vala.Attribute : CodeNode {
}
/**
+ * Returns the expression of the specified named argument.
+ *
+ * @param name argument name
+ * @return expression value
+ */
+ public Expression? get_expression (string name, Expression? default_value = null) {
+ Expression value = args.get (name);
+
+ if (value == null) {
+ return default_value;
+ }
+
+ return value;
+ }
+
+ /**
* Returns the string value of the specified named argument.
*
* @param name argument name
* @return string value
*/
public string? get_string (string name, string? default_value = null) {
- string value = args.get (name);
+ Expression value = args.get (name);
if (value == null) {
return default_value;
}
- /* remove quotes */
- var noquotes = value.substring (1, (uint) (value.length - 2));
- /* unescape string */
- return noquotes.compress ();
+ assert (value is StringLiteral);
+
+ return ((StringLiteral) value).eval ();
}
/**
@@ -103,13 +118,15 @@ public class Vala.Attribute : CodeNode {
* @return integer value
*/
public int get_integer (string name, int default_value = 0) {
- string value = args.get (name);
+ Expression value = args.get (name);
if (value == null) {
return default_value;
}
- return int.parse (value);
+ assert (value is IntegerLiteral);
+
+ return int.parse (((IntegerLiteral) value).value);
}
/**
@@ -119,13 +136,19 @@ public class Vala.Attribute : CodeNode {
* @return double value
*/
public double get_double (string name, double default_value = 0) {
- string value = args.get (name);
+ Expression value = args.get (name);
if (value == null) {
return default_value;
}
- return double.parse (value);
+ assert (value is RealLiteral || value is IntegerLiteral);
+
+ if (value is IntegerLiteral) {
+ return int.parse (((IntegerLiteral) value).value);
+ } else {
+ return double.parse (((RealLiteral) value).value);
+ }
}
/**
@@ -135,12 +158,28 @@ public class Vala.Attribute : CodeNode {
* @return boolean value
*/
public bool get_bool (string name, bool default_value = false) {
- string value = args.get (name);
+ Expression value = args.get (name);
if (value == null) {
return default_value;
}
- return bool.parse (value);
+ assert (value is BooleanLiteral);
+
+ return ((BooleanLiteral) value).value;
+ }
+
+ public override bool check (CodeContext context) {
+ foreach (var attr in args.get_values ()) {
+ if (!attr.check (context)) {
+ return false;
+ }
+ if (!attr.is_constant ()) {
+ Report.error (attr.source_reference, "attribute values must be constant");
+ return false;
+ }
+ }
+
+ return true;
}
}
diff --git a/vala/valaclass.vala b/vala/valaclass.vala
index 436a6b3cf..9575ea4da 100644
--- a/vala/valaclass.vala
+++ b/vala/valaclass.vala
@@ -540,6 +540,8 @@ public class Vala.Class : ObjectTypeSymbol {
}
context.analyzer.current_symbol = this;
+ base.check (context);
+
foreach (DataType base_type_reference in get_base_types ()) {
if (!base_type_reference.check (context)) {
error = true;
diff --git a/vala/valacodenode.vala b/vala/valacodenode.vala
index 4ca44c8d9..fab9a83af 100644
--- a/vala/valacodenode.vala
+++ b/vala/valacodenode.vala
@@ -91,6 +91,10 @@ public abstract class Vala.CodeNode {
}
public virtual bool check (CodeContext context) {
+ foreach (unowned Attribute a in attributes) {
+ a.check (context);
+ }
+
return true;
}
@@ -273,7 +277,7 @@ public abstract class Vala.CodeNode {
}
unowned Attribute a = get_or_create_attribute (attribute);
- a.add_argument (argument, "\"%s\"".printf (value));
+ a.add_argument (argument, new StringLiteral ("\"%s\"".printf (value)));
}
/**
@@ -285,7 +289,7 @@ public abstract class Vala.CodeNode {
*/
public void set_attribute_integer (string attribute, string argument, int value, SourceReference? source_reference = null) {
unowned Attribute a = get_or_create_attribute (attribute);
- a.add_argument (argument, value.to_string ());
+ a.add_argument (argument, new IntegerLiteral (value.to_string (), source_reference));
}
/**
@@ -297,7 +301,7 @@ public abstract class Vala.CodeNode {
*/
public void set_attribute_double (string attribute, string argument, double value, SourceReference? source_reference = null) {
unowned Attribute a = get_or_create_attribute (attribute);
- a.add_argument (argument, value.format (new char[double.DTOSTR_BUF_SIZE]));
+ a.add_argument (argument, new RealLiteral (value.format (new char[double.DTOSTR_BUF_SIZE]), source_reference));
}
/**
@@ -309,7 +313,7 @@ public abstract class Vala.CodeNode {
*/
public void set_attribute_bool (string attribute, string argument, bool value, SourceReference? source_reference = null) {
unowned Attribute a = get_or_create_attribute (attribute);
- a.add_argument (argument, value.to_string ());
+ a.add_argument (argument, new BooleanLiteral (value, source_reference));
}
/**
diff --git a/vala/valacodewriter.vala b/vala/valacodewriter.vala
index f9f1fccd1..d0d8cb93a 100644
--- a/vala/valacodewriter.vala
+++ b/vala/valacodewriter.vala
@@ -1709,7 +1709,8 @@ public class Vala.CodeWriter : CodeVisitor {
if (arg_name == "cheader_filename") {
stream.printf ("%scheader_filename = \"%s\"", separator, get_cheaders (sym));
} else {
- stream.printf ("%s%s = %s", separator, arg_name, attr.args.get (arg_name));
+ stream.printf ("%s%s = ", separator, arg_name);
+ attr.args.get (arg_name).accept (this);
}
separator = ", ";
}
diff --git a/vala/valaconstant.vala b/vala/valaconstant.vala
index 9ada91cb3..de1da2575 100644
--- a/vala/valaconstant.vala
+++ b/vala/valaconstant.vala
@@ -113,6 +113,8 @@ public class Vala.Constant : Symbol {
context.analyzer.current_symbol = this;
}
+ base.check (context);
+
type_reference.check (context);
if (!check_const_type (type_reference, context)) {
diff --git a/vala/valadelegate.vala b/vala/valadelegate.vala
index cb53d2e91..f4979f45e 100644
--- a/vala/valadelegate.vala
+++ b/vala/valadelegate.vala
@@ -314,6 +314,8 @@ public class Vala.Delegate : TypeSymbol, Callable {
context.analyzer.current_source_file = source_reference.file;
}
+ base.check (context);
+
foreach (TypeParameter p in type_parameters) {
p.check (context);
}
diff --git a/vala/valaenum.vala b/vala/valaenum.vala
index 2d403157d..7cdb64571 100644
--- a/vala/valaenum.vala
+++ b/vala/valaenum.vala
@@ -166,6 +166,8 @@ public class Vala.Enum : TypeSymbol {
}
context.analyzer.current_symbol = this;
+ base.check (context);
+
if (values.size <= 0) {
Report.error (source_reference, "Enum `%s' requires at least one value", get_full_name ());
error = true;
diff --git a/vala/valaenumvalue.vala b/vala/valaenumvalue.vala
index be3fcc52e..a02ce178f 100644
--- a/vala/valaenumvalue.vala
+++ b/vala/valaenumvalue.vala
@@ -71,6 +71,8 @@ public class Vala.EnumValue : Constant {
checked = true;
+ base.check (context);
+
if (value != null) {
value.check (context);
diff --git a/vala/valaerrorcode.vala b/vala/valaerrorcode.vala
index 5fcff7585..7c912c5c5 100644
--- a/vala/valaerrorcode.vala
+++ b/vala/valaerrorcode.vala
@@ -112,6 +112,8 @@ public class Vala.ErrorCode : TypeSymbol {
checked = true;
+ base.check (context);
+
if (value != null) {
value.check (context);
}
diff --git a/vala/valaerrordomain.vala b/vala/valaerrordomain.vala
index 889d0b8ab..8bf5f4e34 100644
--- a/vala/valaerrordomain.vala
+++ b/vala/valaerrordomain.vala
@@ -114,6 +114,8 @@ public class Vala.ErrorDomain : TypeSymbol {
checked = true;
+ base.check (context);
+
if (codes.size <= 0) {
Report.error (source_reference, "Error domain `%s' requires at least one code", get_full_name ());
error = true;
diff --git a/vala/valafield.vala b/vala/valafield.vala
index 566a68b12..99b199831 100644
--- a/vala/valafield.vala
+++ b/vala/valafield.vala
@@ -92,6 +92,8 @@ public class Vala.Field : Variable, Lockable {
}
context.analyzer.current_symbol = this;
+ base.check (context);
+
if (variable_type is VoidType) {
error = true;
Report.error (source_reference, "'void' not supported as field type");
diff --git a/vala/valagenieparser.vala b/vala/valagenieparser.vala
index cca9919eb..0a40beadc 100644
--- a/vala/valagenieparser.vala
+++ b/vala/valagenieparser.vala
@@ -2356,31 +2356,6 @@ public class Vala.Genie.Parser : CodeVisitor {
return new DeleteStatement (expr, get_src (begin));
}
- string parse_attribute_value () throws ParseError {
- switch (current ()) {
- case TokenType.NULL:
- case TokenType.TRUE:
- case TokenType.FALSE:
- case TokenType.INTEGER_LITERAL:
- case TokenType.REAL_LITERAL:
- case TokenType.STRING_LITERAL:
- next ();
- return get_last_string ();
- case TokenType.MINUS:
- next ();
- switch (current ()) {
- case TokenType.INTEGER_LITERAL:
- case TokenType.REAL_LITERAL:
- next ();
- return "-" + get_last_string ();
- default:
- throw new ParseError.SYNTAX ("expected number");
- }
- default:
- throw new ParseError.SYNTAX ("expected literal");
- }
- }
-
List<Attribute>? parse_attributes (bool parameter) throws ParseError {
if (current () != TokenType.OPEN_BRACKET) {
return null;
@@ -2396,7 +2371,7 @@ public class Vala.Genie.Parser : CodeVisitor {
do {
id = parse_identifier ();
expect (TokenType.ASSIGN);
- attr.add_argument (id, parse_attribute_value ());
+ attr.add_argument (id, parse_unary_expression ());
} while (accept (TokenType.COMMA));
}
expect (TokenType.CLOSE_PARENS);
diff --git a/vala/valamethod.vala b/vala/valamethod.vala
index 8c5c3af56..ae8fffc2c 100644
--- a/vala/valamethod.vala
+++ b/vala/valamethod.vala
@@ -748,6 +748,8 @@ public class Vala.Method : Subroutine, Callable {
checked = true;
+ base.check (context);
+
if (this_parameter != null) {
this_parameter.check (context);
}
diff --git a/vala/valanamespace.vala b/vala/valanamespace.vala
index d62babb63..050147fc9 100644
--- a/vala/valanamespace.vala
+++ b/vala/valanamespace.vala
@@ -465,6 +465,8 @@ public class Vala.Namespace : Symbol {
checked = true;
+ base.check (context);
+
var a = get_attribute ("CCode");
if (a != null && a.has_argument ("gir_namespace")) {
var new_gir = a.get_string ("gir_namespace");
diff --git a/vala/valaparameter.vala b/vala/valaparameter.vala
index fb68ab069..2dad80bd4 100644
--- a/vala/valaparameter.vala
+++ b/vala/valaparameter.vala
@@ -140,6 +140,8 @@ public class Vala.Parameter : Variable {
}
context.analyzer.current_symbol = parent_symbol;
+ base.check (context);
+
if (variable_type != null) {
if (variable_type is VoidType) {
error = true;
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index 9ac94e4a5..e97f275da 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -2577,31 +2577,6 @@ public class Vala.Parser : CodeVisitor {
return new WithStatement (local, expr, body, src);
}
- string parse_attribute_value () throws ParseError {
- switch (current ()) {
- case TokenType.NULL:
- case TokenType.TRUE:
- case TokenType.FALSE:
- case TokenType.INTEGER_LITERAL:
- case TokenType.REAL_LITERAL:
- case TokenType.STRING_LITERAL:
- next ();
- return get_last_string ();
- case TokenType.MINUS:
- next ();
- switch (current ()) {
- case TokenType.INTEGER_LITERAL:
- case TokenType.REAL_LITERAL:
- next ();
- return "-" + get_last_string ();
- default:
- throw new ParseError.SYNTAX ("expected number");
- }
- default:
- throw new ParseError.SYNTAX ("expected literal");
- }
- }
-
List<Attribute>? parse_attributes () throws ParseError {
if (current () != TokenType.OPEN_BRACKET) {
return null;
@@ -2617,7 +2592,7 @@ public class Vala.Parser : CodeVisitor {
do {
id = parse_identifier ();
expect (TokenType.ASSIGN);
- attr.add_argument (id, parse_attribute_value ());
+ attr.add_argument (id, parse_unary_expression ());
} while (accept (TokenType.COMMA));
}
expect (TokenType.CLOSE_PARENS);
diff --git a/vala/valasignal.vala b/vala/valasignal.vala
index 2b5005e3b..c639564c1 100644
--- a/vala/valasignal.vala
+++ b/vala/valasignal.vala
@@ -183,6 +183,8 @@ public class Vala.Signal : Symbol, Callable {
checked = true;
+ base.check (context);
+
// parent_symbol may be null for dynamic signals
unowned Class? parent_cl = parent_symbol as Class;
if (parent_cl != null && parent_cl.is_compact) {
diff --git a/vala/valastruct.vala b/vala/valastruct.vala
index 5cce4b24b..50dc90aa9 100644
--- a/vala/valastruct.vala
+++ b/vala/valastruct.vala
@@ -502,6 +502,8 @@ public class Vala.Struct : TypeSymbol {
}
context.analyzer.current_symbol = this;
+ base.check (context);
+
if (base_type != null) {
base_type.check (context);