提交 764fbf00 编写于 作者: A Andrey Breslav

Assignments

上级 469f02ef
......@@ -31,6 +31,11 @@ public class BindingTraceContext extends BindingTrace implements BindingContext
resolutionResults.put(expression, descriptor);
}
@Override
public void removeReferenceResolution(@NotNull JetReferenceExpression referenceExpression) {
resolutionResults.remove(referenceExpression);
}
@Override
public void recordTypeResolution(@NotNull JetTypeReference typeReference, @NotNull JetType type) {
types.put(typeReference, type);
......
......@@ -29,4 +29,8 @@ public class BindingTrace {
public void setToplevelScope(JetScope toplevelScope) {
}
public void removeReferenceResolution(@NotNull JetReferenceExpression referenceExpression) {
}
}
......@@ -57,9 +57,9 @@ public class JetTypeInferrer {
}
@Nullable
private FunctionDescriptor lookupFunction(JetScope scope, JetReferenceExpression reference, String name, JetType receiverType, List<JetType> argumentTypes) {
private FunctionDescriptor lookupFunction(JetScope scope, JetReferenceExpression reference, String name, JetType receiverType, List<JetType> argumentTypes, boolean reportUnresolved) {
OverloadDomain overloadDomain = semanticServices.getOverloadResolver().getOverloadDomain(receiverType, scope, name);
overloadDomain = wrapForTracing(overloadDomain, reference);
overloadDomain = wrapForTracing(overloadDomain, reference, reportUnresolved);
return overloadDomain.getFunctionDescriptorForPositionedArguments(Collections.<JetType>emptyList(), argumentTypes);
}
......@@ -129,10 +129,10 @@ public class JetTypeInferrer {
throw new IllegalArgumentException("Unsupported element: " + elem);
}
});
return wrapForTracing(result[0], reference[0]);
return wrapForTracing(result[0], reference[0], true);
}
private OverloadDomain wrapForTracing(final OverloadDomain overloadDomain, @NotNull final JetReferenceExpression referenceExpression) {
private OverloadDomain wrapForTracing(final OverloadDomain overloadDomain, @NotNull final JetReferenceExpression referenceExpression, final boolean reportUnresolved) {
if (overloadDomain == null) return OverloadDomain.EMPTY;
return new OverloadDomain() {
@Override
......@@ -141,7 +141,9 @@ public class JetTypeInferrer {
if (descriptor != null) {
trace.recordReferenceResolution(referenceExpression, descriptor);
} else {
semanticServices.getErrorHandler().unresolvedReference(referenceExpression);
if (reportUnresolved) {
semanticServices.getErrorHandler().unresolvedReference(referenceExpression);
}
}
return descriptor;
}
......@@ -152,7 +154,9 @@ public class JetTypeInferrer {
if (descriptor != null) {
trace.recordReferenceResolution(referenceExpression, descriptor);
} else {
semanticServices.getErrorHandler().unresolvedReference(referenceExpression);
if (reportUnresolved) {
semanticServices.getErrorHandler().unresolvedReference(referenceExpression);
}
}
return descriptor;
}
......@@ -534,7 +538,7 @@ public class JetTypeInferrer {
else {
JetType type = getType(scope, expression.getBaseExpression(), false);
if (type != null) {
FunctionDescriptor functionDescriptor = lookupFunction(scope, expression.getOperationSign(), name, type, Collections.<JetType>emptyList());
FunctionDescriptor functionDescriptor = lookupFunction(scope, expression.getOperationSign(), name, type, Collections.<JetType>emptyList(), true);
if (functionDescriptor != null) {
result = functionDescriptor.getUnsubstitutedReturnType();
}
......@@ -548,10 +552,10 @@ public class JetTypeInferrer {
IElementType operationType = operationSign.getReferencedNameElementType();
if (operationType == JetTokens.IDENTIFIER) {
result = getTypeForBinaryCall(expression, operationSign.getReferencedName(), scope);
result = getTypeForBinaryCall(expression, operationSign.getReferencedName(), scope, true);
}
else if (binaryOperationNames.containsKey(operationType)) {
result = getTypeForBinaryCall(expression, binaryOperationNames.get(operationType), scope);
result = getTypeForBinaryCall(expression, binaryOperationNames.get(operationType), scope, true);
}
else if (operationType == JetTokens.EQ) {
JetExpression left = expression.getLeft();
......@@ -567,7 +571,7 @@ public class JetTypeInferrer {
result = null; // TODO : This is not an expression, in fact!
}
else if (comparisonOperations.contains(operationType)) {
JetType compareToReturnType = getTypeForBinaryCall(expression, "compareTo", scope);
JetType compareToReturnType = getTypeForBinaryCall(expression, "compareTo", scope, true);
if (compareToReturnType != null) {
TypeConstructor constructor = compareToReturnType.getConstructor();
JetStandardLibrary standardLibrary = semanticServices.getStandardLibrary();
......@@ -578,6 +582,30 @@ public class JetTypeInferrer {
semanticServices.getErrorHandler().structuralError(operationSign.getNode(), "compareTo must return Int, but returns " + compareToReturnType);
}
}
}
else if (assignmentOperationNames.containsKey(operationType)) {
String name = assignmentOperationNames.get(operationType);
JetType assignmentOperationType = getTypeForBinaryCall(expression, name, scope, false);
String counterpartName = binaryOperationNames.get(assignmentOperationCounterparts.get(operationType));
JetType counterpartType = getTypeForBinaryCall(expression, counterpartName, scope, false);
if (assignmentOperationType != null) {
if (counterpartType != null) {
semanticServices.getErrorHandler().structuralError(operationSign.getNode(), "Ambiguity: both '" + name + "' and '" + counterpartName + "' are defined");
// TODO : make reference unresolved?
trace.removeReferenceResolution(operationSign);
} else {
result = assignmentOperationType;
}
}
else {
if (counterpartType == null) {
semanticServices.getErrorHandler().unresolvedReference(operationSign);
} else {
result = counterpartType;
}
}
} else {
semanticServices.getErrorHandler().structuralError(operationSign.getNode(), "Unknown operation");
}
......@@ -591,7 +619,7 @@ public class JetTypeInferrer {
List<JetType> argumentTypes = getTypes(scope, indexExpressions);
if (argumentTypes == null) return;
FunctionDescriptor functionDescriptor = lookupFunction(scope, expression, "get", receiverType, argumentTypes);
FunctionDescriptor functionDescriptor = lookupFunction(scope, expression, "get", receiverType, argumentTypes, true);
if (functionDescriptor != null) {
result = functionDescriptor.getUnsubstitutedReturnType();
}
......@@ -608,8 +636,8 @@ public class JetTypeInferrer {
if (receiverType == null) return;
// TODO : nasty hack: effort is duplicated
lookupFunction(scope, arrayAccessExpression, "set", receiverType, argumentTypes);
FunctionDescriptor functionDescriptor = lookupFunction(scope, operationSign, "set", receiverType, argumentTypes);
lookupFunction(scope, arrayAccessExpression, "set", receiverType, argumentTypes, true);
FunctionDescriptor functionDescriptor = lookupFunction(scope, operationSign, "set", receiverType, argumentTypes, true);
if (functionDescriptor != null) {
result = functionDescriptor.getUnsubstitutedReturnType();
}
......@@ -620,7 +648,7 @@ public class JetTypeInferrer {
throw new IllegalArgumentException("Unsupported element: " + elem);
}
private JetType getTypeForBinaryCall(JetBinaryExpression expression, String name, JetScope scope) {
private JetType getTypeForBinaryCall(JetBinaryExpression expression, @NotNull String name, JetScope scope, boolean reportUnresolved) {
JetSimpleNameExpression operationSign = expression.getOperationReference();
JetExpression left = expression.getLeft();
JetType leftType = getType(scope, left, false);
......@@ -629,7 +657,7 @@ public class JetTypeInferrer {
return ErrorType.createErrorType("No right argument"); // TODO
}
JetType rightType = getType(scope, right, false);
FunctionDescriptor functionDescriptor = lookupFunction(scope, operationSign, name, leftType, Collections.singletonList(rightType));
FunctionDescriptor functionDescriptor = lookupFunction(scope, operationSign, name, leftType, Collections.singletonList(rightType), reportUnresolved);
if (functionDescriptor != null) {
return functionDescriptor.getUnsubstitutedReturnType();
}
......@@ -668,5 +696,14 @@ public class JetTypeInferrer {
assignmentOperationNames.put(JetTokens.MINUSEQ, "minusAssign");
}
private static final Map<IElementType, IElementType> assignmentOperationCounterparts = new HashMap<IElementType, IElementType>();
static {
assignmentOperationCounterparts.put(JetTokens.MULTEQ, JetTokens.MUL);
assignmentOperationCounterparts.put(JetTokens.DIVEQ, JetTokens.DIV);
assignmentOperationCounterparts.put(JetTokens.PERCEQ, JetTokens.PERC);
assignmentOperationCounterparts.put(JetTokens.PLUSEQ, JetTokens.PLUS);
assignmentOperationCounterparts.put(JetTokens.MINUSEQ, JetTokens.MINUS);
}
}
......@@ -16,6 +16,7 @@ import util.*
`t`t<`t.T`T>(`t.t`t)`:t.T`
new `X`X<`t.T`T>()
1 `std::Int.plus(Int)`+ 1
1 `std::Int.plus(Int)`+= 1
new X<String>() `plus`+ "1"
new X<String>() `plus`plus "sadfas"
new X<String>().`plus`plus("")
......@@ -32,6 +33,7 @@ import util.*
~get1~fun get(i : Int) : Int {}
~get2~fun get(i : Int, j : Int) : String {}
~get3~fun get(i : Object) : Any {return i }
~+=~fun plusAssign(a : Any?) : Unit {}
}
~Bar~class Bar : Foo {
......@@ -59,6 +61,7 @@ fun <T> tt(t : T) : T {
`inc`++y
`dec`--y
y`dec`--
y `+=`+= 1
1 `std::Int.compareTo(Double)`> 2.0
1 `std::Int.compareTo(Double)`< 2.0
1 `std::Int.compareTo(Double)`>= 2.0
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册