JET-39 Process ?. correctly in the receiver types
This commit is contained in:
@@ -862,23 +862,39 @@ public class JetParsing extends AbstractJetParsing {
|
||||
return FUN;
|
||||
}
|
||||
|
||||
boolean parameterListOccured = false;
|
||||
boolean typeParameterListOccured = false;
|
||||
if (at(LT)) {
|
||||
parseTypeParameterList(TokenSet.create(LBRACKET, LBRACE, LPAR));
|
||||
parameterListOccured = true;
|
||||
typeParameterListOccured = true;
|
||||
}
|
||||
|
||||
|
||||
int lastDot = findLastBefore(TokenSet.create(DOT), TokenSet.create(LPAR), true);
|
||||
TokenSet receiverTypeTerminators = TokenSet.create(DOT, SAFE_ACCESS);
|
||||
int lastDot = findLastBefore(receiverTypeTerminators, TokenSet.create(LPAR), true);
|
||||
|
||||
if (lastDot == -1) { // There's no explicit receiver type specified
|
||||
parseAttributeList();
|
||||
expect(IDENTIFIER, "Expecting function name or receiver type");
|
||||
} else {
|
||||
createTruncatedBuilder(lastDot).parseTypeRef();
|
||||
PsiBuilder.Marker typeRefMarker = mark();
|
||||
PsiBuilder.Marker nullableType = mark();
|
||||
typeRefMarker = createTruncatedBuilder(lastDot).parseTypeRefContents(typeRefMarker);
|
||||
if (at(SAFE_ACCESS)) {
|
||||
nullableType.done(NULLABLE_TYPE);
|
||||
}
|
||||
else {
|
||||
nullableType.drop();
|
||||
}
|
||||
typeRefMarker.done(TYPE_REFERENCE);
|
||||
|
||||
TokenSet functionNameFollow = TokenSet.create(LT, LPAR, COLON, EQ);
|
||||
expect(DOT, "Expecting '.' before a function name", functionNameFollow);
|
||||
if (atSet(receiverTypeTerminators)) {
|
||||
advance(); // expectation
|
||||
}
|
||||
else {
|
||||
errorWithRecovery("Expecting '.' before a function name", functionNameFollow);
|
||||
}
|
||||
|
||||
// expect(DOT, "Expecting '.' before a function name", functionNameFollow);
|
||||
expect(IDENTIFIER, "Expecting function name", functionNameFollow);
|
||||
}
|
||||
|
||||
@@ -887,7 +903,7 @@ public class JetParsing extends AbstractJetParsing {
|
||||
if (at(LT)) {
|
||||
PsiBuilder.Marker error = mark();
|
||||
parseTypeParameterList(TokenSet.orSet(TokenSet.create(LPAR), valueParametersFollow));
|
||||
if (parameterListOccured) {
|
||||
if (typeParameterListOccured) {
|
||||
error.error("Only one type parameter list is allowed for a function"); // TODO : discuss
|
||||
}
|
||||
else {
|
||||
@@ -1158,8 +1174,10 @@ public class JetParsing extends AbstractJetParsing {
|
||||
* : typeDescriptor "?"
|
||||
*/
|
||||
public void parseTypeRef() {
|
||||
PsiBuilder.Marker type = mark();
|
||||
parseTypeRefContents(mark()).done(TYPE_REFERENCE);
|
||||
}
|
||||
|
||||
private PsiBuilder.Marker parseTypeRefContents(PsiBuilder.Marker typeRefMarker) {
|
||||
parseAttributeList();
|
||||
|
||||
if (at(IDENTIFIER) || at(NAMESPACE_KEYWORD)) {
|
||||
@@ -1181,14 +1199,14 @@ public class JetParsing extends AbstractJetParsing {
|
||||
}
|
||||
|
||||
while (at(QUEST)) {
|
||||
PsiBuilder.Marker precede = type.precede();
|
||||
PsiBuilder.Marker precede = typeRefMarker.precede();
|
||||
|
||||
advance(); // QUEST
|
||||
type.done(NULLABLE_TYPE);
|
||||
typeRefMarker.done(NULLABLE_TYPE);
|
||||
|
||||
type = precede;
|
||||
typeRefMarker = precede;
|
||||
}
|
||||
type.done(TYPE_REFERENCE);
|
||||
return typeRefMarker;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -1425,7 +1425,9 @@ public class JetTypeInferrer {
|
||||
trace.getErrorHandler().genericWarning(expression.getNode(), "Expression always evaluates to false"); // TODO : make an error?
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
trace.getErrorHandler().genericError(pattern.getNode(), "Unsupported [JetTypeInferrer]");
|
||||
}
|
||||
result = semanticServices.getStandardLibrary().getBooleanType();
|
||||
}
|
||||
|
||||
@@ -21,3 +21,5 @@ fun [a()] T.foo<T : {(a) : b}>(a : foo) : bar {}
|
||||
|
||||
fun [a] {[a] T<T>.(A<B>) : ()}.foo() {}
|
||||
fun [a()] T.foo<T : [a] {(a) : b}>(a : foo) : bar {}
|
||||
|
||||
fun A?.foo() : bar?
|
||||
@@ -813,4 +813,27 @@ JetFile: Functions.jet
|
||||
PsiWhiteSpace(' ')
|
||||
BLOCK
|
||||
PsiElement(LBRACE)('{')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiElement(RBRACE)('}')
|
||||
PsiWhiteSpace('\n\n')
|
||||
FUN
|
||||
PsiElement(fun)('fun')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
NULLABLE_TYPE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('A')
|
||||
PsiElement(SAFE_ACCESS)('?.')
|
||||
PsiElement(IDENTIFIER)('foo')
|
||||
VALUE_PARAMETER_LIST
|
||||
PsiElement(LPAR)('(')
|
||||
PsiElement(RPAR)(')')
|
||||
PsiWhiteSpace(' ')
|
||||
PsiElement(COLON)(':')
|
||||
PsiWhiteSpace(' ')
|
||||
TYPE_REFERENCE
|
||||
NULLABLE_TYPE
|
||||
USER_TYPE
|
||||
REFERENCE_EXPRESSION
|
||||
PsiElement(IDENTIFIER)('bar')
|
||||
PsiElement(QUEST)('?')
|
||||
Reference in New Issue
Block a user