diff options
author | Luca Bruno <lucabru@src.gnome.org> | 2011-08-07 12:22:15 +0200 |
---|---|---|
committer | Rico Tzschichholz <ricotz@ubuntu.com> | 2019-03-11 13:49:26 +0100 |
commit | 2a5750135a633e743ab70d474aeaded762d5e5bb (patch) | |
tree | 8e72b801d05b1d176a310fc450676794f3316446 /vala | |
parent | 9c8417eaa82f6c2f9cf861e85ef16810758a105c (diff) | |
download | vala-2a5750135a633e743ab70d474aeaded762d5e5bb.tar.gz |
Code transformer
Diffstat (limited to 'vala')
-rw-r--r-- | vala/Makefile.am | 1 | ||||
-rw-r--r-- | vala/valacodetransformer.vala | 264 | ||||
-rw-r--r-- | vala/valamethodcall.vala | 33 |
3 files changed, 265 insertions, 33 deletions
diff --git a/vala/Makefile.am b/vala/Makefile.am index 6be70557d..ccf80e4bd 100644 --- a/vala/Makefile.am +++ b/vala/Makefile.am @@ -51,6 +51,7 @@ libvala_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 000000000..1f0136d79 --- /dev/null +++ b/vala/valacodetransformer.vala @@ -0,0 +1,264 @@ +/* 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_non_local_symbol (expr) is Block)) { + // 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); + var decl = new DeclarationStatement (local, expr.source_reference); + + expr.insert_statement (context.analyzer.get_insert_block (expr), decl); + + var temp_access = SemanticAnalyzer.create_temp_access (local, 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 041d096d2..262b789d8 100644 --- a/vala/valamethodcall.vala +++ b/vala/valamethodcall.vala @@ -643,39 +643,6 @@ public class Vala.MethodCall : Expression { value_type.check (context); - 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_non_local_symbol (this) is Block)) { - // 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.copy (), get_temp_name (), null, source_reference); - var decl = new DeclarationStatement (local, source_reference); - - insert_statement (context.analyzer.get_insert_block (this), decl); - - var temp_access = SemanticAnalyzer.create_temp_access (local, 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 the - // variable is in the same block as the declaration - // otherwise there will be scoping issues in the generated code - 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; } |