Moved method visitNamedFunction from BasicExpressionTypingVisitor to ClosureExpressionsTypingVisitor.
This commit is contained in:
-91
@@ -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)) {
|
||||
|
||||
+89
@@ -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;
|
||||
|
||||
+9
-4
@@ -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
|
||||
|
||||
+7
-3
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user