'do..while' and assignments
This commit is contained in:
@@ -110,7 +110,6 @@ class Double : Number, Comparable<Double> {
|
|||||||
|
|
||||||
class Float : Number, Comparable<Float> {
|
class Float : Number, Comparable<Float> {
|
||||||
fun compareTo(other : Double) : Int
|
fun compareTo(other : Double) : Int
|
||||||
fun compareTo(other : Float) : Int
|
|
||||||
fun compareTo(other : Long) : Int
|
fun compareTo(other : Long) : Int
|
||||||
fun compareTo(other : Int) : Int
|
fun compareTo(other : Int) : Int
|
||||||
fun compareTo(other : Short) : Int
|
fun compareTo(other : Short) : Int
|
||||||
@@ -174,7 +173,6 @@ class Float : Number, Comparable<Float> {
|
|||||||
class Long : Number, Comparable<Long> {
|
class Long : Number, Comparable<Long> {
|
||||||
fun compareTo(other : Double) : Int
|
fun compareTo(other : Double) : Int
|
||||||
fun compareTo(other : Float) : Int
|
fun compareTo(other : Float) : Int
|
||||||
fun compareTo(other : Long) : Int
|
|
||||||
fun compareTo(other : Int) : Int
|
fun compareTo(other : Int) : Int
|
||||||
fun compareTo(other : Short) : Int
|
fun compareTo(other : Short) : Int
|
||||||
fun compareTo(other : Byte) : Int
|
fun compareTo(other : Byte) : Int
|
||||||
@@ -237,7 +235,7 @@ class Long : Number, Comparable<Long> {
|
|||||||
class Int : Number, Comparable<Int> {
|
class Int : Number, Comparable<Int> {
|
||||||
fun compareTo(other : Double) : Int
|
fun compareTo(other : Double) : Int
|
||||||
fun compareTo(other : Float) : Int
|
fun compareTo(other : Float) : Int
|
||||||
fun compareTo(other : Int) : Int
|
fun compareTo(other : Long) : Int
|
||||||
fun compareTo(other : Int) : Int
|
fun compareTo(other : Int) : Int
|
||||||
fun compareTo(other : Short) : Int
|
fun compareTo(other : Short) : Int
|
||||||
fun compareTo(other : Byte) : Int
|
fun compareTo(other : Byte) : Int
|
||||||
@@ -300,11 +298,10 @@ class Int : Number, Comparable<Int> {
|
|||||||
class Char : Number, Comparable<Char> {
|
class Char : Number, Comparable<Char> {
|
||||||
fun compareTo(other : Double) : Int
|
fun compareTo(other : Double) : Int
|
||||||
fun compareTo(other : Float) : Int
|
fun compareTo(other : Float) : Int
|
||||||
fun compareTo(other : Int) : Int
|
fun compareTo(other : Long) : Int
|
||||||
fun compareTo(other : Int) : Int
|
fun compareTo(other : Int) : Int
|
||||||
fun compareTo(other : Short) : Int
|
fun compareTo(other : Short) : Int
|
||||||
fun compareTo(other : Byte) : Int
|
fun compareTo(other : Byte) : Int
|
||||||
fun compareTo(other : Char) : Int
|
|
||||||
|
|
||||||
fun plus(other : Double) : Double
|
fun plus(other : Double) : Double
|
||||||
fun plus(other : Float) : Float
|
fun plus(other : Float) : Float
|
||||||
@@ -360,12 +357,11 @@ class Char : Number, Comparable<Char> {
|
|||||||
fun minus() : Int
|
fun minus() : Int
|
||||||
}
|
}
|
||||||
|
|
||||||
class Short : Number, Comparable<Char> {
|
class Short : Number, Comparable<Short> {
|
||||||
fun compareTo(other : Double) : Int
|
fun compareTo(other : Double) : Int
|
||||||
fun compareTo(other : Float) : Int
|
fun compareTo(other : Float) : Int
|
||||||
|
fun compareTo(other : Long) : Int
|
||||||
fun compareTo(other : Int) : Int
|
fun compareTo(other : Int) : Int
|
||||||
fun compareTo(other : Int) : Int
|
|
||||||
fun compareTo(other : Short) : Int
|
|
||||||
fun compareTo(other : Byte) : Int
|
fun compareTo(other : Byte) : Int
|
||||||
fun compareTo(other : Char) : Int
|
fun compareTo(other : Char) : Int
|
||||||
|
|
||||||
@@ -423,13 +419,12 @@ class Short : Number, Comparable<Char> {
|
|||||||
fun minus() : Int
|
fun minus() : Int
|
||||||
}
|
}
|
||||||
|
|
||||||
class Byte : Number, Comparable<Char> {
|
class Byte : Number, Comparable<Byte> {
|
||||||
fun compareTo(other : Double) : Int
|
fun compareTo(other : Double) : Int
|
||||||
fun compareTo(other : Float) : Int
|
fun compareTo(other : Float) : Int
|
||||||
fun compareTo(other : Int) : Int
|
fun compareTo(other : Long) : Int
|
||||||
fun compareTo(other : Int) : Int
|
fun compareTo(other : Int) : Int
|
||||||
fun compareTo(other : Short) : Int
|
fun compareTo(other : Short) : Int
|
||||||
fun compareTo(other : Byte) : Int
|
|
||||||
fun compareTo(other : Char) : Int
|
fun compareTo(other : Char) : Int
|
||||||
|
|
||||||
fun plus(other : Double) : Double
|
fun plus(other : Double) : Double
|
||||||
|
|||||||
@@ -10,4 +10,9 @@ public class JetContainerNode extends JetElement {
|
|||||||
public JetContainerNode(@NotNull ASTNode node) {
|
public JetContainerNode(@NotNull ASTNode node) {
|
||||||
super(node);
|
super(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override // for visibility
|
||||||
|
protected <T> T findChildByClass(Class<T> aClass) {
|
||||||
|
return super.findChildByClass(aClass);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import org.jetbrains.jet.lexer.JetToken;
|
|||||||
/**
|
/**
|
||||||
* @author max
|
* @author max
|
||||||
*/
|
*/
|
||||||
public abstract class JetDeclaration extends JetElement {
|
public abstract class JetDeclaration extends JetExpression {
|
||||||
public JetDeclaration(@NotNull ASTNode node) {
|
public JetDeclaration(@NotNull ASTNode node) {
|
||||||
super(node);
|
super(node);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
package org.jetbrains.jet.lang.psi;
|
package org.jetbrains.jet.lang.psi;
|
||||||
|
|
||||||
import com.intellij.lang.ASTNode;
|
import com.intellij.lang.ASTNode;
|
||||||
import com.intellij.psi.PsiElement;
|
|
||||||
import com.intellij.psi.util.PsiTreeUtil;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.jet.JetNodeType;
|
import org.jetbrains.jet.JetNodeType;
|
||||||
|
|
||||||
@@ -19,11 +17,10 @@ public class JetExpression extends JetElement {
|
|||||||
visitor.visitExpression(this);
|
visitor.visitExpression(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
protected JetExpression findExpressionUnder(JetNodeType type) {
|
protected JetExpression findExpressionUnder(JetNodeType type) {
|
||||||
PsiElement containerNode = findChildByType(type);
|
JetContainerNode containerNode = (JetContainerNode) findChildByType(type);
|
||||||
if (containerNode == null) return null;
|
if (containerNode == null) return null;
|
||||||
|
|
||||||
return PsiTreeUtil.findChildOfType(containerNode, JetExpression.class);
|
return containerNode.findChildByClass(JetExpression.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -331,7 +331,7 @@ public class JetVisitor extends PsiElementVisitor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void visitNamedDeclaration(JetNamedDeclaration declaration) {
|
public void visitNamedDeclaration(JetNamedDeclaration declaration) {
|
||||||
visitJetElement(declaration);
|
visitDeclaration(declaration);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitNullableType(JetNullableType nullableType) {
|
public void visitNullableType(JetNullableType nullableType) {
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ public class TopDownAnalyzer {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitDeclaration(JetDeclaration dcl) {
|
public void visitDeclaration(JetDeclaration dcl) {
|
||||||
throw new UnsupportedOperationException(); // TODO
|
// Other declarations do not declare visible types
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -231,31 +231,25 @@ public class JetTypeInferrer {
|
|||||||
} else {
|
} else {
|
||||||
DeclarationDescriptor containingDescriptor = outerScope.getContainingDeclaration();
|
DeclarationDescriptor containingDescriptor = outerScope.getContainingDeclaration();
|
||||||
WritableScope scope = semanticServices.createWritableScope(outerScope, containingDescriptor);
|
WritableScope scope = semanticServices.createWritableScope(outerScope, containingDescriptor);
|
||||||
for (JetElement statement : block) {
|
return getBlockReturnedTypeWithWritableScope(scope, block);
|
||||||
// TODO: consider other declarations
|
|
||||||
if (statement instanceof JetProperty) {
|
|
||||||
JetProperty property = (JetProperty) statement;
|
|
||||||
PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolvePropertyDescriptor(containingDescriptor, scope, property);
|
|
||||||
scope.addPropertyDescriptor(propertyDescriptor);
|
|
||||||
trace.recordDeclarationResolution(property, propertyDescriptor);
|
|
||||||
}
|
|
||||||
else if (statement instanceof JetExpression) {
|
|
||||||
getType(scope, (JetExpression) statement, true);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new UnsupportedOperationException(statement.getClass().getCanonicalName()); // TODO
|
|
||||||
}
|
|
||||||
}
|
|
||||||
JetElement lastElement = block.get(block.size() - 1);
|
|
||||||
if (lastElement instanceof JetExpression) {
|
|
||||||
JetExpression expression = (JetExpression) lastElement;
|
|
||||||
return getType(scope, expression, true);
|
|
||||||
}
|
|
||||||
// TODO: functions, classes, etc.
|
|
||||||
throw new IllegalArgumentException("Last item in the block must be an expression, but was " + lastElement.getClass().getCanonicalName());
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private JetType getBlockReturnedTypeWithWritableScope(@NotNull WritableScope scope, @NotNull List<? extends JetElement> block) {
|
||||||
|
assert !block.isEmpty();
|
||||||
|
TypeInferrerVisitorWithWritableScope blockLevelVisitor = new TypeInferrerVisitorWithWritableScope(scope, true);
|
||||||
|
JetType result = null;
|
||||||
|
for (JetElement statement : block) {
|
||||||
|
statement.accept(blockLevelVisitor);
|
||||||
|
result = blockLevelVisitor.getResult();
|
||||||
|
if (result != null) {
|
||||||
|
trace.recordExpressionType((JetExpression) statement, result);
|
||||||
|
}
|
||||||
|
blockLevelVisitor.resetResult(); // TODO : maybe it's better to recreate the visitors with the same scope?
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
private void collectAllReturnTypes(JetWhenExpression whenExpression, JetScope scope, List<JetType> result) {
|
private void collectAllReturnTypes(JetWhenExpression whenExpression, JetScope scope, List<JetType> result) {
|
||||||
for (JetWhenEntry entry : whenExpression.getEntries()) {
|
for (JetWhenEntry entry : whenExpression.getEntries()) {
|
||||||
JetWhenExpression subWhen = entry.getSubWhen();
|
JetWhenExpression subWhen = entry.getSubWhen();
|
||||||
@@ -272,7 +266,7 @@ public class JetTypeInferrer {
|
|||||||
|
|
||||||
private class TypeInferrerVisitor extends JetVisitor {
|
private class TypeInferrerVisitor extends JetVisitor {
|
||||||
private final JetScope scope;
|
private final JetScope scope;
|
||||||
private JetType result;
|
protected JetType result;
|
||||||
private final boolean preferBlock;
|
private final boolean preferBlock;
|
||||||
|
|
||||||
public TypeInferrerVisitor(JetScope scope, boolean preferBlock) {
|
public TypeInferrerVisitor(JetScope scope, boolean preferBlock) {
|
||||||
@@ -540,9 +534,21 @@ public class JetTypeInferrer {
|
|||||||
@Override
|
@Override
|
||||||
public void visitDoWhileExpression(JetDoWhileExpression expression) {
|
public void visitDoWhileExpression(JetDoWhileExpression expression) {
|
||||||
JetExpression body = expression.getBody();
|
JetExpression body = expression.getBody();
|
||||||
JetScope conditionScope = scope; // TODO
|
JetScope conditionScope = scope;
|
||||||
if (body != null) {
|
if (body instanceof JetFunctionLiteralExpression) {
|
||||||
getType(scope, body, true);
|
JetFunctionLiteralExpression function = (JetFunctionLiteralExpression) body;
|
||||||
|
if (!function.hasParameterSpecification()) {
|
||||||
|
WritableScope writableScope = semanticServices.createWritableScope(scope, scope.getContainingDeclaration());
|
||||||
|
conditionScope = writableScope;
|
||||||
|
getBlockReturnedTypeWithWritableScope(writableScope, function.getBody());
|
||||||
|
} else {
|
||||||
|
getType(scope, body, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (body != null) {
|
||||||
|
WritableScope writableScope = semanticServices.createWritableScope(scope, scope.getContainingDeclaration());
|
||||||
|
conditionScope = writableScope;
|
||||||
|
getBlockReturnedTypeWithWritableScope(writableScope, Collections.singletonList(body));
|
||||||
}
|
}
|
||||||
checkCondition(conditionScope, expression.getCondition());
|
checkCondition(conditionScope, expression.getCondition());
|
||||||
result = JetStandardClasses.getUnitType();
|
result = JetStandardClasses.getUnitType();
|
||||||
@@ -762,16 +768,10 @@ public class JetTypeInferrer {
|
|||||||
result = getTypeForBinaryCall(expression, binaryOperationNames.get(operationType), scope, true);
|
result = getTypeForBinaryCall(expression, binaryOperationNames.get(operationType), scope, true);
|
||||||
}
|
}
|
||||||
else if (operationType == JetTokens.EQ) {
|
else if (operationType == JetTokens.EQ) {
|
||||||
JetExpression deparenthesized = deparenthesize(left);
|
visitAssignment(expression);
|
||||||
if (deparenthesized instanceof JetArrayAccessExpression) {
|
}
|
||||||
JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) deparenthesized;
|
else if (assignmentOperationNames.containsKey(operationType)) {
|
||||||
resolveArrayAccessToLValue(arrayAccessExpression, expression.getRight(), expression.getOperationReference());
|
visitAssignmentOperation(expression);
|
||||||
}
|
|
||||||
else {
|
|
||||||
getType(scope, expression.getRight(), false);
|
|
||||||
//throw new UnsupportedOperationException();
|
|
||||||
}
|
|
||||||
result = null; // TODO : This is not an expression, in fact!
|
|
||||||
}
|
}
|
||||||
else if (comparisonOperations.contains(operationType)) {
|
else if (comparisonOperations.contains(operationType)) {
|
||||||
JetType compareToReturnType = getTypeForBinaryCall(expression, "compareTo", scope, true);
|
JetType compareToReturnType = getTypeForBinaryCall(expression, "compareTo", scope, true);
|
||||||
@@ -786,16 +786,6 @@ public class JetTypeInferrer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (assignmentOperationNames.containsKey(operationType)) {
|
|
||||||
String name = assignmentOperationNames.get(operationType);
|
|
||||||
JetType assignmentOperationType = getTypeForBinaryCall(expression, name, scope, false);
|
|
||||||
|
|
||||||
if (assignmentOperationType == null) {
|
|
||||||
String counterpartName = binaryOperationNames.get(assignmentOperationCounterparts.get(operationType));
|
|
||||||
getTypeForBinaryCall(expression, counterpartName, scope, true);
|
|
||||||
}
|
|
||||||
result = null; // TODO : not an expression
|
|
||||||
}
|
|
||||||
else if (equalsOperations.contains(operationType)) {
|
else if (equalsOperations.contains(operationType)) {
|
||||||
String name = "equals";
|
String name = "equals";
|
||||||
JetType equalsType = getTypeForBinaryCall(expression, name, scope, true);
|
JetType equalsType = getTypeForBinaryCall(expression, name, scope, true);
|
||||||
@@ -845,6 +835,18 @@ public class JetTypeInferrer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void visitAssignmentOperation(JetBinaryExpression expression) {
|
||||||
|
assignmentIsNotAnExpressionError(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void visitAssignment(JetBinaryExpression expression) {
|
||||||
|
assignmentIsNotAnExpressionError(expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assignmentIsNotAnExpressionError(JetBinaryExpression expression) {
|
||||||
|
semanticServices.getErrorHandler().genericError(expression.getNode(), "Assignments are not expressions, and only expressions are allowed in this context");
|
||||||
|
}
|
||||||
|
|
||||||
private JetType assureBooleanResult(JetSimpleNameExpression operationSign, String name, JetType resultType) {
|
private JetType assureBooleanResult(JetSimpleNameExpression operationSign, String name, JetType resultType) {
|
||||||
if (resultType != null) {
|
if (resultType != null) {
|
||||||
// TODO : Relax?
|
// TODO : Relax?
|
||||||
@@ -877,30 +879,7 @@ public class JetTypeInferrer {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void resolveArrayAccessToLValue(JetArrayAccessExpression arrayAccessExpression, JetExpression rightHandSide, JetSimpleNameExpression operationSign) {
|
protected JetType getTypeForBinaryCall(JetBinaryExpression expression, @NotNull String name, JetScope scope, boolean reportUnresolved) {
|
||||||
List<JetType> argumentTypes = getTypes(scope, arrayAccessExpression.getIndexExpressions());
|
|
||||||
if (argumentTypes == null) return;
|
|
||||||
JetType rhsType = getType(scope, rightHandSide, false);
|
|
||||||
if (rhsType == null) return;
|
|
||||||
argumentTypes.add(rhsType);
|
|
||||||
|
|
||||||
JetType receiverType = getType(scope, arrayAccessExpression.getArrayExpression(), false);
|
|
||||||
if (receiverType == null) return;
|
|
||||||
|
|
||||||
// TODO : nasty hack: effort is duplicated
|
|
||||||
lookupFunction(scope, arrayAccessExpression, "set", receiverType, argumentTypes, true);
|
|
||||||
FunctionDescriptor functionDescriptor = lookupFunction(scope, operationSign, "set", receiverType, argumentTypes, true);
|
|
||||||
if (functionDescriptor != null) {
|
|
||||||
result = functionDescriptor.getUnsubstitutedReturnType();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitJetElement(JetElement elem) {
|
|
||||||
throw new IllegalArgumentException("Unsupported element: " + elem + " " + elem.getClass().getCanonicalName());
|
|
||||||
}
|
|
||||||
|
|
||||||
private JetType getTypeForBinaryCall(JetBinaryExpression expression, @NotNull String name, JetScope scope, boolean reportUnresolved) {
|
|
||||||
JetExpression left = expression.getLeft();
|
JetExpression left = expression.getLeft();
|
||||||
JetExpression right = expression.getRight();
|
JetExpression right = expression.getRight();
|
||||||
if (right == null) {
|
if (right == null) {
|
||||||
@@ -922,5 +901,119 @@ public class JetTypeInferrer {
|
|||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitDeclaration(JetDeclaration dcl) {
|
||||||
|
semanticServices.getErrorHandler().genericError(dcl.getNode(), "Declarations are not allowed in this position");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitJetElement(JetElement elem) {
|
||||||
|
semanticServices.getErrorHandler().genericError(elem.getNode(), "Unsupported element: " + elem + " " + elem.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TypeInferrerVisitorWithWritableScope extends TypeInferrerVisitor {
|
||||||
|
private final WritableScope scope;
|
||||||
|
|
||||||
|
public TypeInferrerVisitorWithWritableScope(@NotNull WritableScope scope, boolean preferBlock) {
|
||||||
|
super(scope, preferBlock);
|
||||||
|
this.scope = scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void resetResult() {
|
||||||
|
this.result = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitProperty(JetProperty property) {
|
||||||
|
PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolvePropertyDescriptor(scope.getContainingDeclaration(), scope, property);
|
||||||
|
scope.addPropertyDescriptor(propertyDescriptor);
|
||||||
|
trace.recordDeclarationResolution(property, propertyDescriptor);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitFunction(JetFunction function) {
|
||||||
|
super.visitFunction(function); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitClass(JetClass klass) {
|
||||||
|
super.visitClass(klass); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitExtension(JetExtension extension) {
|
||||||
|
super.visitExtension(extension); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitTypedef(JetTypedef typedef) {
|
||||||
|
super.visitTypedef(typedef); // TODO
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitDeclaration(JetDeclaration dcl) {
|
||||||
|
visitJetElement(dcl);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void visitAssignmentOperation(JetBinaryExpression expression) {
|
||||||
|
IElementType operationType = expression.getOperationReference().getReferencedNameElementType();
|
||||||
|
String name = assignmentOperationNames.get(operationType);
|
||||||
|
JetType assignmentOperationType = getTypeForBinaryCall(expression, name, scope, false);
|
||||||
|
|
||||||
|
if (assignmentOperationType == null) {
|
||||||
|
String counterpartName = binaryOperationNames.get(assignmentOperationCounterparts.get(operationType));
|
||||||
|
getTypeForBinaryCall(expression, counterpartName, scope, true);
|
||||||
|
}
|
||||||
|
result = null; // not an expression
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void visitAssignment(JetBinaryExpression expression) {
|
||||||
|
JetExpression left = expression.getLeft();
|
||||||
|
JetExpression deparenthesized = deparenthesize(left);
|
||||||
|
JetExpression right = expression.getRight();
|
||||||
|
if (deparenthesized instanceof JetArrayAccessExpression) {
|
||||||
|
JetArrayAccessExpression arrayAccessExpression = (JetArrayAccessExpression) deparenthesized;
|
||||||
|
resolveArrayAccessToLValue(arrayAccessExpression, right, expression.getOperationReference());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
JetType leftType = getType(scope, left, false);
|
||||||
|
if (right != null) {
|
||||||
|
JetType rightType = getType(scope, right, false);
|
||||||
|
if (rightType != null &&
|
||||||
|
leftType != null &&
|
||||||
|
!semanticServices.getTypeChecker().isConvertibleTo(rightType, leftType)) {
|
||||||
|
semanticServices.getErrorHandler().typeMismatch(right, leftType, rightType);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result = null; // This is not an expression
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resolveArrayAccessToLValue(JetArrayAccessExpression arrayAccessExpression, JetExpression rightHandSide, JetSimpleNameExpression operationSign) {
|
||||||
|
List<JetType> argumentTypes = getTypes(scope, arrayAccessExpression.getIndexExpressions());
|
||||||
|
if (argumentTypes == null) return;
|
||||||
|
JetType rhsType = getType(scope, rightHandSide, false);
|
||||||
|
if (rhsType == null) return;
|
||||||
|
argumentTypes.add(rhsType);
|
||||||
|
|
||||||
|
JetType receiverType = getType(scope, arrayAccessExpression.getArrayExpression(), false);
|
||||||
|
if (receiverType == null) return;
|
||||||
|
|
||||||
|
// TODO : nasty hack: effort is duplicated
|
||||||
|
lookupFunction(scope, arrayAccessExpression, "set", receiverType, argumentTypes, true);
|
||||||
|
FunctionDescriptor functionDescriptor = lookupFunction(scope, operationSign, "set", receiverType, argumentTypes, true);
|
||||||
|
if (functionDescriptor != null) {
|
||||||
|
result = functionDescriptor.getUnsubstitutedReturnType();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visitJetElement(JetElement elem) {
|
||||||
|
semanticServices.getErrorHandler().genericError(elem.getNode(), "Unsupported element in a block: " + elem + " " + elem.getClass().getCanonicalName());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,5 +30,8 @@ fun test() : Unit {
|
|||||||
}
|
}
|
||||||
for (~l~l : Int in 1..2) {
|
for (~l~l : Int in 1..2) {
|
||||||
`l`l`:std::Int`
|
`l`l`:std::Int`
|
||||||
|
while (true) {
|
||||||
|
`l`l
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user