diff options
author | Rico Tzschichholz <ricotz@ubuntu.com> | 2019-03-13 08:40:04 +0100 |
---|---|---|
committer | Rico Tzschichholz <ricotz@ubuntu.com> | 2019-10-06 17:57:44 +0200 |
commit | 96ae8699bda464243bb0226eb180d7f5d0797cb8 (patch) | |
tree | da75902962f1762662c8ad3b7adf1279cc97c416 | |
parent | d9c368ae608060be76b3838aa38e3ede945fcb5b (diff) | |
download | vala-wip/defines.tar.gz |
Support `define' expressions in global scope of source fileswip/defines
Fixes https://gitlab.gnome.org/GNOME/vala/issues/765
-rw-r--r-- | ccode/valaccodefile.vala | 19 | ||||
-rw-r--r-- | codegen/valaccodeattribute.vala | 4 | ||||
-rw-r--r-- | codegen/valaccodebasemodule.vala | 16 | ||||
-rw-r--r-- | tests/Makefile.am | 1 | ||||
-rw-r--r-- | tests/parser/define.vala | 12 | ||||
-rw-r--r-- | vala/Makefile.am | 1 | ||||
-rw-r--r-- | vala/valacodevisitor.vala | 8 | ||||
-rw-r--r-- | vala/valadefine.vala | 63 | ||||
-rw-r--r-- | vala/valaparser.vala | 24 | ||||
-rw-r--r-- | vala/valascanner.vala | 9 | ||||
-rw-r--r-- | vala/valasourcefile.vala | 22 | ||||
-rw-r--r-- | vala/valatokentype.vala | 2 |
12 files changed, 173 insertions, 8 deletions
diff --git a/ccode/valaccodefile.vala b/ccode/valaccodefile.vala index cf4870267..30d7eca5b 100644 --- a/ccode/valaccodefile.vala +++ b/ccode/valaccodefile.vala @@ -26,12 +26,12 @@ public class Vala.CCodeFile { public weak SourceFile? file { get; private set; } - Set<string> features = new HashSet<string> (str_hash, str_equal); + Set<string> defines = new HashSet<string> (str_hash, str_equal); Set<string> declarations = new HashSet<string> (str_hash, str_equal); Set<string> definitions = new HashSet<string> (str_hash, str_equal); Set<string> includes = new HashSet<string> (str_hash, str_equal); CCodeFragment comments = new CCodeFragment (); - CCodeFragment feature_test_macros = new CCodeFragment (); + CCodeFragment define_directives = new CCodeFragment (); CCodeFragment include_directives = new CCodeFragment (); CCodeFragment type_declaration = new CCodeFragment (); CCodeFragment type_definition = new CCodeFragment (); @@ -55,10 +55,17 @@ public class Vala.CCodeFile { comments.append (comment); } + public void add_define (CCodeDefine node) { + if (!(node.name in defines)) { + define_directives.append (node); + defines.add (node.name); + } + } + public void add_feature_test_macro (string feature_test_macro) { - if (!(feature_test_macro in features)) { - feature_test_macros.append (new CCodeDefine (feature_test_macro)); - features.add (feature_test_macro); + if (!(feature_test_macro in defines)) { + define_directives.append (new CCodeDefine (feature_test_macro)); + defines.add (feature_test_macro); } } @@ -156,7 +163,7 @@ public class Vala.CCodeFile { comments.write (writer); writer.write_newline (); - feature_test_macros.write (writer); + define_directives.write (writer); writer.write_newline (); include_directives.write (writer); writer.write_newline (); diff --git a/codegen/valaccodeattribute.vala b/codegen/valaccodeattribute.vala index 316570273..5b9f96b8b 100644 --- a/codegen/valaccodeattribute.vala +++ b/codegen/valaccodeattribute.vala @@ -682,7 +682,9 @@ public class Vala.CCodeAttribute : AttributeCache { private string get_default_name () { if (sym != null) { - if (sym is Constant && !(sym is EnumValue)) { + if (sym is Define) { + return sym.name; + } else if (sym is Constant && !(sym is EnumValue)) { if (sym.parent_symbol is Block) { // local constant return sym.name; diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala index 1349a20aa..273dded01 100644 --- a/codegen/valaccodebasemodule.vala +++ b/codegen/valaccodebasemodule.vala @@ -1047,6 +1047,22 @@ public abstract class Vala.CCodeBaseModule : CodeGenerator { pop_line (); } + public override void visit_define (Define d) { + push_line (d.source_reference); + + d.accept_children (this); + + CCodeDefine cdefine; + if (d.value == null) { + cdefine = new CCodeDefine (get_ccode_name (d)); + } else { + cdefine = new CCodeDefine.with_expression (get_ccode_name (d), get_cvalue (d.value)); + } + cfile.add_define (cdefine); + + pop_line (); + } + public void generate_field_declaration (Field f, CCodeFile decl_space) { if (add_symbol_declaration (decl_space, f, get_ccode_name (f))) { return; diff --git a/tests/Makefile.am b/tests/Makefile.am index 011fefa1a..96d1fa931 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -547,6 +547,7 @@ TESTS = \ parser/creation-no-new.test \ parser/creation-no-override.test \ parser/creation-no-virtual.test \ + parser/define.vala \ parser/delegate-anonymous.test \ parser/delegate-no-new.test \ parser/destructor-class-exists.test \ diff --git a/tests/parser/define.vala b/tests/parser/define.vala new file mode 100644 index 000000000..dbc47f850 --- /dev/null +++ b/tests/parser/define.vala @@ -0,0 +1,12 @@ +define ENABLE_SOMETHING; +define G_LOG_DOMAIN = "vala", VALA_PI = 3.1415; + +void foo () { +} + +define ENABLE_SOMETHING_ELSE; + +void main () { +} + +define ENABLE_SOMETHING_DIFFERENT; diff --git a/vala/Makefile.am b/vala/Makefile.am index 57c758fdc..d7b42cd20 100644 --- a/vala/Makefile.am +++ b/vala/Makefile.am @@ -63,6 +63,7 @@ libvala_la_VALASOURCES = \ valacreationmethod.vala \ valadatatype.vala \ valadeclarationstatement.vala \ + valadefine.vala \ valadelegate.vala \ valadelegatedestroyfield.vala \ valadelegatetargetfield.vala \ diff --git a/vala/valacodevisitor.vala b/vala/valacodevisitor.vala index d961f85e9..59d825b0d 100644 --- a/vala/valacodevisitor.vala +++ b/vala/valacodevisitor.vala @@ -205,6 +205,14 @@ public abstract class Vala.CodeVisitor { } /** + * Visit operation called for defines. + * + * @param ns a define + */ + public virtual void visit_define (Define d) { + } + + /** * Visit operation called for type references. * * @param type a type reference diff --git a/vala/valadefine.vala b/vala/valadefine.vala new file mode 100644 index 000000000..07807d88a --- /dev/null +++ b/vala/valadefine.vala @@ -0,0 +1,63 @@ +/* valadefine.vala + * + * Copyright (C) 2019 Rico Tzschichholz + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Author: + * Rico Tzschichholz <ricotz@ubuntu.com> + */ + +using GLib; + +/** + * Represents a define in the source code. + */ +public class Vala.Define : Constant { + /** + * Creates a new define. + * + * @param name define name + * @param value define value + * @return newly created define + */ + public Define (string name, Expression? value, SourceReference? source_reference = null, Comment? comment = null) { + base (name, null, value, source_reference, comment); + } + + public override void accept (CodeVisitor visitor) { + visitor.visit_define (this); + } + + public override void accept_children (CodeVisitor visitor) { + if (value != null) { + value.accept (visitor); + } + } + + public override bool check (CodeContext context) { + if (checked) { + return !error; + } + + checked = true; + + if (value != null) { + value.check (context); + } + + return !error; + } +} diff --git a/vala/valaparser.vala b/vala/valaparser.vala index 0a424333a..418e99e8b 100644 --- a/vala/valaparser.vala +++ b/vala/valaparser.vala @@ -190,6 +190,7 @@ public class Vala.Parser : CodeVisitor { case TokenType.CONSTRUCT: case TokenType.CONTINUE: case TokenType.DEFAULT: + case TokenType.DEFINE: case TokenType.DELEGATE: case TokenType.DELETE: case TokenType.DO: @@ -2281,6 +2282,10 @@ public class Vala.Parser : CodeVisitor { } switch (current ()) { + case TokenType.DEFINE: + rollback (begin); + parse_define (parent); + return; case TokenType.CONSTRUCT: if (context.profile == Profile.GOBJECT) { rollback (begin); @@ -2557,6 +2562,25 @@ public class Vala.Parser : CodeVisitor { } } + void parse_define (Symbol parent) throws ParseError { + if (parent != context.root) { + throw new ParseError.SYNTAX ("`define' expressions allowed only in root namespace"); + } + + expect (TokenType.DEFINE); + do { + var begin = get_location (); + var name = parse_identifier (); + Expression? val = null; + if (accept (TokenType.ASSIGN)) { + val = parse_literal (); + } + var def = new Define (name, val, get_src (begin), comment); + scanner.source_file.add_define (def); + } while (accept (TokenType.COMMA)); + expect (TokenType.SEMICOLON); + } + void parse_class_declaration (Symbol parent, List<Attribute>? attrs) throws ParseError { var begin = get_location (); var access = parse_access_modifier (); diff --git a/vala/valascanner.vala b/vala/valascanner.vala index 718b65471..293cf6efd 100644 --- a/vala/valascanner.vala +++ b/vala/valascanner.vala @@ -424,7 +424,14 @@ public class Vala.Scanner { case 6: switch (begin[0]) { case 'd': - if (matches (begin, "delete")) return TokenType.DELETE; + switch (begin[2]) { + case 'f': + if (matches (begin, "define")) return TokenType.DEFINE; + break; + case 'l': + if (matches (begin, "delete")) return TokenType.DELETE; + break; + } break; case 'e': if (matches (begin, "extern")) return TokenType.EXTERN; diff --git a/vala/valasourcefile.vala b/vala/valasourcefile.vala index 2e270a06c..1a387631d 100644 --- a/vala/valasourcefile.vala +++ b/vala/valasourcefile.vala @@ -129,6 +129,7 @@ public class Vala.SourceFile { public List<UsingDirective> current_using_directives { get; set; default = new ArrayList<UsingDirective> (); } private List<CodeNode> nodes = new ArrayList<CodeNode> (); + private List<Define> defines = new ArrayList<Define> (); string? _relative_filename; @@ -188,6 +189,24 @@ public class Vala.SourceFile { } /** + * Adds the specified define to this source file. + * + * @param define a define + */ + public void add_define (Define define) { + defines.add (define); + } + + /** + * Returns the list of defines. + * + * @return define list + */ + public List<Define> get_defines () { + return defines; + } + + /** * Adds the specified code node to this source file. * * @param node a code node @@ -214,6 +233,9 @@ public class Vala.SourceFile { } public void accept_children (CodeVisitor visitor) { + foreach (Define define in defines) { + define.accept (visitor); + } foreach (CodeNode node in nodes) { node.accept (visitor); } diff --git a/vala/valatokentype.vala b/vala/valatokentype.vala index 75cf92e6c..aee2cc93a 100644 --- a/vala/valatokentype.vala +++ b/vala/valatokentype.vala @@ -57,6 +57,7 @@ public enum Vala.TokenType { CONSTRUCT, CONTINUE, DEFAULT, + DEFINE, DELEGATE, DELETE, DIV, @@ -190,6 +191,7 @@ public enum Vala.TokenType { case CONSTRUCT: return "`construct'"; case CONTINUE: return "`continue'"; case DEFAULT: return "`default'"; + case DEFINE: return "`define'"; case DELEGATE: return "`delegate'"; case DELETE: return "`delete'"; case DIV: return "`/'"; |