[vala/wip/transform: 4/50] Code transformer
- From: Luca Bruno <lucabru src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/wip/transform: 4/50] Code transformer
- Date: Fri, 13 Apr 2012 13:07:35 +0000 (UTC)
commit 948a501ef660236af0c58b217362cb371635adfa
Author: Luca Bruno <lucabru src gnome org>
Date: Sun Aug 7 12:22:15 2011 +0200
Code transformer
compiler/valacompiler.vala | 7 +
vala/Makefile.am | 1 +
vala/valacodetransformer.vala | 269 +++++++++++++++++++++++++++++++++++++++++
vala/valamethodcall.vala | 41 ------
4 files changed, 277 insertions(+), 41 deletions(-)
---
diff --git a/compiler/valacompiler.vala b/compiler/valacompiler.vala
index 058b501..8415765 100644
--- a/compiler/valacompiler.vala
+++ b/compiler/valacompiler.vala
@@ -342,6 +342,13 @@ class Vala.Compiler {
}
}
+ var transformer = new CodeTransformer ();
+ transformer.transform (context);
+
+ if (context.report.get_errors () > 0 || (fatal_warnings && context.report.get_warnings () > 0)) {
+ return quit ();
+ }
+
if (dump_tree != null) {
var code_writer = new CodeWriter (CodeWriterType.DUMP);
code_writer.write_file (context, dump_tree);
diff --git a/vala/Makefile.am b/vala/Makefile.am
index 999a63a..6b3a79d 100644
--- a/vala/Makefile.am
+++ b/vala/Makefile.am
@@ -37,6 +37,7 @@ libvalacore_la_VALASOURCES = \
valacodecontext.vala \
valacodegenerator.vala \
valacodenode.vala \
+ valacodetransformer.vala \
valacodevisitor.vala \
valacodewriter.vala \
valacomment.vala \
diff --git a/vala/valacodetransformer.vala b/vala/valacodetransformer.vala
new file mode 100644
index 0000000..e370e78
--- /dev/null
+++ b/vala/valacodetransformer.vala
@@ -0,0 +1,269 @@
+/* valacodetransformer.vala
+ *
+ * Copyright (C) 2011 Luca Bruno
+ *
+ * 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:
+ * Luca Bruno <lucabru src gnome org>
+ */
+
+/**
+ * Code visitor for transforming the code tree.
+ */
+public class Vala.CodeTransformer : CodeVisitor {
+ public CodeContext context;
+
+ /**
+ * Transform the code tree for the specified code context.
+ *
+ * @param context a code context
+ */
+ public void transform (CodeContext context) {
+ this.context = context;
+
+ /* we're only interested in non-pkg source files */
+ var source_files = context.get_source_files ();
+ foreach (SourceFile file in source_files) {
+ if (file.file_type == SourceFileType.SOURCE ||
+ (context.header_filename != null && file.file_type == SourceFileType.FAST)) {
+ file.accept (this);
+ }
+ }
+ }
+
+ public void check (CodeNode node) {
+ if (!node.check (context)) {
+ return;
+ }
+ //node.accept (this);
+ }
+
+ public override void visit_source_file (SourceFile source_file) {
+ source_file.accept_children (this);
+ }
+
+ public override void visit_namespace (Namespace ns) {
+ ns.accept_children (this);
+ }
+
+ public override void visit_class (Class cl) {
+ cl.accept_children (this);
+ }
+
+ public override void visit_struct (Struct st) {
+ st.accept_children (this);
+ }
+
+ public override void visit_interface (Interface iface) {
+ iface.accept_children (this);
+ }
+
+ public override void visit_enum (Enum en) {
+ en.accept_children (this);
+ }
+
+ public override void visit_enum_value (EnumValue ev) {
+ ev.accept_children (this);
+ }
+
+ public override void visit_error_domain (ErrorDomain edomain) {
+ edomain.accept_children (this);
+ }
+
+ public override void visit_error_code (ErrorCode ecode) {
+ ecode.accept_children (this);
+ }
+
+ public override void visit_delegate (Delegate d) {
+ d.accept_children (this);
+ }
+
+ public override void visit_constant (Constant c) {
+ c.accept_children (this);
+ }
+
+ public override void visit_field (Field f) {
+ f.accept_children (this);
+ }
+
+ public override void visit_method (Method m) {
+ m.accept_children (this);
+ }
+
+ public override void visit_creation_method (CreationMethod m) {
+ m.accept_children (this);
+ }
+
+ public override void visit_formal_parameter (Parameter p) {
+ p.accept_children (this);
+ }
+
+ public override void visit_property (Property prop) {
+ prop.accept_children (this);
+ }
+
+ public override void visit_property_accessor (PropertyAccessor acc) {
+ acc.accept_children (this);
+ }
+
+ public override void visit_signal (Signal sig) {
+ sig.accept_children (this);
+ }
+
+ public override void visit_constructor (Constructor c) {
+ c.accept_children (this);
+ }
+
+ public override void visit_destructor (Destructor d) {
+ d.accept_children (this);
+ }
+
+ public override void visit_block (Block b) {
+ b.accept_children (this);
+ }
+
+ public override void visit_declaration_statement (DeclarationStatement stmt) {
+ stmt.accept_children (this);
+ }
+
+ public override void visit_local_variable (LocalVariable local) {
+ local.accept_children (this);
+ }
+
+ public override void visit_initializer_list (InitializerList list) {
+ list.accept_children (this);
+ }
+
+ public override void visit_expression_statement (ExpressionStatement stmt) {
+ stmt.accept_children (this);
+ }
+
+ public override void visit_if_statement (IfStatement stmt) {
+ stmt.accept_children (this);
+ }
+
+ public override void visit_switch_statement (SwitchStatement stmt) {
+ stmt.accept_children (this);
+ }
+
+ public override void visit_switch_section (SwitchSection section) {
+ section.accept_children (this);
+ }
+
+ public override void visit_switch_label (SwitchLabel label) {
+ label.accept_children (this);
+ }
+
+ public override void visit_while_statement (WhileStatement stmt) {
+ stmt.accept_children (this);
+ }
+
+ public override void visit_do_statement (DoStatement stmt) {
+ stmt.accept_children (this);
+ }
+
+ public override void visit_for_statement (ForStatement stmt) {
+ stmt.accept_children (this);
+ }
+
+ public override void visit_foreach_statement (ForeachStatement stmt) {
+ stmt.accept_children (this);
+ }
+
+ public override void visit_break_statement (BreakStatement stmt) {
+ stmt.accept_children (this);
+ }
+
+ public override void visit_continue_statement (ContinueStatement stmt) {
+ stmt.accept_children (this);
+ }
+
+ public override void visit_return_statement (ReturnStatement stmt) {
+ stmt.accept_children (this);
+ }
+
+ public override void visit_yield_statement (YieldStatement stmt) {
+ stmt.accept_children (this);
+ }
+
+ public override void visit_throw_statement (ThrowStatement stmt) {
+ stmt.accept_children (this);
+ }
+
+ public override void visit_try_statement (TryStatement stmt) {
+ stmt.accept_children (this);
+ }
+
+ public override void visit_catch_clause (CatchClause clause) {
+ clause.accept_children (this);
+ }
+
+ public override void visit_lock_statement (LockStatement stmt) {
+ stmt.accept_children (this);
+ }
+
+ public override void visit_unlock_statement (UnlockStatement stmt) {
+ stmt.accept_children (this);
+ }
+
+ public override void visit_delete_statement (DeleteStatement stmt) {
+ stmt.accept_children (this);
+ }
+
+ public override void visit_expression (Expression expr) {
+ expr.accept_children (this);
+ }
+
+ public override void visit_method_call (MethodCall expr) {
+ if (expr.tree_can_fail) {
+ if (expr.parent_node is LocalVariable || expr.parent_node is ExpressionStatement) {
+ // simple statements, no side effects after method call
+ } else if (!(context.analyzer.get_current_symbol (expr) is Block)) {
+ if (context.profile != Profile.DOVA) {
+ // can't handle errors in field initializers
+ Report.error (expr.source_reference, "Field initializers must not throw errors");
+ }
+ } else {
+ // store parent_node as we need to replace the expression in the old parent node later on
+ var old_parent_node = expr.parent_node;
+
+ var local = new LocalVariable (expr.value_type, expr.get_temp_name (), null, expr.source_reference);
+ // use floating variable to avoid unnecessary (and sometimes impossible) copies
+ local.floating = true;
+ var decl = new DeclarationStatement (local, expr.source_reference);
+
+ expr.insert_statement (context.analyzer.get_insert_block (expr), decl);
+
+ Expression temp_access = new MemberAccess.simple (local.name, expr.source_reference);
+ temp_access.target_type = expr.target_type;
+
+ // don't set initializer earlier as this changes parent_node and parent_statement
+ local.initializer = expr;
+ check (decl);
+
+ // move temp variable to insert block to ensure
+ // variable is in the same block as the declarat
+ // otherwise there will be scoping issues in the
+ var block = context.analyzer.get_current_block (expr);
+ block.remove_local_variable (local);
+ context.analyzer.get_insert_block (expr).add_local_variable (local);
+
+ old_parent_node.replace_expression (expr, temp_access);
+ check (temp_access);
+ }
+ }
+ }
+}
diff --git a/vala/valamethodcall.vala b/vala/valamethodcall.vala
index afdf6b9..6ac0e1a 100644
--- a/vala/valamethodcall.vala
+++ b/vala/valamethodcall.vala
@@ -588,8 +588,6 @@ public class Vala.MethodCall : Expression {
formal_value_type = ret_type;
value_type = formal_value_type.get_actual_type (target_object_type, call as MemberAccess, this);
- bool may_throw = false;
-
if (mtype is MethodType) {
var m = ((MethodType) mtype).method_symbol;
if (is_yield_expression) {
@@ -604,7 +602,6 @@ public class Vala.MethodCall : Expression {
}
current_method.yield_count++;
}
-
if (m.returns_floating_reference) {
value_type.floating_reference = true;
}
@@ -698,44 +695,6 @@ public class Vala.MethodCall : Expression {
return false;
}
- if (tree_can_fail) {
- if (parent_node is LocalVariable || parent_node is ExpressionStatement) {
- // simple statements, no side effects after method call
- } else if (!(context.analyzer.get_current_symbol (this) is Block)) {
- if (context.profile != Profile.DOVA) {
- // can't handle errors in field initializers
- Report.error (source_reference, "Field initializers must not throw errors");
- }
- } else {
- // store parent_node as we need to replace the expression in the old parent node later on
- var old_parent_node = parent_node;
-
- var local = new LocalVariable (value_type, get_temp_name (), null, source_reference);
- // use floating variable to avoid unnecessary (and sometimes impossible) copies
- local.floating = true;
- var decl = new DeclarationStatement (local, source_reference);
-
- insert_statement (context.analyzer.get_insert_block (this), decl);
-
- Expression temp_access = new MemberAccess.simple (local.name, source_reference);
- temp_access.target_type = target_type;
-
- // don't set initializer earlier as this changes parent_node and parent_statement
- local.initializer = this;
- decl.check (context);
-
- // move temp variable to insert block to ensure
- // variable is in the same block as the declarat
- // otherwise there will be scoping issues in the
- var block = context.analyzer.get_current_block (this);
- block.remove_local_variable (local);
- context.analyzer.get_insert_block (this).add_local_variable (local);
-
- old_parent_node.replace_expression (this, temp_access);
- temp_access.check (context);
- }
- }
-
return !error;
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]