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