summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRico Tzschichholz <ricotz@ubuntu.com>2019-03-13 08:40:04 +0100
committerRico Tzschichholz <ricotz@ubuntu.com>2019-10-06 17:57:44 +0200
commit96ae8699bda464243bb0226eb180d7f5d0797cb8 (patch)
treeda75902962f1762662c8ad3b7adf1279cc97c416
parentd9c368ae608060be76b3838aa38e3ede945fcb5b (diff)
downloadvala-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.vala19
-rw-r--r--codegen/valaccodeattribute.vala4
-rw-r--r--codegen/valaccodebasemodule.vala16
-rw-r--r--tests/Makefile.am1
-rw-r--r--tests/parser/define.vala12
-rw-r--r--vala/Makefile.am1
-rw-r--r--vala/valacodevisitor.vala8
-rw-r--r--vala/valadefine.vala63
-rw-r--r--vala/valaparser.vala24
-rw-r--r--vala/valascanner.vala9
-rw-r--r--vala/valasourcefile.vala22
-rw-r--r--vala/valatokentype.vala2
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 "`/'";