[vala] Add suport for local constants
- From: Jürg Billeter <juergbi src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala] Add suport for local constants
- Date: Wed, 13 Oct 2010 20:19:08 +0000 (UTC)
commit 46fece1d814e59bb1443697fda41132a93bc4978
Author: Jürg Billeter <j bitron ch>
Date: Wed Oct 13 22:17:41 2010 +0200
Add suport for local constants
Fixes bug 530623.
codegen/valaccodebasemodule.vala | 30 ++++++++++++++++++++++++++++++
vala/valablock.vala | 20 +++++++++++++++++++-
vala/valaconstant.vala | 2 ++
vala/valaparser.vala | 29 +++++++++++++++++++++++++++++
vala/valasymbolresolver.vala | 3 +++
5 files changed, 83 insertions(+), 1 deletions(-)
---
diff --git a/codegen/valaccodebasemodule.vala b/codegen/valaccodebasemodule.vala
index 61eb626..3d8b005 100644
--- a/codegen/valaccodebasemodule.vala
+++ b/codegen/valaccodebasemodule.vala
@@ -719,6 +719,11 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
public void generate_constant_declaration (Constant c, CCodeFile decl_space, bool definition = false) {
+ if (c.parent_symbol is Block) {
+ // local constant
+ return;
+ }
+
if (add_symbol_declaration (decl_space, c, c.get_cname ())) {
return;
}
@@ -759,6 +764,31 @@ public class Vala.CCodeBaseModule : CodeGenerator {
}
public override void visit_constant (Constant c) {
+ if (c.parent_symbol is Block) {
+ // local constant
+
+ generate_type_declaration (c.type_reference, cfile);
+
+ c.value.emit (this);
+
+ string type_name = c.type_reference.get_const_cname ();
+ string arr = "";
+ if (c.type_reference is ArrayType) {
+ arr = "[]";
+ }
+
+ if (c.type_reference.compatible (string_type)) {
+ type_name = "const char";
+ arr = "[]";
+ }
+
+ var cinitializer = get_cvalue (c.value);
+
+ ccode.add_declaration (type_name, new CCodeVariableDeclarator ("%s%s".printf (c.get_cname (), arr), cinitializer), CCodeModifiers.STATIC);
+
+ return;
+ }
+
generate_constant_declaration (c, cfile, true);
if (!c.is_internal_symbol ()) {
diff --git a/vala/valablock.vala b/vala/valablock.vala
index d7b35f2..c5b044d 100644
--- a/vala/valablock.vala
+++ b/vala/valablock.vala
@@ -36,6 +36,7 @@ public class Vala.Block : Symbol, Statement {
private List<Statement> statement_list = new ArrayList<Statement> ();
private List<LocalVariable> local_variables = new ArrayList<LocalVariable> ();
+ private List<Constant> local_constants = new ArrayList<Constant> ();
/**
* Creates a new block.
@@ -90,7 +91,7 @@ public class Vala.Block : Symbol, Statement {
var parent_block = parent_symbol;
while (parent_block is Block || parent_block is Method || parent_block is PropertyAccessor) {
if (parent_block.scope.lookup (local.name) != null) {
- Report.error (local.source_reference, "Local variable `%s' conflicts with another local variable declared in a parent scope".printf (local.name));
+ Report.error (local.source_reference, "Local variable `%s' conflicts with a local variable or constant declared in a parent scope".printf (local.name));
break;
}
parent_block = parent_block.parent_symbol;
@@ -111,6 +112,19 @@ public class Vala.Block : Symbol, Statement {
return local_variables;
}
+ public void add_local_constant (Constant constant) {
+ var parent_block = parent_symbol;
+ while (parent_block is Block || parent_block is Method || parent_block is PropertyAccessor) {
+ if (parent_block.scope.lookup (constant.name) != null) {
+ Report.error (constant.source_reference, "Local constant `%s' conflicts with a local variable or constant declared in a parent scope".printf (constant.name));
+ break;
+ }
+ parent_block = parent_block.parent_symbol;
+ }
+ local_constants.add (constant);
+ scope.add (constant.name, constant);
+ }
+
public override void accept (CodeVisitor visitor) {
visitor.visit_block (this);
}
@@ -143,6 +157,10 @@ public class Vala.Block : Symbol, Statement {
local.active = false;
}
+ foreach (Constant constant in local_constants) {
+ constant.active = false;
+ }
+
// use get_statements () instead of statement_list to not miss errors within StatementList objects
foreach (Statement stmt in get_statements ()) {
add_error_types (stmt.get_error_types ());
diff --git a/vala/valaconstant.vala b/vala/valaconstant.vala
index 02b815f..9860c3a 100644
--- a/vala/valaconstant.vala
+++ b/vala/valaconstant.vala
@@ -217,6 +217,8 @@ public class Vala.Constant : Symbol, Lockable {
analyzer.current_source_file = old_source_file;
analyzer.current_symbol = old_symbol;
+ active = true;
+
return !error;
}
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index 44fbd00..43dd8e0 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -1495,6 +1495,10 @@ public class Vala.Parser : CodeVisitor {
is_decl = true;
parse_local_variable_declarations (block);
break;
+ case TokenType.CONST:
+ is_decl = true;
+ parse_local_constant_declarations (block);
+ break;
case TokenType.OP_INC:
case TokenType.OP_DEC:
case TokenType.BASE:
@@ -1709,6 +1713,31 @@ public class Vala.Parser : CodeVisitor {
return new LocalVariable (type, id, initializer, get_src (begin));
}
+ void parse_local_constant_declarations (Block block) throws ParseError {
+ expect (TokenType.CONST);
+ var constant_type = parse_type (false, false);
+ do {
+ DataType type_copy = constant_type.copy ();
+ var local = parse_local_constant (type_copy);
+ block.add_statement (new DeclarationStatement (local, local.source_reference));
+ block.add_local_constant (local);
+ local.active = false;
+ } while (accept (TokenType.COMMA));
+ expect (TokenType.SEMICOLON);
+ }
+
+ Constant parse_local_constant (DataType constant_type) throws ParseError {
+ var begin = get_location ();
+ string id = parse_identifier ();
+
+ var type = parse_inline_array_type (constant_type);
+
+ expect (TokenType.ASSIGN);
+ var initializer = parse_expression ();
+
+ return new Constant (id, type, initializer, get_src (begin));
+ }
+
Statement parse_expression_statement () throws ParseError {
var begin = get_location ();
var expr = parse_statement_expression ();
diff --git a/vala/valasymbolresolver.vala b/vala/valasymbolresolver.vala
index 0afb976..54b3309 100644
--- a/vala/valasymbolresolver.vala
+++ b/vala/valasymbolresolver.vala
@@ -158,9 +158,12 @@ public class Vala.SymbolResolver : CodeVisitor {
}
public override void visit_constant (Constant c) {
+ var old_scope = current_scope;
current_scope = c.scope;
c.accept_children (this);
+
+ current_scope = old_scope;
}
public override void visit_field (Field f) {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]