Cascaded invocations
#327 (closed).
Final proposal for an implementation ofWork done
-
Change scope inside of with
-
Declare local variable explicitly: with (var x = y ())
-
Assign the given expression to a local variable implicitly if needed: with (y ())
-
Perform semantic checks -
Support for --enable-experimental-non-null
-
30 test cases for all of these points -
Linted code
Tests
All tests are passing, the compiler can compile itself and run tests
Syntax
The follwing formal grammar has been implemented:
statement ::= block | ";" | if_statement | switch_statement | while_statement | for_statement | foreach_statement |
break_statement | continue_statement | return_statement | yield_statement | throw_statement |
try_statement | lock_statement | WITH_STATEMENT | delete_statement | local_variable_declarations | expression_statement
with_statement ::= "with" "(" [ ("var" | type) identifier "=" ] expression ")" embedded_statement
It must comply with the following semantic:
- Eventually, the explicit local variable declaration must have compatible types
- The expression must refer to an object or basic type
- It can be a dereferenced pointer
- In experimental non-null mode it mustn't be nullable
A special effort was made to provide meaningful error messages.
Behavior
- Within the
with
-block the expression's members can be directly accessed without the member access operator - Members may hide local, class and instance varibales with the same name
- Instance variables are still accessible through
this
- A local variable can be directly declared in the
with
statement header - Hidden local and class variables are currently not directly accessible (using
this
for class members generates a warning, just as it always does)
Examples
class Foo {
public int field;
public static Foo.factory () { }
public void method () { }
}
void function () {
with (var f = new Foo ()) {
field = 100;
method ();
log (f);
}
}
void function (Foo f) {
with (f) {
field = 100;
method ();
}
}
class Bar {
public int field;
void m () {
Foo f;
with (f = Foo.factory ()) {
field = 100;
this.field = 200;
method ();
}
log (f);
}
}
Edited by Nick Schrader