JET-39 Process ?. correctly in the receiver types
This commit is contained in:
@@ -862,23 +862,39 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
return FUN;
|
return FUN;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean parameterListOccured = false;
|
boolean typeParameterListOccured = false;
|
||||||
if (at(LT)) {
|
if (at(LT)) {
|
||||||
parseTypeParameterList(TokenSet.create(LBRACKET, LBRACE, LPAR));
|
parseTypeParameterList(TokenSet.create(LBRACKET, LBRACE, LPAR));
|
||||||
parameterListOccured = true;
|
typeParameterListOccured = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TokenSet receiverTypeTerminators = TokenSet.create(DOT, SAFE_ACCESS);
|
||||||
int lastDot = findLastBefore(TokenSet.create(DOT), TokenSet.create(LPAR), true);
|
int lastDot = findLastBefore(receiverTypeTerminators, TokenSet.create(LPAR), true);
|
||||||
|
|
||||||
if (lastDot == -1) { // There's no explicit receiver type specified
|
if (lastDot == -1) { // There's no explicit receiver type specified
|
||||||
parseAttributeList();
|
parseAttributeList();
|
||||||
expect(IDENTIFIER, "Expecting function name or receiver type");
|
expect(IDENTIFIER, "Expecting function name or receiver type");
|
||||||
} else {
|
} 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);
|
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);
|
expect(IDENTIFIER, "Expecting function name", functionNameFollow);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -887,7 +903,7 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
if (at(LT)) {
|
if (at(LT)) {
|
||||||
PsiBuilder.Marker error = mark();
|
PsiBuilder.Marker error = mark();
|
||||||
parseTypeParameterList(TokenSet.orSet(TokenSet.create(LPAR), valueParametersFollow));
|
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
|
error.error("Only one type parameter list is allowed for a function"); // TODO : discuss
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
@@ -1158,8 +1174,10 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
* : typeDescriptor "?"
|
* : typeDescriptor "?"
|
||||||
*/
|
*/
|
||||||
public void parseTypeRef() {
|
public void parseTypeRef() {
|
||||||
PsiBuilder.Marker type = mark();
|
parseTypeRefContents(mark()).done(TYPE_REFERENCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
private PsiBuilder.Marker parseTypeRefContents(PsiBuilder.Marker typeRefMarker) {
|
||||||
parseAttributeList();
|
parseAttributeList();
|
||||||
|
|
||||||
if (at(IDENTIFIER) || at(NAMESPACE_KEYWORD)) {
|
if (at(IDENTIFIER) || at(NAMESPACE_KEYWORD)) {
|
||||||
@@ -1181,14 +1199,14 @@ public class JetParsing extends AbstractJetParsing {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while (at(QUEST)) {
|
while (at(QUEST)) {
|
||||||
PsiBuilder.Marker precede = type.precede();
|
PsiBuilder.Marker precede = typeRefMarker.precede();
|
||||||
|
|
||||||
advance(); // QUEST
|
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?
|
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();
|
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] {[a] T<T>.(A<B>) : ()}.foo() {}
|
||||||
fun [a()] T.foo<T : [a] {(a) : b}>(a : foo) : bar {}
|
fun [a()] T.foo<T : [a] {(a) : b}>(a : foo) : bar {}
|
||||||
|
|
||||||
|
fun A?.foo() : bar?
|
||||||
@@ -813,4 +813,27 @@ JetFile: Functions.jet
|
|||||||
PsiWhiteSpace(' ')
|
PsiWhiteSpace(' ')
|
||||||
BLOCK
|
BLOCK
|
||||||
PsiElement(LBRACE)('{')
|
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