diff --git a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 2c4c3709a7f..bfb9a80b673 100644 --- a/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/idea/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -137,7 +137,7 @@ public class ExpressionCodegen extends JetVisitor { gen(expr, expressionType(expr)); } - private StackValue generateIntermediateValue(final JetExpression baseExpression) { + public StackValue generateIntermediateValue(final JetExpression baseExpression) { int oldStackSize = myStack.size(); gen(baseExpression); if (myStack.size() != oldStackSize+1) { @@ -1317,14 +1317,7 @@ public class ExpressionCodegen extends JetVisitor { DeclarationDescriptor op = bindingContext.resolveReferenceExpression(expression.getOperationSign()); if (op instanceof FunctionDescriptor) { final Type asmType = expressionType(expression); - DeclarationDescriptor cls = op.getContainingDeclaration(); - if (isNumberPrimitive(cls)) { - if (generateUnaryOp(op, asmType, expression)) return; - } - else if (isClass(cls, "Boolean") && op.getName().equals("not")) { - generateNot(expression); - return; - } + if (generateUnaryOp(op, asmType, expression)) return; } throw new UnsupportedOperationException("Don't know how to generate this prefix expression"); } @@ -1359,18 +1352,13 @@ public class ExpressionCodegen extends JetVisitor { myStack.push(intrinsic.generate(this, v, asmType, unaryExpression, Collections.singletonList(operand))); return true; } - else if (op.getName().equals("inc") || op.getName().equals("dec")) { + else if (isNumberPrimitive(asmType) && (op.getName().equals("inc") || op.getName().equals("dec"))) { myStack.push(generateIncrement(op, asmType, operand)); return true; } return false; } - private void generateNot(JetPrefixExpression expression) { - final StackValue stackValue = generateIntermediateValue(expression.getBaseExpression()); - myStack.push(StackValue.not(stackValue)); - } - private StackValue generateIncrement(DeclarationDescriptor op, Type asmType, JetExpression operand) { int increment = op.getName().equals("inc") ? 1 : -1; if (operand instanceof JetReferenceExpression) { diff --git a/idea/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java b/idea/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java index 9045645ed61..bcd224780ab 100644 --- a/idea/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java +++ b/idea/src/org/jetbrains/jet/codegen/intrinsics/IntrinsicMethods.java @@ -57,6 +57,8 @@ public class IntrinsicMethods { declareBinaryOp("or", Opcodes.IOR); declareBinaryOp("xor", Opcodes.IXOR); + declareIntrinsicFunction("Boolean", "not", 0, new Not()); + declareIntrinsicFunction("String", "plus", 1, new Concat()); } @@ -82,7 +84,7 @@ public class IntrinsicMethods { private void declareOverload(FunctionGroup group, int arity, IntrinsicMethod implementation) { for (FunctionDescriptor descriptor : group.getFunctionDescriptors()) { if (descriptor.getValueParameters().size() == arity) { - myMethods.put(descriptor, implementation); + myMethods.put(descriptor.getOriginal(), implementation); } } } diff --git a/idea/src/org/jetbrains/jet/codegen/intrinsics/Not.java b/idea/src/org/jetbrains/jet/codegen/intrinsics/Not.java new file mode 100644 index 00000000000..dd4cd938ce7 --- /dev/null +++ b/idea/src/org/jetbrains/jet/codegen/intrinsics/Not.java @@ -0,0 +1,21 @@ +package org.jetbrains.jet.codegen.intrinsics; + +import com.intellij.psi.PsiElement; +import org.jetbrains.jet.codegen.ExpressionCodegen; +import org.jetbrains.jet.codegen.StackValue; +import org.jetbrains.jet.lang.psi.JetExpression; +import org.objectweb.asm.Type; +import org.objectweb.asm.commons.InstructionAdapter; + +import java.util.List; + +/** + * @author yole + */ +public class Not implements IntrinsicMethod { + @Override + public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List arguments) { + final StackValue stackValue = codegen.generateIntermediateValue(arguments.get(0)); + return StackValue.not(stackValue); + } +}