[vala/wip/issue/327: 3/27] Value type not right
- From: Rico Tzschichholz <ricotz src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [vala/wip/issue/327: 3/27] Value type not right
- Date: Thu, 23 Apr 2020 17:38:08 +0000 (UTC)
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]