Prefix, postfix and basic infix operations
This commit is contained in:
@@ -2,21 +2,15 @@ package org.jetbrains.jet.lang.psi;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.JetNodeTypes;
|
||||
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public class JetPostfixExpression extends JetExpression {
|
||||
public class JetPostfixExpression extends JetUnaryExpression {
|
||||
public JetPostfixExpression(@NotNull ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void accept(JetVisitor visitor) {
|
||||
visitor.visitPostfixExpression(this);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetExpression getBaseExpression() {
|
||||
JetExpression answer = findChildByClass(JetExpression.class);
|
||||
@@ -24,8 +18,9 @@ public class JetPostfixExpression extends JetExpression {
|
||||
return answer;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetSimpleNameExpression getOperationSign() {
|
||||
return (JetSimpleNameExpression) findChildByType(JetNodeTypes.OPERATION_REFERENCE);
|
||||
@Override
|
||||
public void accept(JetVisitor visitor) {
|
||||
visitor.visitPostfixExpression(this);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ import org.jetbrains.jet.JetNodeTypes;
|
||||
/**
|
||||
* @author max
|
||||
*/
|
||||
public class JetPrefixExpression extends JetExpression {
|
||||
public class JetPrefixExpression extends JetUnaryExpression {
|
||||
public JetPrefixExpression(@NotNull ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
@@ -27,9 +27,4 @@ public class JetPrefixExpression extends JetExpression {
|
||||
assert expression != null;
|
||||
return (JetExpression) expression;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetSimpleNameExpression getOperationSign() {
|
||||
return (JetSimpleNameExpression) findChildByType(JetNodeTypes.OPERATION_REFERENCE);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,22 @@
|
||||
package org.jetbrains.jet.lang.psi;
|
||||
|
||||
import com.intellij.lang.ASTNode;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.JetNodeTypes;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public abstract class JetUnaryExpression extends JetExpression {
|
||||
public JetUnaryExpression(ASTNode node) {
|
||||
super(node);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public abstract JetExpression getBaseExpression();
|
||||
|
||||
@NotNull
|
||||
public JetSimpleNameExpression getOperationSign() {
|
||||
return (JetSimpleNameExpression) findChildByType(JetNodeTypes.OPERATION_REFERENCE);
|
||||
}
|
||||
}
|
||||
@@ -151,10 +151,14 @@ public class JetVisitor extends PsiElementVisitor {
|
||||
}
|
||||
|
||||
public void visitPrefixExpression(JetPrefixExpression expression) {
|
||||
visitExpression(expression);
|
||||
visitUnaryExpression(expression);
|
||||
}
|
||||
|
||||
public void visitPostfixExpression(JetPostfixExpression expression) {
|
||||
visitUnaryExpression(expression);
|
||||
}
|
||||
|
||||
public void visitUnaryExpression(JetUnaryExpression expression) {
|
||||
visitExpression(expression);
|
||||
}
|
||||
|
||||
|
||||
@@ -525,21 +525,21 @@ public class JetTypeInferrer {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitPrefixExpression(JetPrefixExpression expression) {
|
||||
public void visitUnaryExpression(JetUnaryExpression expression) {
|
||||
JetSimpleNameExpression operationSign = expression.getOperationSign();
|
||||
if (operationSign.getReferencedNameElementType() == JetTokens.EXCL) {
|
||||
JetExpression baseExpression = expression.getBaseExpression();
|
||||
JetType type = getType(scope, baseExpression, false);
|
||||
String name = unaryOperationNames.get(operationSign.getReferencedNameElementType());
|
||||
if (name == null) {
|
||||
semanticServices.getErrorHandler().structuralError(operationSign.getNode(), "Unknown unary operation");
|
||||
}
|
||||
else {
|
||||
JetType type = getType(scope, expression.getBaseExpression(), false);
|
||||
if (type != null) {
|
||||
FunctionDescriptor functionDescriptor = lookupFunction(scope, operationSign, "not", type, Collections.<JetType>emptyList());
|
||||
FunctionDescriptor functionDescriptor = lookupFunction(scope, expression.getOperationSign(), name, type, Collections.<JetType>emptyList());
|
||||
if (functionDescriptor != null) {
|
||||
result = functionDescriptor.getUnsubstitutedReturnType();
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -550,8 +550,8 @@ public class JetTypeInferrer {
|
||||
if (operationType == JetTokens.IDENTIFIER) {
|
||||
result = getTypeForBinaryCall(expression, operationSign.getReferencedName(), scope);
|
||||
}
|
||||
else if (operationType == JetTokens.PLUS) {
|
||||
result = getTypeForBinaryCall(expression, "plus", scope);
|
||||
else if (binaryOperationNames.containsKey(operationType)) {
|
||||
result = getTypeForBinaryCall(expression, binaryOperationNames.get(operationType), scope);
|
||||
}
|
||||
else if (operationType == JetTokens.EQ) {
|
||||
JetExpression left = expression.getLeft();
|
||||
@@ -566,7 +566,7 @@ public class JetTypeInferrer {
|
||||
}
|
||||
result = null; // TODO : This is not an expression, in fact!
|
||||
}
|
||||
else if (operationType == JetTokens.LT) {
|
||||
else if (comparisonOperations.contains(operationType)) {
|
||||
JetExpression left = expression.getLeft();
|
||||
JetExpression deparenthesized = deparenthesize(left);
|
||||
if (deparenthesized instanceof JetArrayAccessExpression) {
|
||||
@@ -579,7 +579,7 @@ public class JetTypeInferrer {
|
||||
}
|
||||
result = null; // TODO : This is not an expression, in fact!
|
||||
} else {
|
||||
throw new UnsupportedOperationException(); // TODO
|
||||
semanticServices.getErrorHandler().structuralError(operationSign.getNode(), "Unknown operation");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -637,38 +637,35 @@ public class JetTypeInferrer {
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
Map<IElementType, String> operationToMethodName = new HashMap<IElementType, String>();
|
||||
private static final Map<IElementType, String> unaryOperationNames = new HashMap<IElementType, String>();
|
||||
static {
|
||||
unaryOperationNames.put(JetTokens.PLUSPLUS, "inc");
|
||||
unaryOperationNames.put(JetTokens.MINUSMINUS, "dec");
|
||||
unaryOperationNames.put(JetTokens.EXCL, "not");
|
||||
}
|
||||
|
||||
// operationToMethodName.put(JetTokens.EXCL, "excl");
|
||||
//
|
||||
// operationToMethodName.put(JetTokens.LT, "lt");
|
||||
// operationToMethodName.put(JetTokens.GT, "gt");
|
||||
// operationToMethodName.put(JetTokens.LTEQ, "lteq");
|
||||
// operationToMethodName.put(JetTokens.GTEQ, "gteq");
|
||||
//
|
||||
// operationToMethodName.put(JetTokens.EQEQ, "eqeq");
|
||||
// operationToMethodName.put(JetTokens.EXCLEQ, "excleq");
|
||||
//
|
||||
// operationToMethodName.put(JetTokens.MULTEQ, "multeq");
|
||||
// operationToMethodName.put(JetTokens.DIVEQ, "diveq");
|
||||
// operationToMethodName.put(JetTokens.PERCEQ, "perceq");
|
||||
// operationToMethodName.put(JetTokens.PLUSEQ, "pluseq");
|
||||
// operationToMethodName.put(JetTokens.MINUSEQ, "minuseq");
|
||||
//
|
||||
// operationToMethodName.put(JetTokens.PLUSPLUS, "plusplus");
|
||||
// operationToMethodName.put(JetTokens.MINUSMINUS, "minusminus");
|
||||
private static final Map<IElementType, String> binaryOperationNames = new HashMap<IElementType, String>();
|
||||
static {
|
||||
binaryOperationNames.put(JetTokens.MUL, "times");
|
||||
binaryOperationNames.put(JetTokens.PLUS, "plus");
|
||||
binaryOperationNames.put(JetTokens.MINUS, "minus");
|
||||
binaryOperationNames.put(JetTokens.DIV, "div");
|
||||
binaryOperationNames.put(JetTokens.PERC, "mod");
|
||||
binaryOperationNames.put(JetTokens.ARROW, "arrow");
|
||||
binaryOperationNames.put(JetTokens.RANGE, "rangeTo");
|
||||
}
|
||||
|
||||
operationToMethodName.put(JetTokens.MUL, "times");
|
||||
operationToMethodName.put(JetTokens.PLUS, "plus");
|
||||
operationToMethodName.put(JetTokens.MINUS, "minus");
|
||||
operationToMethodName.put(JetTokens.DIV, "div");
|
||||
operationToMethodName.put(JetTokens.PERC, "mod");
|
||||
operationToMethodName.put(JetTokens.ARROW, "arrow");
|
||||
operationToMethodName.put(JetTokens.RANGE, "rangeTo");
|
||||
private static final Set<IElementType> comparisonOperations = new HashSet<IElementType>(Arrays.asList(JetTokens.LT, JetTokens.GT, JetTokens.LTEQ, JetTokens.GTEQ));
|
||||
private static final Set<IElementType> equalsOperations = new HashSet<IElementType>(Arrays.asList(JetTokens.EQEQ, JetTokens.EXCLEQ));
|
||||
private static final Set<IElementType> inOperations = new HashSet<IElementType>(Arrays.asList(JetTokens.IN_KEYWORD, JetTokens.NOT_IN));
|
||||
|
||||
// operationToMethodName.put(JetTokens.IN_KEYWORD, "contains");
|
||||
// operationToMethodName.put(JetTokens.NOT_IN, "not_in");
|
||||
private static final Map<IElementType, String> assignmentOperationNames = new HashMap<IElementType, String>();
|
||||
static {
|
||||
assignmentOperationNames.put(JetTokens.MULTEQ, "timesAssign");
|
||||
assignmentOperationNames.put(JetTokens.DIVEQ, "divAssign");
|
||||
assignmentOperationNames.put(JetTokens.PERCEQ, "modAssign");
|
||||
assignmentOperationNames.put(JetTokens.PLUSEQ, "plusAssign");
|
||||
assignmentOperationNames.put(JetTokens.MINUSEQ, "minusAssign");
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -4,6 +4,11 @@ import util.*
|
||||
~X~class X<~T~T> {
|
||||
fun foo(a : `T`T) : `X`X<`T`T>{}
|
||||
~plus~fun plus(t : `T`T) : Int {}
|
||||
~minus~fun minus(t : String) : Int {}
|
||||
~times~fun times(t : String) : Int {}
|
||||
~div~fun div(t : String) : Int {}
|
||||
~mod~fun mod(t : String) : Int {}
|
||||
~rangeTo~fun rangeTo(t : String) : Int {}
|
||||
}
|
||||
|
||||
~t~fun <~t.T~T> t(~t.t~t : `t.T`T) : `t.T`T {
|
||||
@@ -14,6 +19,12 @@ import util.*
|
||||
new X<String>() `plus`+ "1"
|
||||
new X<String>() `plus`plus "sadfas"
|
||||
new X<String>().`plus`plus("")
|
||||
val x = new X<String>
|
||||
x `minus`- ""
|
||||
x `times`* ""
|
||||
x `div`/ ""
|
||||
x `mod`% ""
|
||||
x `rangeTo`.. ""
|
||||
}
|
||||
|
||||
~Foo~class Foo {
|
||||
@@ -25,6 +36,8 @@ import util.*
|
||||
|
||||
~Bar~class Bar : Foo {
|
||||
~not~fun not() : String {}
|
||||
~inc~fun inc() : Unit
|
||||
~dec~fun dec() : Unit
|
||||
}
|
||||
|
||||
fun <T> tt(t : T) : T {
|
||||
@@ -41,4 +54,10 @@ fun <T> tt(t : T) : T {
|
||||
x`!`[null] = null
|
||||
(x`!`[null, 2]) = null
|
||||
(`not`!foo)[1]`:std::Char`
|
||||
val y = new Bar
|
||||
y`inc`++
|
||||
`inc`++y
|
||||
`dec`--y
|
||||
y`dec`--
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user