]> git.ipfire.org Git - thirdparty/vala.git/commitdiff
parser: Add support for explicit "unlock" syntax
authorRico Tzschichholz <ricotz@ubuntu.com>
Wed, 25 Apr 2018 14:08:06 +0000 (16:08 +0200)
committerRico Tzschichholz <ricotz@ubuntu.com>
Wed, 25 Apr 2018 17:51:14 +0000 (19:51 +0200)
By providing more control over the internal support for Mutex creation and
usage, this allows a more complex resource control while having an explicit
way to unlock a previously locked lockable.

  lock (foo);
  ...
  unlock (foo);

https://bugzilla.gnome.org/show_bug.cgi?id=795545

tests/Makefile.am
tests/parser/lock-statement.vala [new file with mode: 0644]
vala/valaparser.vala
vala/valascanner.vala
vala/valatokentype.vala

index 025d0f891ef835d31dcfcdf4794171caf91e9eb1..134369b6c5152bb8ed8940b151cb1c359fe8a346 100644 (file)
@@ -420,6 +420,7 @@ TESTS = \
        parser/function-syntax-error.test \
        parser/inner-array-size.test \
        parser/invalid-brace.test \
+       parser/lock-statement.vala \
        parser/method-no-abstract-override.test \
        parser/method-no-abstract-virtual-override.test \
        parser/method-no-abstract-virtual.test \
diff --git a/tests/parser/lock-statement.vala b/tests/parser/lock-statement.vala
new file mode 100644 (file)
index 0000000..65d9d82
--- /dev/null
@@ -0,0 +1,19 @@
+class Foo {
+       int lockable;
+
+       public void explicit_unlocking () {
+               lock (lockable);
+               unlock (lockable);
+       }
+
+       public void implicit_unlocking () {
+               lock (lockable) {
+               }
+       }
+}
+
+void main () {
+       var foo = new Foo ();
+       foo.explicit_unlocking ();
+       foo.implicit_unlocking ();
+}
index 3df315d1fe9190d11e5a8654751bf93b11d391b0..eca5565cfdd170915bb06f7400cee15da2f19766 100644 (file)
@@ -238,6 +238,7 @@ public class Vala.Parser : CodeVisitor {
                case TokenType.TRUE:
                case TokenType.TRY:
                case TokenType.TYPEOF:
+               case TokenType.UNLOCK:
                case TokenType.UNOWNED:
                case TokenType.USING:
                case TokenType.VAR:
@@ -1576,6 +1577,9 @@ public class Vala.Parser : CodeVisitor {
                                case TokenType.LOCK:
                                        stmt = parse_lock_statement ();
                                        break;
+                               case TokenType.UNLOCK:
+                                       stmt = parse_unlock_statement ();
+                                       break;
                                case TokenType.DELETE:
                                        stmt = parse_delete_statement ();
                                        break;
@@ -1740,6 +1744,7 @@ public class Vala.Parser : CodeVisitor {
                case TokenType.THROW:     return parse_throw_statement ();
                case TokenType.TRY:       return parse_try_statement ();
                case TokenType.LOCK:      return parse_lock_statement ();
+               case TokenType.UNLOCK:    return parse_unlock_statement ();
                case TokenType.DELETE:    return parse_delete_statement ();
                case TokenType.VAR:
                case TokenType.CONST:
@@ -2134,10 +2139,23 @@ public class Vala.Parser : CodeVisitor {
                expect (TokenType.OPEN_PARENS);
                var expr = parse_expression ();
                expect (TokenType.CLOSE_PARENS);
-               var stmt = parse_embedded_statement ("lock", false);
+               Block? stmt = null;
+               if (current () != TokenType.SEMICOLON) {
+                       stmt = parse_embedded_statement ("lock", false);
+               }
                return new LockStatement (expr, stmt, get_src (begin));
        }
 
+       Statement parse_unlock_statement () throws ParseError {
+               var begin = get_location ();
+               expect (TokenType.UNLOCK);
+               expect (TokenType.OPEN_PARENS);
+               var expr = parse_expression ();
+               expect (TokenType.CLOSE_PARENS);
+               expect (TokenType.SEMICOLON);
+               return new UnlockStatement (expr, get_src (begin));
+       }
+
        Statement parse_delete_statement () throws ParseError {
                var begin = get_location ();
                expect (TokenType.DELETE);
@@ -2265,6 +2283,7 @@ public class Vala.Parser : CodeVisitor {
                case TokenType.THROW:
                case TokenType.TRY:
                case TokenType.LOCK:
+               case TokenType.UNLOCK:
                case TokenType.DELETE:
                case TokenType.VAR:
                case TokenType.OP_INC:
@@ -2450,6 +2469,7 @@ public class Vala.Parser : CodeVisitor {
                        case TokenType.SWITCH:
                        case TokenType.THROW:
                        case TokenType.TRY:
+                       case TokenType.UNLOCK:
                        case TokenType.VAR:
                        case TokenType.WHILE:
                        case TokenType.YIELD:
index 8b50a59d4eb94c90b80796c7a316b886f334e867..2cb705064afd77aa905f468336836d5558ec05c5 100644 (file)
@@ -473,6 +473,9 @@ public class Vala.Scanner {
                                        break;
                                }
                                break;
+                       case 'u':
+                               if (matches (begin, "unlock")) return TokenType.UNLOCK;
+                               break;
                        }
                        break;
                case 7:
index a3867f5fb428f465fe0b73f8d7ed045d70bb0e41..38be631b7c4dd46f86926b154a855f42271149b1 100644 (file)
@@ -143,6 +143,7 @@ public enum Vala.TokenType {
        TRUE,
        TRY,
        TYPEOF,
+       UNLOCK,
        UNOWNED,
        USING,
        VAR,
@@ -275,6 +276,7 @@ public enum Vala.TokenType {
                case TRUE: return "`true'";
                case TRY: return "`try'";
                case TYPEOF: return "`typeof'";
+               case UNLOCK: return "`unlock'";
                case UNOWNED: return "`unowned'";
                case USING: return "`using'";
                case VAR: return "`var'";