[vala/wip/issue/327: 3/27] Value type not right



commit 30cda46674135b8f39ee77bd2aabf5212e14753b
Author: Nick Schrader <nick schrader mailbox org>
Date:   Fri Mar 27 13:12:09 2020 -0300

    Value type not right

 vala/Makefile.am               |   1 +
 vala/valacodevisitor.vala      |   8 ++
 vala/valamemberaccess.vala     |  24 +++++
 vala/valaparser.vala           |  19 +++-
 vala/valascanner.vala          |  10 ++-
 vala/valasemanticanalyzer.vala |   8 +-
 vala/valasymbolresolver.vala   |  29 ++++++-
 vala/valatokentype.vala        |   2 +-
 vala/valawithstatement.vala    | 193 +++++++++++++++++++++++++++++++++++++++++
 9 files changed, 285 insertions(+), 9 deletions(-)
---
diff --git a/vala/Makefile.am b/vala/Makefile.am
index 78e4c9390..4cbce1371 100644
--- a/vala/Makefile.am
+++ b/vala/Makefile.am
@@ -182,6 +182,7 @@ libvala_la_VALASOURCES = \
        valaversionattribute.vala \
        valavoidtype.vala \
        valawhilestatement.vala \
+       valawithstatement.vala \
        valayieldstatement.vala \
        $(NULL)
 
