diff --git a/idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java b/idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java
index ef5eb18a511..eb410248fc5 100644
--- a/idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java
+++ b/idea/src/org/jetbrains/jet/lang/cfg/JetControlFlowProcessor.java
@@ -213,17 +213,32 @@ public class JetControlFlowProcessor {
@Override
public void visitUnaryExpression(JetUnaryExpression expression) {
- IElementType operationType = expression.getOperationSign().getReferencedNameElementType();
+ JetSimpleNameExpression operationSign = expression.getOperationSign();
+ IElementType operationType = operationSign.getReferencedNameElementType();
+ JetExpression baseExpression = expression.getBaseExpression();
if (JetTokens.LABELS.contains(operationType)) {
- String referencedName = expression.getOperationSign().getReferencedName();
+ String referencedName = operationSign.getReferencedName();
referencedName = referencedName == null ? " >" : referencedName;
- visitLabeledExpression(referencedName.substring(1), expression.getBaseExpression());
+ visitLabeledExpression(referencedName.substring(1), baseExpression);
}
else {
- visitElement(expression);
+ value(baseExpression, false, false);
+ value(operationSign, false, false);
+
+ boolean incrementOrDecrement = isIncrementOrDecrement(operationType);
+ if (incrementOrDecrement) {
+ builder.writeNode(expression, baseExpression);
+ }
+
+ builder.readNode(expression);
}
}
+ private boolean isIncrementOrDecrement(IElementType operationType) {
+ return operationType == JetTokens.PLUSPLUS || operationType == JetTokens.MINUSMINUS;
+ }
+
+
@Override
public void visitIfExpression(JetIfExpression expression) {
value(expression.getCondition(), false, true);
@@ -462,6 +477,16 @@ public class JetControlFlowProcessor {
builder.readNode(expression);
}
+ @Override
+ public void visitBinaryWithTypeRHSExpression(JetBinaryExpressionWithTypeRHS expression) {
+ if (expression.getOperationSign().getReferencedNameElementType() == JetTokens.COLON) {
+ value(expression.getLeft(), false, false);
+ }
+ else {
+ visitJetElement(expression); // TODO
+ }
+ }
+
@Override
public void visitTypeProjection(JetTypeProjection typeProjection) {
// TODO : Support Type Arguments. Class object may be initialized at this point");
diff --git a/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java b/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java
index 51faa346f18..773f969e38c 100644
--- a/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java
+++ b/idea/src/org/jetbrains/jet/lang/resolve/TopDownAnalyzer.java
@@ -362,7 +362,7 @@ public class TopDownAnalyzer {
@Override
public void visitUnsupportedElementInstruction(UnsupportedElementInstruction instruction) {
- semanticServices.getErrorHandler().genericError(instruction.getElement().getNode(), "Unsupported by control-flow builder");
+ semanticServices.getErrorHandler().genericError(instruction.getElement().getNode(), "Unsupported by control-flow builder " + instruction.getElement());
}
@Override
diff --git a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java
index 6636ff00dd9..8f555f7170b 100644
--- a/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java
+++ b/idea/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java
@@ -1082,11 +1082,16 @@ public class JetTypeInferrer {
if (functionDescriptor != null) {
JetType returnType = functionDescriptor.getUnsubstitutedReturnType();
if (operationType == JetTokens.PLUSPLUS || operationType == JetTokens.MINUSMINUS) {
- if (!semanticServices.getTypeChecker().isSubtypeOf(returnType, receiverType)) {
- semanticServices.getErrorHandler().genericError(operationSign.getNode(), name + " must return " + receiverType + " but returns " + returnType);
+ if (semanticServices.getTypeChecker().isSubtypeOf(returnType, JetStandardClasses.getUnitType())) {
+ result = JetStandardClasses.getUnitType();
+ }
+ else {
+ if (!semanticServices.getTypeChecker().isSubtypeOf(returnType, receiverType)) {
+ semanticServices.getErrorHandler().genericError(operationSign.getNode(), name + " must return " + receiverType + " but returns " + returnType);
+ }
+ // TODO : Maybe returnType?
+ result = receiverType;
}
- // TODO : Maybe returnType?
- result = receiverType;
} else {
result = returnType;
}
@@ -1386,7 +1391,7 @@ public class JetTypeInferrer {
String counterpartName = binaryOperationNames.get(assignmentOperationCounterparts.get(operationType));
getTypeForBinaryCall(expression, counterpartName, scope, true);
}
- result = null; // not an element
+ result = null; // not an expression
}
@Override
diff --git a/idea/testData/checker/IncDec.jet b/idea/testData/checker/IncDec.jet
new file mode 100644
index 00000000000..1c763ee6774
--- /dev/null
+++ b/idea/testData/checker/IncDec.jet
@@ -0,0 +1,46 @@
+class IncDec {
+ fun inc() : IncDec = this
+ fun dec() : IncDec = this
+}
+
+fun testIncDec() {
+ var x = new IncDec()
+ x++
+ ++x
+ x--
+ --x
+ x = x++
+ x = x--
+ x = ++x
+ x = --x
+}
+
+class WrongIncDec {
+ fun inc() : Int = 1
+ fun dec() : Int = 1
+}
+
+fun testWrongIncDec() {
+ var x = new WrongIncDec()
+ x++
+ ++x
+ x--
+ --x
+}
+
+class UnitIncDec {
+ fun inc() : Unit {}
+ fun dec() : Unit {}
+}
+
+fun testUnitIncDec() {
+ var x = new UnitIncDec()
+ x++
+ ++x
+ x--
+ --x
+ x = x++
+ x = x--
+ x = ++x
+ x = --x
+}
\ No newline at end of file
diff --git a/idea/testData/resolve/ResolveOfInfixExpressions.jet b/idea/testData/resolve/ResolveOfInfixExpressions.jet
index 0c072ad25ca..458921abd93 100644
--- a/idea/testData/resolve/ResolveOfInfixExpressions.jet
+++ b/idea/testData/resolve/ResolveOfInfixExpressions.jet
@@ -85,3 +85,15 @@ fun tt(t : T) : T {
1 `std::Int.compareTo(Double)`>= 2.0
1 `std::Int.compareTo(Double)`<= 2.0
}
+
+
+class UnitIncDec {
+ ~uinc~fun inc() : Unit
+ ~udec~fun dec() : Unit
+}
+
+fun testUnitIncDec() {
+ var x = new UnitIncDec()
+ x`uinc`++
+ x`udec`--
+}
\ No newline at end of file