Moved method visitNamedFunction from BasicExpressionTypingVisitor to ClosureExpressionsTypingVisitor.

This commit is contained in:
Stanislav Erokhin
2015-02-24 16:27:19 +03:00
parent bd525eac31
commit ee4892c99f
4 changed files with 105 additions and 98 deletions
@@ -20,8 +20,6 @@ import com.google.common.collect.Lists;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import com.intellij.psi.tree.TokenSet;
import com.intellij.util.Function;
import com.intellij.util.containers.ContainerUtil;
import kotlin.Function0;
import kotlin.Function1;
import org.jetbrains.annotations.NotNull;
@@ -32,7 +30,6 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor;
import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor;
import org.jetbrains.kotlin.diagnostics.Diagnostic;
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
import org.jetbrains.kotlin.lexer.JetTokens;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
@@ -60,7 +57,6 @@ import org.jetbrains.kotlin.resolve.constants.CompileTimeConstantChecker;
import org.jetbrains.kotlin.resolve.constants.IntegerValueTypeConstant;
import org.jetbrains.kotlin.resolve.constants.evaluate.ConstantExpressionEvaluator;
import org.jetbrains.kotlin.resolve.scopes.JetScope;
import org.jetbrains.kotlin.resolve.scopes.WritableScope;
import org.jetbrains.kotlin.resolve.scopes.WritableScopeImpl;
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver;
import org.jetbrains.kotlin.resolve.scopes.receivers.ReceiverValue;
@@ -1343,93 +1339,6 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
return JetTypeInfo.create(null, context.dataFlowInfo);
}
@Override
public JetTypeInfo visitNamedFunction(
@NotNull JetNamedFunction function, ExpressionTypingContext data
) {
return visitNamedFunction(function, data, false, null);
}
public JetTypeInfo visitNamedFunction(
@NotNull JetNamedFunction function,
@NotNull ExpressionTypingContext context,
boolean isStatement,
@Nullable WritableScope statementScope // must be not null if isStatement
) {
if (!isStatement) { // function expression
if (!function.getTypeParameters().isEmpty()) {
context.trace.report(TYPE_PARAMETERS_NOT_ALLOWED.on(function));
}
for (JetParameter parameter : function.getValueParameters()) {
if (parameter.hasDefaultValue()) {
context.trace.report(FUNCTION_EXPRESSION_PARAMETER_WITH_DEFAULT_VALUE.on(parameter));
}
if (parameter.isVarArg()) {
context.trace.report(USELESS_VARARG_ON_PARAMETER.on(parameter));
}
}
}
ExpressionTypingServices services = components.expressionTypingServices;
SimpleFunctionDescriptor functionDescriptor;
if (isStatement) {
functionDescriptor = services.getDescriptorResolver().
resolveFunctionDescriptorWithAnnotationArguments(
context.scope.getContainingDeclaration(), context.scope, function, context.trace, context.dataFlowInfo);
assert statementScope != null : "statementScope must be not null for function: " +
function.getName() +
" at location " +
DiagnosticUtils.atLocation(function);
statementScope.addFunctionDescriptor(functionDescriptor);
}
else {
functionDescriptor = services.getDescriptorResolver().resolveFunctionExpressionDescriptor(
context.scope.getContainingDeclaration(), context.scope, function, context.trace, context.dataFlowInfo);
}
JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(context.scope, functionDescriptor, context.trace);
services.checkFunctionReturnType(functionInnerScope, function, functionDescriptor, context.dataFlowInfo, null, context.trace);
services.resolveValueParameters(function.getValueParameters(), functionDescriptor.getValueParameters(), context.scope,
context.dataFlowInfo, context.trace);
ModifiersChecker.create(context.trace, components.additionalCheckerProvider).checkModifiersForLocalDeclaration(function,
functionDescriptor);
if (!function.hasBody()) {
context.trace.report(NON_MEMBER_FUNCTION_NO_BODY.on(function, functionDescriptor));
}
if (isStatement) {
return DataFlowUtils.checkStatementType(function, context, context.dataFlowInfo);
}
else {
return DataFlowUtils.checkType(createFunctionType(functionDescriptor), function, context, context.dataFlowInfo);
}
}
@Nullable
private JetType createFunctionType(@NotNull SimpleFunctionDescriptor functionDescriptor) {
JetType receiverType = functionDescriptor.getExtensionReceiverParameter() != null
? functionDescriptor.getExtensionReceiverParameter().getType()
: null;
JetType returnType = functionDescriptor.getReturnType();
if (returnType == null) {
return null;
}
List<JetType> parameters =
ContainerUtil.map(functionDescriptor.getValueParameters(), new Function<ValueParameterDescriptor, JetType>() {
@Override
public JetType fun(ValueParameterDescriptor descriptor) {
return descriptor.getType();
}
});
return components.builtIns.getFunctionType(Annotations.EMPTY, receiverType, parameters, returnType);
}
@Override
public JetTypeInfo visitRootPackageExpression(@NotNull JetRootPackageExpression expression, ExpressionTypingContext context) {
if (!JetPsiUtil.isLHSOfDot(expression)) {
@@ -27,10 +27,12 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.*;
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.psi.*;
import org.jetbrains.kotlin.resolve.*;
import org.jetbrains.kotlin.resolve.scopes.JetScope;
import org.jetbrains.kotlin.resolve.scopes.WritableScope;
import org.jetbrains.kotlin.types.*;
import org.jetbrains.kotlin.types.checker.JetTypeChecker;
@@ -50,6 +52,93 @@ public class ClosureExpressionsTypingVisitor extends ExpressionTypingVisitor {
super(facade);
}
@Override
public JetTypeInfo visitNamedFunction(
@NotNull JetNamedFunction function, ExpressionTypingContext data
) {
return visitNamedFunction(function, data, false, null);
}
public JetTypeInfo visitNamedFunction(
@NotNull JetNamedFunction function,
@NotNull ExpressionTypingContext context,
boolean isStatement,
@Nullable WritableScope statementScope // must be not null if isStatement
) {
if (!isStatement) { // function expression
if (!function.getTypeParameters().isEmpty()) {
context.trace.report(TYPE_PARAMETERS_NOT_ALLOWED.on(function));
}
for (JetParameter parameter : function.getValueParameters()) {
if (parameter.hasDefaultValue()) {
context.trace.report(FUNCTION_EXPRESSION_PARAMETER_WITH_DEFAULT_VALUE.on(parameter));
}
if (parameter.isVarArg()) {
context.trace.report(USELESS_VARARG_ON_PARAMETER.on(parameter));
}
}
}
ExpressionTypingServices services = components.expressionTypingServices;
SimpleFunctionDescriptor functionDescriptor;
if (isStatement) {
functionDescriptor = services.getDescriptorResolver().
resolveFunctionDescriptorWithAnnotationArguments(
context.scope.getContainingDeclaration(), context.scope, function, context.trace, context.dataFlowInfo);
assert statementScope != null : "statementScope must be not null for function: " +
function.getName() +
" at location " +
DiagnosticUtils.atLocation(function);
statementScope.addFunctionDescriptor(functionDescriptor);
}
else {
functionDescriptor = services.getDescriptorResolver().resolveFunctionExpressionDescriptor(
context.scope.getContainingDeclaration(), context.scope, function, context.trace, context.dataFlowInfo);
}
JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(context.scope, functionDescriptor, context.trace);
services.checkFunctionReturnType(functionInnerScope, function, functionDescriptor, context.dataFlowInfo, null, context.trace);
services.resolveValueParameters(function.getValueParameters(), functionDescriptor.getValueParameters(), context.scope,
context.dataFlowInfo, context.trace);
ModifiersChecker.create(context.trace, components.additionalCheckerProvider).checkModifiersForLocalDeclaration(function,
functionDescriptor);
if (!function.hasBody()) {
context.trace.report(NON_MEMBER_FUNCTION_NO_BODY.on(function, functionDescriptor));
}
if (isStatement) {
return DataFlowUtils.checkStatementType(function, context, context.dataFlowInfo);
}
else {
return DataFlowUtils.checkType(createFunctionType(functionDescriptor), function, context, context.dataFlowInfo);
}
}
@Nullable
private JetType createFunctionType(@NotNull SimpleFunctionDescriptor functionDescriptor) {
JetType receiverType = functionDescriptor.getExtensionReceiverParameter() != null
? functionDescriptor.getExtensionReceiverParameter().getType()
: null;
JetType returnType = functionDescriptor.getReturnType();
if (returnType == null) {
return null;
}
List<JetType> parameters =
ContainerUtil.map(functionDescriptor.getValueParameters(), new Function<ValueParameterDescriptor, JetType>() {
@Override
public JetType fun(ValueParameterDescriptor descriptor) {
return descriptor.getType();
}
});
return components.builtIns.getFunctionType(Annotations.EMPTY, receiverType, parameters, returnType);
}
@Override
public JetTypeInfo visitFunctionLiteralExpression(@NotNull JetFunctionLiteralExpression expression, ExpressionTypingContext context) {
if (!expression.getFunctionLiteral().hasBody()) return null;
@@ -57,16 +57,16 @@ public class ExpressionTypingVisitorDispatcher extends JetVisitor<JetTypeInfo, E
private ExpressionTypingVisitorDispatcher(@NotNull ExpressionTypingComponents components, WritableScope writableScope) {
this.components = components;
this.basic = new BasicExpressionTypingVisitor(this);
basic = new BasicExpressionTypingVisitor(this);
controlStructures = new ControlStructureTypingVisitor(this);
patterns = new PatternMatchingTypingVisitor(this);
closures = new ClosureExpressionsTypingVisitor(this);
if (writableScope != null) {
this.statements = new ExpressionTypingVisitorForStatements(this, writableScope, basic, controlStructures, patterns);
this.statements = new ExpressionTypingVisitorForStatements(this, writableScope, basic, controlStructures, patterns, closures);
}
else {
this.statements = null;
}
this.closures = new ClosureExpressionsTypingVisitor(this);
}
@Override
@@ -116,7 +116,7 @@ public class ExpressionTypingVisitorDispatcher extends JetVisitor<JetTypeInfo, E
private ExpressionTypingVisitorForStatements createStatementVisitor(ExpressionTypingContext context) {
return new ExpressionTypingVisitorForStatements(this,
ExpressionTypingUtils.newWritableScopeImpl(context, "statement scope"),
basic, controlStructures, patterns);
basic, controlStructures, patterns, closures);
}
@Override
@@ -178,6 +178,11 @@ public class ExpressionTypingVisitorDispatcher extends JetVisitor<JetTypeInfo, E
return expression.accept(closures, data);
}
@Override
public JetTypeInfo visitNamedFunction(@NotNull JetNamedFunction function, ExpressionTypingContext data) {
return function.accept(closures, data);
}
//////////////////////////////////////////////////////////////////////////////////////////////
@Override
@@ -61,18 +61,22 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
private final BasicExpressionTypingVisitor basic;
private final ControlStructureTypingVisitor controlStructures;
private final PatternMatchingTypingVisitor patterns;
private final ClosureExpressionsTypingVisitor closures;
public ExpressionTypingVisitorForStatements(
@NotNull ExpressionTypingInternals facade,
@NotNull WritableScope scope,
BasicExpressionTypingVisitor basic,
@NotNull BasicExpressionTypingVisitor basic,
@NotNull ControlStructureTypingVisitor controlStructures,
@NotNull PatternMatchingTypingVisitor patterns) {
@NotNull PatternMatchingTypingVisitor patterns,
@NotNull ClosureExpressionsTypingVisitor closures
) {
super(facade);
this.scope = scope;
this.basic = basic;
this.controlStructures = controlStructures;
this.patterns = patterns;
this.closures = closures;
}
@Nullable
@@ -175,7 +179,7 @@ public class ExpressionTypingVisitorForStatements extends ExpressionTypingVisito
@Override
public JetTypeInfo visitNamedFunction(@NotNull JetNamedFunction function, ExpressionTypingContext context) {
return basic.visitNamedFunction(function, context, true, scope);
return closures.visitNamedFunction(function, context, true, scope);
}
@Override