Supporting function literals as selectors
This commit is contained in:
@@ -228,6 +228,8 @@ public interface Errors {
|
|||||||
SimpleDiagnosticFactory SUPERTYPE_APPEARS_TWICE = SimpleDiagnosticFactory.create(ERROR, "A supertype appears twice");
|
SimpleDiagnosticFactory SUPERTYPE_APPEARS_TWICE = SimpleDiagnosticFactory.create(ERROR, "A supertype appears twice");
|
||||||
SimpleDiagnosticFactory FINAL_SUPERTYPE = SimpleDiagnosticFactory.create(ERROR, "This type is final, so it cannot be inherited from");
|
SimpleDiagnosticFactory FINAL_SUPERTYPE = SimpleDiagnosticFactory.create(ERROR, "This type is final, so it cannot be inherited from");
|
||||||
|
|
||||||
|
ParameterizedDiagnosticFactory1<String> ILLEGAL_SELECTOR = ParameterizedDiagnosticFactory1.create(ERROR, "Expression ''{0}'' cannot be a selector (occur after a dot)");
|
||||||
|
|
||||||
SimpleDiagnosticFactory REF_PARAMETER_WITH_VAL_OR_VAR = SimpleDiagnosticFactory.create(ERROR, "'val' and 'var' are not allowed on ref-parameters");
|
SimpleDiagnosticFactory REF_PARAMETER_WITH_VAL_OR_VAR = SimpleDiagnosticFactory.create(ERROR, "'val' and 'var' are not allowed on ref-parameters");
|
||||||
SimpleDiagnosticFactory VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION = SimpleDiagnosticFactory.create(ERROR, "A type annotation is required on a value parameter");
|
SimpleDiagnosticFactory VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION = SimpleDiagnosticFactory.create(ERROR, "A type annotation is required on a value parameter");
|
||||||
SimpleDiagnosticFactory BREAK_OR_CONTINUE_OUTSIDE_A_LOOP = SimpleDiagnosticFactory.create(ERROR, "'break' and 'continue' are only allowed inside a loop");
|
SimpleDiagnosticFactory BREAK_OR_CONTINUE_OUTSIDE_A_LOOP = SimpleDiagnosticFactory.create(ERROR, "'break' and 'continue' are only allowed inside a loop");
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
package org.jetbrains.jet.lang.psi;
|
package org.jetbrains.jet.lang.psi;
|
||||||
|
|
||||||
import com.intellij.lang.ASTNode;
|
import com.intellij.lang.ASTNode;
|
||||||
|
import com.intellij.psi.PsiElement;
|
||||||
|
import com.intellij.util.SmartList;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.JetNodeTypes;
|
import org.jetbrains.jet.JetNodeTypes;
|
||||||
@@ -46,6 +48,26 @@ public class JetCallExpression extends JetExpression implements JetCallElement {
|
|||||||
@Override
|
@Override
|
||||||
@NotNull
|
@NotNull
|
||||||
public List<JetExpression> getFunctionLiteralArguments() {
|
public List<JetExpression> getFunctionLiteralArguments() {
|
||||||
|
JetExpression calleeExpression = getCalleeExpression();
|
||||||
|
if (calleeExpression instanceof JetFunctionLiteralExpression) {
|
||||||
|
List<JetExpression> result = new SmartList<JetExpression>();
|
||||||
|
ASTNode treeNext = calleeExpression.getNode().getTreeNext();
|
||||||
|
while (treeNext != null) {
|
||||||
|
PsiElement psi = treeNext.getPsi();
|
||||||
|
if (psi instanceof JetFunctionLiteralExpression) {
|
||||||
|
result.add((JetFunctionLiteralExpression) psi);
|
||||||
|
}
|
||||||
|
else if (psi instanceof JetLabelQualifiedExpression) {
|
||||||
|
JetLabelQualifiedExpression labelQualifiedExpression = (JetLabelQualifiedExpression) psi;
|
||||||
|
JetExpression labeledExpression = labelQualifiedExpression.getLabeledExpression();
|
||||||
|
if (labeledExpression instanceof JetFunctionLiteralExpression) {
|
||||||
|
result.add(labeledExpression);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
treeNext = treeNext.getTreeNext();
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
return findChildrenByType(JetNodeTypes.FUNCTION_LITERAL_EXPRESSION);
|
return findChildrenByType(JetNodeTypes.FUNCTION_LITERAL_EXPRESSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -187,9 +187,10 @@ public class CallResolver {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(scope.getContainingDeclaration(), Collections.<AnnotationDescriptor>emptyList(), "for expression " + calleeExpression.getText());
|
FunctionDescriptorImpl functionDescriptor = new FunctionDescriptorImpl(scope.getContainingDeclaration(), Collections.<AnnotationDescriptor>emptyList(), "[for expression " + calleeExpression.getText() + "]");
|
||||||
FunctionDescriptorUtil.initializeFromFunctionType(functionDescriptor, calleeType);
|
FunctionDescriptorUtil.initializeFromFunctionType(functionDescriptor, calleeType);
|
||||||
ResolvedCallImpl<FunctionDescriptor> resolvedCall = ResolvedCallImpl.<FunctionDescriptor>create(functionDescriptor);
|
ResolvedCallImpl<FunctionDescriptor> resolvedCall = ResolvedCallImpl.<FunctionDescriptor>create(functionDescriptor);
|
||||||
|
resolvedCall.setReceiverArgument(call.getExplicitReceiver());
|
||||||
prioritizedTasks = Collections.singletonList(new ResolutionTask<FunctionDescriptor>(
|
prioritizedTasks = Collections.singletonList(new ResolutionTask<FunctionDescriptor>(
|
||||||
Collections.singleton(resolvedCall), call, dataFlowInfo));
|
Collections.singleton(resolvedCall), call, dataFlowInfo));
|
||||||
functionReference = new JetReferenceExpression(calleeExpression.getNode()) {
|
functionReference = new JetReferenceExpression(calleeExpression.getNode()) {
|
||||||
|
|||||||
+1
-2
@@ -525,8 +525,7 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// TODO : not a simple name -> resolve in scope, expect property type or a function type
|
context.trace.report(ILLEGAL_SELECTOR.on(selectorExpression, selectorExpression.getText()));
|
||||||
context.trace.report(UNSUPPORTED.on(selectorExpression, "getSelectorReturnType"));
|
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -47,4 +47,26 @@ fun main(args : Array<String>) {
|
|||||||
<!CALLEE_NOT_A_FUNCTION!>1<!>()
|
<!CALLEE_NOT_A_FUNCTION!>1<!>()
|
||||||
<!CALLEE_NOT_A_FUNCTION!>1<!>{}
|
<!CALLEE_NOT_A_FUNCTION!>1<!>{}
|
||||||
<!CALLEE_NOT_A_FUNCTION!>1<!>(){}
|
<!CALLEE_NOT_A_FUNCTION!>1<!>(){}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun f() : fun Int.() : Unit = {}
|
||||||
|
|
||||||
|
fun main1(args : Array<String>) {
|
||||||
|
1.{Int.() => 1}();
|
||||||
|
{1}()
|
||||||
|
{(x : Int) => x}(1)
|
||||||
|
1.{Int.(x : Int) => x}(1)
|
||||||
|
@l{1}()
|
||||||
|
1.({Int.() => 1})()
|
||||||
|
1.(f())()
|
||||||
|
1.if(true){f()}else{f()}()
|
||||||
|
1.if(true){Int.() => 1}else{f()}()
|
||||||
|
1.if(true){Int.() => 1}else{Int.() => 1}()
|
||||||
|
|
||||||
|
1.<!CALLEE_NOT_A_FUNCTION!>"sdf"<!>()
|
||||||
|
|
||||||
|
1.<!ILLEGAL_SELECTOR!>"sdf"<!>
|
||||||
|
1.<!ILLEGAL_SELECTOR!>{}<!>
|
||||||
|
1.<!ILLEGAL_SELECTOR!>if (true) {}<!>
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user