KT-287 Infer constructor type arguments

This commit is contained in:
Andrey Breslav
2011-11-09 21:48:36 +03:00
parent a24e448973
commit 0c492ae0eb
4 changed files with 18 additions and 25 deletions
@@ -484,16 +484,17 @@ public class BodyResolver {
private void resolvePropertyInitializer(JetProperty property, PropertyDescriptor propertyDescriptor, JetExpression initializer, JetScope scope) { private void resolvePropertyInitializer(JetProperty property, PropertyDescriptor propertyDescriptor, JetExpression initializer, JetScope scope) {
//JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData(property, initializer); // TODO : flow JET-15 //JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData(property, initializer); // TODO : flow JET-15
ExpressionTypingServices typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors); ExpressionTypingServices typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors);
JetType type = typeInferrer.getType(getPropertyDeclarationInnerScope(scope, propertyDescriptor), initializer, NO_EXPECTED_TYPE); JetType expectedTypeForInitializer = property.getPropertyTypeRef() != null ? propertyDescriptor.getOutType() : NO_EXPECTED_TYPE;
JetType type = typeInferrer.getType(getPropertyDeclarationInnerScope(scope, propertyDescriptor), initializer, expectedTypeForInitializer);
JetType expectedType = propertyDescriptor.getInType(); //
if (expectedType == null) { // JetType expectedType = propertyDescriptor.getInType();
expectedType = propertyDescriptor.getOutType(); // if (expectedType == null) {
} // expectedType = propertyDescriptor.getOutType();
if (type != null && expectedType != null // }
&& !context.getSemanticServices().getTypeChecker().isSubtypeOf(type, expectedType)) { // if (type != null && expectedType != null
context.getTrace().report(TYPE_MISMATCH.on(initializer, expectedType, type)); // && !context.getSemanticServices().getTypeChecker().isSubtypeOf(type, expectedType)) {
} //// context.getTrace().report(TYPE_MISMATCH.on(initializer, expectedType, type));
// }
} }
private void resolveFunctionBodies() { private void resolveFunctionBodies() {
@@ -52,11 +52,8 @@ public class CallResolver {
public VariableDescriptor resolveSimpleProperty( public VariableDescriptor resolveSimpleProperty(
@NotNull BindingTrace trace, @NotNull BindingTrace trace,
@NotNull JetScope scope, @NotNull JetScope scope,
// @NotNull ReceiverDescriptor receiver, @NotNull Call call,
// @NotNull final JetSimpleNameExpression nameExpression,
@NotNull Call call,
@NotNull JetType expectedType) { @NotNull JetType expectedType) {
// Call call = CallMaker.makePropertyCall(receiver, null, nameExpression);
JetExpression calleeExpression = call.getCalleeExpression(); JetExpression calleeExpression = call.getCalleeExpression();
assert calleeExpression instanceof JetSimpleNameExpression; assert calleeExpression instanceof JetSimpleNameExpression;
JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) calleeExpression; JetSimpleNameExpression nameExpression = (JetSimpleNameExpression) calleeExpression;
@@ -116,7 +113,6 @@ public class CallResolver {
if (descriptor instanceof ConstructorDescriptor) { if (descriptor instanceof ConstructorDescriptor) {
Modality modality = ((ConstructorDescriptor) descriptor).getContainingDeclaration().getModality(); Modality modality = ((ConstructorDescriptor) descriptor).getContainingDeclaration().getModality();
if (modality == Modality.ABSTRACT) { if (modality == Modality.ABSTRACT) {
// tracing.reportOverallResolutionError(trace, "Can not create an instance of an abstract class");
tracing.instantiationOfAbstractClass(trace); tracing.instantiationOfAbstractClass(trace);
return false; return false;
} }
@@ -149,14 +145,12 @@ public class CallResolver {
ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor; ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor;
Set<FunctionDescriptor> constructors = classDescriptor.getConstructors(); Set<FunctionDescriptor> constructors = classDescriptor.getConstructors();
if (constructors.isEmpty()) { if (constructors.isEmpty()) {
// trace.getErrorHandler().genericError(reportAbsenceOn, "This class does not have a constructor");
trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn)); trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn));
return checkArgumentTypesAndFail(trace, scope, call); return checkArgumentTypesAndFail(trace, scope, call);
} }
prioritizedTasks.add(new ResolutionTask<FunctionDescriptor>(TaskPrioritizer.convertWithImpliedThis(scope, Collections.<ReceiverDescriptor>singletonList(NO_RECEIVER), constructors), call, DataFlowInfo.EMPTY)); prioritizedTasks.add(new ResolutionTask<FunctionDescriptor>(TaskPrioritizer.convertWithImpliedThis(scope, Collections.<ReceiverDescriptor>singletonList(NO_RECEIVER), constructors), call, DataFlowInfo.EMPTY));
} }
else { else {
// trace.getErrorHandler().genericError(calleeExpression.getNode(), "Not a class");
trace.report(NOT_A_CLASS.on(calleeExpression)); trace.report(NOT_A_CLASS.on(calleeExpression));
return checkArgumentTypesAndFail(trace, scope, call); return checkArgumentTypesAndFail(trace, scope, call);
} }
@@ -169,7 +163,6 @@ public class CallResolver {
Set<FunctionDescriptor> constructors = classDescriptor.getConstructors(); Set<FunctionDescriptor> constructors = classDescriptor.getConstructors();
if (constructors.isEmpty()) { if (constructors.isEmpty()) {
// trace.getErrorHandler().genericError(reportAbsenceOn, "This class does not have a constructor");
trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn)); trace.report(NO_CONSTRUCTOR.on(reportAbsenceOn));
return checkArgumentTypesAndFail(trace, scope, call); return checkArgumentTypesAndFail(trace, scope, call);
} }
@@ -296,11 +289,9 @@ public class CallResolver {
public void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount) { public void wrongNumberOfTypeArguments(@NotNull BindingTrace trace, int expectedTypeArgumentCount) {
JetTypeArgumentList typeArgumentList = call.getTypeArgumentList(); JetTypeArgumentList typeArgumentList = call.getTypeArgumentList();
if (typeArgumentList != null) { if (typeArgumentList != null) {
// trace.getErrorHandler().genericError(typeArgumentList.getNode(), message);
trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(typeArgumentList, expectedTypeArgumentCount)); trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(typeArgumentList, expectedTypeArgumentCount));
} }
else { else {
// reportOverallResolutionError(trace, message);
trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(reference, expectedTypeArgumentCount)); trace.report(WRONG_NUMBER_OF_TYPE_ARGUMENTS.on(reference, expectedTypeArgumentCount));
} }
} }
@@ -439,8 +430,6 @@ public class CallResolver {
} }
} }
// checkReceiverAbsence(candidateCall, tracing, candidate);
// Error is already reported if something is missing // Error is already reported if something is missing
ReceiverDescriptor receiverParameter = candidateCall.getReceiverArgument(); ReceiverDescriptor receiverParameter = candidateCall.getReceiverArgument();
ReceiverDescriptor candidateReceiver = candidate.getReceiverParameter(); ReceiverDescriptor candidateReceiver = candidate.getReceiverParameter();
@@ -453,7 +442,6 @@ public class CallResolver {
} }
ConstraintSystemSolution solution = constraintSystem.solve(); ConstraintSystemSolution solution = constraintSystem.solve();
// solutions.put(candidate, solution);
if (solution.isSuccessful()) { if (solution.isSuccessful()) {
D substitute = (D) candidate.substitute(solution.getSubstitutor()); D substitute = (D) candidate.substitute(solution.getSubstitutor());
assert substitute != null; assert substitute != null;
@@ -506,7 +494,6 @@ public class CallResolver {
} }
else { else {
candidateCall.setStatus(OTHER_ERROR); candidateCall.setStatus(OTHER_ERROR);
// tracing.reportWrongTypeArguments(temporaryTrace, "Number of type arguments does not match " + DescriptorRenderer.TEXT.render(candidate));
tracing.wrongNumberOfTypeArguments(temporaryTrace, expectedTypeArgumentCount); tracing.wrongNumberOfTypeArguments(temporaryTrace, expectedTypeArgumentCount);
} }
} }
@@ -260,7 +260,7 @@ public class CompileTimeConstantResolver {
} }
private boolean noExpectedType(JetType expectedType) { private boolean noExpectedType(JetType expectedType) {
return expectedType == TypeUtils.NO_EXPECTED_TYPE || JetStandardClasses.isUnit(expectedType); return expectedType == TypeUtils.NO_EXPECTED_TYPE || JetStandardClasses.isUnit(expectedType) || ErrorUtils.isErrorType(expectedType);
} }
} }
@@ -0,0 +1,5 @@
// KT-287 Infer constructor type arguments
import java.util.*
fun attributes() : Map<String, String> = HashMap() // Should be inferred;
val attributes : Map<String, String> = HashMap() // Should be inferred;