"it" inference supported

This commit is contained in:
Andrey Breslav
2011-09-16 15:40:13 +04:00
parent adb44244b5
commit ccaa5ee7f9
9 changed files with 165 additions and 38 deletions
@@ -3,6 +3,7 @@ package org.jetbrains.jet.lang.psi;
import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiElement;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lexer.JetTokens;
/**
@@ -36,4 +37,20 @@ public class JetFunctionLiteral extends JetFunction {
public JetBlockExpression getBodyExpression() {
return (JetBlockExpression) super.getBodyExpression();
}
@NotNull
public ASTNode getOpenBraceNode() {
return getNode().findChildByType(JetTokens.LBRACE);
}
@Nullable
@IfNotParsed
public ASTNode getClosingBraceNode() {
return getNode().findChildByType(JetTokens.RBRACE);
}
@Nullable
public ASTNode getArrowNode() {
return getNode().findChildByType(JetTokens.DOUBLE_ARROW);
}
}
@@ -2,7 +2,9 @@ package org.jetbrains.jet.lang.psi;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.JetNodeTypes;
import org.jetbrains.jet.lexer.JetTokens;
/**
* @author max
@@ -47,4 +49,5 @@ public class JetFunctionLiteralExpression extends JetExpression implements JetDe
public JetElement asElement() {
return this;
}
}
@@ -32,7 +32,8 @@ public interface BindingContext {
WritableSlice<JetExpression, JetScope> RESOLUTION_SCOPE = Slices.createSimpleSlice("RESOLUTION_SCOPE");
WritableSlice<JetExpression, Boolean> VARIABLE_REASSIGNMENT = Slices.createSimpleSetSlice("VARIABLE_REASSIGNMENT");
WritableSlice<JetExpression, DeclarationDescriptor> VARIABLE_ASSIGNMENT = Slices.createSimpleSlice("VARIABLE_ASSIGNMENT");
WritableSlice<ValueParameterDescriptor, Boolean> AUTO_CREATED_IT = Slices.createSimpleSetSlice("AUTO_CREATED_IT");
WritableSlice<JetExpression, DeclarationDescriptor> VARIABLE_ASSIGNMENT = Slices.createSimpleSlice("VARIABLE_ASSIGNMENT");
WritableSlice<JetExpression, Boolean> PROCESSED = Slices.createSimpleSetSlice("PROCESSED");
WritableSlice<JetElement, Boolean> STATEMENT = Slices.createRemovableSetSlice("STATEMENT");
@@ -899,36 +899,46 @@ public class JetTypeInferrer {
List<JetType> parameterTypes = new ArrayList<JetType>();
List<ValueParameterDescriptor> valueParameterDescriptors = Lists.newArrayList();
List<JetParameter> parameters = functionLiteral.getValueParameters();
List<JetParameter> declaredValueParameters = functionLiteral.getValueParameters();
JetType expectedType = context.expectedType;
List<ValueParameterDescriptor> valueParameters = null;
boolean functionTypeExpected = expectedType != NO_EXPECTED_TYPE && JetStandardClasses.isFunctionType(expectedType);
if (functionTypeExpected) {
valueParameters = JetStandardClasses.getValueParameters(functionDescriptor, expectedType);
List<ValueParameterDescriptor> expectedValueParameters = (functionTypeExpected)
? JetStandardClasses.getValueParameters(functionDescriptor, expectedType)
: null;
if (functionTypeExpected && declaredValueParameters.isEmpty() && expectedValueParameters.size() == 1) {
ValueParameterDescriptor valueParameterDescriptor = expectedValueParameters.get(0);
ValueParameterDescriptor it = new ValueParameterDescriptorImpl(
functionDescriptor, 0, Collections.<AnnotationDescriptor>emptyList(), "it", valueParameterDescriptor.getInType(), valueParameterDescriptor.getOutType(), valueParameterDescriptor.hasDefaultValue(), valueParameterDescriptor.isVararg()
);
valueParameterDescriptors.add(it);
parameterTypes.add(it.getOutType());
context.trace.record(AUTO_CREATED_IT, it);
}
else {
for (int i = 0; i < declaredValueParameters.size(); i++) {
JetParameter declaredParameter = declaredValueParameters.get(i);
JetTypeReference typeReference = declaredParameter.getTypeReference();
for (int i = 0, parametersSize = parameters.size(); i < parametersSize; i++) {
JetParameter parameter = parameters.get(i);
JetTypeReference typeReference = parameter.getTypeReference();
JetType type;
if (typeReference != null) {
type = context.typeResolver.resolveType(context.scope, typeReference);
}
else {
if (valueParameters != null) {
type = valueParameters.get(i).getOutType();
JetType type;
if (typeReference != null) {
type = context.typeResolver.resolveType(context.scope, typeReference);
}
else {
// context.trace.getErrorHandler().genericError(parameter.getNode(), "Cannot infer a type for this parameter. To specify it explicitly use the {(p : Type) => ...} notation");
context.trace.report(CANNOT_INFER_PARAMETER_TYPE.on(parameter));
type = ErrorUtils.createErrorType("Cannot be inferred");
if (expectedValueParameters != null && i < expectedValueParameters.size()) {
type = expectedValueParameters.get(i).getOutType();
}
else {
// context.trace.getErrorHandler().genericError(declaredParameter.getNode(), "Cannot infer a type for this declaredParameter. To specify it explicitly use the {(p : Type) => ...} notation");
context.trace.report(CANNOT_INFER_PARAMETER_TYPE.on(declaredParameter));
type = ErrorUtils.createErrorType("Cannot be inferred");
}
}
ValueParameterDescriptor valueParameterDescriptor = context.classDescriptorResolver.resolveValueParameterDescriptor(functionDescriptor, declaredParameter, i, type);
parameterTypes.add(valueParameterDescriptor.getOutType());
valueParameterDescriptors.add(valueParameterDescriptor);
}
ValueParameterDescriptor valueParameterDescriptor = context.classDescriptorResolver.resolveValueParameterDescriptor(functionDescriptor, parameter, i, type);
parameterTypes.add(valueParameterDescriptor.getOutType());
valueParameterDescriptors.add(valueParameterDescriptor);
}
JetType effectiveReceiverType;