diff --git a/vala/valacodevisitor.vala b/vala/valacodevisitor.vala
index d961f85e9..a18e0e7fd 100644
--- a/vala/valacodevisitor.vala
+++ b/vala/valacodevisitor.vala
@@ -404,6 +404,14 @@ public abstract class Vala.CodeVisitor {
        public virtual void visit_unlock_statement (UnlockStatement stmt) {
        }
 
+       /**
+        * Visit operation called for with statements.
+        *
+        * @param stmt a with statement
+        */
+       public virtual void visit_with_statement (WithStatement stmt) {
+       }
+
        /**
         * Visit operation called for delete statements.
         *
diff --git a/vala/valamemberaccess.vala b/vala/valamemberaccess.vala
index 2c0355e1d..7940f1190 100644
--- a/vala/valamemberaccess.vala
+++ b/vala/valamemberaccess.vala
@@ -201,6 +201,10 @@ public class Vala.MemberAccess : Expression {
        }
 
        public override bool check (CodeContext context) {
+               if (member_name == "field" || member_name == "foo") {
+                       stdout.printf("member %s, inner %s\n", member_name, inner != null ? 
Type.from_instance(inner).name() : "(null)");
+               }
+
                if (checked) {
                        return !error;
                }
@@ -273,6 +277,9 @@ public class Vala.MemberAccess : Expression {
                                                may_access_instance_members = (m.binding == 
MemberBinding.INSTANCE);
                                                may_access_klass_members = (m.binding != 
MemberBinding.STATIC);
                                                method_found = true;
+                                       } else if (sym is WithStatement) {
+                                               unowned WithStatement w = (WithStatement) sym;
+                                               stdout.printf("Got ittttttttttttttttttttttttttttt\n");
                                        }
                                }
 
@@ -302,6 +309,15 @@ public class Vala.MemberAccess : Expression {
                                        }
                                }
 
+                               var x = "null";
+                               if (sym != null)
+                                       x = Type.from_instance(sym).name();
+
+                               var y = "null";
+                               if (sym.parent_symbol != null)
+                                       y = Type.from_instance(sym.parent_symbol).name();
+       
+                               stdout.printf("sym: %s, parent %s\n", x, y);
                                sym = sym.parent_symbol;
                        }
 
@@ -535,6 +551,7 @@ public class Vala.MemberAccess : Expression {
                                // block as closures (to support nested closures)
                                unowned Symbol? sym = context.analyzer.current_method_or_property_accessor;
                                while (sym != block) {
+                                       stdout.printf("local: %s, block %s, current_sym: %s, sym : %s\n", 
Type.from_instance(local).name(), Type.from_instance(block).name(), 
Type.from_instance(context.analyzer.current_symbol).name(), sym != null ? Type.from_instance(sym).name() : 
"(null)");
                                        unowned Method? method = sym as Method;
                                        if (method != null) {
                                                method.closure = true;
@@ -543,6 +560,8 @@ public class Vala.MemberAccess : Expression {
                                                method.add_captured_variable (local);
                                        }
                                        sym = sym.parent_symbol;
+                                       if (sym == null) // DEBUG infinite loop
+                                               return false;
                                }
 
                                local.captured = true;
@@ -764,6 +783,10 @@ public class Vala.MemberAccess : Expression {
                }
                member.version.check (source_reference);
 
+               if (member_name == "field" || member_name == "foo") {
+                       stdout.printf("member %s, inner %s\n", member_name, inner != null ? 
Type.from_instance(inner).name() : "(null)");
+               }
+
                if (access == SymbolAccessibility.PROTECTED && member.parent_symbol is TypeSymbol) {
                        unowned TypeSymbol target_type = (TypeSymbol) member.parent_symbol;
 
@@ -909,6 +932,7 @@ public class Vala.MemberAccess : Expression {
                }
 
                if (value_type != null) {
+                       stdout.printf("Value type: %s\n",value_type.to_prototype_string() );
                        value_type.check (context);
                }
 
diff --git a/vala/valaparser.vala b/vala/valaparser.vala
index 26595b3ac..6dac79016 100644
--- a/vala/valaparser.vala
+++ b/vala/valaparser.vala
@@ -1616,6 +1616,10 @@ public class Vala.Parser : CodeVisitor {
                                case TokenType.DELETE:
                                        stmt = parse_delete_statement ();
                                        break;
+                               case TokenType.WITH:
+                                       stdout.printf("With");
+                                       stmt = parse_with_statement ();
+                                       break;
                                case TokenType.VAR:
                                        is_decl = true;
                                        parse_local_variable_declarations (block);
@@ -2261,6 +2265,20 @@ public class Vala.Parser : CodeVisitor {
                return new DeleteStatement (expr, src);
        }
 
+       Statement parse_with_statement () throws ParseError {
+               var begin = get_location ();
+               expect (TokenType.WITH);
+               expect (TokenType.OPEN_PARENS);
+               var expr = parse_expression ();
+               expect (TokenType.CLOSE_PARENS);
+               var src = get_src (begin);
+               Block? stmt = null;
+               if (current () != TokenType.SEMICOLON) {
+                       stmt = parse_embedded_statement ("with", false);
+               }
+               return new WithStatement (expr, stmt, src);
+       }
+
        string parse_attribute_value () throws ParseError {
                switch (current ()) {
                case TokenType.NULL:
@@ -3706,4 +3724,3 @@ public errordomain Vala.ParseError {
        FAILED,
        SYNTAX
 }
-
diff --git a/vala/valascanner.vala b/vala/valascanner.vala
index a2e76b4d5..7b6881396 100644
--- a/vala/valascanner.vala
+++ b/vala/valascanner.vala
@@ -386,7 +386,14 @@ public class Vala.Scanner {
                                if (matches (begin, "void")) return TokenType.VOID;
                                break;
                        case 'w':
-                               if (matches (begin, "weak")) return TokenType.WEAK;
+                               switch  (begin[1]) {
+                                       case 'e':
+                                               if (matches (begin, "weak")) return TokenType.WEAK;
+                                               break;
+                                       case 'i':
+                                               if (matches (begin, "with")) return TokenType.WITH;
+                                               break;
+                               }
                                break;
                        }
                        break;
@@ -1679,4 +1686,3 @@ public class Vala.Scanner {
                return comment;
        }
 }
-
diff --git a/vala/valasemanticanalyzer.vala b/vala/valasemanticanalyzer.vala
index f2d2bdd1f..5bef6f277 100644
--- a/vala/valasemanticanalyzer.vala
+++ b/vala/valasemanticanalyzer.vala
@@ -93,7 +93,7 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
        public Symbol? current_method_or_property_accessor {
                get {
                        unowned Symbol? sym = current_symbol;
-                       while (sym is Block) {
+                       while (sym is Block || sym is WithStatement) {
                                sym = sym.parent_symbol;
                        }
                        if (sym is Method) {
@@ -318,7 +318,11 @@ public class Vala.SemanticAnalyzer : CodeVisitor {
                        return result;
                }
 
-               if (sym is Class) {
+               if (sym is WithStatement) {
+                       unowned WithStatement w = (WithStatement) sym;
+                       stdout.printf("Resolved with statement\n");
+                       return w.expression.symbol_reference;
+               } else if (sym is Class) {
                        unowned Class cl = (Class) sym;
                        // first check interfaces without prerequisites
                        // (prerequisites can be assumed to be met already)
diff --git a/vala/valasymbolresolver.vala b/vala/valasymbolresolver.vala
index dbe9b1f21..47370658b 100644
--- a/vala/valasymbolresolver.vala
+++ b/vala/valasymbolresolver.vala
@@ -15,9 +15,7 @@
 
  * 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:
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110visit
  *     Jürg Billeter <j bitron ch>
  *     Raffaele Sandrini <raffaele sandrini ch>
  */
@@ -54,6 +52,9 @@ public class Vala.SymbolResolver : CodeVisitor {
        }
 
        public override void visit_class (Class cl) {
+               if (cl.name == "Foo") {
+                       stdout.printf("visit %s\n", cl.name);
+               }
                if (cl.checked) {
                        return;
                }
@@ -480,6 +481,28 @@ public class Vala.SymbolResolver : CodeVisitor {
                list.accept_children (this);
        }
 
+       public override void visit_with_statement (WithStatement stmt) {
+               //  var unresolved = UnresolvedSymbol.new_from_expression (stmt.expression);
+               //  stdout.printf("Unresolved: %s\n", unresolved.to_string());
+               //  var symbol = resolve_symbol(unresolved);
+
+               //  var old_scope = current_scope;
+               //  current_scope = symbol.scope;
+
+               //  current_scope = old_scope;
+
+               //  if (stmt.checked) {
+               //      return;
+               //  }
+
+               //  var old_scope = current_scope;
+               //  //current_scope = stmt.innerScope;
+
+               stmt.accept_children (this);
+
+               //  current_scope = old_scope;
+       }
+
        public override void visit_expression_statement (ExpressionStatement stmt) {
                if (stmt.checked) {
                        return;
diff --git a/vala/valatokentype.vala b/vala/valatokentype.vala
index 75cf92e6c..08fbb9840 100644
--- a/vala/valatokentype.vala
+++ b/vala/valatokentype.vala
@@ -153,6 +153,7 @@ public enum Vala.TokenType {
        VOLATILE,
        WEAK,
        WHILE,
+       WITH,
        YIELD;
 
        public unowned string to_string () {
@@ -291,4 +292,3 @@ public enum Vala.TokenType {
                }
        }
 }
-
diff --git a/vala/valawithstatement.vala b/vala/valawithstatement.vala
new file mode 100644
index 000000000..6908f62f4
--- /dev/null
+++ b/vala/valawithstatement.vala
@@ -0,0 +1,193 @@
+/* valalockstatement.vala
+ *
+ * Copyright (C) 2009  Jiří Zárevúcky
+ * Copyright (C) 2006-2010  Jürg Billeter
+ * Copyright (C) 2006-2007  Raffaele Sandrini
+ *
+ * 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
+ *
+ * Authors:
+ *     Raffaele Sandrini <raffaele sandrini ch>
+ *     Jiří Zárevúcky <zarevucky jiri gmail com>
+ */
+
+using GLib;
+
+/**
+ * Represents a lock statement e.g. {{{ lock (a); }}} or {{{ lock (a) { f(a); } }}}.
+ *
+ * If the statement is empty, the mutex remains locked until a corresponding UnlockStatement
+ * occurs. Otherwise it's translated into a try/finally statement which unlocks the mutex
+ * after the block is finished.
+ */
+public class Vala.WithStatement : Symbol, Statement {
+       /**
+        * Expression representing the expression to be locked.
+        */
+       public Expression expression {
+               get { return _expression; }
+               set {
+                       _expression = value;
+                       _expression.parent_node = this;
+               }
+       }
+
+       /**
+        * The statement during its execution the expression is locked.
+        */
+       public Block? body {
+               get { return _body; }
+               set {
+                       _body = value;
+                       if (_body != null) {
+                               _body.parent_node = this;
+                       }
+               }
+       }
+
+       /* public Scope scope {
+               get { 
+                       stdout.printf("with scope\n");
+                       return expression.symbol_reference.scope; 
+               }
+       } */
+
+       private Expression _expression;
+       private Block _body;
+
+       public WithStatement (Expression expression, Block? body, SourceReference? source_reference = null) {
+               base("with", source_reference);
+               this.body = body;
+               this.source_reference = source_reference;
+               this.expression = expression;
+       }
+
+       public override void accept (CodeVisitor visitor) {
+               stdout.printf("Accept with\n");
+               visitor.visit_with_statement (this);
+       }
+
+       public override void accept_children(CodeVisitor visitor) {
+               stdout.printf("Accept children with\n");
+               expression.accept (visitor);
+               if (body != null) {
+                       body.accept (visitor);
+               }
+       }
+
+       public override void replace_expression (Expression old_node, Expression new_node) {
+               if (expression == old_node) {
+                       expression = new_node;
+               }
+       }
+
+       public override bool check (CodeContext context) {
+               stdout.printf("Check with\n");
+
+               expression.check(context);
+
+               var old_symbol = context.analyzer.current_symbol;
+               var old_insert_block = context.analyzer.insert_block;
+               owner = context.analyzer.current_symbol.scope;
+               //owner = expression.symbol_reference.scope;
+               context.analyzer.current_symbol = this;
+
+               stdout.printf("With expression: %s\n", Type.from_instance(expression).name());
+
+               /*var sr = expression.symbol_reference;
+               var sc = sr.scope;
+               var st = sc.get_symbol_table();
+               var iter = st.map_iterator();
+               while (iter.next()) {
+                       scope.add(iter.get_key(), iter.get_value());
+                       stdout.printf("Symbol %s\n", iter.get_key());
+               }*/
+
+               //context.analyzer.current_symbol = expression.symbol_reference;
+               //context.analyzer.insert_block = body;
+
+               //  var cc = context.analyzer.current_class;
+               //  var cs = context.analyzer.current_symbol;
+               //  var cm = context.analyzer.current_method_or_property_accessor;
+
+               //  stdout.printf("cs %s, cc %s, cm %s\n", cc.name, cs.name, cm.name);
+
+               //body.parent_node = expression;
+               body.check(context);
+
+               //context.analyzer.current_symbol = old_symbol;
+               //context.analyzer.insert_block = old_insert_block;
+               context.analyzer.current_symbol = old_symbol;
+               return true;
+               // Ehh change context somehow...
+               //  if (body != null) {
+               //      // if the statement isn't empty, it is converted into a try statement
+
+               //      var fin_body = new Block (source_reference);
+               //      fin_body.add_statement (new UnlockStatement (resource, source_reference));
+
+               //      var block = new Block (source_reference);
+               //      block.add_statement (new LockStatement (resource, null, source_reference));
+               //      block.add_statement (new TryStatement (body, fin_body, source_reference));
+
+               //      var parent_block = (Block) parent_node;
+               //      parent_block.replace_statement (this, block);
+
+               //      return block.check (context);
+               //  }
+
+               //  if (checked) {
+               //      return !error;
+               //  }
+
+               //  checked = true;
+
+               //  resource.check (context);
+
+               //  /* resource must be a member access and denote a Lockable */
+               //  if (!(resource is MemberAccess && resource.symbol_reference is Lockable)) {
+               //      error = true;
+               //      resource.error = true;
+               //      Report.error (resource.source_reference, "Expression is either not a member access or 
does not denote a lockable member");
+               //      return false;
+               //  }
+
+               //  /* parent symbol must be the current class */
+               //  if (resource.symbol_reference.parent_symbol != context.analyzer.current_class) {
+               //      error = true;
+               //      resource.error = true;
+               //      Report.error (resource.source_reference, "Only members of the current class are 
lockable");
+               //      return false;
+               //  }
+
+               //  /* parent class must not be compact */
+               //  if (context.analyzer.current_class.is_compact) {
+               //      error = true;
+               //      resource.error = true;
+               //      Report.error (resource.source_reference, "Only members of the non-compact classes are 
lockable");
+               //      return false;
+               //  }
+
+               //  ((Lockable) resource.symbol_reference).lock_used = true;
+
+               //  return !error;
+       }
+
+       public override void emit (CodeGenerator codegen) {
+               expression.emit (codegen);
+               body.emit (codegen);
+               //codegen.visit_with_statement (this);
+       }
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]