range literals initial
This commit is contained in:
Generated
+1
@@ -6,6 +6,7 @@
|
||||
<module fileurl="file://$PROJECT_DIR$/examples/examples.iml" filepath="$PROJECT_DIR$/examples/examples.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/grammar/grammar.iml" filepath="$PROJECT_DIR$/grammar/grammar.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/idea/idea.iml" filepath="$PROJECT_DIR$/idea/idea.iml" />
|
||||
<module fileurl="file://$PROJECT_DIR$/stdlib/stdlib.iml" filepath="$PROJECT_DIR$/stdlib/stdlib.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
|
||||
@@ -10,6 +10,7 @@
|
||||
<orderEntry type="jdk" jdkName="IDEA 10.x" jdkType="IDEA JDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="asm" level="project" />
|
||||
<orderEntry type="module" module-name="stdlib" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.intellij.openapi.project.Project;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.search.ProjectScope;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
import jet.IntRange;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
@@ -32,11 +33,15 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
private static final String CLASS_ITERABLE = "java/lang/Iterable";
|
||||
private static final String CLASS_ITERATOR = "java/util/Iterator";
|
||||
|
||||
private static final String CLASS_INT_RANGE = "jet/IntRange";
|
||||
|
||||
private static final String ITERABLE_ITERATOR_DESCRIPTOR = "()Ljava/util/Iterator;";
|
||||
private static final String ITERATOR_HASNEXT_DESCRIPTOR = "()Z";
|
||||
private static final String ITERATOR_NEXT_DESCRIPTOR = "()Ljava/lang/Object;";
|
||||
private static final String INT_RANGE_CONSTRUCTOR_DESCRIPTOR = "(II)V";
|
||||
|
||||
private static final Type ITERATOR_TYPE = Type.getType(Iterator.class);
|
||||
private static final Type INT_RANGE_TYPE = Type.getType(IntRange.class);
|
||||
|
||||
private final Stack<Label> myContinueTargets = new Stack<Label>();
|
||||
private final Stack<Label> myBreakTargets = new Stack<Label>();
|
||||
@@ -706,6 +711,9 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
else if (opToken == JetTokens.ELVIS) {
|
||||
generateElvis(expression);
|
||||
}
|
||||
else if (opToken == JetTokens.RANGE) {
|
||||
generateRange(expression);
|
||||
}
|
||||
else {
|
||||
DeclarationDescriptor op = bindingContext.resolveReferenceExpression(expression.getOperationReference());
|
||||
if (op instanceof FunctionDescriptor) {
|
||||
@@ -816,6 +824,21 @@ public class ExpressionCodegen extends JetVisitor {
|
||||
myStack.push(StackValue.onStack(exprType));
|
||||
}
|
||||
|
||||
private void generateRange(JetBinaryExpression expression) {
|
||||
final Type leftType = expressionType(expression.getLeft());
|
||||
if (isIntPrimitive(leftType)) {
|
||||
v.anew(INT_RANGE_TYPE);
|
||||
v.dup();
|
||||
gen(expression.getLeft(), Type.INT_TYPE);
|
||||
gen(expression.getRight(), Type.INT_TYPE);
|
||||
v.invokespecial(CLASS_INT_RANGE, "<init>", INT_RANGE_CONSTRUCTOR_DESCRIPTOR);
|
||||
myStack.push(StackValue.onStack(INT_RANGE_TYPE));
|
||||
}
|
||||
else {
|
||||
throw new UnsupportedOperationException("ranges are only supported for int objects");
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isNumberPrimitive(DeclarationDescriptor descriptor) {
|
||||
if (!(descriptor instanceof ClassDescriptor)) {
|
||||
return false;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package org.jetbrains.jet.codegen;
|
||||
|
||||
import jet.IntRange;
|
||||
import org.jetbrains.jet.parsing.JetParsingTest;
|
||||
|
||||
import java.awt.*;
|
||||
@@ -358,4 +359,13 @@ public class NamespaceGenTest extends CodegenTestCase {
|
||||
main.invoke(null, new Object[] { data });
|
||||
assertEquals(10, data[0]);
|
||||
}
|
||||
|
||||
public void testIntRange() throws Exception {
|
||||
loadText("fun foo() = 1..10");
|
||||
final Method main = generateFunction();
|
||||
IntRange result = (IntRange) main.invoke(null);
|
||||
assertTrue(result.contains(1));
|
||||
assertTrue(result.contains(10));
|
||||
assertFalse(result.contains(11));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,20 @@
|
||||
package jet;
|
||||
|
||||
public class IntRange implements Range<Integer> {
|
||||
private final int startValue;
|
||||
private final int endValue;
|
||||
|
||||
public IntRange(int startValue, int endValue) {
|
||||
this.startValue = startValue;
|
||||
this.endValue = endValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Integer item) {
|
||||
if (item == null) return false;
|
||||
if (startValue <= endValue) {
|
||||
return item >= startValue && item <= endValue;
|
||||
}
|
||||
return item <= startValue && item >= endValue;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
package jet;
|
||||
|
||||
public interface Range<T extends Comparable<T>> {
|
||||
boolean contains(T item);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="inheritedJdk" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
</module>
|
||||
|
||||
Reference in New Issue
Block a user