Graet Syntactic Shift : Syntax for function literals fixed
This commit is contained in:
@@ -1082,83 +1082,112 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
myBuilder.enableNewlines();
|
||||
advance(); // LBRACE
|
||||
|
||||
int doubleArrowPos = matchTokenStreamPredicate(new FirstBefore(new At(ARROW), new At(RBRACE)) {
|
||||
@Override
|
||||
public boolean isTopLevel(int openAngleBrackets, int openBrackets, int openBraces, int openParentheses) {
|
||||
return openBraces == 0;
|
||||
boolean paramsFound = false;
|
||||
|
||||
if (at(ARROW)) {
|
||||
// { -> ...}
|
||||
advance(); // ARROW
|
||||
mark().done(VALUE_PARAMETER_LIST);
|
||||
paramsFound = true;
|
||||
}
|
||||
else if (at(LPAR)) {
|
||||
// Look for ARROW after matching RPAR
|
||||
// {(a, b) -> ...}
|
||||
|
||||
{
|
||||
PsiBuilder.Marker rollbackMarker = mark();
|
||||
|
||||
parseFunctionLiteralParametersAndType();
|
||||
|
||||
paramsFound = rollbackOrDropAt(rollbackMarker, ARROW);
|
||||
}
|
||||
});
|
||||
|
||||
boolean doubleArrowPresent = doubleArrowPos >= 0;
|
||||
if (doubleArrowPresent) {
|
||||
boolean dontExpectParameters = false;
|
||||
|
||||
int lastDot = matchTokenStreamPredicate(new LastBefore(new At(DOT), new AtOffset(doubleArrowPos)));
|
||||
if (lastDot >= 0) { // There is a receiver type
|
||||
createTruncatedBuilder(lastDot).parseTypeRef();
|
||||
|
||||
expect(DOT, "Expecting '.'");
|
||||
|
||||
if (!at(LPAR)) {
|
||||
int firstLParPos = matchTokenStreamPredicate(new FirstBefore(new At(LPAR), new AtOffset(doubleArrowPos)));
|
||||
|
||||
if (firstLParPos >= 0) {
|
||||
errorUntilOffset("Expecting '('", firstLParPos);
|
||||
} else {
|
||||
errorUntilOffset("To specify a receiver type, use the full notation: {ReceiverType.(parameters) [: ReturnType] => ...}",
|
||||
doubleArrowPos);
|
||||
dontExpectParameters = true;
|
||||
if (!paramsFound) {
|
||||
// If not found, try a typeRef DOT and then LPAR .. RPAR ARROW
|
||||
// {((A) -> B).(x) -> ... }
|
||||
PsiBuilder.Marker rollbackMarker = mark();
|
||||
int lastDot = matchTokenStreamPredicate(new LastBefore(new At(DOT), new AtSet(ARROW, RPAR)));
|
||||
if (lastDot >= 0) {
|
||||
createTruncatedBuilder(lastDot).parseTypeRef();
|
||||
if (at(DOT)) {
|
||||
advance(); // DOT
|
||||
parseFunctionLiteralParametersAndType();
|
||||
}
|
||||
}
|
||||
|
||||
paramsFound = rollbackOrDropAt(rollbackMarker, ARROW);
|
||||
}
|
||||
|
||||
if (at(LPAR)) {
|
||||
parseFunctionLiteralParameterList();
|
||||
|
||||
if (at(COLON)) {
|
||||
advance(); // COLON
|
||||
if (at(ARROW)) {
|
||||
error("Expecting a type");
|
||||
}
|
||||
else {
|
||||
myJetParsing.parseTypeRef();
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (!dontExpectParameters) {
|
||||
PsiBuilder.Marker parameterList = mark();
|
||||
|
||||
while (!eof()) {
|
||||
PsiBuilder.Marker parameter = mark();
|
||||
|
||||
int parameterNamePos = matchTokenStreamPredicate(new LastBefore(new At(IDENTIFIER), new AtOffset(doubleArrowPos)));
|
||||
createTruncatedBuilder(parameterNamePos).parseModifierList(MODIFIER_LIST, false);
|
||||
|
||||
expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(ARROW));
|
||||
|
||||
parameter.done(VALUE_PARAMETER);
|
||||
|
||||
if (at(COLON)) {
|
||||
errorUntilOffset("To specify a type of a parameter or a return type, use the full notation: {(parameter : Type) : ReturnType => ...}", doubleArrowPos);
|
||||
}
|
||||
else if (at(ARROW)) {
|
||||
break;
|
||||
}
|
||||
else if (!at(COMMA)) {
|
||||
errorUntilOffset("Expecting '=>' or ','", doubleArrowPos);
|
||||
}
|
||||
else {
|
||||
advance(); // COMMA
|
||||
}
|
||||
}
|
||||
|
||||
parameterList.done(VALUE_PARAMETER_LIST);
|
||||
}
|
||||
|
||||
expectNoAdvance(ARROW, "Expecting '=>'");
|
||||
}
|
||||
else {
|
||||
if (at(IDENTIFIER)) {
|
||||
// Try to parse a simple name list followed by an ARROW
|
||||
// {a -> ...}
|
||||
// {a, b -> ...}
|
||||
PsiBuilder.Marker rollbackMarker = mark();
|
||||
parseFunctionLiteralShorthandParameterList();
|
||||
parseOptionalFunctionLiteralType();
|
||||
paramsFound = rollbackOrDropAt(rollbackMarker, ARROW);
|
||||
}
|
||||
if (!paramsFound && atSet(JetParsing.TYPE_REF_FIRST)) {
|
||||
// Try to parse a type DOT valueParameterList ARROW
|
||||
// {A.(b) -> ...}
|
||||
PsiBuilder.Marker rollbackMarker = mark();
|
||||
int lastDot = matchTokenStreamPredicate(new LastBefore(new At(DOT), new AtSet(ARROW, RBRACE)));
|
||||
if (lastDot >= 0) { // There is a receiver type
|
||||
createTruncatedBuilder(lastDot).parseTypeRef();
|
||||
}
|
||||
|
||||
if (at(DOT)) {
|
||||
advance(); // DOT
|
||||
parseFunctionLiteralParametersAndType();
|
||||
paramsFound = rollbackOrDropAt(rollbackMarker, ARROW);
|
||||
}
|
||||
else {
|
||||
rollbackMarker.rollbackTo();
|
||||
}
|
||||
}
|
||||
// int doubleArrowPos = matchTokenStreamPredicate(new FirstBefore(new At(ARROW), new At(RBRACE)) {
|
||||
// @Override
|
||||
// public boolean isTopLevel(int openAngleBrackets, int openBrackets, int openBraces, int openParentheses) {
|
||||
// return openBraces == 0;
|
||||
// }
|
||||
// });
|
||||
//
|
||||
// boolean doubleArrowPresent = doubleArrowPos >= 0;
|
||||
// if (doubleArrowPresent) {
|
||||
// boolean dontExpectParameters = false;
|
||||
//
|
||||
// int lastDot = matchTokenStreamPredicate(new LastBefore(new At(DOT), new AtOffset(doubleArrowPos)));
|
||||
// if (lastDot >= 0) { // There is a receiver type
|
||||
// createTruncatedBuilder(lastDot).parseTypeRef();
|
||||
//
|
||||
// expect(DOT, "Expecting '.'");
|
||||
//
|
||||
// if (!at(LPAR)) {
|
||||
// int firstLParPos = matchTokenStreamPredicate(new FirstBefore(new At(LPAR), new AtOffset(doubleArrowPos)));
|
||||
//
|
||||
// if (firstLParPos >= 0) {
|
||||
// errorUntilOffset("Expecting '('", firstLParPos);
|
||||
// } else {
|
||||
// errorUntilOffset("To specify a receiver type, use the full notation: {ReceiverType.(parameters) [: ReturnType] => ...}",
|
||||
// doubleArrowPos);
|
||||
// dontExpectParameters = true;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
//
|
||||
// if (at(LPAR)) {
|
||||
// parseFunctionLiteralParametersAndType();
|
||||
// }
|
||||
// else if (!dontExpectParameters) {
|
||||
// parseFunctionLiteralShorthandParameterList();
|
||||
// }
|
||||
//
|
||||
// expectNoAdvance(ARROW, "Expecting '=>'");
|
||||
// }
|
||||
}
|
||||
if (!paramsFound) {
|
||||
if (preferBlock) {
|
||||
literal.drop();
|
||||
parseStatements();
|
||||
@@ -1180,6 +1209,74 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
||||
literalExpression.done(FUNCTION_LITERAL_EXPRESSION);
|
||||
}
|
||||
|
||||
private boolean rollbackOrDropAt(PsiBuilder.Marker rollbackMarker, IElementType dropAt) {
|
||||
if (at(dropAt)) {
|
||||
advance(); // dropAt
|
||||
rollbackMarker.drop();
|
||||
return true;
|
||||
}
|
||||
rollbackMarker.rollbackTo();
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* SimpleName{,}
|
||||
*/
|
||||
private void parseFunctionLiteralShorthandParameterList() {
|
||||
PsiBuilder.Marker parameterList = mark();
|
||||
|
||||
while (!eof()) {
|
||||
PsiBuilder.Marker parameter = mark();
|
||||
|
||||
// int parameterNamePos = matchTokenStreamPredicate(new LastBefore(new At(IDENTIFIER), new AtOffset(doubleArrowPos)));
|
||||
// createTruncatedBuilder(parameterNamePos).parseModifierList(MODIFIER_LIST, false);
|
||||
|
||||
expect(IDENTIFIER, "Expecting parameter name", TokenSet.create(ARROW));
|
||||
|
||||
parameter.done(VALUE_PARAMETER);
|
||||
|
||||
if (at(COLON)) {
|
||||
PsiBuilder.Marker errorMarker = mark();
|
||||
advance(); // COLON
|
||||
myJetParsing.parseTypeRef();
|
||||
errorMarker.error("To specify a type of a parameter or a return type, use the full notation: {(parameter : Type) : ReturnType => ...}");
|
||||
}
|
||||
else if (at(ARROW)) {
|
||||
break;
|
||||
}
|
||||
else if (at(COMMA)) {
|
||||
advance(); // COMMA
|
||||
}
|
||||
else {
|
||||
error("Expecting '->' or ','");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
parameterList.done(VALUE_PARAMETER_LIST);
|
||||
}
|
||||
|
||||
private void parseFunctionLiteralParametersAndType() {
|
||||
parseFunctionLiteralParameterList();
|
||||
|
||||
parseOptionalFunctionLiteralType();
|
||||
}
|
||||
|
||||
/*
|
||||
* (":" type)?
|
||||
*/
|
||||
private void parseOptionalFunctionLiteralType() {
|
||||
if (at(COLON)) {
|
||||
advance(); // COLON
|
||||
if (at(ARROW)) {
|
||||
error("Expecting a type");
|
||||
}
|
||||
else {
|
||||
myJetParsing.parseTypeRef();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* "(" (modifiers SimpleName (":" type)?){","} ")"
|
||||
*/
|
||||
|
||||
@@ -1354,7 +1354,13 @@ public class JetParsing extends AbstractJetParsing {
|
||||
typeRefMarker.done(TYPE_REFERENCE);
|
||||
|
||||
advance(); // DOT
|
||||
parseFunctionTypeContents().drop();
|
||||
|
||||
if (at(LPAR)) {
|
||||
parseFunctionTypeContents().drop();
|
||||
}
|
||||
else {
|
||||
error("Expecting function type");
|
||||
}
|
||||
typeRefMarker = precede.precede();
|
||||
|
||||
precede.done(FUNCTION_TYPE);
|
||||
@@ -1519,8 +1525,9 @@ public class JetParsing extends AbstractJetParsing {
|
||||
}
|
||||
|
||||
private PsiBuilder.Marker parseFunctionTypeContents() {
|
||||
assert _at(LPAR) : tt();
|
||||
//
|
||||
// assert _at(LPAR) : tt();
|
||||
if (!_at(LPAR))
|
||||
System.out.println(myBuilder.getTokenText());
|
||||
PsiBuilder.Marker functionType = mark();
|
||||
|
||||
// advance(); // LPAR
|
||||
|
||||
@@ -19,6 +19,7 @@ import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.UNRESOLVED_REFERENCE;
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.UNSUPPORTED;
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.WRONG_NUMBER_OF_TYPE_ARGUMENTS;
|
||||
import static org.jetbrains.jet.lang.resolve.BindingContext.REFERENCE_TARGET;
|
||||
|
||||
@@ -173,7 +174,8 @@ public class TypeResolver {
|
||||
|
||||
@Override
|
||||
public void visitJetElement(JetElement element) {
|
||||
throw new IllegalArgumentException("Unsupported type: " + element);
|
||||
trace.report(UNSUPPORTED.on(element, "Self-types are not supported yet"));
|
||||
// throw new IllegalArgumentException("Unsupported type: " + element);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -121,17 +121,17 @@ sink:
|
||||
<SINK> NEXT:[] PREV:[<END>]
|
||||
=====================
|
||||
== flfun ==
|
||||
fun flfun(f : fun () : Any) : Unit {}
|
||||
fun flfun(f : () -> Any) : Unit {}
|
||||
---------------------
|
||||
l0:
|
||||
<START> NEXT:[v(f : fun () : Any)] PREV:[]
|
||||
v(f : fun () : Any) NEXT:[w(f)] PREV:[<START>]
|
||||
w(f) NEXT:[read (Unit)] PREV:[v(f : fun () : Any)]
|
||||
read (Unit) NEXT:[<END>] PREV:[w(f)]
|
||||
<START> NEXT:[v(f : () -> Any)] PREV:[]
|
||||
v(f : () -> Any) NEXT:[w(f)] PREV:[<START>]
|
||||
w(f) NEXT:[read (Unit)] PREV:[v(f : () -> Any)]
|
||||
read (Unit) NEXT:[<END>] PREV:[w(f)]
|
||||
l1:
|
||||
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
||||
<END> NEXT:[<SINK>] PREV:[read (Unit)]
|
||||
error:
|
||||
<ERROR> NEXT:[] PREV:[]
|
||||
<ERROR> NEXT:[] PREV:[]
|
||||
sink:
|
||||
<SINK> NEXT:[] PREV:[<END>]
|
||||
<SINK> NEXT:[] PREV:[<END>]
|
||||
=====================
|
||||
|
||||
@@ -20,4 +20,4 @@ fun foo(a : Boolean, b : Int) : Unit {}
|
||||
|
||||
fun genfun<T>() : Unit {}
|
||||
|
||||
fun flfun(f : fun () : Any) : Unit {}
|
||||
fun flfun(f : () -> Any) : Unit {}
|
||||
@@ -0,0 +1,43 @@
|
||||
class Foo
|
||||
class Bar
|
||||
|
||||
fun a(vararg a : Any) = a
|
||||
|
||||
fun test() {
|
||||
a(1
|
||||
, {}
|
||||
, { -> 1}
|
||||
, {1}
|
||||
, {x}
|
||||
, {-> 1}
|
||||
, {x -> 1}
|
||||
, {x, y -> 1}
|
||||
, {(x, y) -> 1}
|
||||
, {(x, y) : Int -> 1}
|
||||
, {(x) -> 1}
|
||||
, {(x) : Int -> 1}
|
||||
, {(x)}
|
||||
, {(x).(y)}
|
||||
, {x.(y)}
|
||||
, {Int.(x) -> 1}
|
||||
, {A.B.(x) -> 1}
|
||||
, {A.B.(x, y) -> 1}
|
||||
, {Int.(x) : Int -> 1}
|
||||
, {Int.(x, y) -> 1}
|
||||
, {Int.(x, y) : Int -> 1}
|
||||
, {(Int).(x, y) -> 1}
|
||||
, {(Int).(x, y) : Int -> 1}
|
||||
, {(Int).(x, y) : (Int) -> Int -> {1}}
|
||||
, {Int? .(x, y) -> 1}
|
||||
, {This.(x, y) -> 1}
|
||||
, {#(A, B).(x, y) -> 1}
|
||||
, {#(a, b).(y)}
|
||||
, {#(a, b)}
|
||||
, {Foo<Bar>.x}
|
||||
, {Foo<Bar>.(x)}
|
||||
, {Foo<Bar>.(x) -> x}
|
||||
, {Foo.Bar.Baz.(x) -> x}
|
||||
, {Foo<Bar>.(x) : Int -> x}
|
||||
, {Foo.Bar.Baz.(x) : Int -> x}
|
||||
)
|
||||
}
|
||||
@@ -48,7 +48,7 @@ public abstract class JetTestCaseBuilder {
|
||||
}
|
||||
|
||||
public static void appendTestsInDirectory(String baseDataDir, String dataPath, boolean recursive, final FilenameFilter filter, NamedTestFactory factory, TestSuite suite) {
|
||||
final String extensionJet = ".jet.jet";
|
||||
final String extensionJet = ".jet";
|
||||
final String extensionKt = ".kt";
|
||||
final FilenameFilter extensionFilter = new FilenameFilter() {
|
||||
@Override
|
||||
|
||||
@@ -10,7 +10,6 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.JetLiteFixture;
|
||||
import org.jetbrains.jet.JetTestCaseBuilder;
|
||||
import org.jetbrains.jet.lang.Configuration;
|
||||
import org.jetbrains.jet.lang.JetSemanticServices;
|
||||
import org.jetbrains.jet.lang.cfg.pseudocode.JetControlFlowDataTraceFactory;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
|
||||
import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||
@@ -85,7 +84,7 @@ public class JetDiagnosticsTest extends JetLiteFixture {
|
||||
|
||||
@Override
|
||||
public void runTest() throws Exception {
|
||||
String testFileName = name + ".kt";
|
||||
String testFileName = name + ".jet";
|
||||
|
||||
String expectedText = loadFile(testFileName);
|
||||
|
||||
|
||||
@@ -86,7 +86,7 @@ public class PatternMatchingTest extends CodegenTestCase {
|
||||
}
|
||||
|
||||
public void testTuplePattern() throws Exception {
|
||||
loadText("fun foo(x: (Any, Any)) = when(x) { is #(1,2) -> \"one,two\"; else -> \"something\" }");
|
||||
loadText("fun foo(x: #(Any, Any)) = when(x) { is #(1,2) -> \"one,two\"; else -> \"something\" }");
|
||||
Method foo = generateFunction();
|
||||
final Object result;
|
||||
try {
|
||||
|
||||
Reference in New Issue
Block a user