Merge remote branch 'origin/master'

Conflicts:
	compiler/frontend/src/org/jetbrains/jet/lang/types/JetTypeInferrer.java
This commit is contained in:
Andrey Breslav
2011-10-13 17:55:59 +04:00
79 changed files with 2607 additions and 505 deletions
@@ -13,6 +13,7 @@ import org.jetbrains.jet.lang.psi.JetFunctionLiteralExpression;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.ProjectionErasingJetType;
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
@@ -117,7 +118,7 @@ public class ClosureCodegen {
final Type enclosingType = context.enclosingClassType(state.getTypeMapper());
if (enclosingType == null) captureThis = false;
final Method constructor = generateConstructor(funClass, captureThis);
final Method constructor = generateConstructor(funClass, captureThis, funDescriptor.getReturnType());
if (captureThis) {
cv.visitField(Opcodes.ACC_PRIVATE, "this$0", enclosingType.getDescriptor(), null, null);
@@ -175,7 +176,7 @@ public class ClosureCodegen {
mv.visitEnd();
}
private Method generateConstructor(String funClass, boolean captureThis) {
private Method generateConstructor(String funClass, boolean captureThis, JetType returnType) {
int argCount = closure.size();
if (captureThis) {
@@ -199,9 +200,11 @@ public class ClosureCodegen {
final MethodVisitor mv = cv.visitMethod(Opcodes.ACC_PUBLIC, "<init>", constructor.getDescriptor(), null, new String[0]);
mv.visitCode();
InstructionAdapter iv = new InstructionAdapter(mv);
ExpressionCodegen expressionCodegen = new ExpressionCodegen(mv, null, Type.VOID_TYPE, context, state);
iv.load(0, Type.getObjectType(funClass));
iv.invokespecial(funClass, "<init>", "()V");
expressionCodegen.generateTypeInfo(new ProjectionErasingJetType(returnType));
iv.invokespecial(funClass, "<init>", "(Ljet/typeinfo/TypeInfo;)V");
i = 1;
for (Type type : argTypes) {
@@ -52,8 +52,10 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
private final InstructionAdapter v;
private final FrameMap myMap;
private final JetTypeMapper typeMapper;
private final GenerationState state;
private final Type returnType;
private final BindingContext bindingContext;
private final Map<TypeParameterDescriptor, StackValue> typeParameterExpressions = new HashMap<TypeParameterDescriptor, StackValue>();
private final ClassContext context;
@@ -74,6 +76,14 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
this.intrinsics = state.getIntrinsics();
}
public GenerationState getState() {
return state;
}
public BindingContext getBindingContext() {
return bindingContext;
}
public JetTypeMapper getTypeMapper() {
return state.getTypeMapper();
}
@@ -207,7 +217,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
else {
assert expressionType != null;
final DeclarationDescriptor descriptor = expressionType.getConstructor().getDeclarationDescriptor();
if (isClass(descriptor, "IntRange")) { // TODO IntRange subclasses
if (isClass(descriptor, "IntRange")) { // TODO IntRange subclasses (now IntRange is final)
new ForInRangeLoopGenerator(expression, loopRangeType).invoke();
return StackValue.none();
}
@@ -921,7 +931,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
callableMethod = ClosureCodegen.asCallableMethod((FunctionDescriptor) fd);
}
else if (fd instanceof FunctionDescriptor) {
callableMethod = ClosureCodegen.asCallableMethod((FunctionDescriptor) fd);
callableMethod = typeMapper.mapToCallableMethod((FunctionDescriptor) fd, null);
}
else {
throw new UnsupportedOperationException("can't resolve declaration to callable: " + fd);
@@ -2076,7 +2086,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
}
void generateTypeInfo(JetType jetType) {
public void generateTypeInfo(JetType jetType) {
String knownTypeInfo = typeMapper.isKnownTypeInfo(jetType);
if(knownTypeInfo != null) {
v.getstatic("jet/typeinfo/TypeInfo", knownTypeInfo, "Ljet/typeinfo/TypeInfo;");
@@ -2287,7 +2297,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
JetType jetType = bindingContext.get(BindingContext.EXPRESSION_TYPE, rangeExpression);
assert jetType != null;
final DeclarationDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor();
if (isClass(descriptor, "IntRange")) { // TODO IntRange subclasses
if (isClass(descriptor, "IntRange")) {
return true;
}
}
@@ -2308,7 +2318,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
final String className = "jet/Tuple" + entries.size();
Type tupleType = Type.getObjectType(className);
StringBuilder signature = new StringBuilder("(");
StringBuilder signature = new StringBuilder("(Ljet/typeinfo/TypeInfo;");
for (int i = 0; i != entries.size(); ++i) {
signature.append("Ljava/lang/Object;");
}
@@ -2316,6 +2326,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
v.anew(tupleType);
v.dup();
generateTypeInfo(new ProjectionErasingJetType(bindingContext.get(BindingContext.EXPRESSION_TYPE, expression)));
for (JetExpression entry : entries) {
gen(entry, OBJECT_TYPE);
}
@@ -57,6 +57,8 @@ public class JetTypeMapper {
private final HashMap<JetType,String> knowTypes = new HashMap<JetType, String>();
public static final Type TYPE_FUNCTION1 = Type.getObjectType("jet/Function1");
public static final Type TYPE_ITERATOR = Type.getObjectType("jet/Iterator");
public static final Type TYPE_INT_RANGE = Type.getObjectType("jet/IntRange");
public JetTypeMapper(JetStandardLibrary standardLibrary, BindingContext bindingContext) {
this.standardLibrary = standardLibrary;
@@ -316,6 +318,9 @@ public class JetTypeMapper {
if (jetType.equals(JetStandardClasses.getUnitType()) || jetType.equals(JetStandardClasses.getNothingType())) {
return Type.VOID_TYPE;
}
if (jetType.equals(JetStandardClasses.getNullableNothingType())) {
return TYPE_OBJECT;
}
return mapType(jetType, kind);
}
@@ -460,17 +465,16 @@ public class JetTypeMapper {
}
private Method mapSignature(JetNamedFunction f, List<Type> valueParameterTypes, OwnerKind kind) {
final JetTypeReference receiverTypeRef = f.getReceiverTypeRef();
final JetType receiverType = receiverTypeRef == null ? null : bindingContext.get(BindingContext.TYPE, receiverTypeRef);
final List<JetParameter> parameters = f.getValueParameters();
private Method mapSignature(FunctionDescriptor f, List<Type> valueParameterTypes, OwnerKind kind) {
final ReceiverDescriptor receiverTypeRef = f.getReceiver();
final JetType receiverType = receiverTypeRef == ReceiverDescriptor.NO_RECEIVER ? null : receiverTypeRef.getType();
final List<ValueParameterDescriptor> parameters = f.getValueParameters();
List<Type> parameterTypes = new ArrayList<Type>();
if (receiverType != null) {
parameterTypes.add(mapType(receiverType));
}
FunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, f);
if(kind == OwnerKind.TRAIT_IMPL) {
ClassDescriptor containingDeclaration = (ClassDescriptor) functionDescriptor.getContainingDeclaration();
ClassDescriptor containingDeclaration = (ClassDescriptor) f.getContainingDeclaration();
JetType jetType = TraitImplBodyCodegen.getSuperClass(containingDeclaration, bindingContext);
Type type = mapType(jetType);
if(type.getInternalName().equals("java/lang/Object")) {
@@ -480,24 +484,15 @@ public class JetTypeMapper {
valueParameterTypes.add(type);
parameterTypes.add(type);
}
for (JetParameter parameter : parameters) {
final Type type = mapType(bindingContext.get(BindingContext.TYPE, parameter.getTypeReference()));
for (ValueParameterDescriptor parameter : parameters) {
final Type type = mapType(parameter.getOutType());
valueParameterTypes.add(type);
parameterTypes.add(type);
}
for (int n = f.getTypeParameters().size(); n > 0; n--) {
parameterTypes.add(TYPE_TYPEINFO);
}
final JetTypeReference returnTypeRef = f.getReturnTypeRef();
Type returnType;
if (returnTypeRef == null) {
assert functionDescriptor != null;
final JetType type = functionDescriptor.getReturnType();
returnType = mapReturnType(type);
}
else {
returnType = mapReturnType(bindingContext.get(BindingContext.TYPE, returnTypeRef));
}
Type returnType = mapReturnType(f.getReturnType());
return new Method(f.getName(), returnType, parameterTypes.toArray(new Type[parameterTypes.size()]));
}
@@ -511,9 +506,13 @@ public class JetTypeMapper {
JetNamedFunction f = (JetNamedFunction) declaration;
final FunctionDescriptor functionDescriptor = bindingContext.get(BindingContext.FUNCTION, f);
assert functionDescriptor != null;
return mapToCallableMethod(functionDescriptor, kind);
}
public CallableMethod mapToCallableMethod(FunctionDescriptor functionDescriptor, OwnerKind kind) {
final DeclarationDescriptor functionParent = functionDescriptor.getContainingDeclaration();
final List<Type> valueParameterTypes = new ArrayList<Type>();
Method descriptor = mapSignature(f, valueParameterTypes, kind);
Method descriptor = mapSignature(functionDescriptor.getOriginal(), valueParameterTypes, kind);
String owner;
int invokeOpcode;
boolean needsReceiver;
@@ -521,7 +520,7 @@ public class JetTypeMapper {
if (functionParent instanceof NamespaceDescriptor) {
owner = NamespaceCodegen.getJVMClassName(DescriptorRenderer.getFQName(functionParent));
invokeOpcode = Opcodes.INVOKESTATIC;
needsReceiver = f.getReceiverTypeRef() != null;
needsReceiver = functionDescriptor.getReceiver() != ReceiverDescriptor.NO_RECEIVER;
}
else if (functionParent instanceof ClassDescriptor) {
ClassDescriptor containingClass = (ClassDescriptor) functionParent;
@@ -197,6 +197,9 @@ public abstract class StackValue {
if (type.getSort() == Type.BOOLEAN) {
v.checkcast(JetTypeMapper.JL_BOOLEAN_TYPE);
}
else if (type.getSort() == Type.CHAR) {
v.checkcast(JetTypeMapper.JL_CHAR_TYPE);
}
else {
v.checkcast(JetTypeMapper.JL_NUMBER_TYPE);
}
@@ -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.JetTypeMapper;
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;
public class ArrayIndices implements IntrinsicMethod {
@Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
v.arraylength();
v.invokestatic("jet/IntRange", "count", "(I)Ljet/IntRange;");
return StackValue.onStack(JetTypeMapper.TYPE_INT_RANGE);
}
}
@@ -0,0 +1,65 @@
package org.jetbrains.jet.codegen.intrinsics;
import com.intellij.psi.PsiElement;
import org.jetbrains.jet.codegen.ExpressionCodegen;
import org.jetbrains.jet.codegen.JetTypeMapper;
import org.jetbrains.jet.codegen.StackValue;
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.psi.JetCallExpression;
import org.jetbrains.jet.lang.psi.JetExpression;
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.types.JetStandardLibrary;
import org.jetbrains.jet.lang.types.JetType;
import org.objectweb.asm.Type;
import org.objectweb.asm.commons.InstructionAdapter;
import java.util.List;
/**
* @author alex.tkachman
*/
public class ArrayIterator implements IntrinsicMethod {
@Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
receiver.put(JetTypeMapper.TYPE_OBJECT, v);
JetCallExpression call = (JetCallExpression) element;
FunctionDescriptor funDescriptor = (FunctionDescriptor) codegen.getBindingContext().get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) call.getCalleeExpression());
ClassDescriptor containingDeclaration = (ClassDescriptor) funDescriptor.getContainingDeclaration().getOriginal();
JetStandardLibrary standardLibrary = codegen.getState().getStandardLibrary();
if(containingDeclaration.equals(standardLibrary.getArray())) {
codegen.generateTypeInfo(funDescriptor.getReturnType().getArguments().get(0).getType());
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([Ljava/lang/Object;Ljet/typeinfo/TypeInfo;)Ljet/Iterator;");
}
else if(containingDeclaration.equals(standardLibrary.getByteArrayClass())) {
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([B)Ljet/Iterator;");
}
else if(containingDeclaration.equals(standardLibrary.getShortArrayClass())) {
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([S)Ljet/Iterator;");
}
else if(containingDeclaration.equals(standardLibrary.getIntArrayClass())) {
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([I)Ljet/Iterator;");
}
else if(containingDeclaration.equals(standardLibrary.getLongArrayClass())) {
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([J)Ljet/Iterator;");
}
else if(containingDeclaration.equals(standardLibrary.getFloatArrayClass())) {
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([F)Ljet/Iterator;");
}
else if(containingDeclaration.equals(standardLibrary.getDoubleArrayClass())) {
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([D)Ljet/Iterator;");
}
else if(containingDeclaration.equals(standardLibrary.getCharArrayClass())) {
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([C)Ljet/Iterator;");
}
else if(containingDeclaration.equals(standardLibrary.getBooleanArrayClass())) {
v.invokestatic("jet/arrays/ArrayIterator", "iterator", "([Z)Ljet/Iterator;");
}
else {
throw new UnsupportedOperationException(containingDeclaration.toString());
}
return StackValue.onStack(JetTypeMapper.TYPE_ITERATOR);
}
}
@@ -29,11 +29,13 @@ public class IntrinsicMethods {
private static final IntrinsicMethod DEC = new Increment(-1);
private static final List<String> PRIMITIVE_NUMBER_TYPES = ImmutableList.of("Boolean", "Byte", "Char", "Short", "Int", "Float", "Long", "Double");
public static final ArraySize ARRAY_SIZE = new ArraySize();
public static final IntrinsicMethod ARRAY_SIZE = new ArraySize();
public static final IntrinsicMethod ARRAY_INDICES = new ArrayIndices();
private final Project myProject;
private final JetStandardLibrary myStdLib;
private final Map<DeclarationDescriptor, IntrinsicMethod> myMethods = new HashMap<DeclarationDescriptor, IntrinsicMethod>();
private static final IntrinsicMethod ARRAY_ITERATOR = new ArrayIterator();
public IntrinsicMethods(Project project, JetStandardLibrary stdlib) {
myProject = project;
@@ -87,6 +89,30 @@ public class IntrinsicMethods {
declareIntrinsicProperty("DoubleArray", "size", ARRAY_SIZE);
declareIntrinsicProperty("CharArray", "size", ARRAY_SIZE);
declareIntrinsicProperty("BooleanArray", "size", ARRAY_SIZE);
declareIntrinsicProperty("Array", "indices", ARRAY_INDICES);
declareIntrinsicProperty("ByteArray", "indices", ARRAY_INDICES);
declareIntrinsicProperty("ShortArray", "indices", ARRAY_INDICES);
declareIntrinsicProperty("IntArray", "indices", ARRAY_INDICES);
declareIntrinsicProperty("LongArray", "indices", ARRAY_INDICES);
declareIntrinsicProperty("FloatArray", "indices", ARRAY_INDICES);
declareIntrinsicProperty("DoubleArray", "indices", ARRAY_INDICES);
declareIntrinsicProperty("CharArray", "indices", ARRAY_INDICES);
declareIntrinsicProperty("BooleanArray", "indices", ARRAY_INDICES);
declareIterator(myStdLib.getArray());
declareIterator(myStdLib.getByteArrayClass());
declareIterator(myStdLib.getShortArrayClass());
declareIterator(myStdLib.getIntArrayClass());
declareIterator(myStdLib.getLongArrayClass());
declareIterator(myStdLib.getFloatArrayClass());
declareIterator(myStdLib.getDoubleArrayClass());
declareIterator(myStdLib.getCharArrayClass());
declareIterator(myStdLib.getBooleanArrayClass());
}
private void declareIterator(ClassDescriptor classDescriptor) {
declareOverload(classDescriptor.getDefaultType().getMemberScope().getFunctions("iterator"), 0, ARRAY_ITERATOR);
}
private void declareIntrinsicStringMethods() {
@@ -16,21 +16,15 @@ import java.util.List;
* @author yole
*/
public class RangeTo implements IntrinsicMethod {
private static final String INT_RANGE_CONSTRUCTOR_DESCRIPTOR = "(II)V";
private static final Type INT_RANGE_TYPE = Type.getType(IntRange.class);
private static final String CLASS_INT_RANGE = "jet/IntRange";
@Override
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
JetBinaryExpression expression = (JetBinaryExpression) element;
final Type leftType = codegen.expressionType(expression.getLeft());
if (JetTypeMapper.isIntPrimitive(leftType)) {
v.anew(INT_RANGE_TYPE);
v.dup();
codegen.gen(expression.getLeft(), Type.INT_TYPE);
codegen.gen(expression.getRight(), Type.INT_TYPE);
v.invokespecial(CLASS_INT_RANGE, "<init>", INT_RANGE_CONSTRUCTOR_DESCRIPTOR);
return StackValue.onStack(INT_RANGE_TYPE);
v.invokestatic("jet/IntRange", "rangeTo", "(II)Ljet/IntRange;");
return StackValue.onStack(JetTypeMapper.TYPE_INT_RANGE);
}
else {
throw new UnsupportedOperationException("ranges are only supported for int objects");
+65 -27
View File
@@ -42,7 +42,7 @@ fun Any?.toString() : String// = this === other
trait Iterator<out T> {
fun next() : T
abstract fun hasNext() : Boolean
fun hasNext() : Boolean
}
trait Iterable<out T> {
@@ -54,6 +54,8 @@ class Array<T>(val size : Int, init : fun(Int) : T = null ) {
fun set(index : Int, value : T) : Unit
fun iterator() : Iterator<T>
val indices : IntRange
}
class ByteArray(val size : Int) {
@@ -61,6 +63,8 @@ class ByteArray(val size : Int) {
fun set(index : Int, value : Byte) : Unit
fun iterator() : Iterator<Byte>
val indices : IntRange
}
class ShortArray(val size : Int) {
@@ -68,6 +72,8 @@ class ShortArray(val size : Int) {
fun set(index : Int, value : Short) : Unit
fun iterator() : Iterator<Short>
val indices : IntRange
}
class IntArray(val size : Int) {
@@ -75,6 +81,8 @@ class IntArray(val size : Int) {
fun set(index : Int, value : Int) : Unit
fun iterator() : Iterator<Int>
val indices : IntRange
}
class LongArray(val size : Int) {
@@ -82,6 +90,8 @@ class LongArray(val size : Int) {
fun set(index : Int, value : Long) : Unit
fun iterator() : Iterator<Long>
val indices : IntRange
}
class FloatArray(val size : Int) {
@@ -89,6 +99,8 @@ class FloatArray(val size : Int) {
fun set(index : Int, value : Float) : Unit
fun iterator() : Iterator<Float>
val indices : IntRange
}
class DoubleArray(val size : Int) {
@@ -96,6 +108,8 @@ class DoubleArray(val size : Int) {
fun set(index : Int, value : Double) : Unit
fun iterator() : Iterator<Double>
val indices : IntRange
}
class CharArray(val size : Int) {
@@ -103,6 +117,8 @@ class CharArray(val size : Int) {
fun set(index : Int, value : Char) : Unit
fun iterator() : Iterator<Char>
val indices : IntRange
}
class BooleanArray(val size : Int) {
@@ -110,6 +126,8 @@ class BooleanArray(val size : Int) {
fun set(index : Int, value : Boolean) : Unit
fun iterator() : Iterator<Boolean>
val indices : IntRange
}
trait Comparable<in T> {
@@ -152,8 +170,28 @@ trait Range<in T : Comparable<T>> {
fun contains(item : T) : Boolean
}
class IntRange<T : Comparable<T>>(val start : Int, val end : Int) : Range<T>, Iterable<T> {
class IntRange(val start : Int, size : Int, reversed : Boolean = false) : Range<Int>, Iterable<Int> {
fun iterator () : Iterator<Int>
fun contains (elem: Int) : Boolean
val size : Int
val end : Int
val reversed : Boolean
}
class LongRange(val start : Long, size : Long, reversed : Boolean = false) : Range<Long>, Iterable<Long> {
fun iterator () : Iterator<Long>
fun contains (elem: Long) : Boolean
val size : Long
val end : Long
val reversed : Boolean
}
abstract class Number : Hashable {
@@ -349,11 +387,11 @@ class Long : Number, Comparable<Long> {
fun rangeTo(other : Double) : Range<Double>
fun rangeTo(other : Float) : Range<Double>
fun rangeTo(other : Long) : IntRange<Long>
fun rangeTo(other : Int) : IntRange<Long>
fun rangeTo(other : Short) : IntRange<Long>
fun rangeTo(other : Byte) : IntRange<Long>
fun rangeTo(other : Char) : IntRange<Long>
fun rangeTo(other : Long) : LongRange
fun rangeTo(other : Int) : LongRange
fun rangeTo(other : Short) : LongRange
fun rangeTo(other : Byte) : LongRange
fun rangeTo(other : Char) : LongRange
fun inc() : Long
fun dec() : Long
@@ -420,11 +458,11 @@ class Int : Number, Comparable<Int> {
fun rangeTo(other : Double) : Range<Double>
fun rangeTo(other : Float) : Range<Double>
fun rangeTo(other : Long) : IntRange<Long>
fun rangeTo(other : Int) : IntRange<Int>
fun rangeTo(other : Short) : IntRange<Int>
fun rangeTo(other : Byte) : IntRange<Int>
fun rangeTo(other : Char) : IntRange<Int>
fun rangeTo(other : Long) : LongRange
fun rangeTo(other : Int) : IntRange
fun rangeTo(other : Short) : IntRange
fun rangeTo(other : Byte) : IntRange
fun rangeTo(other : Char) : IntRange
fun inc() : Int
fun dec() : Int
@@ -491,11 +529,11 @@ class Char : Number, Comparable<Char> {
fun rangeTo(other : Double) : Range<Double>
fun rangeTo(other : Float) : Range<Float>
fun rangeTo(other : Long) : IntRange<Long>
fun rangeTo(other : Int) : IntRange<Int>
fun rangeTo(other : Short) : IntRange<Short>
fun rangeTo(other : Byte) : IntRange<Byte>
fun rangeTo(other : Char) : IntRange<Char>
fun rangeTo(other : Long) : LongRange
fun rangeTo(other : Int) : IntRange
fun rangeTo(other : Short) : IntRange
fun rangeTo(other : Byte) : IntRange
fun rangeTo(other : Char) : IntRange
fun inc() : Char
fun dec() : Char
@@ -554,11 +592,11 @@ class Short : Number, Comparable<Short> {
fun rangeTo(other : Double) : Range<Double>
fun rangeTo(other : Float) : Range<Float>
fun rangeTo(other : Long) : IntRange<Long>
fun rangeTo(other : Int) : IntRange<Int>
fun rangeTo(other : Short) : IntRange<Short>
fun rangeTo(other : Byte) : IntRange<Short>
fun rangeTo(other : Char) : IntRange<Int>
fun rangeTo(other : Long) : LongRange
fun rangeTo(other : Int) : IntRange
fun rangeTo(other : Short) : IntRange
fun rangeTo(other : Byte) : IntRange
fun rangeTo(other : Char) : IntRange
fun inc() : Short
fun dec() : Short
@@ -617,11 +655,11 @@ class Byte : Number, Comparable<Byte> {
fun rangeTo(other : Double) : Range<Double>
fun rangeTo(other : Float) : Range<Float>
fun rangeTo(other : Long) : IntRange<Long>
fun rangeTo(other : Int) : IntRange<Int>
fun rangeTo(other : Short) : IntRange<Short>
fun rangeTo(other : Byte) : IntRange<Byte>
fun rangeTo(other : Char) : IntRange<Int>
fun rangeTo(other : Long) : LongRange
fun rangeTo(other : Int) : IntRange
fun rangeTo(other : Short) : IntRange
fun rangeTo(other : Byte) : IntRange
fun rangeTo(other : Char) : IntRange
fun inc() : Byte
fun dec() : Byte
@@ -44,8 +44,8 @@ public class JetSemanticServices {
}
@NotNull
public JetTypeInferrer.Services getTypeInferrerServices(@NotNull BindingTrace trace, @NotNull JetFlowInformationProvider flowInformationProvider) {
return new JetTypeInferrer(flowInformationProvider, this).getServices(trace);
public JetTypeInferrer.Services getTypeInferrerServices(@NotNull BindingTrace trace) {
return new JetTypeInferrer(this).getServices(trace);
}
@NotNull
@@ -25,6 +25,7 @@ public interface JetControlFlowBuilder {
void jumpOnTrue(@NotNull Label label);
void nondeterministicJump(Label label); // Maybe, jump to label
void jumpToError(JetThrowExpression expression);
void jumpToError(JetExpression nothingExpression);
// Entry/exit points
Label getEntryPoint(@NotNull JetElement labelElement);
@@ -62,6 +62,11 @@ public class JetControlFlowBuilderAdapter implements JetControlFlowBuilder {
builder.jumpToError(expression);
}
@Override
public void jumpToError(JetExpression nothingExpression) {
builder.jumpToError(nothingExpression);
}
@Override
public Label getEntryPoint(@NotNull JetElement labelElement) {
return builder.getEntryPoint(labelElement);
@@ -1,11 +1,15 @@
package org.jetbrains.jet.lang.cfg;
import com.intellij.psi.PsiElement;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.BindingContext;
import org.jetbrains.jet.lang.resolve.BindingContextUtils;
import org.jetbrains.jet.lang.resolve.BindingTrace;
import org.jetbrains.jet.lang.types.JetStandardClasses;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.JetTypeInferrer;
import org.jetbrains.jet.lexer.JetTokens;
@@ -18,7 +22,7 @@ import static org.jetbrains.jet.lang.diagnostics.Errors.*;
*/
public class JetControlFlowProcessor {
private final Map<String, Stack<JetElement>> labeledElements = new HashMap<String, Stack<JetElement>>();
// private final Map<String, Stack<JetElement>> labeledElements = new HashMap<String, Stack<JetElement>>();
private final JetControlFlowBuilder builder;
private final BindingTrace trace;
@@ -33,10 +37,10 @@ public class JetControlFlowProcessor {
}
public void generateSubroutineControlFlow(@NotNull JetElement subroutineElement, @NotNull List<? extends JetElement> body) {
if (subroutineElement instanceof JetNamedDeclaration) {
JetNamedDeclaration namedDeclaration = (JetNamedDeclaration) subroutineElement;
enterLabeledElement(JetPsiUtil.safeName(namedDeclaration.getName()), namedDeclaration);
}
// if (subroutineElement instanceof JetNamedDeclaration) {
// JetNamedDeclaration namedDeclaration = (JetNamedDeclaration) subroutineElement;
// enterLabeledElement(JetPsiUtil.safeName(namedDeclaration.getName()), namedDeclaration);
// }
boolean functionLiteral = subroutineElement instanceof JetFunctionLiteralExpression;
builder.enterSubroutine(subroutineElement, functionLiteral);
for (JetElement statement : body) {
@@ -45,57 +49,55 @@ public class JetControlFlowProcessor {
builder.exitSubroutine(subroutineElement, functionLiteral);
}
private void enterLabeledElement(@NotNull String labelName, @NotNull JetElement labeledElement) {
Stack<JetElement> stack = labeledElements.get(labelName);
if (stack == null) {
stack = new Stack<JetElement>();
labeledElements.put(labelName, stack);
}
stack.push(labeledElement);
}
// private void enterLabeledElement(@NotNull String labelName, @NotNull JetElement labeledElement) {
// Stack<JetElement> stack = labeledElements.get(labelName);
// if (stack == null) {
// stack = new Stack<JetElement>();
// labeledElements.put(labelName, stack);
// }
// stack.push(labeledElement);
// }
//
// private void exitElement(JetElement element) {
// // TODO : really suboptimal
// for (Iterator<Map.Entry<String, Stack<JetElement>>> mapIter = labeledElements.entrySet().iterator(); mapIter.hasNext(); ) {
// Map.Entry<String, Stack<JetElement>> entry = mapIter.next();
// Stack<JetElement> stack = entry.getValue();
// for (Iterator<JetElement> stackIter = stack.iterator(); stackIter.hasNext(); ) {
// JetElement recorded = stackIter.next();
// if (recorded == element) {
// stackIter.remove();
// }
// }
// if (stack.isEmpty()) {
// mapIter.remove();
// }
// }
// }
private void exitElement(JetElement element) {
// TODO : really suboptimal
for (Iterator<Map.Entry<String, Stack<JetElement>>> mapIter = labeledElements.entrySet().iterator(); mapIter.hasNext(); ) {
Map.Entry<String, Stack<JetElement>> entry = mapIter.next();
Stack<JetElement> stack = entry.getValue();
for (Iterator<JetElement> stackIter = stack.iterator(); stackIter.hasNext(); ) {
JetElement recorded = stackIter.next();
if (recorded == element) {
stackIter.remove();
}
}
if (stack.isEmpty()) {
mapIter.remove();
}
}
}
@Nullable
private JetElement resolveLabel(@NotNull String labelName, @NotNull JetSimpleNameExpression labelExpression, boolean reportUnresolved) {
Stack<JetElement> stack = labeledElements.get(labelName);
if (stack == null || stack.isEmpty()) {
if (reportUnresolved) {
trace.report(UNRESOLVED_REFERENCE.on(labelExpression));
}
return null;
}
else if (stack.size() > 1) {
// trace.getErrorHandler().genericWarning(labelExpression.getNode(), "There is more than one label with such a name in this scope");
trace.report(LABEL_NAME_CLASH.on(labelExpression));
}
JetElement result = stack.peek();
trace.record(BindingContext.LABEL_TARGET, labelExpression, result);
return result;
}
// @Nullable
// private JetElement resolveLabel(@NotNull String labelName, @NotNull JetSimpleNameExpression labelExpression, boolean reportUnresolved) {
// Stack<JetElement> stack = labeledElements.get(labelName);
// if (stack == null || stack.isEmpty()) {
// if (reportUnresolved) {
//// trace.report(UNRESOLVED_REFERENCE.on(labelExpression));
// }
// return null;
// }
// else if (stack.size() > 1) {
//// trace.getErrorHandler().genericWarning(labelExpression.getNode(), "There is more than one label with such a name in this scope");
//// trace.report(LABEL_NAME_CLASH.on(labelExpression));
// }
//
// JetElement result = stack.peek();
//// trace.record(BindingContext.LABEL_TARGET, labelExpression, result);
// return result;
// }
private class CFPVisitor extends JetVisitorVoid {
// private final boolean preferBlock;
private final boolean inCondition;
private CFPVisitor(boolean inCondition) {
// this.preferBlock = preferBlock;
this.inCondition = inCondition;
}
@@ -109,7 +111,7 @@ public class JetControlFlowProcessor {
visitor = new CFPVisitor(inCondition);
}
element.accept(visitor);
exitElement(element);
// exitElement(element);
}
@Override
@@ -122,12 +124,12 @@ public class JetControlFlowProcessor {
@Override
public void visitThisExpression(JetThisExpression expression) {
JetSimpleNameExpression targetLabel = expression.getTargetLabel();
if (targetLabel != null) {
String labelName = expression.getLabelName();
assert labelName != null;
resolveLabel(labelName, targetLabel, false);
}
// JetSimpleNameExpression targetLabel = expression.getTargetLabel();
// if (targetLabel != null) {
// String labelName = expression.getLabelName();
// assert labelName != null;
// resolveLabel(labelName, targetLabel, false);
// }
builder.read(expression);
}
@@ -139,6 +141,12 @@ public class JetControlFlowProcessor {
@Override
public void visitSimpleNameExpression(JetSimpleNameExpression expression) {
builder.read(expression);
if (trace.get(BindingContext.PROCESSED, expression)) {
JetType type = trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression);
if (type != null && JetStandardClasses.isNothing(type)) {
builder.jumpToError(expression);
}
}
}
@Override
@@ -153,7 +161,7 @@ public class JetControlFlowProcessor {
private void visitLabeledExpression(@NotNull String labelName, @NotNull JetExpression labeledExpression) {
JetExpression deparenthesized = JetPsiUtil.deparenthesize(labeledExpression);
if (deparenthesized != null) {
enterLabeledElement(labelName, deparenthesized);
// enterLabeledElement(labelName, deparenthesized);
value(labeledExpression, inCondition);
}
}
@@ -437,12 +445,20 @@ public class JetControlFlowProcessor {
if (labelName != null) {
JetSimpleNameExpression targetLabel = expression.getTargetLabel();
assert targetLabel != null;
loop = resolveLabel(labelName, targetLabel, true);
if (!isLoop(loop)) {
// trace.getErrorHandler().genericError(expression.getNode(), "The label '" + targetLabel.getText() + "' does not denote a loop");
PsiElement labeledElement = BindingContextUtils.resolveToDeclarationPsiElement(trace.getBindingContext(), targetLabel);
if (labeledElement instanceof JetLoopExpression) {
loop = (JetLoopExpression) labeledElement;
}
else {
trace.report(NOT_A_LOOP_LABEL.on(expression, targetLabel.getText()));
loop = null;
}
// loop = resolveLabel(labelName, targetLabel, true);
// if (!isLoop(loop)) {
//// trace.getErrorHandler().genericError(expression.getNode(), "The label '" + targetLabel.getText() + "' does not denote a loop");
// trace.report(NOT_A_LOOP_LABEL.on(expression, targetLabel.getText()));
// loop = null;
// }
}
else {
loop = builder.getCurrentLoop();
@@ -454,11 +470,11 @@ public class JetControlFlowProcessor {
return loop;
}
private boolean isLoop(JetElement loop) {
return loop instanceof JetWhileExpression ||
loop instanceof JetDoWhileExpression ||
loop instanceof JetForExpression;
}
// private boolean isLoop(JetElement loop) {
// return loop instanceof JetWhileExpression ||
// loop instanceof JetDoWhileExpression ||
// loop instanceof JetForExpression;
// }
@Override
public void visitReturnExpression(JetReturnExpression expression) {
@@ -471,13 +487,21 @@ public class JetControlFlowProcessor {
if (labelElement != null) {
String labelName = expression.getLabelName();
assert labelName != null;
subroutine = resolveLabel(labelName, labelElement, true);
PsiElement labeledElement = BindingContextUtils.resolveToDeclarationPsiElement(trace.getBindingContext(), labelElement);
if (labeledElement != null) {
assert labeledElement instanceof JetElement;
subroutine = (JetElement) labeledElement;
}
else {
subroutine = null;
}
//subroutine = resolveLabel(labelName, labelElement, true);
}
else {
subroutine = builder.getCurrentSubroutine();
// TODO : a context check
}
if (subroutine != null) {
if (subroutine instanceof JetFunction || subroutine instanceof JetFunctionLiteralExpression) {
if (returnedExpression == null) {
builder.returnNoValue(expression, subroutine);
}
@@ -485,6 +509,11 @@ public class JetControlFlowProcessor {
builder.returnValue(expression, subroutine);
}
}
else {
if (labelElement != null) {
trace.report(NOT_A_RETURN_LABEL.on(expression, expression.getLabelName()));
}
}
}
@Override
@@ -524,6 +553,12 @@ public class JetControlFlowProcessor {
value(selectorExpression, false);
}
builder.read(expression);
if (trace.get(BindingContext.PROCESSED, expression)) {
JetType type = trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression);
if (type != null && JetStandardClasses.isNothing(type)) {
builder.jumpToError(expression);
}
}
}
private void visitCall(JetCallElement call) {
@@ -549,6 +584,12 @@ public class JetControlFlowProcessor {
value(expression.getCalleeExpression(), false);
builder.read(expression);
if (trace.get(BindingContext.PROCESSED, expression)) {
JetType type = trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, expression);
if (type != null && JetStandardClasses.isNothing(type)) {
builder.jumpToError(expression);
}
}
}
// @Override
@@ -11,61 +11,61 @@ import java.util.Collection;
* @author abreslav
*/
public interface JetFlowInformationProvider {
JetFlowInformationProvider THROW_EXCEPTION = new JetFlowInformationProvider() {
@Override
public void collectReturnedInformation(@NotNull JetElement subroutine, @NotNull Collection<JetExpression> returnedExpressions, @NotNull Collection<JetElement> elementsReturningUnit) {
throw new UnsupportedOperationException();
}
@Override
public void collectReturnExpressions(@NotNull JetElement subroutine, @NotNull Collection<JetExpression> returnedExpressions) {
throw new UnsupportedOperationException();
}
@Override
public void collectUnreachableExpressions(@NotNull JetElement subroutine, @NotNull Collection<JetElement> unreachableElements) {
throw new UnsupportedOperationException();
}
@Override
public void collectDominatedExpressions(@NotNull JetExpression dominator, @NotNull Collection<JetElement> dominated) {
throw new UnsupportedOperationException();
}
@Override
public boolean isBreakable(JetLoopExpression loop) {
throw new UnsupportedOperationException();
}
};
JetFlowInformationProvider NONE = new JetFlowInformationProvider() {
@Override
public void collectReturnedInformation(@NotNull JetElement subroutine, @NotNull Collection<JetExpression> returnedExpressions, @NotNull Collection<JetElement> elementsReturningUnit) {
}
@Override
public void collectReturnExpressions(@NotNull JetElement subroutine, @NotNull Collection<JetExpression> returnedExpressions) {
}
@Override
public void collectUnreachableExpressions(@NotNull JetElement subroutine, @NotNull Collection<JetElement> unreachableElements) {
}
@Override
public void collectDominatedExpressions(@NotNull JetExpression dominator, @NotNull Collection<JetElement> dominated) {
}
@Override
public boolean isBreakable(JetLoopExpression loop) {
return false;
}
};
// JetFlowInformationProvider THROW_EXCEPTION = new JetFlowInformationProvider() {
// @Override
// public void collectReturnedInformation(@NotNull JetElement subroutine, @NotNull Collection<JetExpression> returnedExpressions, @NotNull Collection<JetElement> elementsReturningUnit) {
// throw new UnsupportedOperationException();
// }
//
// @Override
// public void collectReturnExpressions(@NotNull JetElement subroutine, @NotNull Collection<JetExpression> returnedExpressions) {
// throw new UnsupportedOperationException();
// }
//
// @Override
// public void collectUnreachableExpressions(@NotNull JetElement subroutine, @NotNull Collection<JetElement> unreachableElements) {
// throw new UnsupportedOperationException();
// }
//
// @Override
// public void collectDominatedExpressions(@NotNull JetExpression dominator, @NotNull Collection<JetElement> dominated) {
// throw new UnsupportedOperationException();
// }
//
// @Override
// public boolean isBreakable(JetLoopExpression loop) {
// throw new UnsupportedOperationException();
// }
//
// };
//
// JetFlowInformationProvider NONE = new JetFlowInformationProvider() {
// @Override
// public void collectReturnedInformation(@NotNull JetElement subroutine, @NotNull Collection<JetExpression> returnedExpressions, @NotNull Collection<JetElement> elementsReturningUnit) {
//
// }
//
// @Override
// public void collectReturnExpressions(@NotNull JetElement subroutine, @NotNull Collection<JetExpression> returnedExpressions) {
//
// }
//
// @Override
// public void collectUnreachableExpressions(@NotNull JetElement subroutine, @NotNull Collection<JetElement> unreachableElements) {
//
// }
//
// @Override
// public void collectDominatedExpressions(@NotNull JetExpression dominator, @NotNull Collection<JetElement> dominated) {
//
// }
//
// @Override
// public boolean isBreakable(JetLoopExpression loop) {
// return false;
// }
//
// };
/**
* Collects expressions returned from the given subroutine and 'return;' expressions
@@ -250,6 +250,11 @@ public class JetControlFlowInstructionsGenerator extends JetControlFlowBuilderAd
public void jumpToError(JetThrowExpression expression) {
add(new UnconditionalJumpInstruction(error));
}
@Override
public void jumpToError(JetExpression nothingExpression) {
add(new UnconditionalJumpInstruction(error));
}
@Override
public void enterTryFinally(@NotNull GenerationTrigger generationTrigger) {
@@ -143,7 +143,6 @@ public interface Errors {
PsiElementOnlyDiagnosticFactory3<JetModifierListOwner, CallableMemberDescriptor, CallableMemberDescriptor, DeclarationDescriptor> VIRTUAL_MEMBER_HIDDEN = PsiElementOnlyDiagnosticFactory3.create(ERROR, "''{0}'' hides ''{1}'' in class {2} and needs 'override' modifier", DescriptorRenderer.TEXT);
SimpleDiagnosticFactory UNREACHABLE_CODE = SimpleDiagnosticFactory.create(ERROR, "Unreachable code");
ParameterizedDiagnosticFactory1<String> UNREACHABLE_BECAUSE_OF_NOTHING = ParameterizedDiagnosticFactory1.create(ERROR, "This code is unreachable, because ''{0}'' never terminates normally");
SimpleDiagnosticFactory MANY_CLASS_OBJECTS = SimpleDiagnosticFactory.create(ERROR, "Only one class object is allowed per class");
SimpleDiagnosticFactory CLASS_OBJECT_NOT_ALLOWED = SimpleDiagnosticFactory.create(ERROR, "A class object is not allowed here");
@@ -191,6 +190,7 @@ public interface Errors {
SimpleDiagnosticFactory RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY = SimpleDiagnosticFactory.create(ERROR, "Returns are not allowed for functions with expression body. Use block body in '{...}'");
SimpleDiagnosticFactory NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY = SimpleDiagnosticFactory.create(ERROR, "A 'return' expression required in a function with a block body ('{...}')");
ParameterizedDiagnosticFactory1<JetType> RETURN_TYPE_MISMATCH = ParameterizedDiagnosticFactory1.create(ERROR, "This function must return a value of type {0}");
ParameterizedDiagnosticFactory1<JetType> EXPECTED_TYPE_MISMATCH = ParameterizedDiagnosticFactory1.create(ERROR, "Expected a value of type {0}");
ParameterizedDiagnosticFactory1<JetType> UPPER_BOUND_VIOLATED = ParameterizedDiagnosticFactory1.create(ERROR, "An upper bound {0} is violated"); // TODO : Message
ParameterizedDiagnosticFactory1<JetType> FINAL_CLASS_OBJECT_UPPER_BOUND = ParameterizedDiagnosticFactory1.create(ERROR, "{0} is a final type, and thus a class object cannot extend it");
@@ -221,6 +221,7 @@ public interface Errors {
SimpleDiagnosticFactory VALUE_PARAMETER_WITH_NO_TYPE_ANNOTATION = SimpleDiagnosticFactory.create(ERROR, "A type annotation is required on a value parameter");
SimpleDiagnosticFactory BREAK_OR_CONTINUE_OUTSIDE_A_LOOP = SimpleDiagnosticFactory.create(ERROR, "'break' and 'continue' are only allowed inside a loop");
ParameterizedDiagnosticFactory1<String> NOT_A_LOOP_LABEL = ParameterizedDiagnosticFactory1.create(ERROR, "The label ''{0}'' does not denote a loop");
ParameterizedDiagnosticFactory1<String> NOT_A_RETURN_LABEL = ParameterizedDiagnosticFactory1.create(ERROR, "The label ''{0}'' does not reference to a context from which we can return");
SimpleDiagnosticFactory ANONYMOUS_INITIALIZER_WITHOUT_CONSTRUCTOR = SimpleDiagnosticFactory.create(ERROR, "Anonymous initializers are only allowed in the presence of a primary constructor");
SimpleDiagnosticFactory NULLABLE_SUPERTYPE = SimpleDiagnosticFactory.create(ERROR, "A supertype cannot be nullable");
@@ -7,7 +7,7 @@ import org.jetbrains.jet.JetNodeType;
/**
* @author max
*/
public class JetExpression extends JetElement {
public abstract class JetExpression extends JetElement {
public JetExpression(@NotNull ASTNode node) {
super(node);
}
@@ -0,0 +1,796 @@
package org.jetbrains.jet.lang.psi;
import java.util.List;
/**
* @author svtk
*/
public class JetTreeVisitor<D> extends JetVisitor<Void, D> {
@Override
public Void visitNamespace(JetNamespace namespace, D data) {
List<JetImportDirective> importDirectives = namespace.getImportDirectives();
for (JetImportDirective directive : importDirectives) {
directive.visit(this, data);
}
List<JetDeclaration> declarations = namespace.getDeclarations();
for (JetDeclaration declaration : declarations) {
declaration.visit(this, data);
}
return null;
}
@Override
public Void visitClass(JetClass klass, D data) {
List<JetDeclaration> declarations = klass.getDeclarations();
for (JetDeclaration declaration : declarations) {
declaration.visit(this, data);
}
return null;
}
@Override
public Void visitClassObject(JetClassObject classObject, D data) {
JetObjectDeclaration objectDeclaration = classObject.getObjectDeclaration();
if (objectDeclaration != null) {
objectDeclaration.visit(this, data);
}
return null;
}
@Override
public Void visitConstructor(JetConstructor constructor, D data) {
visitDeclarationWithBody(constructor, data);
return null;
}
@Override
public Void visitNamedFunction(JetNamedFunction function, D data) {
visitDeclarationWithBody(function, data);
return null;
}
@Override
public Void visitProperty(JetProperty property, D data) {
List<JetPropertyAccessor> accessors = property.getAccessors();
for (JetPropertyAccessor accessor : accessors) {
accessor.visit(this, data);
}
JetExpression initializer = property.getInitializer();
if (initializer != null) {
initializer.visit(this, data);
}
return null;
}
@Override
public Void visitTypedef(JetTypedef typedef, D data) {
return super.visitTypedef(typedef, data);
}
@Override
public Void visitJetFile(JetFile file, D data) {
JetNamespace rootNamespace = file.getRootNamespace();
return rootNamespace.visit(this, data);
}
@Override
public Void visitImportDirective(JetImportDirective importDirective, D data) {
return super.visitImportDirective(importDirective, data);
}
@Override
public Void visitClassBody(JetClassBody classBody, D data) {
List<JetDeclaration> declarations = classBody.getDeclarations();
for (JetDeclaration declaration : declarations) {
declaration.visit(this, data);
}
List<JetConstructor> secondaryConstructors = classBody.getSecondaryConstructors();
for (JetConstructor constructor : secondaryConstructors) {
constructor.visit(this, data);
}
return null;
}
@Override
public Void visitNamespaceBody(JetNamespaceBody body, D data) {
List<JetDeclaration> declarations = body.getDeclarations();
for (JetDeclaration declaration : declarations) {
declaration.visit(this, data);
}
return null;
}
@Override
public Void visitModifierList(JetModifierList list, D data) {
return super.visitModifierList(list, data);
}
@Override
public Void visitAnnotation(JetAnnotation annotation, D data) {
return super.visitAnnotation(annotation, data);
}
@Override
public Void visitAnnotationEntry(JetAnnotationEntry annotationEntry, D data) {
return super.visitAnnotationEntry(annotationEntry, data);
}
@Override
public Void visitTypeParameterList(JetTypeParameterList list, D data) {
List<JetTypeParameter> parameters = list.getParameters();
for (JetTypeParameter parameter : parameters) {
parameter.visit(this, data);
}
return null;
}
@Override
public Void visitTypeParameter(JetTypeParameter parameter, D data) {
return super.visitTypeParameter(parameter, data);
}
@Override
public Void visitEnumEntry(JetEnumEntry enumEntry, D data) {
List<JetDelegationSpecifier> delegationSpecifiers = enumEntry.getDelegationSpecifiers();
for (JetDelegationSpecifier delegationSpecifier : delegationSpecifiers) {
delegationSpecifier.visit(this, data);
}
JetModifierList modifierList = enumEntry.getModifierList();
if (modifierList != null) {
modifierList.visit(this, data);
}
return null;
}
@Override
public Void visitParameterList(JetParameterList list, D data) {
List<JetParameter> parameters = list.getParameters();
for (JetParameter parameter : parameters) {
parameter.visit(this, data);
}
return null;
}
@Override
public Void visitParameter(JetParameter parameter, D data) {
return super.visitParameter(parameter, data);
}
@Override
public Void visitDelegationSpecifierList(JetDelegationSpecifierList list, D data) {
List<JetDelegationSpecifier> delegationSpecifiers = list.getDelegationSpecifiers();
for (JetDelegationSpecifier delegationSpecifier : delegationSpecifiers) {
delegationSpecifier.visit(this, data);
}
return null;
}
@Override
public Void visitDelegationSpecifier(JetDelegationSpecifier specifier, D data) {
return super.visitDelegationSpecifier(specifier, data);
}
@Override
public Void visitDelegationByExpressionSpecifier(JetDelegatorByExpressionSpecifier specifier, D data) {
return super.visitDelegationByExpressionSpecifier(specifier, data);
}
@Override
public Void visitDelegationToSuperCallSpecifier(JetDelegatorToSuperCall call, D data) {
return super.visitDelegationToSuperCallSpecifier(call, data);
}
@Override
public Void visitDelegationToSuperClassSpecifier(JetDelegatorToSuperClass specifier, D data) {
return super.visitDelegationToSuperClassSpecifier(specifier, data);
}
@Override
public Void visitDelegationToThisCall(JetDelegatorToThisCall thisCall, D data) {
return super.visitDelegationToThisCall(thisCall, data);
}
@Override
public Void visitTypeReference(JetTypeReference typeReference, D data) {
return super.visitTypeReference(typeReference, data);
}
@Override
public Void visitValueArgumentList(JetValueArgumentList list, D data) {
List<JetValueArgument> arguments = list.getArguments();
for (JetValueArgument argument : arguments) {
argument.visit(this, data);
}
return null;
}
@Override
public Void visitArgument(JetValueArgument argument, D data) {
return super.visitArgument(argument, data);
}
@Override
public Void visitLoopExpression(JetLoopExpression loopExpression, D data) {
JetExpression body = loopExpression.getBody();
if (body != null) {
body.visit(this, data);
}
return null;
}
@Override
public Void visitConstantExpression(JetConstantExpression expression, D data) {
return super.visitConstantExpression(expression, data);
}
@Override
public Void visitSimpleNameExpression(JetSimpleNameExpression expression, D data) {
return super.visitSimpleNameExpression(expression, data);
}
@Override
public Void visitReferenceExpression(JetReferenceExpression expression, D data) {
return super.visitReferenceExpression(expression, data);
}
@Override
public Void visitTupleExpression(JetTupleExpression expression, D data) {
return super.visitTupleExpression(expression, data);
}
@Override
public Void visitPrefixExpression(JetPrefixExpression expression, D data) {
JetExpression baseExpression = expression.getBaseExpression();
if (baseExpression != null) {
baseExpression.visit(this, data);
}
return null;
}
@Override
public Void visitPostfixExpression(JetPostfixExpression expression, D data) {
JetExpression baseExpression = expression.getBaseExpression();
baseExpression.visit(this, data);
return null;
}
@Override
public Void visitUnaryExpression(JetUnaryExpression expression, D data) {
JetExpression baseExpression = expression.getBaseExpression();
assert baseExpression != null;
baseExpression.visit(this, data);
return null;
}
@Override
public Void visitBinaryExpression(JetBinaryExpression expression, D data) {
JetExpression left = expression.getLeft();
left.visit(this, data);
JetExpression right = expression.getRight();
if (right != null) {
right.visit(this, data);
}
return super.visitBinaryExpression(expression, data);
}
@Override
public Void visitReturnExpression(JetReturnExpression expression, D data) {
JetExpression returnedExpression = expression.getReturnedExpression();
if (returnedExpression != null) {
returnedExpression.visit(this, data);
}
return null;
}
@Override
public Void visitLabelQualifiedExpression(JetLabelQualifiedExpression expression, D data) {
JetExpression labeledExpression = expression.getLabeledExpression();
if (labeledExpression != null) {
labeledExpression.visit(this, data);
}
return null;
}
@Override
public Void visitThrowExpression(JetThrowExpression expression, D data) {
JetExpression thrownExpression = expression.getThrownExpression();
if (thrownExpression != null) {
thrownExpression.visit(this, data);
}
return null;
}
@Override
public Void visitBreakExpression(JetBreakExpression expression, D data) {
return super.visitBreakExpression(expression, data);
}
@Override
public Void visitContinueExpression(JetContinueExpression expression, D data) {
return super.visitContinueExpression(expression, data);
}
@Override
public Void visitIfExpression(JetIfExpression expression, D data) {
JetExpression condition = expression.getCondition();
if (condition != null) {
condition.visit(this, data);
}
JetExpression then = expression.getThen();
if (then != null) {
then.visit(this, data);
}
JetExpression anElse = expression.getElse();
if (anElse != null) {
anElse.visit(this, data);
}
return null;
}
@Override
public Void visitWhenExpression(JetWhenExpression expression, D data) {
List<JetWhenEntry> entries = expression.getEntries();
for (JetWhenEntry entry : entries) {
entry.visit(this, data);
}
JetExpression subjectExpression = expression.getSubjectExpression();
if (subjectExpression != null) {
subjectExpression.visit(this, data);
}
return null;
}
@Override
public Void visitTryExpression(JetTryExpression expression, D data) {
JetBlockExpression tryBlock = expression.getTryBlock();
tryBlock.visit(this, data);
List<JetCatchClause> catchClauses = expression.getCatchClauses();
for (JetCatchClause catchClause : catchClauses) {
catchClause.visit(this, data);
}
JetFinallySection finallyBlock = expression.getFinallyBlock();
if (finallyBlock != null) {
finallyBlock.visit(this, data);
}
return null;
}
@Override
public Void visitForExpression(JetForExpression expression, D data) {
JetParameter loopParameter = expression.getLoopParameter();
if (loopParameter != null) {
loopParameter.visit(this, data);
}
JetExpression loopRange = expression.getLoopRange();
if (loopRange != null) {
loopRange.visit(this, data);
}
visitLoopExpression(expression, data);
return null;
}
@Override
public Void visitWhileExpression(JetWhileExpression expression, D data) {
JetExpression condition = expression.getCondition();
if (condition != null) {
condition.visit(this, data);
}
visitLoopExpression(expression, data);
return null;
}
@Override
public Void visitDoWhileExpression(JetDoWhileExpression expression, D data) {
JetExpression condition = expression.getCondition();
if (condition != null) {
condition.visit(this, data);
}
visitLoopExpression(expression, data);
return null;
}
@Override
public Void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression, D data) {
JetFunctionLiteral functionLiteral = expression.getFunctionLiteral();
functionLiteral.visit(this, data);
visitDeclarationWithBody(expression, data);
return null;
}
@Override
public Void visitAnnotatedExpression(JetAnnotatedExpression expression, D data) {
JetExpression baseExpression = expression.getBaseExpression();
baseExpression.visit(this, data);
return null;
}
@Override
public Void visitCallExpression(JetCallExpression expression, D data) {
JetExpression calleeExpression = expression.getCalleeExpression();
if (calleeExpression != null) {
calleeExpression.visit(this, data);
}
return null;
}
@Override
public Void visitArrayAccessExpression(JetArrayAccessExpression expression, D data) {
JetExpression arrayExpression = expression.getArrayExpression();
arrayExpression.visit(this, data);
List<JetExpression> indexExpressions = expression.getIndexExpressions();
for (JetExpression indexExpression : indexExpressions) {
indexExpression.visit(this, data);
}
return null;
}
@Override
public Void visitQualifiedExpression(JetQualifiedExpression expression, D data) {
JetExpression receiver = expression.getReceiverExpression();
receiver.visit(this, data);
JetExpression selector = expression.getSelectorExpression();
if (selector != null) {
selector.visit(this, data);
}
return null;
}
@Override
public Void visitHashQualifiedExpression(JetHashQualifiedExpression expression, D data) {
visitQualifiedExpression(expression, data);
return null;
}
@Override
public Void visitDotQualifiedExpression(JetDotQualifiedExpression expression, D data) {
visitQualifiedExpression(expression, data);
return null;
}
@Override
public Void visitPredicateExpression(JetPredicateExpression expression, D data) {
visitQualifiedExpression(expression, data);
return null;
}
@Override
public Void visitSafeQualifiedExpression(JetSafeQualifiedExpression expression, D data) {
visitQualifiedExpression(expression, data);
return null;
}
@Override
public Void visitObjectLiteralExpression(JetObjectLiteralExpression expression, D data) {
JetObjectDeclaration objectDeclaration = expression.getObjectDeclaration();
objectDeclaration.visit(this, data);
return null;
}
@Override
public Void visitRootNamespaceExpression(JetRootNamespaceExpression expression, D data) {
return super.visitRootNamespaceExpression(expression, data);
}
@Override
public Void visitBlockExpression(JetBlockExpression expression, D data) {
List<JetElement> statements = expression.getStatements();
for (JetElement statement : statements) {
statement.visit(this, data);
}
return null;
}
@Override
public Void visitCatchSection(JetCatchClause catchClause, D data) {
JetParameter catchParameter = catchClause.getCatchParameter();
if (catchParameter != null) {
catchParameter.visit(this, data);
}
JetExpression catchBody = catchClause.getCatchBody();
if (catchBody != null) {
catchBody.visit(this, data);
}
return null;
}
@Override
public Void visitFinallySection(JetFinallySection finallySection, D data) {
JetBlockExpression finalExpression = finallySection.getFinalExpression();
finalExpression.visit(this, data);
return null;
}
@Override
public Void visitTypeArgumentList(JetTypeArgumentList typeArgumentList, D data) {
List<JetTypeProjection> arguments = typeArgumentList.getArguments();
for (JetTypeProjection argument : arguments) {
argument.visit(this, data);
}
return null;
}
@Override
public Void visitThisExpression(JetThisExpression expression, D data) {
JetReferenceExpression thisReference = expression.getThisReference();
thisReference.visit(this, data);
JetTypeReference superTypeQualifier = expression.getSuperTypeQualifier();
if (superTypeQualifier != null) {
superTypeQualifier.visit(this, data);
}
visitLabelQualifiedExpression(expression, data);
return null;
}
@Override
public Void visitParenthesizedExpression(JetParenthesizedExpression expression, D data) {
JetExpression innerExpression = expression.getExpression();
if (innerExpression != null) {
innerExpression.visit(this, data);
}
return null;
}
@Override
public Void visitInitializerList(JetInitializerList list, D data) {
List<JetDelegationSpecifier> initializers = list.getInitializers();
for (JetDelegationSpecifier initializer : initializers) {
initializer.visit(this, data);
}
return null;
}
@Override
public Void visitAnonymousInitializer(JetClassInitializer initializer, D data) {
JetExpression body = initializer.getBody();
body.visit(this, data);
return null;
}
@Override
public Void visitPropertyAccessor(JetPropertyAccessor accessor, D data) {
visitDeclarationWithBody(accessor, data);
return null;
}
@Override
public Void visitTypeConstraintList(JetTypeConstraintList list, D data) {
List<JetTypeConstraint> constraints = list.getConstraints();
for (JetTypeConstraint constraint : constraints) {
constraint.visit(this, data);
}
return null;
}
@Override
public Void visitTypeConstraint(JetTypeConstraint constraint, D data) {
JetSimpleNameExpression subjectTypeParameterName = constraint.getSubjectTypeParameterName();
if (subjectTypeParameterName != null) {
subjectTypeParameterName.visit(this, data);
}
return null;
}
@Override
public Void visitUserType(JetUserType type, D data) {
return super.visitUserType(type, data);
}
@Override
public Void visitTupleType(JetTupleType type, D data) {
return super.visitTupleType(type, data);
}
@Override
public Void visitFunctionType(JetFunctionType type, D data) {
return super.visitFunctionType(type, data);
}
@Override
public Void visitSelfType(JetSelfType type, D data) {
return super.visitSelfType(type, data);
}
@Override
public Void visitBinaryWithTypeRHSExpression(JetBinaryExpressionWithTypeRHS expression, D data) {
JetExpression left = expression.getLeft();
left.visit(this, data);
JetTypeReference right = expression.getRight();
if (right != null) {
right.visit(this, data);
}
return null;
}
@Override
public Void visitStringTemplateExpression(JetStringTemplateExpression expression, D data) {
JetStringTemplateEntry[] entries = expression.getEntries();
for (JetStringTemplateEntry entry : entries) {
entry.visit(this, data);
}
return null;
}
@Override
public Void visitNamedDeclaration(JetNamedDeclaration declaration, D data) {
return super.visitNamedDeclaration(declaration, data);
}
@Override
public Void visitNullableType(JetNullableType nullableType, D data) {
return super.visitNullableType(nullableType, data);
}
@Override
public Void visitTypeProjection(JetTypeProjection typeProjection, D data) {
return super.visitTypeProjection(typeProjection, data);
}
@Override
public Void visitWhenEntry(JetWhenEntry jetWhenEntry, D data) {
JetExpression expression = jetWhenEntry.getExpression();
if (expression != null) {
expression.visit(this, data);
}
JetWhenCondition[] conditions = jetWhenEntry.getConditions();
for (JetWhenCondition condition : conditions) {
condition.visit(this, data);
}
return null;
}
@Override
public Void visitIsExpression(JetIsExpression expression, D data) {
JetExpression leftHandSide = expression.getLeftHandSide();
leftHandSide.visit(this, data);
JetSimpleNameExpression operationReference = expression.getOperationReference();
operationReference.visit(this, data);
JetPattern pattern = expression.getPattern();
if (pattern != null) {
pattern.visit(this, data);
}
return null;
}
@Override
public Void visitWhenConditionCall(JetWhenConditionCall condition, D data) {
JetExpression callSuffixExpression = condition.getCallSuffixExpression();
if (callSuffixExpression != null) {
callSuffixExpression.visit(this, data);
}
return null;
}
@Override
public Void visitWhenConditionIsPattern(JetWhenConditionIsPattern condition, D data) {
JetPattern pattern = condition.getPattern();
if (pattern != null) {
pattern.visit(this, data);
}
return null;
}
@Override
public Void visitWhenConditionInRange(JetWhenConditionInRange condition, D data) {
JetSimpleNameExpression operationReference = condition.getOperationReference();
operationReference.visit(this, data);
JetExpression rangeExpression = condition.getRangeExpression();
if (rangeExpression != null) {
rangeExpression.visit(this, data);
}
return null;
}
@Override
public Void visitTypePattern(JetTypePattern pattern, D data) {
return super.visitTypePattern(pattern, data);
}
@Override
public Void visitWildcardPattern(JetWildcardPattern pattern, D data) {
return super.visitWildcardPattern(pattern, data);
}
@Override
public Void visitExpressionPattern(JetExpressionPattern pattern, D data) {
JetExpression expression = pattern.getExpression();
if (expression != null) {
expression.visit(this, data);
}
return null;
}
@Override
public Void visitTuplePattern(JetTuplePattern pattern, D data) {
List<JetTuplePatternEntry> entries = pattern.getEntries();
for (JetTuplePatternEntry entry : entries) {
entry.visit(this, data);
}
return null;
}
@Override
public Void visitDecomposerPattern(JetDecomposerPattern pattern, D data) {
JetTuplePattern argumentList = pattern.getArgumentList();
argumentList.visit(this, data);
JetExpression decomposerExpression = pattern.getDecomposerExpression();
if (decomposerExpression != null) {
decomposerExpression.visit(this, data);
}
return null;
}
@Override
public Void visitObjectDeclaration(JetObjectDeclaration objectDeclaration, D data) {
List<JetDeclaration> declarations = objectDeclaration.getDeclarations();
for (JetDeclaration declaration : declarations) {
declaration.visit(this, data);
}
JetDelegationSpecifierList delegationSpecifierList = objectDeclaration.getDelegationSpecifierList();
if (delegationSpecifierList != null) {
delegationSpecifierList.visit(this, data);
}
return null;
}
@Override
public Void visitBindingPattern(JetBindingPattern pattern, D data) {
JetWhenCondition condition = pattern.getCondition();
if (condition != null) {
condition.visit(this, data);
}
JetProperty variableDeclaration = pattern.getVariableDeclaration();
variableDeclaration.visit(this, data);
return null;
}
@Override
public Void visitStringTemplateEntry(JetStringTemplateEntry entry, D data) {
JetExpression expression = entry.getExpression();
if (expression != null) {
expression.visit(this, data);
}
return null;
}
@Override
public Void visitStringTemplateEntryWithExpression(JetStringTemplateEntryWithExpression entry, D data) {
visitStringTemplateEntry(entry, data);
return null;
}
@Override
public Void visitBlockStringTemplateEntry(JetBlockStringTemplateEntry entry, D data) {
visitStringTemplateEntry(entry, data);
return null;
}
@Override
public Void visitSimpleNameStringTemplateEntry(JetSimpleNameStringTemplateEntry entry, D data) {
visitStringTemplateEntry(entry, data);
return null;
}
@Override
public Void visitLiteralStringTemplateEntry(JetLiteralStringTemplateEntry entry, D data) {
visitStringTemplateEntry(entry, data);
return null;
}
@Override
public Void visitEscapeStringTemplateEntry(JetEscapeStringTemplateEntry entry, D data) {
visitStringTemplateEntry(entry, data);
return null;
}
private Void visitDeclarationWithBody(JetDeclarationWithBody declaration, D data) {
JetExpression bodyExpression = declaration.getBodyExpression();
if (bodyExpression != null) {
bodyExpression.visit(this, data);
}
List<JetParameter> valueParameters = declaration.getValueParameters();
for (JetParameter valueParameter : valueParameters) {
valueParameter.visit(this, data);
}
return null;
}
}
@@ -34,7 +34,7 @@ public class AnnotationResolver {
this.trace = trace;
// this.typeInferrer = new JetTypeInferrer(JetFlowInformationProvider.THROW_EXCEPTION, semanticServices);
// this.services = typeInferrer.getServices(this.trace);
this.callResolver = new CallResolver(semanticServices, new JetTypeInferrer(JetFlowInformationProvider.THROW_EXCEPTION, semanticServices), DataFlowInfo.getEmpty());
this.callResolver = new CallResolver(semanticServices, new JetTypeInferrer(semanticServices), DataFlowInfo.getEmpty());
}
@NotNull
@@ -125,7 +125,7 @@ public class BodyResolver {
final JetScope scopeForConstructor = primaryConstructor == null
? null
: getInnerScopeForConstructor(primaryConstructor, descriptor.getScopeForMemberResolution(), true);
final JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors, JetFlowInformationProvider.NONE); // TODO : flow
final JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors); // TODO : flow
final Map<JetTypeReference, JetType> supertypes = Maps.newLinkedHashMap();
JetVisitorVoid visitor = new JetVisitorVoid() {
@@ -292,7 +292,7 @@ public class BodyResolver {
ConstructorDescriptor primaryConstructor = classDescriptor.getUnsubstitutedPrimaryConstructor();
assert primaryConstructor != null;
final JetScope scopeForConstructor = getInnerScopeForConstructor(primaryConstructor, classDescriptor.getScopeForMemberResolution(), true);
JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(createFieldAssignTrackingTrace(), JetFlowInformationProvider.NONE); // TODO : flow
JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(createFieldAssignTrackingTrace()); // TODO : flow
for (JetClassInitializer anonymousInitializer : anonymousInitializers) {
typeInferrer.getType(scopeForConstructor, anonymousInitializer.getBody(), NO_EXPECTED_TYPE);
}
@@ -318,7 +318,7 @@ public class BodyResolver {
private void resolveSecondaryConstructorBody(JetConstructor declaration, final ConstructorDescriptor descriptor, final JetScope declaringScope) {
final JetScope functionInnerScope = getInnerScopeForConstructor(descriptor, declaringScope, false);
final JetTypeInferrer.Services typeInferrerForInitializers = context.getSemanticServices().getTypeInferrerServices(traceForConstructors, JetFlowInformationProvider.NONE);
final JetTypeInferrer.Services typeInferrerForInitializers = context.getSemanticServices().getTypeInferrerServices(traceForConstructors);
JetClass containingClass = PsiTreeUtil.getParentOfType(declaration, JetClass.class);
assert containingClass != null : "This must be guaranteed by the parser";
@@ -380,11 +380,11 @@ public class BodyResolver {
}
JetExpression bodyExpression = declaration.getBodyExpression();
if (bodyExpression != null) {
context.getClassDescriptorResolver().computeFlowData(declaration, bodyExpression);
JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData(declaration, bodyExpression);
JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors, flowInformationProvider);
//context.getClassDescriptorResolver().computeFlowData(declaration, bodyExpression);
//JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData(declaration, bodyExpression);
JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors);
typeInferrer.checkFunctionReturnType(functionInnerScope, declaration, JetStandardClasses.getUnitType());
typeInferrer.checkFunctionReturnType(functionInnerScope, declaration, descriptor, JetStandardClasses.getUnitType());
}
}
@@ -519,8 +519,8 @@ public class BodyResolver {
}
private void resolvePropertyInitializer(JetProperty property, PropertyDescriptor propertyDescriptor, JetExpression initializer, JetScope scope) {
JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData(property, initializer); // TODO : flow JET-15
JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors, flowInformationProvider);
//JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData(property, initializer); // TODO : flow JET-15
JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(traceForConstructors);
JetType type = typeInferrer.getType(getPropertyDeclarationInnerScope(scope, propertyDescriptor), initializer, NO_EXPECTED_TYPE);
JetType expectedType = propertyDescriptor.getInType();
@@ -555,13 +555,13 @@ public class BodyResolver {
JetExpression bodyExpression = function.getBodyExpression();
if (bodyExpression != null) {
JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData(function.asElement(), bodyExpression);
JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(trace, flowInformationProvider);
//JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData(function.asElement(), bodyExpression);
JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(trace);
typeInferrer.checkFunctionReturnType(declaringScope, function, functionDescriptor);
}
JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(trace, JetFlowInformationProvider.THROW_EXCEPTION);
JetTypeInferrer.Services typeInferrer = context.getSemanticServices().getTypeInferrerServices(trace);
List<JetParameter> valueParameters = function.getValueParameters();
for (int i = 0; i < valueParameters.size(); i++) {
ValueParameterDescriptor valueParameterDescriptor = functionDescriptor.getValueParameters().get(i);
@@ -178,8 +178,8 @@ public class ClassDescriptorResolver {
returnType = DeferredType.create(trace, new LazyValueWithDefault<JetType>(ErrorUtils.createErrorType("Recursive dependency")) {
@Override
protected JetType compute() {
JetFlowInformationProvider flowInformationProvider = computeFlowData(function, bodyExpression);
return semanticServices.getTypeInferrerServices(trace, flowInformationProvider).inferFunctionReturnType(scope, function, functionDescriptor);
//JetFlowInformationProvider flowInformationProvider = computeFlowData(function, bodyExpression);
return semanticServices.getTypeInferrerServices(trace).inferFunctionReturnType(scope, function, functionDescriptor);
}
});
}
@@ -540,8 +540,8 @@ public class ClassDescriptorResolver {
LazyValue<JetType> lazyValue = new LazyValueWithDefault<JetType>(ErrorUtils.createErrorType("Recursive dependency")) {
@Override
protected JetType compute() {
JetFlowInformationProvider flowInformationProvider = computeFlowData(property, initializer);
return semanticServices.getTypeInferrerServices(trace, flowInformationProvider).safeGetType(scope, initializer, JetTypeInferrer.NO_EXPECTED_TYPE);
//JetFlowInformationProvider flowInformationProvider = computeFlowData(property, initializer);
return semanticServices.getTypeInferrerServices(trace).safeGetType(scope, initializer, JetTypeInferrer.NO_EXPECTED_TYPE);
}
};
if (allowDeferred) {
@@ -0,0 +1,114 @@
package org.jetbrains.jet.lang.resolve;
import com.google.common.collect.Lists;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider;
import org.jetbrains.jet.lang.descriptors.ConstructorDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptor;
import org.jetbrains.jet.lang.descriptors.FunctionDescriptorImpl;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import org.jetbrains.jet.lang.types.JetStandardClasses;
import org.jetbrains.jet.lang.types.JetType;
import org.jetbrains.jet.lang.types.JetTypeInferrer;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.types.JetTypeInferrer.NO_EXPECTED_TYPE;
/**
* @author svtk
*/
public class ControlFlowAnalyzer {
private TopDownAnalysisContext context;
private JetTypeInferrer.Services typeInferrer;
public ControlFlowAnalyzer(TopDownAnalysisContext context) {
this.context = context;
typeInferrer = context.getSemanticServices().getTypeInferrerServices(context.getTrace());
}
public void process() {
for (Map.Entry<JetNamedFunction, FunctionDescriptorImpl> entry : context.getFunctions().entrySet()) {
JetNamedFunction function = entry.getKey();
FunctionDescriptorImpl functionDescriptor = entry.getValue();
final JetType expectedReturnType = !function.hasBlockBody() && !function.hasDeclaredReturnType() ? NO_EXPECTED_TYPE : functionDescriptor.getReturnType();
checkFunction(function, functionDescriptor, expectedReturnType);
}
for (Map.Entry<JetDeclaration, ConstructorDescriptor> entry : this.context.getConstructors().entrySet()) {
JetDeclaration declaration = entry.getKey();
assert declaration instanceof JetConstructor;
JetConstructor constructor = (JetConstructor) declaration;
ConstructorDescriptor descriptor = entry.getValue();
checkFunction(constructor, descriptor, JetStandardClasses.getUnitType());
}
for (JetProperty property : context.getProperties().keySet()) {
checkProperty(property);
}
}
private void checkFunction(JetDeclarationWithBody function, FunctionDescriptor functionDescriptor, final @NotNull JetType expectedReturnType) {
JetExpression bodyExpression = function.getBodyExpression();
if (bodyExpression == null) return;
JetFlowInformationProvider flowInformationProvider = context.getClassDescriptorResolver().computeFlowData((JetElement) function, bodyExpression);
final boolean blockBody = function.hasBlockBody();
List<JetElement> unreachableElements = Lists.newArrayList();
flowInformationProvider.collectUnreachableExpressions(function.asElement(), unreachableElements);
// This is needed in order to highlight only '1 < 2' and not '1', '<' and '2' as well
final Set<JetElement> rootUnreachableElements = JetPsiUtil.findRootExpressions(unreachableElements);
for (JetElement element : rootUnreachableElements) {
context.getTrace().report(UNREACHABLE_CODE.on(element));
}
List<JetExpression> returnedExpressions = Lists.newArrayList();
flowInformationProvider.collectReturnExpressions(function.asElement(), returnedExpressions);
boolean nothingReturned = returnedExpressions.isEmpty();
returnedExpressions.remove(function); // This will be the only "expression" if the body is empty
final JetScope scope = this.context.getDeclaringScopes().get(function);
if (expectedReturnType != NO_EXPECTED_TYPE && !JetStandardClasses.isUnit(expectedReturnType) && returnedExpressions.isEmpty() && !nothingReturned) {
context.getTrace().report(RETURN_TYPE_MISMATCH.on(bodyExpression, expectedReturnType));
}
for (JetExpression returnedExpression : returnedExpressions) {
returnedExpression.accept(new JetVisitorVoid() {
@Override
public void visitReturnExpression(JetReturnExpression expression) {
if (!blockBody) {
context.getTrace().report(RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY.on(expression));
}
}
@Override
public void visitExpression(JetExpression expression) {
if (blockBody && expectedReturnType != NO_EXPECTED_TYPE && !JetStandardClasses.isUnit(expectedReturnType) && !rootUnreachableElements.contains(expression)) {
JetType type = typeInferrer.getType(scope, expression, expectedReturnType);
if (type == null || !JetStandardClasses.isNothing(type)) {
context.getTrace().report(NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY.on(expression));
}
}
}
});
}
}
private void checkProperty(JetProperty property) {
JetExpression initializer = property.getInitializer();
if (initializer == null) return;
context.getClassDescriptorResolver().computeFlowData(property, initializer);
}
}
@@ -69,6 +69,7 @@ public class TopDownAnalyzer {
new OverrideResolver(context).process();
new BodyResolver(context).resolveBehaviorDeclarationBodies();
new DeclarationsChecker(context).process();
new ControlFlowAnalyzer(context).process();
}
public static void processStandardLibraryNamespace(
@@ -218,7 +218,7 @@ public class TypeHierarchyResolver {
if (importDirective.isAllUnder()) {
JetExpression importedReference = importDirective.getImportedReference();
if (importedReference != null) {
JetTypeInferrer.Services typeInferrerServices = context.getSemanticServices().getTypeInferrerServices(context.getTrace(), JetFlowInformationProvider.THROW_EXCEPTION);
JetTypeInferrer.Services typeInferrerServices = context.getSemanticServices().getTypeInferrerServices(context.getTrace());
JetType type = typeInferrerServices.getTypeWithNamespaces(namespaceScope, importedReference);
if (type != null) {
namespaceScope.importScope(type.getMemberScope());
@@ -233,7 +233,7 @@ public class TypeHierarchyResolver {
JetExpression importedReference = importDirective.getImportedReference();
if (importedReference instanceof JetDotQualifiedExpression) {
JetDotQualifiedExpression reference = (JetDotQualifiedExpression) importedReference;
JetType type = context.getSemanticServices().getTypeInferrerServices(context.getTrace(), JetFlowInformationProvider.THROW_EXCEPTION).getTypeWithNamespaces(namespaceScope, reference.getReceiverExpression());
JetType type = context.getSemanticServices().getTypeInferrerServices(context.getTrace()).getTypeWithNamespaces(namespaceScope, reference.getReceiverExpression());
JetExpression selectorExpression = reference.getSelectorExpression();
if (selectorExpression != null) {
referenceExpression = (JetSimpleNameExpression) selectorExpression;
@@ -312,8 +312,7 @@ public class JetStandardLibrary {
@NotNull
public JetType getArrayType(@NotNull JetType argument) {
Variance variance = Variance.INVARIANT;
return getArrayType(variance, argument);
return getArrayType(Variance.INVARIANT, argument);
}
@NotNull
@@ -12,7 +12,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.JetNodeTypes;
import org.jetbrains.jet.lang.JetSemanticServices;
import org.jetbrains.jet.lang.cfg.JetFlowInformationProvider;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
@@ -175,14 +174,16 @@ public class JetTypeInferrer {
}
private final JetSemanticServices semanticServices;
private final JetFlowInformationProvider flowInformationProvider;
// private final JetFlowInformationProvider flowInformationProvider;
private final Map<JetPattern, DataFlowInfo> patternsToDataFlowInfo = Maps.newHashMap();
private final Map<JetPattern, List<VariableDescriptor>> patternsToBoundVariableLists = Maps.newHashMap();
private final LabelsResolver labelsResolver = new LabelsResolver();
public JetTypeInferrer(@NotNull JetFlowInformationProvider flowInformationProvider, @NotNull JetSemanticServices semanticServices) {
public JetTypeInferrer(@NotNull JetSemanticServices semanticServices) {
this.semanticServices = semanticServices;
this.flowInformationProvider = flowInformationProvider;
// this.flowInformationProvider = flowInformationProvider;
}
public Services getServices(@NotNull BindingTrace trace) {
@@ -269,7 +270,7 @@ public class JetTypeInferrer {
expectedReturnType = NO_EXPECTED_TYPE;
}
JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(outerScope, functionDescriptor, trace);
checkFunctionReturnType(functionInnerScope, function, expectedReturnType, dataFlowInfo);
checkFunctionReturnType(functionInnerScope, function, functionDescriptor, expectedReturnType, dataFlowInfo);
// Map<JetElement, JetType> typeMap = collectReturnedExpressionsWithTypes(outerScope, function, functionDescriptor, expectedReturnType);
// if (typeMap.isEmpty()) {
// return; // The function returns Nothing
@@ -303,11 +304,11 @@ public class JetTypeInferrer {
// }
}
public void checkFunctionReturnType(JetScope functionInnerScope, JetDeclarationWithBody function, @NotNull final JetType expectedReturnType) {
checkFunctionReturnType(functionInnerScope, function, expectedReturnType, DataFlowInfo.getEmpty());
public void checkFunctionReturnType(JetScope functionInnerScope, JetDeclarationWithBody function, FunctionDescriptor functionDescriptor, @NotNull final JetType expectedReturnType) {
checkFunctionReturnType(functionInnerScope, function, functionDescriptor, expectedReturnType, DataFlowInfo.getEmpty());
}
private void checkFunctionReturnType(JetScope functionInnerScope, JetDeclarationWithBody function, @NotNull final JetType expectedReturnType, @NotNull DataFlowInfo dataFlowInfo) {
private void checkFunctionReturnType(JetScope functionInnerScope, JetDeclarationWithBody function, FunctionDescriptor functionDescriptor, @NotNull final JetType expectedReturnType, @NotNull DataFlowInfo dataFlowInfo) {
JetExpression bodyExpression = function.getBodyExpression();
if (bodyExpression == null) return;
@@ -325,56 +326,62 @@ public class JetTypeInferrer {
typeInferrerVisitor.getType(bodyExpression, context);
}
List<JetElement> unreachableElements = Lists.newArrayList();
flowInformationProvider.collectUnreachableExpressions(function.asElement(), unreachableElements);
// List<JetElement> unreachableElements = Lists.newArrayList();
// flowInformationProvider.collectUnreachableExpressions(function.asElement(), unreachableElements);
// This is needed in order to highlight only '1 < 2' and not '1', '<' and '2' as well
final Set<JetElement> rootUnreachableElements = JetPsiUtil.findRootExpressions(unreachableElements);
// final Set<JetElement> rootUnreachableElements = JetPsiUtil.findRootExpressions(unreachableElements);
// TODO : (return 1) || (return 2) -- only || and right of it is unreachable
// TODO : try {return 1} finally {return 2}. Currently 'return 1' is reported as unreachable,
// though it'd better be reported more specifically
for (JetElement element : rootUnreachableElements) {
// trace.getErrorHandler().genericError(element.getNode(), "Unreachable code");
trace.report(UNREACHABLE_CODE.on(element));
}
// for (JetElement element : rootUnreachableElements) {
// //trace.report(UNREACHABLE_CODE.on(element));
// }
List<JetExpression> returnedExpressions = Lists.newArrayList();
flowInformationProvider.collectReturnExpressions(function.asElement(), returnedExpressions);
// List<JetExpression> returnedExpressions = Lists.newArrayList();
// flowInformationProvider.collectReturnExpressions(function.asElement(), returnedExpressions);
boolean nothingReturned = returnedExpressions.isEmpty();
// boolean nothingReturned = returnedExpressions.isEmpty();
returnedExpressions.remove(function); // This will be the only "expression" if the body is empty
//returnedExpressions.remove(function); // This will be the only "expression" if the body is empty
// Map<JetExpression, JetType> typeMap = collectReturnedExpressionsWithTypes(trace, functionInnerScope, function, functionDescriptor);
// Set<JetExpression> returnedExpressions = typeMap.keySet();
//
//
// if (expectedReturnType != NO_EXPECTED_TYPE && !JetStandardClasses.isUnit(expectedReturnType) && returnedExpressions.isEmpty()) {
// trace.report(RETURN_TYPE_MISMATCH.on(bodyExpression, expectedReturnType));
// }
if (expectedReturnType != NO_EXPECTED_TYPE && !JetStandardClasses.isUnit(expectedReturnType) && returnedExpressions.isEmpty() && !nothingReturned) {
// trace.getErrorHandler().genericError(bodyExpression.getNode(), "This function must return a value of type " + expectedReturnType);
trace.report(RETURN_TYPE_MISMATCH.on(bodyExpression, expectedReturnType));
}
for (JetExpression returnedExpression : returnedExpressions) {
returnedExpression.accept(new JetVisitorVoid() {
@Override
public void visitReturnExpression(JetReturnExpression expression) {
if (!blockBody) {
// trace.getErrorHandler().genericError(expression.getNode(), "Returns are not allowed for functions with expression body. Use block body in '{...}'");
trace.report(RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY.on(expression));
}
}
@Override
public void visitExpression(JetExpression expression) {
if (blockBody && !JetStandardClasses.isUnit(expectedReturnType) && !rootUnreachableElements.contains(expression)) {
//TODO move to pseudocode
JetType type = typeInferrerVisitor.getType(expression, context.replaceExpectedType(NO_EXPECTED_TYPE));
if (type == null || !JetStandardClasses.isNothing(type)) {
// trace.getErrorHandler().genericError(expression.getNode(), "A 'return' expression required in a function with a block body ('{...}')");
trace.report(NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY.on(expression));
}
}
}
});
}
// if (expectedReturnType != NO_EXPECTED_TYPE && !JetStandardClasses.isUnit(expectedReturnType) && returnedExpressions.isEmpty() && !nothingReturned) {
//// trace.getErrorHandler().genericError(bodyExpression.getNode(), "This function must return a value of type " + expectedReturnType);
// trace.report(RETURN_TYPE_MISMATCH.on(bodyExpression, expectedReturnType));
// }
//
// for (JetExpression returnedExpression : returnedExpressions) {
// returnedExpression.accept(new JetVisitorVoid() {
// @Override
// public void visitReturnExpression(JetReturnExpression expression) {
// if (!blockBody) {
//// trace.getErrorHandler().genericError(expression.getNode(), "Returns are not allowed for functions with expression body. Use block body in '{...}'");
// trace.report(RETURN_IN_FUNCTION_WITH_EXPRESSION_BODY.on(expression));
// }
// }
//
// @Override
// public void visitExpression(JetExpression expression) {
// if (blockBody && !JetStandardClasses.isUnit(expectedReturnType) && !rootUnreachableElements.contains(expression)) {
// //TODO move to pseudocode
// JetType type = typeInferrerVisitor.getType(expression, context.replaceExpectedType(NO_EXPECTED_TYPE));
// if (type == null || !JetStandardClasses.isNothing(type)) {
//// trace.getErrorHandler().genericError(expression.getNode(), "A 'return' expression required in a function with a block body ('{...}')");
// trace.report(NO_RETURN_IN_FUNCTION_WITH_BLOCK_BODY.on(expression));
// }
// }
// }
// });
// }
}
@Nullable
@@ -391,26 +398,52 @@ public class JetTypeInferrer {
@NotNull
public JetType inferFunctionReturnType(@NotNull JetScope outerScope, JetDeclarationWithBody function, FunctionDescriptor functionDescriptor) {
Map<JetElement, JetType> typeMap = collectReturnedExpressionsWithTypes(trace, outerScope, function, functionDescriptor);
Map<JetExpression, JetType> typeMap = collectReturnedExpressionsWithTypes(trace, outerScope, function, functionDescriptor);
Collection<JetType> types = typeMap.values();
return types.isEmpty()
? JetStandardClasses.getNothingType()
: semanticServices.getTypeChecker().commonSupertype(types);
}
private Map<JetElement, JetType> collectReturnedExpressionsWithTypes(
@NotNull BindingTrace trace,
private Map<JetExpression, JetType> collectReturnedExpressionsWithTypes(
final @NotNull BindingTrace trace,
JetScope outerScope,
JetDeclarationWithBody function,
final JetDeclarationWithBody function,
FunctionDescriptor functionDescriptor) {
JetExpression bodyExpression = function.getBodyExpression();
assert bodyExpression != null;
JetScope functionInnerScope = FunctionDescriptorUtil.getFunctionInnerScope(outerScope, functionDescriptor, trace);
typeInferrerVisitor.getType(bodyExpression, newContext(trace, functionInnerScope, DataFlowInfo.getEmpty(), NO_EXPECTED_TYPE, FORBIDDEN));
Collection<JetExpression> returnedExpressions = new ArrayList<JetExpression>();
Collection<JetElement> elementsReturningUnit = new ArrayList<JetElement>();
flowInformationProvider.collectReturnedInformation(function.asElement(), returnedExpressions, elementsReturningUnit);
Map<JetElement,JetType> typeMap = new HashMap<JetElement, JetType>();
//todo function literals
final Collection<JetExpression> returnedExpressions = new ArrayList<JetExpression>();
if (function.hasBlockBody()) {
//now this code is never invoked!, it should be invoked for inference of return type of function literal with local returns
bodyExpression.visit(new JetTreeVisitor<JetDeclarationWithBody>() {
@Override
public Void visitReturnExpression(JetReturnExpression expression, JetDeclarationWithBody outerFunction) {
JetSimpleNameExpression targetLabel = expression.getTargetLabel();
PsiElement element = targetLabel != null ? trace.get(LABEL_TARGET, targetLabel) : null;
if (element == function || (targetLabel == null && outerFunction == function)) {
returnedExpressions.add(expression);
}
return null;
}
@Override
public Void visitFunctionLiteralExpression(JetFunctionLiteralExpression expression, JetDeclarationWithBody outerFunction) {
return super.visitFunctionLiteralExpression(expression, expression.getFunctionLiteral());
}
@Override
public Void visitNamedFunction(JetNamedFunction function, JetDeclarationWithBody outerFunction) {
return super.visitNamedFunction(function, function);
}
}, function);
}
else {
returnedExpressions.add(bodyExpression);
}
Map<JetExpression, JetType> typeMap = new HashMap<JetExpression, JetType>();
for (JetExpression returnedExpression : returnedExpressions) {
JetType cachedType = trace.getBindingContext().get(BindingContext.EXPRESSION_TYPE, returnedExpression);
trace.record(STATEMENT, returnedExpression, false);
@@ -418,9 +451,6 @@ public class JetTypeInferrer {
typeMap.put(returnedExpression, cachedType);
}
}
for (JetElement jetElement : elementsReturningUnit) {
typeMap.put(jetElement, JetStandardClasses.getUnitType());
}
return typeMap;
}
@@ -438,35 +468,57 @@ public class JetTypeInferrer {
trace.record(STATEMENT, statement);
final JetExpression statementExpression = (JetExpression) statement;
//TODO constructor assert context.expectedType != FORBIDDEN : ""
if (!iterator.hasNext() && context.expectedType != NO_EXPECTED_TYPE) {
if (coercionStrategyForLastExpression == CoercionStrategy.COERCION_TO_UNIT && JetStandardClasses.isUnit(context.expectedType)) {
// This implements coercion to Unit
TemporaryBindingTrace temporaryTraceExpectingUnit = TemporaryBindingTrace.create(trace);
final boolean[] mismatch = new boolean[1];
ObservableBindingTrace errorInterceptingTrace = makeTraceInterceptingTypeMismatch(temporaryTraceExpectingUnit, statementExpression, mismatch);
newContext = newContext(errorInterceptingTrace, scope, newContext.dataFlowInfo, context.expectedType, context.expectedReturnType);
result = blockLevelVisitor.getType(statementExpression, newContext);
if (mismatch[0]) {
TemporaryBindingTrace temporaryTraceNoExpectedType = TemporaryBindingTrace.create(trace);
mismatch[0] = false;
ObservableBindingTrace interceptingTrace = makeTraceInterceptingTypeMismatch(temporaryTraceNoExpectedType, statementExpression, mismatch);
newContext = newContext(interceptingTrace, scope, newContext.dataFlowInfo, NO_EXPECTED_TYPE, context.expectedReturnType);
if (!iterator.hasNext()) {
if (context.expectedType != NO_EXPECTED_TYPE) {
if (coercionStrategyForLastExpression == CoercionStrategy.COERCION_TO_UNIT && JetStandardClasses.isUnit(context.expectedType)) {
// This implements coercion to Unit
TemporaryBindingTrace temporaryTraceExpectingUnit = TemporaryBindingTrace.create(trace);
final boolean[] mismatch = new boolean[1];
ObservableBindingTrace errorInterceptingTrace = makeTraceInterceptingTypeMismatch(temporaryTraceExpectingUnit, statementExpression, mismatch);
newContext = newContext(errorInterceptingTrace, scope, newContext.dataFlowInfo, context.expectedType, context.expectedReturnType);
result = blockLevelVisitor.getType(statementExpression, newContext);
if (mismatch[0]) {
temporaryTraceExpectingUnit.commit();
TemporaryBindingTrace temporaryTraceNoExpectedType = TemporaryBindingTrace.create(trace);
mismatch[0] = false;
ObservableBindingTrace interceptingTrace = makeTraceInterceptingTypeMismatch(temporaryTraceNoExpectedType, statementExpression, mismatch);
newContext = newContext(interceptingTrace, scope, newContext.dataFlowInfo, NO_EXPECTED_TYPE, context.expectedReturnType);
result = blockLevelVisitor.getType(statementExpression, newContext);
if (mismatch[0]) {
temporaryTraceExpectingUnit.commit();
}
else {
temporaryTraceNoExpectedType.commit();
}
}
else {
temporaryTraceNoExpectedType.commit();
temporaryTraceExpectingUnit.commit();
}
}
else {
temporaryTraceExpectingUnit.commit();
newContext = newContext(trace, scope, newContext.dataFlowInfo, context.expectedType, context.expectedReturnType);
result = blockLevelVisitor.getType(statementExpression, newContext);
}
}
else {
newContext = newContext(trace, scope, newContext.dataFlowInfo, context.expectedType, context.expectedReturnType);
result = blockLevelVisitor.getType(statementExpression, newContext);
if (coercionStrategyForLastExpression == CoercionStrategy.COERCION_TO_UNIT) {
boolean mightBeUnit = false;
if (statementExpression instanceof JetDeclaration) {
mightBeUnit = true;
}
if (statementExpression instanceof JetBinaryExpression) {
JetBinaryExpression binaryExpression = (JetBinaryExpression) statementExpression;
IElementType operationType = binaryExpression.getOperationToken();
if (operationType == JetTokens.EQ || assignmentOperationNames.containsKey(operationType)) {
mightBeUnit = true;
}
}
if (mightBeUnit) {
// TypeInferrerVisitorWithWritableScope should return only null or Unit for declarations and assignments
assert result == null || JetStandardClasses.isUnit(result);
result = JetStandardClasses.getUnitType();
}
}
}
}
else {
@@ -712,7 +764,6 @@ public class JetTypeInferrer {
}
private class TypeInferrerVisitor extends JetVisitor<JetType, TypeInferenceContext> {
protected DataFlowInfo resultDataFlowInfo;
@Nullable
@@ -761,10 +812,11 @@ public class JetTypeInferrer {
}
if (result != null) {
context.trace.record(BindingContext.EXPRESSION_TYPE, expression, result);
if (JetStandardClasses.isNothing(result) && !result.isNullable()) {
markDominatedExpressionsAsUnreachable(expression, context);
}
// if (JetStandardClasses.isNothing(result) && !result.isNullable()) {
// markDominatedExpressionsAsUnreachable(expression, context);
// }
}
// }
}
catch (ReenteringLazyValueComputationException e) {
// context.trace.getErrorHandler().genericError(expression.getNode(), "Type checking has run into a recursive problem"); // TODO : message
@@ -792,16 +844,16 @@ public class JetTypeInferrer {
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
private void markDominatedExpressionsAsUnreachable(JetExpression expression, TypeInferenceContext context) {
List<JetElement> dominated = new ArrayList<JetElement>();
flowInformationProvider.collectDominatedExpressions(expression, dominated);
Set<JetElement> rootExpressions = JetPsiUtil.findRootExpressions(dominated);
for (JetElement rootExpression : rootExpressions) {
// context.trace.getErrorHandler().genericError(rootExpression.getNode(),
// "This code is unreachable, because '" + expression.getText() + "' never terminates normally");
context.trace.report(UNREACHABLE_BECAUSE_OF_NOTHING.on(rootExpression, expression.getText()));
}
}
// private void markDominatedExpressionsAsUnreachable(JetExpression expression, TypeInferenceContext context) {
// List<JetElement> dominated = new ArrayList<JetElement>();
// flowInformationProvider.collectDominatedExpressions(expression, dominated);
// Set<JetElement> rootExpressions = JetPsiUtil.findRootExpressions(dominated);
// for (JetElement rootExpression : rootExpressions) {
//// context.trace.getErrorHandler().genericError(rootExpression.getNode(),
//// "This code is unreachable, because '" + expression.getText() + "' never terminates normally");
// context.trace.report(UNREACHABLE_BECAUSE_OF_NOTHING.on(rootExpression, expression.getText()));
// }
// }
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -1031,7 +1083,7 @@ public class JetTypeInferrer {
JetTypeReference returnTypeRef = functionLiteral.getReturnTypeRef();
if (returnTypeRef != null) {
returnType = context.typeResolver.resolveType(context.scope, returnTypeRef);
context.services.checkFunctionReturnType(functionInnerScope, expression, returnType, context.dataFlowInfo);
context.services.checkFunctionReturnType(functionInnerScope, expression, functionDescriptor, returnType, context.dataFlowInfo);
}
else {
if (functionTypeExpected) {
@@ -1045,6 +1097,7 @@ public class JetTypeInferrer {
if (functionTypeExpected) {
JetType expectedReturnType = JetStandardClasses.getReturnType(expectedType);
if (JetStandardClasses.isUnit(expectedReturnType)) {
functionDescriptor.setReturnType(expectedReturnType);
return context.services.checkType(JetStandardClasses.getFunctionType(Collections.<AnnotationDescriptor>emptyList(), effectiveReceiverType, parameterTypes, expectedReturnType), expression, context);
}
@@ -1140,6 +1193,7 @@ public class JetTypeInferrer {
@Override
public JetType visitReturnExpression(JetReturnExpression expression, TypeInferenceContext context) {
labelsResolver.recordLabel(expression, context);
if (context.expectedReturnType == FORBIDDEN) {
// context.trace.getErrorHandler().genericError(expression.getNode(), "'return' is not allowed here");
context.trace.report(RETURN_NOT_ALLOWED.on(expression));
@@ -1162,11 +1216,13 @@ public class JetTypeInferrer {
@Override
public JetType visitBreakExpression(JetBreakExpression expression, TypeInferenceContext context) {
labelsResolver.recordLabel(expression, context);
return context.services.checkType(JetStandardClasses.getNothingType(), expression, context);
}
@Override
public JetType visitContinueExpression(JetContinueExpression expression, TypeInferenceContext context) {
labelsResolver.recordLabel(expression, context);
return context.services.checkType(JetStandardClasses.getNothingType(), expression, context);
}
@@ -1286,50 +1342,7 @@ public class JetTypeInferrer {
ReceiverDescriptor thisReceiver = null;
String labelName = expression.getLabelName();
if (labelName != null) {
Collection<DeclarationDescriptor> declarationsByLabel = context.scope.getDeclarationsByLabel(labelName);
int size = declarationsByLabel.size();
final JetSimpleNameExpression targetLabel = expression.getTargetLabel();
assert targetLabel != null;
if (size == 1) {
DeclarationDescriptor declarationDescriptor = declarationsByLabel.iterator().next();
if (declarationDescriptor instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor;
thisReceiver = classDescriptor.getImplicitReceiver();
}
else if (declarationDescriptor instanceof FunctionDescriptor) {
FunctionDescriptor functionDescriptor = (FunctionDescriptor) declarationDescriptor;
thisReceiver = functionDescriptor.getReceiverParameter();
}
else {
throw new UnsupportedOperationException(); // TODO
}
context.trace.record(REFERENCE_TARGET, targetLabel, declarationDescriptor);
context.trace.record(REFERENCE_TARGET, expression.getThisReference(), declarationDescriptor);
}
else if (size == 0) {
// This uses the info written by the control flow processor
PsiElement psiElement = BindingContextUtils.resolveToDeclarationPsiElement(context.trace.getBindingContext(), targetLabel);
if (psiElement instanceof JetFunctionLiteralExpression) {
DeclarationDescriptor declarationDescriptor = context.trace.getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, psiElement);
if (declarationDescriptor instanceof FunctionDescriptor) {
thisReceiver = ((FunctionDescriptor) declarationDescriptor).getReceiverParameter();
if (thisReceiver.exists()) {
context.trace.record(REFERENCE_TARGET, targetLabel, declarationDescriptor);
context.trace.record(REFERENCE_TARGET, expression.getThisReference(), declarationDescriptor);
}
}
else {
context.trace.report(UNRESOLVED_REFERENCE.on(targetLabel));
}
}
else {
context.trace.report(UNRESOLVED_REFERENCE.on(targetLabel));
}
}
else {
// context.trace.getErrorHandler().genericError(targetLabel.getNode(), "Ambiguous label");
context.trace.report(AMBIGUOUS_LABEL.on(targetLabel));
}
thisReceiver = labelsResolver.resolveThisLabel(expression, context, thisReceiver, labelName);
}
else {
thisReceiver = context.scope.getImplicitReceiver();
@@ -1861,12 +1874,36 @@ public class JetTypeInferrer {
DataFlowInfo conditionInfo = condition == null ? context.dataFlowInfo : extractDataFlowInfoFromCondition(condition, true, scopeToExtend, context);
getTypeWithNewScopeAndDataFlowInfo(scopeToExtend, body, conditionInfo, context);
}
if (!flowInformationProvider.isBreakable(expression)) {
if (!containsBreak(expression, context)) {
// resultScope = newWritableScopeImpl();
resultDataFlowInfo = extractDataFlowInfoFromCondition(condition, false, null, context);
}
return context.services.checkType(JetStandardClasses.getUnitType(), expression, contextWithExpectedType);
}
private boolean containsBreak(final JetLoopExpression loopExpression, final TypeInferenceContext context) {
final boolean[] result = new boolean[1];
result[0] = false;
//todo breaks in inline function literals
loopExpression.visit(new JetTreeVisitor<JetLoopExpression>() {
@Override
public Void visitBreakExpression(JetBreakExpression breakExpression, JetLoopExpression outerLoop) {
JetSimpleNameExpression targetLabel = breakExpression.getTargetLabel();
PsiElement element = targetLabel != null ? context.trace.get(LABEL_TARGET, targetLabel) : null;
if (element == loopExpression || (targetLabel == null && outerLoop == loopExpression)) {
result[0] = true;
}
return null;
}
@Override
public Void visitLoopExpression(JetLoopExpression loopExpression, JetLoopExpression outerLoop) {
return super.visitLoopExpression(loopExpression, loopExpression);
}
}, loopExpression);
return result[0];
}
@Override
public JetType visitDoWhileExpression(JetDoWhileExpression expression, TypeInferenceContext contextWithExpectedType) {
@@ -1891,7 +1928,7 @@ public class JetTypeInferrer {
}
JetExpression condition = expression.getCondition();
checkCondition(conditionScope, condition, context);
if (!flowInformationProvider.isBreakable(expression)) {
if (!containsBreak(expression, context)) {
// resultScope = newWritableScopeImpl();
resultDataFlowInfo = extractDataFlowInfoFromCondition(condition, false, null, context);
}
@@ -2276,8 +2313,13 @@ public class JetTypeInferrer {
if (baseExpression == null) return null;
JetSimpleNameExpression operationSign = expression.getOperationSign();
if (JetTokens.LABELS.contains(operationSign.getReferencedNameElementType())) {
String referencedName = operationSign.getReferencedName();
referencedName = referencedName == null ? " <?>" : referencedName;
labelsResolver.enterLabeledElement(referencedName.substring(1), baseExpression);
// TODO : Some processing for the label?
return context.services.checkType(getType(baseExpression, context.replaceExpectedReturnType(context.expectedType)), expression, context);
JetType type = context.services.checkType(getType(baseExpression, context.replaceExpectedReturnType(context.expectedType)), expression, context);
labelsResolver.exitLabeledElement(baseExpression);
return type;
}
IElementType operationType = operationSign.getReferencedNameElementType();
String name = unaryOperationNames.get(operationType);
@@ -2318,6 +2360,7 @@ public class JetTypeInferrer {
else {
result = returnType;
}
return context.services.checkType(result, expression, context);
}
@@ -2341,10 +2384,10 @@ public class JetTypeInferrer {
result = getTypeForBinaryCall(context.scope, binaryOperationNames.get(operationType), context, expression);
}
else if (operationType == JetTokens.EQ) {
result = visitAssignment(expression, context);
result = visitAssignment(expression, contextWithExpectedType);
}
else if (assignmentOperationNames.containsKey(operationType)) {
result = visitAssignmentOperation(expression, context);
result = visitAssignmentOperation(expression, contextWithExpectedType);
}
else if (comparisonOperations.contains(operationType)) {
JetType compareToReturnType = getTypeForBinaryCall(context.scope, "compareTo", context, expression);
@@ -2658,7 +2701,7 @@ public class JetTypeInferrer {
PropertyDescriptor propertyDescriptor = context.classDescriptorResolver.resolveObjectDeclarationAsPropertyDescriptor(scope.getContainingDeclaration(), declaration, classDescriptor);
scope.addVariableDescriptor(propertyDescriptor);
}
return null;
return checkExpectedType(declaration, context);
}
@Override
@@ -2694,7 +2737,7 @@ public class JetTypeInferrer {
}
scope.addVariableDescriptor(propertyDescriptor);
return null;
return checkExpectedType(property, context);
}
@Override
@@ -2702,7 +2745,7 @@ public class JetTypeInferrer {
FunctionDescriptorImpl functionDescriptor = context.classDescriptorResolver.resolveFunctionDescriptor(scope.getContainingDeclaration(), scope, function);
scope.addFunctionDescriptor(functionDescriptor);
context.services.checkFunctionReturnType(context.scope, function, functionDescriptor, context.dataFlowInfo);
return null;
return checkExpectedType(function, context);
}
@Override
@@ -2717,7 +2760,7 @@ public class JetTypeInferrer {
@Override
public JetType visitDeclaration(JetDeclaration dcl, TypeInferenceContext context) {
return visitJetElement(dcl, context);
return checkExpectedType(dcl, context);
}
@Override
@@ -2739,6 +2782,17 @@ public class JetTypeInferrer {
else {
temporaryBindingTrace.commit();
}
return checkExpectedType(expression, context);
}
@Nullable
private JetType checkExpectedType(JetExpression expression, TypeInferenceContext context) {
if (context.expectedType != NO_EXPECTED_TYPE) {
if (JetStandardClasses.isUnit(context.expectedType)) {
return JetStandardClasses.getUnitType();
}
context.trace.report(EXPECTED_TYPE_MISMATCH.on(expression, context.expectedType));
}
return null;
}
@@ -2771,7 +2825,7 @@ public class JetTypeInferrer {
}
}
}
return null;
return checkExpectedType(expression, context);
}
private JetType resolveArrayAccessToLValue(JetArrayAccessExpression arrayAccessExpression, JetExpression rightHandSide, JetSimpleNameExpression operationSign, TypeInferenceContext context) {
@@ -2794,6 +2848,11 @@ public class JetTypeInferrer {
return context.services.checkType(functionDescriptor.getReturnType(), arrayAccessExpression, context);
}
@Override
public JetType visitAnnotatedExpression(JetAnnotatedExpression expression, TypeInferenceContext data) {
return getType(expression.getBaseExpression(), data);
}
@Override
public JetType visitJetElement(JetElement element, TypeInferenceContext context) {
context.trace.report(UNSUPPORTED.on(element, "in a block"));
@@ -2801,4 +2860,135 @@ public class JetTypeInferrer {
return null;
}
}
private class LabelsResolver {
private final Map<String, Stack<JetElement>> labeledElements = new HashMap<String, Stack<JetElement>>();
public void enterLabeledElement(@NotNull String labelName, @NotNull JetExpression labeledExpression) {
JetExpression deparenthesized = JetPsiUtil.deparenthesize(labeledExpression);
if (deparenthesized != null) {
Stack<JetElement> stack = labeledElements.get(labelName);
if (stack == null) {
stack = new Stack<JetElement>();
labeledElements.put(labelName, stack);
}
stack.push(deparenthesized);
}
}
public void exitLabeledElement(@NotNull JetExpression expression) {
JetExpression deparenthesized = JetPsiUtil.deparenthesize(expression);
// TODO : really suboptimal
for (Iterator<Map.Entry<String, Stack<JetElement>>> mapIter = labeledElements.entrySet().iterator(); mapIter.hasNext(); ) {
Map.Entry<String, Stack<JetElement>> entry = mapIter.next();
Stack<JetElement> stack = entry.getValue();
for (Iterator<JetElement> stackIter = stack.iterator(); stackIter.hasNext(); ) {
JetElement recorded = stackIter.next();
if (recorded == deparenthesized) {
stackIter.remove();
}
}
if (stack.isEmpty()) {
mapIter.remove();
}
}
}
private JetElement resolveControlLabel(@NotNull String labelName, @NotNull JetSimpleNameExpression labelExpression, boolean reportUnresolved, TypeInferenceContext context) {
Collection<DeclarationDescriptor> declarationsByLabel = context.scope.getDeclarationsByLabel(labelName);
int size = declarationsByLabel.size();
if (size == 1) {
DeclarationDescriptor declarationDescriptor = declarationsByLabel.iterator().next();
JetElement element;
if (declarationDescriptor instanceof FunctionDescriptor || declarationDescriptor instanceof ClassDescriptor) {
element = (JetElement) context.trace.get(BindingContext.DESCRIPTOR_TO_DECLARATION, declarationDescriptor);
}
else {
throw new UnsupportedOperationException(); // TODO
}
context.trace.record(LABEL_TARGET, labelExpression, element);
return element;
}
else if (size == 0) {
return resolveNamedLabel(labelName, labelExpression, reportUnresolved, context);
}
context.trace.report(AMBIGUOUS_LABEL.on(labelExpression));
return null;
}
public void recordLabel(JetLabelQualifiedExpression expression, TypeInferenceContext context) {
JetSimpleNameExpression labelElement = expression.getTargetLabel();
if (labelElement != null) {
String labelName = expression.getLabelName();
assert labelName != null;
resolveControlLabel(labelName, labelElement, true, context);
}
}
private JetElement resolveNamedLabel(@NotNull String labelName, @NotNull JetSimpleNameExpression labelExpression, boolean reportUnresolved, TypeInferenceContext context) {
Stack<JetElement> stack = labeledElements.get(labelName);
if (stack == null || stack.isEmpty()) {
if (reportUnresolved) {
context.trace.report(UNRESOLVED_REFERENCE.on(labelExpression));
}
return null;
}
else if (stack.size() > 1) {
context.trace.report(LABEL_NAME_CLASH.on(labelExpression));
}
JetElement result = stack.peek();
context.trace.record(BindingContext.LABEL_TARGET, labelExpression, result);
return result;
}
public ReceiverDescriptor resolveThisLabel(JetThisExpression expression, TypeInferenceContext context, ReceiverDescriptor thisReceiver, String labelName) {
Collection<DeclarationDescriptor> declarationsByLabel = context.scope.getDeclarationsByLabel(labelName);
int size = declarationsByLabel.size();
final JetSimpleNameExpression targetLabel = expression.getTargetLabel();
assert targetLabel != null;
if (size == 1) {
DeclarationDescriptor declarationDescriptor = declarationsByLabel.iterator().next();
if (declarationDescriptor instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor;
thisReceiver = classDescriptor.getImplicitReceiver();
}
else if (declarationDescriptor instanceof FunctionDescriptor) {
FunctionDescriptor functionDescriptor = (FunctionDescriptor) declarationDescriptor;
thisReceiver = functionDescriptor.getReceiver();
}
else {
throw new UnsupportedOperationException(); // TODO
}
PsiElement element = context.trace.get(DESCRIPTOR_TO_DECLARATION, declarationDescriptor);
assert element != null;
context.trace.record(LABEL_TARGET, targetLabel, element);
context.trace.record(REFERENCE_TARGET, expression.getThisReference(), declarationDescriptor);
}
else if (size == 0) {
JetElement element = labelsResolver.resolveNamedLabel(labelName, targetLabel, false, context);
if (element instanceof JetFunctionLiteralExpression) {
DeclarationDescriptor declarationDescriptor = context.trace.getBindingContext().get(BindingContext.DECLARATION_TO_DESCRIPTOR, element);
if (declarationDescriptor instanceof FunctionDescriptor) {
thisReceiver = ((FunctionDescriptor) declarationDescriptor).getReceiver();
if (thisReceiver.exists()) {
context.trace.record(LABEL_TARGET, targetLabel, element);
context.trace.record(REFERENCE_TARGET, expression.getThisReference(), declarationDescriptor);
}
}
else {
context.trace.report(UNRESOLVED_REFERENCE.on(targetLabel));
}
}
else {
context.trace.report(UNRESOLVED_REFERENCE.on(targetLabel));
}
}
else {
context.trace.report(AMBIGUOUS_LABEL.on(targetLabel));
}
return thisReceiver;
}
}
}
@@ -0,0 +1,63 @@
package org.jetbrains.jet.lang.types;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
import java.util.*;
/**
* @author alex.tkachman
*
* Utility class used by back-end to
*/
public class ProjectionErasingJetType implements JetType {
private final JetType delegate;
private List<TypeProjection> arguments;
public ProjectionErasingJetType(JetType delegate) {
this.delegate = delegate;
arguments = new ArrayList<TypeProjection>();
for(TypeProjection tp : delegate.getArguments()) {
arguments.add(new TypeProjection(Variance.INVARIANT, tp.getType()));
}
}
@NotNull
@Override
public TypeConstructor getConstructor() {
return delegate.getConstructor();
}
@NotNull
@Override
public List<TypeProjection> getArguments() {
return arguments;
}
@Override
public boolean isNullable() {
return false;
}
@NotNull
@Override
public JetScope getMemberScope() {
return delegate.getMemberScope();
}
@Override
public List<AnnotationDescriptor> getAnnotations() {
return delegate.getAnnotations();
}
@Override
public int hashCode() {
return delegate.hashCode();
}
@Override
public boolean equals(Object obj) {
return ((obj instanceof ProjectionErasingJetType) && delegate.equals(((ProjectionErasingJetType)obj).delegate)) || delegate.equals(obj);
}
}
@@ -136,6 +136,7 @@ public interface JetTokens {
JetKeywordToken CATCH_KEYWORD = JetKeywordToken.softKeyword("catch");
JetKeywordToken OUT_KEYWORD = JetKeywordToken.softKeyword("out");
JetKeywordToken VARARG_KEYWORD = JetKeywordToken.softKeyword("vararg");
JetKeywordToken INLINE_KEYWORD = JetKeywordToken.softKeyword("inline");
JetKeywordToken FINALLY_KEYWORD = JetKeywordToken.softKeyword("finally");
JetKeywordToken FINAL_KEYWORD = JetKeywordToken.softKeyword("final");
@@ -155,12 +156,12 @@ public interface JetTokens {
TokenSet SOFT_KEYWORDS = TokenSet.create(IMPORT_KEYWORD, WHERE_KEYWORD, BY_KEYWORD, GET_KEYWORD,
SET_KEYWORD, ABSTRACT_KEYWORD, ENUM_KEYWORD, OPEN_KEYWORD, ANNOTATION_KEYWORD,
OVERRIDE_KEYWORD, PRIVATE_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD, PROTECTED_KEYWORD,
CATCH_KEYWORD, FINALLY_KEYWORD, REF_KEYWORD, OUT_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD
CATCH_KEYWORD, FINALLY_KEYWORD, REF_KEYWORD, OUT_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD, INLINE_KEYWORD
);
TokenSet MODIFIER_KEYWORDS = TokenSet.create(ABSTRACT_KEYWORD, ENUM_KEYWORD,
OPEN_KEYWORD, ANNOTATION_KEYWORD, OVERRIDE_KEYWORD, PRIVATE_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD,
PROTECTED_KEYWORD, REF_KEYWORD, OUT_KEYWORD, IN_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD
PROTECTED_KEYWORD, REF_KEYWORD, OUT_KEYWORD, IN_KEYWORD, FINAL_KEYWORD, VARARG_KEYWORD, INLINE_KEYWORD
);
TokenSet WHITE_SPACE_OR_COMMENT_BIT_SET = TokenSet.create(WHITE_SPACE, BLOCK_COMMENT, EOL_COMMENT, DOC_COMMENT);
TokenSet WHITESPACES = TokenSet.create(TokenType.WHITE_SPACE);
@@ -36,15 +36,3 @@ l1:
error:
<ERROR>
=====================
== a ==
val a = Array<Int>
---------------------
l0:
<START>
r(Array)
r(Array<Int>)
l1:
<END>
error:
<ERROR>
=====================
@@ -55,56 +55,3 @@ l1:
error:
<ERROR>
=====================
== x ==
var x = 1
---------------------
l0:
<START>
r(1)
l1:
<END>
error:
<ERROR>
=====================
== y ==
val y = true && false
---------------------
l0:
<START>
r(true)
jf(l2)
r(false)
l2:
r(true && false)
l1:
<END>
error:
<ERROR>
=====================
== z ==
val z = false && true
---------------------
l0:
<START>
r(false)
jf(l2)
r(true)
l2:
r(false && true)
l1:
<END>
error:
<ERROR>
=====================
== t ==
val t = Test()
---------------------
l0:
<START>
r(Test)
r(Test())
l1:
<END>
error:
<ERROR>
=====================
+2 -2
View File
@@ -136,9 +136,9 @@ fun tf() : Int {
}
fun failtest(a : Int) : Int {
<error>if (fail() || true) {
if (fail() || <error>true</error>) {
}</error>
}
<error>return 1</error>
}
@@ -25,4 +25,61 @@ class C {
<!NOT_A_LOOP_LABEL!>break@f<!>
}
fun containsBreak(a: String?, b: String?) {
while (a == null) {
break;
}
a?.compareTo("2")
}
fun notContainsBreak(a: String?, b: String?) {
while (a == null) {
while (b == null) {
break;
}
}
a<!UNNECESSARY_SAFE_CALL!>?.<!>compareTo("2")
}
fun containsBreakWithLabel(a: String?) {
@loop while(a == null) {
break@loop
}
a?.compareTo("2")
}
fun containsIllegalBreak(a: String?) {
@loop while(a == null) {
<!NOT_A_LOOP_LABEL!>break<!UNRESOLVED_REFERENCE!>@label<!><!>
}
a<!UNNECESSARY_SAFE_CALL!>?.<!>compareTo("2")
}
fun containsBreakToOuterLoop(a: String?, b: String?) {
@loop while(b == null) {
while(a == null) {
break@loop
}
a<!UNNECESSARY_SAFE_CALL!>?.<!>compareTo("2")
}
}
fun containsBreakInsideLoopWithLabel(a: String?, array: Array<Int>) {
@ while(a == null) {
for (el in array) {
break@
}
}
a?.compareTo("2")
}
fun unresolvedBreak(a: String?, array: Array<Int>) {
while(a == null) {
@ for (el in array) {
break
}
if (true) break else <!NOT_A_LOOP_LABEL!>break<!UNRESOLVED_REFERENCE!>@<!><!>
}
a?.compareTo("2")
}
}
@@ -168,4 +168,42 @@ fun f(): Int = if (1 < 2) 1 else returnNothing()
public fun <!PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE!>f<!>() = 1
class B() {
protected fun <!PUBLIC_MEMBER_SHOULD_SPECIFY_TYPE!>f<!>() = "ss"
}
fun testFunctionLiterals() {
val endsWithVarDeclaration : fun() : Boolean = {
<!EXPECTED_TYPE_MISMATCH!>val x = 2<!>
}
val endsWithAssignment = { () : Int =>
val x = 1
<!EXPECTED_TYPE_MISMATCH!>x = 333<!>
}
val endsWithReAssignment = { () : Int =>
val x = 1
<!EXPECTED_TYPE_MISMATCH!>x += 333<!>
}
val endsWithFunDeclaration : fun() : String = {
val x = 1
x = 333
<!EXPECTED_TYPE_MISMATCH!>fun meow() : Unit {}<!>
}
val endsWithObjectDeclaration : fun() : Int = {
val x = 1
x = 333
<!EXPECTED_TYPE_MISMATCH!>object A {}<!>
}
val expectedUnitReturnType1 = { () : Unit =>
val x = 1
}
val expectedUnitReturnType2 = { () : Unit =>
fun meow() : Unit {}
object A {}
}
}
@@ -0,0 +1,17 @@
namespace return
class A {
fun outer() {
fun inner() {
if (1 < 2)
return@inner
else
return@outer
}
if (1 < 2)
<!NOT_A_RETURN_LABEL!>return@A<!>
else if (2 < 3)
<!NOT_A_RETURN_LABEL!>return<!UNRESOLVED_REFERENCE!>@inner<!><!>
return@outer
}
}
@@ -136,16 +136,16 @@ fun tf() : Int {
}
fun failtest(a : Int) : Int {
<!UNREACHABLE_BECAUSE_OF_NOTHING!>if (fail() || true) {
if (fail() || <!UNREACHABLE_CODE!>true<!>) {
}<!>
<!UNREACHABLE_BECAUSE_OF_NOTHING!>return 1<!>
}
<!UNREACHABLE_CODE!>return 1<!>
}
fun foo(a : Nothing) : Unit {
1
a
<!UNREACHABLE_BECAUSE_OF_NOTHING!>2<!>
<!UNREACHABLE_CODE!>2<!>
}
fun fail() : Nothing {
@@ -0,0 +1,24 @@
import java.util.ArrayList
fun launch(f : fun() : Unit) {
f()
}
fun box(): String {
val list = ArrayList<Int>()
val foo : fun() : Unit = {
list.add(2) //first exception
}
foo()
launch({
list.add(3)
})
val bar = {
val x = 1 //second exception
}
bar()
return if (list.size() == 2 && list.get(0) == 2 && list.get(1) == 3) "OK" else "fail"
}
@@ -58,4 +58,46 @@ public class ArrayGenTest extends CodegenTestCase {
System.out.println(invoke.getClass());
assertTrue(invoke instanceof Integer);
}
public void testIterator () throws Exception {
loadText("fun box() { val x = Array<Int>(5, { it } ).iterator(); while(x.hasNext()) { java.lang.System.out?.println(x.next()) } }");
System.out.println(generateToText());
Method foo = generateFunction();
foo.invoke(null);
}
public void testPrimitiveIterator () throws Exception {
loadText("fun box() { val x = ByteArray(5).iterator(); while(x.hasNext()) { java.lang.System.out?.println(x.next()) } }");
System.out.println(generateToText());
Method foo = generateFunction();
foo.invoke(null);
}
public void testLongIterator () throws Exception {
loadText("fun box() { val x = LongArray(5).iterator(); while(x.hasNext()) { java.lang.System.out?.println(x.next()) } }");
System.out.println(generateToText());
Method foo = generateFunction();
foo.invoke(null);
}
public void testCharIterator () throws Exception {
loadText("fun box() { val x = CharArray(5).iterator(); while(x.hasNext()) { java.lang.System.out?.println(x.next()) } }");
System.out.println(generateToText());
Method foo = generateFunction();
foo.invoke(null);
}
public void testArrayIndices () throws Exception {
loadText("fun box() { val x = Array<Int>(5, {it}).indices.iterator(); while(x.hasNext()) { java.lang.System.out?.println(x.next()) } }");
System.out.println(generateToText());
Method foo = generateFunction();
foo.invoke(null);
}
public void testCharIndices () throws Exception {
loadText("fun box() { val x = CharArray(5).indices.iterator(); while(x.hasNext()) { java.lang.System.out?.println(x.next()) } }");
System.out.println(generateToText());
Method foo = generateFunction();
foo.invoke(null);
}
}
@@ -178,4 +178,16 @@ public class ClassGenTest extends CodegenTestCase {
blackBoxFile("regressions/kt48.jet");
System.out.println(generateToText());
}
public void testKt309 () throws Exception {
loadText("fun box() = null");
final Method method = generateFunction("box");
assertEquals(method.getReturnType().getName(), "java.lang.Object");
System.out.println(generateToText());
}
public void testKt343 () throws Exception {
blackBoxFile("regressions/kt343.jet");
System.out.println(generateToText());
}
}
@@ -6,6 +6,7 @@ package org.jetbrains.jet.codegen;
public class ClosuresGenTest extends CodegenTestCase {
public void testSimplestClosure() throws Exception {
blackBoxFile("classes/simplestClosure.jet");
System.out.println(generateToText());
}
public void testSimplestClosureAndBoxing() throws Exception {
@@ -2,6 +2,8 @@ package org.jetbrains.jet.codegen;
import jet.IntRange;
import jet.Tuple2;
import jet.Tuple3;
import jet.Tuple4;
import jet.typeinfo.TypeInfo;
import org.jetbrains.jet.parsing.JetParsingTest;
@@ -9,6 +11,7 @@ import java.awt.*;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
/**
* @author yole
@@ -489,12 +492,23 @@ public class NamespaceGenTest extends CodegenTestCase {
public void testTupleLiteral() throws Exception {
loadText("fun foo() = (1, \"foo\")");
System.out.println(generateToText());
final Method main = generateFunction();
Tuple2 tuple2 = (Tuple2) main.invoke(null);
assertEquals(1, tuple2._1);
assertEquals("foo", tuple2._2);
}
public void testParametrizedTupleLiteral() throws Exception {
loadText("fun <E,D> E.foo(extra: java.util.List<D>) = (1, \"foo\", this, extra)");
System.out.println(generateToText());
final Method main = generateFunction();
Tuple4 tuple4 = (Tuple4) main.invoke(null, "aaa", Arrays.asList(10), TypeInfo.STRING_TYPE_INFO, TypeInfo.INT_TYPE_INFO);
assertEquals(1, tuple4._1);
assertEquals("foo", tuple4._2);
assertEquals("aaa", tuple4._3);
}
public void testPredicateOperator() throws Exception {
loadText("fun foo(s: String) = s?startsWith(\"J\")");
final Method main = generateFunction();
@@ -90,13 +90,13 @@ public class PatternMatchingTest extends CodegenTestCase {
Method foo = generateFunction();
final Object result;
try {
result = foo.invoke(null, new Tuple2<Integer, Integer>(1, 2));
result = foo.invoke(null, new Tuple2<Integer, Integer>(null, 1, 2));
} catch (Exception e) {
System.out.println(generateToText());
throw e;
}
assertEquals("one,two", result);
assertEquals("something", foo.invoke(null, new Tuple2<String, String>("not", "tuple")));
assertEquals("something", foo.invoke(null, new Tuple2<String, String>(null, "not", "tuple")));
}
public void testCall() throws Exception {
@@ -119,8 +119,8 @@ public class PatternMatchingTest extends CodegenTestCase {
public void testNames() throws Exception {
loadText("fun foo(x: (Any, Any)) = when(x) { is (val a is String, *) => a; else => \"something\" }");
Method foo = generateFunction();
assertEquals("JetBrains", foo.invoke(null, new Tuple2<String, String>("JetBrains", "s.r.o.")));
assertEquals("something", foo.invoke(null, new Tuple2<Integer, Integer>(1, 2)));
assertEquals("JetBrains", foo.invoke(null, new Tuple2<String, String>(null, "JetBrains", "s.r.o.")));
assertEquals("something", foo.invoke(null, new Tuple2<Integer, Integer>(null, 1, 2)));
}
public void testMultipleConditions() throws Exception {
@@ -106,7 +106,7 @@ public class JetResolveTest extends ExtensibleResolveTestCase {
@NotNull
private FunctionDescriptor standardFunction(ClassDescriptor classDescriptor, List<TypeProjection> typeArguments, String name, JetType... parameterType) {
List<JetType> parameterTypeList = Arrays.asList(parameterType);
JetTypeInferrer.Services typeInferrerServices = JetSemanticServices.createSemanticServices(getProject()).getTypeInferrerServices(new BindingTraceContext(), JetFlowInformationProvider.NONE);
JetTypeInferrer.Services typeInferrerServices = JetSemanticServices.createSemanticServices(getProject()).getTypeInferrerServices(new BindingTraceContext());
OverloadResolutionResults<FunctionDescriptor> functions = typeInferrerServices.getCallResolver().resolveExactSignature(
classDescriptor.getMemberScope(typeArguments), ReceiverDescriptor.NO_RECEIVER, name, parameterTypeList);
@@ -493,14 +493,14 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
private void assertType(String expression, JetType expectedType) {
Project project = getProject();
JetExpression jetExpression = JetPsiFactory.createExpression(project, expression);
JetType type = semanticServices.getTypeInferrerServices(JetTestUtils.DUMMY_TRACE, JetFlowInformationProvider.NONE).getType(scopeWithImports, jetExpression, JetTypeInferrer.NO_EXPECTED_TYPE);
JetType type = semanticServices.getTypeInferrerServices(JetTestUtils.DUMMY_TRACE).getType(scopeWithImports, jetExpression, JetTypeInferrer.NO_EXPECTED_TYPE);
assertTrue(type + " != " + expectedType, type.equals(expectedType));
}
private void assertErrorType(String expression) {
Project project = getProject();
JetExpression jetExpression = JetPsiFactory.createExpression(project, expression);
JetType type = semanticServices.getTypeInferrerServices(JetTestUtils.DUMMY_TRACE, JetFlowInformationProvider.NONE).safeGetType(scopeWithImports, jetExpression, JetTypeInferrer.NO_EXPECTED_TYPE);
JetType type = semanticServices.getTypeInferrerServices(JetTestUtils.DUMMY_TRACE).safeGetType(scopeWithImports, jetExpression, JetTypeInferrer.NO_EXPECTED_TYPE);
assertTrue("Error type expected but " + type + " returned", ErrorUtils.isErrorType(type));
}
@@ -523,7 +523,7 @@ public class JetTypeCheckerTest extends LightDaemonAnalyzerTestCase {
private void assertType(JetScope scope, String expression, String expectedTypeStr) {
Project project = getProject();
JetExpression jetExpression = JetPsiFactory.createExpression(project, expression);
JetType type = semanticServices.getTypeInferrerServices(JetTestUtils.DUMMY_TRACE, JetFlowInformationProvider.NONE).getType(addImports(scope), jetExpression, JetTypeInferrer.NO_EXPECTED_TYPE);
JetType type = semanticServices.getTypeInferrerServices(JetTestUtils.DUMMY_TRACE).getType(addImports(scope), jetExpression, JetTypeInferrer.NO_EXPECTED_TYPE);
JetType expectedType = expectedTypeStr == null ? null : makeType(expectedTypeStr);
assertEquals(expectedType, type);
}
+19
View File
@@ -0,0 +1,19 @@
package jet;
import jet.typeinfo.TypeInfo;
/**
* @author alex.tkachman
*/
public class DefaultJetObject implements JetObject {
private TypeInfo<?> typeInfo;
protected DefaultJetObject(TypeInfo<?> typeInfo) {
this.typeInfo = typeInfo;
}
@Override
public TypeInfo<?> getTypeInfo() {
return typeInfo;
}
}
+7 -1
View File
@@ -3,7 +3,13 @@
*/
package jet;
public abstract class ExtensionFunction0<E, R> {
import jet.typeinfo.TypeInfo;
public abstract class ExtensionFunction0<E, R> extends DefaultJetObject{
protected ExtensionFunction0(TypeInfo<?> typeInfo) {
super(typeInfo);
}
public abstract R invoke(E receiver);
@Override
+7 -1
View File
@@ -3,7 +3,13 @@
*/
package jet;
public abstract class ExtensionFunction1<E, D, R> {
import jet.typeinfo.TypeInfo;
public abstract class ExtensionFunction1<E, D, R> extends DefaultJetObject{
protected ExtensionFunction1(TypeInfo<?> typeInfo) {
super(typeInfo);
}
public abstract R invoke(E receiver, D d);
@Override
+7 -1
View File
@@ -3,7 +3,13 @@
*/
package jet;
public abstract class ExtensionFunction2<E, D1, D2, R> {
import jet.typeinfo.TypeInfo;
public abstract class ExtensionFunction2<E, D1, D2, R> extends DefaultJetObject{
protected ExtensionFunction2(TypeInfo<?> typeInfo) {
super(typeInfo);
}
public abstract R invoke(E receiver, D1 d1, D2 d2);
@Override
+7 -1
View File
@@ -3,7 +3,13 @@
*/
package jet;
public abstract class ExtensionFunction3<E, D1, D2, D3, R> {
import jet.typeinfo.TypeInfo;
public abstract class ExtensionFunction3<E, D1, D2, D3, R> extends DefaultJetObject{
protected ExtensionFunction3(TypeInfo<?> typeInfo) {
super(typeInfo);
}
public abstract R invoke(E receiver, D1 d1, D2 d2, D3 d3);
@Override
+7 -1
View File
@@ -3,7 +3,13 @@
*/
package jet;
public abstract class Function0<R> {
import jet.typeinfo.TypeInfo;
public abstract class Function0<R> extends DefaultJetObject {
protected Function0(TypeInfo<?> typeInfo) {
super(typeInfo);
}
public abstract R invoke();
@Override
+7 -1
View File
@@ -3,7 +3,13 @@
*/
package jet;
public abstract class Function1<D, R> {
import jet.typeinfo.TypeInfo;
public abstract class Function1<D, R> extends DefaultJetObject {
protected Function1(TypeInfo<?> typeInfo) {
super(typeInfo);
}
public abstract R invoke(D d);
@Override
+7 -1
View File
@@ -3,7 +3,13 @@
*/
package jet;
public abstract class Function2<D1, D2, R> {
import jet.typeinfo.TypeInfo;
public abstract class Function2<D1, D2, R> extends DefaultJetObject {
protected Function2(TypeInfo<?> typeInfo) {
super(typeInfo);
}
public abstract R invoke(D1 d1, D2 d2);
@Override
+7 -1
View File
@@ -3,7 +3,13 @@
*/
package jet;
public abstract class Function3<D1, D2, D3, R> {
import jet.typeinfo.TypeInfo;
public abstract class Function3<D1, D2, D3, R> extends DefaultJetObject{
protected Function3(TypeInfo<?> typeInfo) {
super(typeInfo);
}
public abstract R invoke(D1 d1, D2 d2, D3 d3);
@Override
+84 -13
View File
@@ -1,28 +1,99 @@
package jet;
public class IntRange implements Range<Integer> {
private final int startValue;
private final int endValue;
import jet.typeinfo.TypeInfo;
public IntRange(int startValue, int endValue) {
this.startValue = startValue;
this.endValue = endValue;
public final class IntRange implements Range<Integer>, Iterable<Integer>, JetObject {
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(IntRange.class, false);
private final int start;
private final int count;
public IntRange(int startValue, int count) {
this.start = startValue;
this.count = count;
}
public IntRange(int startValue, int count, boolean reversed) {
this(startValue, reversed ? -count : count);
}
@Override
public boolean contains(Integer item) {
if (item == null) return false;
if (startValue <= endValue) {
return item >= startValue && item <= endValue;
if (count >= 0) {
return item >= start && item < start + count;
}
return item <= startValue && item >= endValue;
return item <= start && item > start + count;
}
public int getStartValue() {
return startValue;
public int getStart() {
return start;
}
public int getEndValue() {
return endValue;
public int getEnd() {
return start+count-1;
}
public int getSize() {
return count < 0 ? -count : count;
}
@Override
public Iterator<Integer> iterator() {
return new MyIterator(start, count);
}
@Override
public TypeInfo<?> getTypeInfo() {
return typeInfo;
}
public static IntRange count(int length) {
return new IntRange(0, length);
}
public static IntRange rangeTo(int from, int to) {
if(from > to) {
return new IntRange(to, from-to+1, true);
}
else {
return new IntRange(from, to-from+1);
}
}
private static class MyIterator implements Iterator<Integer> {
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false);
private int cur;
private int count;
private final boolean reversed;
public MyIterator(int startValue, int count) {
cur = startValue;
reversed = count < 0;
this.count = reversed ? -count : count;
}
@Override
public boolean hasNext() {
return count > 0;
}
@Override
public Integer next() {
count--;
if(reversed) {
return cur--;
}
else {
return cur++;
}
}
@Override
public TypeInfo<?> getTypeInfo() {
return typeInfo;
}
}
}
+99
View File
@@ -0,0 +1,99 @@
package jet;
import jet.typeinfo.TypeInfo;
public final class LongRange implements Range<Long>, Iterable<Long>, JetObject {
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(IntRange.class, false);
private final long start;
private final long count;
public LongRange(long startValue, long count) {
this.start = startValue;
this.count = count;
}
public LongRange(long startValue, long count, boolean reversed) {
this(startValue, reversed ? -count : count);
}
@Override
public boolean contains(Long item) {
if (item == null) return false;
if (count >= 0) {
return item >= start && item < start + count;
}
return item <= start && item > start + count;
}
public long getStart() {
return start;
}
public long getEnd() {
return start+count-1;
}
public long getSize() {
return count < 0 ? -count : count;
}
@Override
public Iterator<Long> iterator() {
return new MyIterator(start, count);
}
@Override
public TypeInfo<?> getTypeInfo() {
return typeInfo;
}
public static IntRange count(int length) {
return new IntRange(0, length);
}
public static IntRange rangeTo(int from, int to) {
if(from > to) {
return new IntRange(to, from-to+1, true);
}
else {
return new IntRange(from, to-from+1);
}
}
private static class MyIterator implements Iterator<Long> {
private final static TypeInfo typeInfo = TypeInfo.getTypeInfo(MyIterator.class, false);
private long cur;
private long count;
private final boolean reversed;
public MyIterator(long startValue, long count) {
cur = startValue;
reversed = count < 0;
this.count = reversed ? -count : count;
}
@Override
public boolean hasNext() {
return count > 0;
}
@Override
public Long next() {
count--;
if(reversed) {
return cur--;
}
else {
return cur++;
}
}
@Override
public TypeInfo<?> getTypeInfo() {
return typeInfo;
}
}
}
+9 -1
View File
@@ -1,10 +1,13 @@
package jet;
import jet.typeinfo.TypeInfo;
/**
* @author alex.tkachman
*/
public class Tuple0 {
public class Tuple0 implements JetObject {
public static final Tuple0 INSTANCE = new Tuple0();
private static final TypeInfo<?> typeInfo = TypeInfo.getTypeInfo(Tuple0.class, false);
private Tuple0() {
}
@@ -23,4 +26,9 @@ public class Tuple0 {
public int hashCode() {
return 239;
}
@Override
public TypeInfo<?> getTypeInfo() {
return typeInfo;
}
}
+5 -2
View File
@@ -1,9 +1,12 @@
package jet;
public class Tuple1<T1> {
import jet.typeinfo.TypeInfo;
public class Tuple1<T1> extends DefaultJetObject {
public final T1 _1;
public Tuple1(T1 t1) {
public Tuple1(TypeInfo typeInfo, T1 t1) {
super(typeInfo);
_1 = t1;
}
+5 -2
View File
@@ -1,6 +1,8 @@
package jet;
public class Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> {
import jet.typeinfo.TypeInfo;
public class Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> extends DefaultJetObject{
public final T1 _1;
public final T2 _2;
public final T3 _3;
@@ -12,7 +14,8 @@ public class Tuple10<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10> {
public final T9 _9;
public final T10 _10;
public Tuple10(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10) {
public Tuple10(TypeInfo typeInfo, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10) {
super(typeInfo);
_1 = t1;
_2 = t2;
_3 = t3;
+5 -2
View File
@@ -1,6 +1,8 @@
package jet;
public class Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> {
import jet.typeinfo.TypeInfo;
public class Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> extends DefaultJetObject{
public final T1 _1;
public final T2 _2;
public final T3 _3;
@@ -13,7 +15,8 @@ public class Tuple11<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11> {
public final T10 _10;
public final T11 _11;
public Tuple11(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11) {
public Tuple11(TypeInfo typeInfo, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11) {
super(typeInfo);
_1 = t1;
_2 = t2;
_3 = t3;
+5 -2
View File
@@ -1,6 +1,8 @@
package jet;
public class Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> {
import jet.typeinfo.TypeInfo;
public class Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> extends DefaultJetObject {
public final T1 _1;
public final T2 _2;
public final T3 _3;
@@ -14,7 +16,8 @@ public class Tuple12<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12> {
public final T11 _11;
public final T12 _12;
public Tuple12(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12) {
public Tuple12(TypeInfo typeInfo, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12) {
super(typeInfo);
_1 = t1;
_2 = t2;
_3 = t3;
+5 -2
View File
@@ -1,6 +1,8 @@
package jet;
public class Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> {
import jet.typeinfo.TypeInfo;
public class Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> extends DefaultJetObject{
public final T1 _1;
public final T2 _2;
public final T3 _3;
@@ -15,7 +17,8 @@ public class Tuple13<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13> {
public final T12 _12;
public final T13 _13;
public Tuple13(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13) {
public Tuple13(TypeInfo typeInfo, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13) {
super(typeInfo);
_1 = t1;
_2 = t2;
_3 = t3;
+5 -2
View File
@@ -1,6 +1,8 @@
package jet;
public class Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> {
import jet.typeinfo.TypeInfo;
public class Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14> extends DefaultJetObject{
public final T1 _1;
public final T2 _2;
public final T3 _3;
@@ -16,7 +18,8 @@ public class Tuple14<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14
public final T13 _13;
public final T14 _14;
public Tuple14(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14) {
public Tuple14(TypeInfo typeInfo, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14) {
super(typeInfo);
_1 = t1;
_2 = t2;
_3 = t3;
+5 -2
View File
@@ -1,6 +1,8 @@
package jet;
public class Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> {
import jet.typeinfo.TypeInfo;
public class Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15> extends DefaultJetObject {
public final T1 _1;
public final T2 _2;
public final T3 _3;
@@ -17,7 +19,8 @@ public class Tuple15<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14
public final T14 _14;
public final T15 _15;
public Tuple15(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15) {
public Tuple15(TypeInfo typeInfo, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15) {
super(typeInfo);
_1 = t1;
_2 = t2;
_3 = t3;
+5 -2
View File
@@ -1,6 +1,8 @@
package jet;
public class Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> {
import jet.typeinfo.TypeInfo;
public class Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16> extends DefaultJetObject {
public final T1 _1;
public final T2 _2;
public final T3 _3;
@@ -18,7 +20,8 @@ public class Tuple16<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14
public final T15 _15;
public final T16 _16;
public Tuple16(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16) {
public Tuple16(TypeInfo typeInfo, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16) {
super(typeInfo);
_1 = t1;
_2 = t2;
_3 = t3;
+5 -2
View File
@@ -1,6 +1,8 @@
package jet;
public class Tuple17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17> {
import jet.typeinfo.TypeInfo;
public class Tuple17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17> extends DefaultJetObject {
public final T1 _1;
public final T2 _2;
public final T3 _3;
@@ -19,7 +21,8 @@ public class Tuple17<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14
public final T16 _16;
public final T17 _17;
public Tuple17(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16, T17 t17) {
public Tuple17(TypeInfo typeInfo, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16, T17 t17) {
super(typeInfo);
_1 = t1;
_2 = t2;
_3 = t3;
+5 -2
View File
@@ -1,6 +1,8 @@
package jet;
public class Tuple18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18> {
import jet.typeinfo.TypeInfo;
public class Tuple18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18> extends DefaultJetObject{
public final T1 _1;
public final T2 _2;
public final T3 _3;
@@ -20,7 +22,8 @@ public class Tuple18<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14
public final T17 _17;
public final T18 _18;
public Tuple18(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16, T17 t17, T18 t18) {
public Tuple18(TypeInfo typeInfo, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16, T17 t17, T18 t18) {
super(typeInfo);
_1 = t1;
_2 = t2;
_3 = t3;
+5 -2
View File
@@ -1,6 +1,8 @@
package jet;
public class Tuple19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19> {
import jet.typeinfo.TypeInfo;
public class Tuple19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19> extends DefaultJetObject {
public final T1 _1;
public final T2 _2;
public final T3 _3;
@@ -21,7 +23,8 @@ public class Tuple19<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14
public final T18 _18;
public final T19 _19;
public Tuple19(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16, T17 t17, T18 t18, T19 t19) {
public Tuple19(TypeInfo typeInfo, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16, T17 t17, T18 t18, T19 t19) {
super(typeInfo);
_1 = t1;
_2 = t2;
_3 = t3;
+5 -2
View File
@@ -1,10 +1,13 @@
package jet;
public class Tuple2<T1, T2> {
import jet.typeinfo.TypeInfo;
public class Tuple2<T1, T2> extends DefaultJetObject {
public final T1 _1;
public final T2 _2;
public Tuple2(T1 t1, T2 t2) {
public Tuple2(TypeInfo typeInfo, T1 t1, T2 t2) {
super(typeInfo);
_1 = t1;
_2 = t2;
}
+5 -2
View File
@@ -1,6 +1,8 @@
package jet;
public class Tuple20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20> {
import jet.typeinfo.TypeInfo;
public class Tuple20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20> extends DefaultJetObject{
public final T1 _1;
public final T2 _2;
public final T3 _3;
@@ -22,7 +24,8 @@ public class Tuple20<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14
public final T19 _19;
public final T20 _20;
public Tuple20(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16, T17 t17, T18 t18, T19 t19, T20 t20) {
public Tuple20(TypeInfo typeInfo, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16, T17 t17, T18 t18, T19 t19, T20 t20) {
super(typeInfo);
_1 = t1;
_2 = t2;
_3 = t3;
+5 -2
View File
@@ -1,6 +1,8 @@
package jet;
public class Tuple21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21> {
import jet.typeinfo.TypeInfo;
public class Tuple21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21> extends DefaultJetObject {
public final T1 _1;
public final T2 _2;
public final T3 _3;
@@ -23,7 +25,8 @@ public class Tuple21<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14
public final T20 _20;
public final T21 _21;
public Tuple21(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16, T17 t17, T18 t18, T19 t19, T20 t20, T21 t21) {
public Tuple21(TypeInfo typeInfo, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16, T17 t17, T18 t18, T19 t19, T20 t20, T21 t21) {
super(typeInfo);
_1 = t1;
_2 = t2;
_3 = t3;
+5 -2
View File
@@ -1,6 +1,8 @@
package jet;
public class Tuple22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22> {
import jet.typeinfo.TypeInfo;
public class Tuple22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15, T16, T17, T18, T19, T20, T21, T22> extends DefaultJetObject {
public final T1 _1;
public final T2 _2;
public final T3 _3;
@@ -24,7 +26,8 @@ public class Tuple22<T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14
public final T21 _21;
public final T22 _22;
public Tuple22(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16, T17 t17, T18 t18, T19 t19, T20 t20, T21 t21, T22 t22) {
public Tuple22(TypeInfo typeInfo, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9, T10 t10, T11 t11, T12 t12, T13 t13, T14 t14, T15 t15, T16 t16, T17 t17, T18 t18, T19 t19, T20 t20, T21 t21, T22 t22) {
super(typeInfo);
_1 = t1;
_2 = t2;
_3 = t3;
+5 -2
View File
@@ -1,11 +1,14 @@
package jet;
public class Tuple3<T1, T2, T3> {
import jet.typeinfo.TypeInfo;
public class Tuple3<T1, T2, T3> extends DefaultJetObject {
public final T1 _1;
public final T2 _2;
public final T3 _3;
public Tuple3(T1 t1, T2 t2, T3 t3) {
public Tuple3(TypeInfo typeInfo, T1 t1, T2 t2, T3 t3) {
super(typeInfo);
_1 = t1;
_2 = t2;
_3 = t3;
+5 -2
View File
@@ -1,12 +1,15 @@
package jet;
public class Tuple4<T1, T2, T3, T4> {
import jet.typeinfo.TypeInfo;
public class Tuple4<T1, T2, T3, T4> extends DefaultJetObject {
public final T1 _1;
public final T2 _2;
public final T3 _3;
public final T4 _4;
public Tuple4(T1 t1, T2 t2, T3 t3, T4 t4) {
public Tuple4(TypeInfo typeInfo, T1 t1, T2 t2, T3 t3, T4 t4) {
super(typeInfo);
_1 = t1;
_2 = t2;
_3 = t3;
+5 -2
View File
@@ -1,13 +1,16 @@
package jet;
public class Tuple5<T1, T2, T3, T4, T5> {
import jet.typeinfo.TypeInfo;
public class Tuple5<T1, T2, T3, T4, T5> extends DefaultJetObject{
public final T1 _1;
public final T2 _2;
public final T3 _3;
public final T4 _4;
public final T5 _5;
public Tuple5(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) {
public Tuple5(TypeInfo typeInfo, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5) {
super(typeInfo);
_1 = t1;
_2 = t2;
_3 = t3;
+5 -2
View File
@@ -1,6 +1,8 @@
package jet;
public class Tuple6<T1, T2, T3, T4, T5, T6> {
import jet.typeinfo.TypeInfo;
public class Tuple6<T1, T2, T3, T4, T5, T6> extends DefaultJetObject {
public final T1 _1;
public final T2 _2;
public final T3 _3;
@@ -8,7 +10,8 @@ public class Tuple6<T1, T2, T3, T4, T5, T6> {
public final T5 _5;
public final T6 _6;
public Tuple6(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) {
public Tuple6(TypeInfo typeInfo, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6) {
super(typeInfo);
_1 = t1;
_2 = t2;
_3 = t3;
+5 -2
View File
@@ -1,6 +1,8 @@
package jet;
public class Tuple7<T1, T2, T3, T4, T5, T6, T7> {
import jet.typeinfo.TypeInfo;
public class Tuple7<T1, T2, T3, T4, T5, T6, T7> extends DefaultJetObject{
public final T1 _1;
public final T2 _2;
public final T3 _3;
@@ -9,7 +11,8 @@ public class Tuple7<T1, T2, T3, T4, T5, T6, T7> {
public final T6 _6;
public final T7 _7;
public Tuple7(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) {
public Tuple7(TypeInfo typeInfo, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7) {
super(typeInfo);
_1 = t1;
_2 = t2;
_3 = t3;
+5 -2
View File
@@ -1,6 +1,8 @@
package jet;
public class Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> {
import jet.typeinfo.TypeInfo;
public class Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> extends DefaultJetObject{
public final T1 _1;
public final T2 _2;
public final T3 _3;
@@ -10,7 +12,8 @@ public class Tuple8<T1, T2, T3, T4, T5, T6, T7, T8> {
public final T7 _7;
public final T8 _8;
public Tuple8(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) {
public Tuple8(TypeInfo typeInfo, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8) {
super(typeInfo);
_1 = t1;
_2 = t2;
_3 = t3;
+5 -2
View File
@@ -1,6 +1,8 @@
package jet;
public class Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> {
import jet.typeinfo.TypeInfo;
public class Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> extends DefaultJetObject{
public final T1 _1;
public final T2 _2;
public final T3 _3;
@@ -11,7 +13,8 @@ public class Tuple9<T1, T2, T3, T4, T5, T6, T7, T8, T9> {
public final T8 _8;
public final T9 _9;
public Tuple9(T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9) {
public Tuple9(TypeInfo typeInfo, T1 t1, T2 t2, T3 t3, T4 t4, T5 t5, T6 t6, T7 t7, T8 t8, T9 t9) {
super(typeInfo);
_1 = t1;
_2 = t2;
_3 = t3;
+274
View File
@@ -0,0 +1,274 @@
package jet.arrays;
import jet.Iterator;
import jet.typeinfo.TypeInfo;
import jet.typeinfo.TypeInfoProjection;
import java.lang.reflect.GenericArrayType;
import java.util.Arrays;
/**
* @author alex.tkachman
*/
public abstract class ArrayIterator<T> implements Iterator<T> {
private final int size;
protected int index;
protected ArrayIterator(int size) {
this.size = size;
}
@Override
public boolean hasNext() {
return index < size;
}
private static class GenericIterator<T> extends ArrayIterator<T> {
private final T[] array;
private final TypeInfo elementTypeInfo;
private GenericIterator(T[] array, TypeInfo elementTypeInfo) {
super(array.length);
this.array = array;
this.elementTypeInfo = elementTypeInfo;
}
@Override
public T next() {
return array[index++];
}
@Override
public TypeInfo<?> getTypeInfo() {
return TypeInfo.getTypeInfo(GenericIterator.class, false, null, new TypeInfoProjection[] {(TypeInfoProjection) elementTypeInfo});
}
}
public static <T> Iterator<T> iterator(T[] array, TypeInfo elementTypeInfo) {
return new GenericIterator<T>(array, elementTypeInfo);
}
private static class ByteIterator extends ArrayIterator<Byte> {
private final byte[] array;
private static final TypeInfo typeInfo = TypeInfo.getTypeInfo(ByteIterator.class, false);
private ByteIterator(byte[] array) {
super(array.length);
this.array = array;
}
@Override
public Byte next() {
return array[index++];
}
@Override
public TypeInfo<?> getTypeInfo() {
return typeInfo;
}
}
public static Iterator<Byte> iterator(byte[] array) {
return new ByteIterator(array);
}
private static class ShortIterator extends ArrayIterator<Short> {
private final short[] array;
private static final TypeInfo typeInfo = TypeInfo.getTypeInfo(ShortIterator.class, false);
private ShortIterator(short[] array) {
super(array.length);
this.array = array;
}
@Override
public Short next() {
return array[index++];
}
@Override
public TypeInfo<?> getTypeInfo() {
return typeInfo;
}
}
public static Iterator<Short> iterator(short[] array) {
return new ShortIterator(array);
}
private static class IntegerIterator extends ArrayIterator<Integer> {
private final int[] array;
private static final TypeInfo typeInfo = TypeInfo.getTypeInfo(IntegerIterator.class, false);
private IntegerIterator(int[] array) {
super(array.length);
this.array = array;
}
@Override
public Integer next() {
return array[index++];
}
@Override
public TypeInfo<?> getTypeInfo() {
return typeInfo;
}
}
public static Iterator<Integer> iterator(int[] array) {
return new IntegerIterator(array);
}
private static class LongIterator extends ArrayIterator<Long> {
private final long[] array;
private static final TypeInfo typeInfo = TypeInfo.getTypeInfo(LongIterator.class, false);
private LongIterator(long[] array) {
super(array.length);
this.array = array;
}
@Override
public Long next() {
return array[index++];
}
@Override
public TypeInfo<?> getTypeInfo() {
return typeInfo;
}
}
public static Iterator<Long> iterator(long[] array) {
return new LongIterator(array);
}
private static class FloatIterator extends ArrayIterator<Float> {
private final float[] array;
private static final TypeInfo typeInfo = TypeInfo.getTypeInfo(FloatIterator.class, false);
private FloatIterator(float[] array) {
super(array.length);
this.array = array;
}
@Override
public Float next() {
return array[index++];
}
@Override
public TypeInfo<?> getTypeInfo() {
return typeInfo;
}
}
public static Iterator<Float> iterator(float[] array) {
return new FloatIterator(array);
}
private static class DoubleIterator extends ArrayIterator<Double> {
private final double[] array;
private static final TypeInfo typeInfo = TypeInfo.getTypeInfo(DoubleIterator.class, false);
private DoubleIterator(double[] array) {
super(array.length);
this.array = array;
}
@Override
public Double next() {
return array[index++];
}
@Override
public TypeInfo<?> getTypeInfo() {
return typeInfo;
}
}
public static Iterator<Double> iterator(double[] array) {
return new DoubleIterator(array);
}
private static class CharacterIterator extends ArrayIterator<Character> {
private final char[] array;
private static final TypeInfo typeInfo = TypeInfo.getTypeInfo(CharacterIterator.class, false);
private CharacterIterator(char[] array) {
super(array.length);
this.array = array;
}
@Override
public Character next() {
return array[index++];
}
@Override
public TypeInfo<?> getTypeInfo() {
return typeInfo;
}
}
public static Iterator<Character> iterator(char[] array) {
return new CharacterIterator(array);
}
private static class BooleanIterator extends ArrayIterator<Boolean> {
private final boolean[] array;
private static final TypeInfo typeInfo = TypeInfo.getTypeInfo(BooleanIterator.class, false);
private BooleanIterator(boolean[] array) {
super(array.length);
this.array = array;
}
@Override
public Boolean next() {
return array[index++];
}
@Override
public TypeInfo<?> getTypeInfo() {
return typeInfo;
}
}
public static Iterator<Boolean> iterator(boolean[] array) {
return new BooleanIterator(array);
}
public static void main(String[] args) {
String[] strings = {"Byte", "byte", "Short", "short", "Integer", "int", "Long", "long", "Float", "float", "Double", "double", "Character", "char", "Boolean", "boolean"};
for(int i = 0; i != strings.length; i += 2) {
String boxed = strings[i];
String unboxed = strings[i+1];
System.out.println(" private static class " + boxed + "Iterator extends ArrayIterator<" + boxed + "> {\n" +
" private final " + unboxed + "[] array;\n" +
" private static final TypeInfo typeInfo = TypeInfo.getTypeInfo(" + boxed + "Iterator.class, false);\n" +
"\n" +
" private " + boxed + "Iterator(" + unboxed + "[] array) {\n" +
" super(array.length);\n" +
" this.array = array;\n" +
" }\n" +
"\n" +
" @Override\n" +
" public " + boxed + " next() {\n" +
" return array[index++];\n" +
" }\n" +
"\n" +
" @Override\n" +
" public TypeInfo<?> getTypeInfo() {\n" +
" return typeInfo;\n" +
" }\n" +
" }\n" +
"\n" +
" public static Iterator<" + boxed + "> iterator(" + unboxed + "[] array) {\n" +
" return new " + boxed + "Iterator(array);\n" +
" }\n" +
"");
}
}
}
+1 -1
View File
@@ -22,7 +22,7 @@ public abstract class TypeInfo<T> implements JetObject {
public static final TypeInfo<Integer> INT_TYPE_INFO = getTypeInfo(Integer.class, false);
public static final TypeInfo<Long> LONG_TYPE_INFO = getTypeInfo(Long.class, false);
public static final TypeInfo<Character> CHAR_TYPE_INFO = getTypeInfo(Character.class, false);
public static final TypeInfo<Boolean> BOOL_TYPE_INFO = getTypeInfo(Boolean.class, false);
public static final TypeInfo<Boolean> BOOLEAN_TYPE_INFO = getTypeInfo(Boolean.class, false);
public static final TypeInfo<Float> FLOAT_TYPE_INFO = getTypeInfo(Float.class, false);
public static final TypeInfo<Double> DOUBLE_TYPE_INFO = getTypeInfo(Double.class, false);