diff options
author | Rico Tzschichholz <ricotz@ubuntu.com> | 2023-01-30 20:19:50 +0100 |
---|---|---|
committer | Rico Tzschichholz <ricotz@ubuntu.com> | 2023-03-09 12:33:51 +0100 |
commit | 4c26e30c0a9b698d7909722abfe66a91239e4e5a (patch) | |
tree | 05551c4989137308988faded30a26be3560ef7b7 | |
parent | d5ecd13849a6a9126d3b90d16a3268f860800b41 (diff) | |
download | vala-wip/attribute-expression.tar.gz |
WIP vala: Use Vala.Expression as Vala.Attribute valueswip/attribute-expression
-rw-r--r-- | codegen/valagdbusclientmodule.vala | 18 | ||||
-rw-r--r-- | codegen/valagdbusmodule.vala | 9 | ||||
-rw-r--r-- | vala/valaattribute.vala | 67 | ||||
-rw-r--r-- | vala/valaclass.vala | 2 | ||||
-rw-r--r-- | vala/valacodenode.vala | 12 | ||||
-rw-r--r-- | vala/valacodewriter.vala | 3 | ||||
-rw-r--r-- | vala/valaconstant.vala | 2 | ||||
-rw-r--r-- | vala/valadelegate.vala | 2 | ||||
-rw-r--r-- | vala/valaenum.vala | 2 | ||||
-rw-r--r-- | vala/valaenumvalue.vala | 2 | ||||
-rw-r--r-- | vala/valaerrorcode.vala | 2 | ||||
-rw-r--r-- | vala/valaerrordomain.vala | 2 | ||||
-rw-r--r-- | vala/valafield.vala | 2 | ||||
-rw-r--r-- | vala/valagenieparser.vala | 27 | ||||
-rw-r--r-- | vala/valamethod.vala | 2 | ||||
-rw-r--r-- | vala/valanamespace.vala | 2 | ||||
-rw-r--r-- | vala/valaparameter.vala | 2 | ||||
-rw-r--r-- | vala/valaparser.vala | 27 | ||||
-rw-r--r-- | vala/valasignal.vala | 2 | ||||
-rw-r--r-- | vala/valastruct.vala | 2 |
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); |