Divided resolveFunctionDescriptor method in to several pieces

This commit is contained in:
Stanislav Erokhin
2015-03-02 15:49:14 +03:00
parent 07a691f4b7
commit 8ed3314b2c
@@ -29,6 +29,7 @@ import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.descriptors.impl.*;
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1;
import org.jetbrains.kotlin.diagnostics.DiagnosticUtils;
import org.jetbrains.kotlin.lexer.JetKeywordToken;
import org.jetbrains.kotlin.lexer.JetModifierKeywordToken;
import org.jetbrains.kotlin.lexer.JetTokens;
@@ -236,8 +237,20 @@ public class DescriptorResolver {
@NotNull BindingTrace trace,
@NotNull DataFlowInfo dataFlowInfo
) {
return resolveFunctionDescriptor(containingDescriptor, scope, function, trace, dataFlowInfo,
annotationResolver.resolveAnnotationsWithArguments(scope, function.getModifierList(), trace), false);
if (function.getName() == null) {
trace.report(FUNCTION_DECLARATION_WITH_NO_NAME.on(function));
}
SimpleFunctionDescriptorImpl functionDescriptor = SimpleFunctionDescriptorImpl.create(
containingDescriptor,
annotationResolver.resolveAnnotationsWithArguments(scope, function.getModifierList(), trace),
function.getNameAsSafeName(),
CallableMemberDescriptor.Kind.DECLARATION,
toSourceElement(function)
);
initializeFunctionDescriptorAndExplicitReturnType(containingDescriptor, scope, function, functionDescriptor, trace);
initializeFunctionReturnTypeBasedOnFunctionBody(scope, function, functionDescriptor, trace, dataFlowInfo);
BindingContextUtils.recordFunctionDeclarationToDescriptor(trace, function, functionDescriptor);
return functionDescriptor;
}
@NotNull
@@ -248,43 +261,63 @@ public class DescriptorResolver {
@NotNull BindingTrace trace,
@NotNull DataFlowInfo dataFlowInfo
) {
return resolveFunctionDescriptor(containingDescriptor, scope, function, trace, dataFlowInfo,
annotationResolver.resolveAnnotationsWithArguments(scope, function.getModifierList(), trace), true);
FunctionExpressionDescriptor functionDescriptor = new FunctionExpressionDescriptor(
containingDescriptor,
annotationResolver.resolveAnnotationsWithArguments(scope, function.getModifierList(), trace),
function.getNameAsSafeName(),
CallableMemberDescriptor.Kind.DECLARATION,
toSourceElement(function)
);
initializeFunctionDescriptorAndExplicitReturnType(containingDescriptor, scope, function, functionDescriptor, trace);
initializeFunctionReturnTypeBasedOnFunctionBody(scope, function, functionDescriptor, trace, dataFlowInfo);
BindingContextUtils.recordFunctionDeclarationToDescriptor(trace, function, functionDescriptor);
return functionDescriptor;
}
private void initializeFunctionReturnTypeBasedOnFunctionBody(
@NotNull final JetScope scope,
@NotNull final JetNamedFunction function,
@NotNull final SimpleFunctionDescriptorImpl functionDescriptor,
@NotNull final BindingTrace trace,
@NotNull final DataFlowInfo dataFlowInfo
) {
if (functionDescriptor.getReturnType() != null) return;
assert function.getTypeReference() == null : "Return type must be initialized early for function: "
+ function.getText() + ", at: "
+ DiagnosticUtils.atLocation(function);
JetType returnType;
if (function.hasBlockBody()) {
returnType = builtIns.getUnitType();
}
else if (function.hasBody()) {
returnType =
DeferredType.createRecursionIntolerant(
storageManager,
trace,
new Function0<JetType>() {
@Override
public JetType invoke() {
JetType type = expressionTypingServices
.getBodyExpressionType(trace, scope, dataFlowInfo, function, functionDescriptor);
return transformAnonymousTypeIfNeeded(functionDescriptor, function, type, trace);
}
});
}
else {
returnType = ErrorUtils.createErrorType("No type, no body");
}
functionDescriptor.setReturnType(returnType);
}
@NotNull
private SimpleFunctionDescriptor resolveFunctionDescriptor(
private void initializeFunctionDescriptorAndExplicitReturnType(
@NotNull DeclarationDescriptor containingDescriptor,
@NotNull final JetScope scope,
@NotNull final JetNamedFunction function,
@NotNull final BindingTrace trace,
@NotNull final DataFlowInfo dataFlowInfo,
@NotNull Annotations annotations,
boolean nameCanBeOmitted
@NotNull JetScope scope,
@NotNull JetFunction function,
@NotNull SimpleFunctionDescriptorImpl functionDescriptor,
@NotNull BindingTrace trace
) {
if (!nameCanBeOmitted && function.getName() == null) {
trace.report(FUNCTION_DECLARATION_WITH_NO_NAME.on(function));
}
final SimpleFunctionDescriptorImpl functionDescriptor;
if (nameCanBeOmitted) { // todo remove this hack
functionDescriptor = new FunctionExpressionDescriptor(
containingDescriptor,
annotations,
function.getNameAsSafeName(),
CallableMemberDescriptor.Kind.DECLARATION,
toSourceElement(function)
);
}
else {
functionDescriptor = SimpleFunctionDescriptorImpl.create(
containingDescriptor,
annotations,
function.getNameAsSafeName(),
CallableMemberDescriptor.Kind.DECLARATION,
toSourceElement(function)
);
}
WritableScope innerScope = new WritableScopeImpl(scope, functionDescriptor, new TraceBasedRedeclarationHandler(trace),
"Function descriptor header scope");
innerScope.addLabeledDeclaration(functionDescriptor);
@@ -297,11 +330,7 @@ public class DescriptorResolver {
JetType receiverType = null;
JetTypeReference receiverTypeRef = function.getReceiverTypeReference();
if (receiverTypeRef != null) {
JetScope scopeForReceiver =
function.hasTypeParameterListBeforeFunctionName()
? innerScope
: scope;
receiverType = typeResolver.resolveType(scopeForReceiver, receiverTypeRef, trace, true);
receiverType = typeResolver.resolveType(innerScope, receiverTypeRef, trace, true);
}
List<ValueParameterDescriptor> valueParameterDescriptors =
@@ -310,32 +339,11 @@ public class DescriptorResolver {
innerScope.changeLockLevel(WritableScope.LockLevel.READING);
JetTypeReference returnTypeRef = function.getTypeReference();
JetType returnType;
JetType returnType = null;
if (returnTypeRef != null) {
returnType = typeResolver.resolveType(innerScope, returnTypeRef, trace, true);
}
else if (function.hasBlockBody()) {
returnType = builtIns.getUnitType();
}
else {
if (function.hasBody()) {
returnType =
DeferredType.createRecursionIntolerant(
storageManager,
trace,
new Function0<JetType>() {
@Override
public JetType invoke() {
JetType type = expressionTypingServices
.getBodyExpressionType(trace, scope, dataFlowInfo, function, functionDescriptor);
return transformAnonymousTypeIfNeeded(functionDescriptor, function, type, trace);
}
});
}
else {
returnType = ErrorUtils.createErrorType("No type, no body");
}
}
Modality modality = resolveModalityFromModifiers(function, getDefaultModality(containingDescriptor, function.hasBody()));
Visibility visibility = resolveVisibilityFromModifiers(function, getDefaultVisibility(function, containingDescriptor));
functionDescriptor.initialize(
@@ -347,11 +355,10 @@ public class DescriptorResolver {
modality,
visibility
);
BindingContextUtils.recordFunctionDeclarationToDescriptor(trace, function, functionDescriptor);
return functionDescriptor;
}
@NotNull
public static SimpleFunctionDescriptor createComponentFunctionDescriptor(
int parameterIndex,