allow a newline before dot usage, for chained/fluent interfaces

This commit is contained in:
underscorediscovery
2020-06-10 10:13:29 -07:00
committed by ruby0x1
parent 1c5ac28831
commit 4c496c56a6
2 changed files with 125 additions and 0 deletions

View File

@ -1169,6 +1169,12 @@ static void consumeLine(Compiler* compiler, const char* errorMessage)
ignoreNewlines(compiler);
}
static void allowLineBeforeDot(Compiler* compiler) {
if (peek(compiler) == TOKEN_LINE && peekNext(compiler) == TOKEN_DOT) {
nextToken(compiler->parser);
}
}
// Variables and scopes --------------------------------------------------------
// Emits one single-byte argument. Returns its index.
@ -1956,6 +1962,7 @@ static void namedCall(Compiler* compiler, bool canAssign, Code instruction)
else
{
methodCall(compiler, instruction, &signature);
allowLineBeforeDot(compiler);
}
}
@ -2152,6 +2159,8 @@ static void field(Compiler* compiler, bool canAssign)
loadThis(compiler);
emitByteArg(compiler, isLoad ? CODE_LOAD_FIELD : CODE_STORE_FIELD, field);
}
allowLineBeforeDot(compiler);
}
// Compiles a read or assignment to [variable].
@ -2183,6 +2192,8 @@ static void bareName(Compiler* compiler, bool canAssign, Variable variable)
// Emit the load instruction.
loadVariable(compiler, variable);
allowLineBeforeDot(compiler);
}
static void staticField(Compiler* compiler, bool canAssign)

View File

@ -0,0 +1,114 @@
class Test {
construct new() {}
test0() {
System.print("test0")
return this
}
test1() {
System.print("test1")
return this
}
test2() {
System.print("test2")
return this
}
}
class Tester {
construct new() {
var test = _test = Test.new()
//test local access
test.
test0(). // expect: test0
test1(). // expect: test1
test2() // expect: test2
test
.test0() // expect: test0
.test1() // expect: test1
.test2() // expect: test2
test
.test0() // expect: test0
.test1(). // expect: test1
test2() // expect: test2
//test field access
_test.
test0(). // expect: test0
test1(). // expect: test1
test2() // expect: test2
_test
.test0() // expect: test0
.test1() // expect: test1
.test2() // expect: test2
_test
.test0(). // expect: test0
test1(). // expect: test1
test2() // expect: test2
}
getter { _test }
method() { _test }
} //Tester
//access via methods/getter
var external = Tester.new()
external.getter.
test0(). // expect: test0
test1(). // expect: test1
test2() // expect: test2
external.getter
.test0() // expect: test0
.test1() // expect: test1
.test2() // expect: test2
external.getter.
test0() // expect: test0
.test1() // expect: test1
.test2() // expect: test2
external.method().
test0(). // expect: test0
test1(). // expect: test1
test2() // expect: test2
external.method()
.test0() // expect: test0
.test1() // expect: test1
.test2() // expect: test2
external.method().
test0() // expect: test0
.test1(). // expect: test1
test2() // expect: test2
//regular access in module scope
var other = Test.new()
other.
test0(). // expect: test0
test1(). // expect: test1
test2() // expect: test2
other
.test0() // expect: test0
.test1() // expect: test1
.test2() // expect: test2
other
.test0(). // expect: test0
test1() // expect: test1
.test2() // expect: test2