Merge remote branch 'origin/master'
This commit is contained in:
@@ -1,4 +1,21 @@
|
|||||||
<project name="Jet CI Bootstrap" default="unzipIdeaSDK">
|
<project name="Jet CI Bootstrap" default="unzipIdeaSDK">
|
||||||
|
<macrodef name="echoprop">
|
||||||
|
<attribute name="prop"/>
|
||||||
|
<sequential>
|
||||||
|
<echo>@{prop}=${@{prop}}</echo>
|
||||||
|
</sequential>
|
||||||
|
</macrodef>
|
||||||
|
|
||||||
|
<echoprop prop="os.name"/>
|
||||||
|
<echoprop prop="os.version"/>
|
||||||
|
<echoprop prop="os.arch"/>
|
||||||
|
<echoprop prop="java.home"/>
|
||||||
|
<echoprop prop="java.vendor"/>
|
||||||
|
<echoprop prop="java.version"/>
|
||||||
|
<echoprop prop="user.name"/>
|
||||||
|
<echoprop prop="user.home"/>
|
||||||
|
<echoprop prop="user.dir"/>
|
||||||
|
|
||||||
<target name="unzipIdeaSDK">
|
<target name="unzipIdeaSDK">
|
||||||
<unzip dest="ideaSDK">
|
<unzip dest="ideaSDK">
|
||||||
<fileset dir="ideaSDK" includes="ideaIC*.zip"/>
|
<fileset dir="ideaSDK" includes="ideaIC*.zip"/>
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
<target name="compileRT">
|
<target name="compileRT">
|
||||||
<mkdir dir="${output}/classes/runtime"/>
|
<mkdir dir="${output}/classes/runtime"/>
|
||||||
<javac destdir="${output}/classes/runtime">
|
<javac destdir="${output}/classes/runtime" debug="true" debuglevel="lines,vars,source">
|
||||||
<src path="${basedir}/stdlib/src"/>
|
<src path="${basedir}/stdlib/src"/>
|
||||||
<classpath refid="classpath"/>
|
<classpath refid="classpath"/>
|
||||||
</javac>
|
</javac>
|
||||||
@@ -36,7 +36,7 @@
|
|||||||
|
|
||||||
<target name="compile" depends="compileRT">
|
<target name="compile" depends="compileRT">
|
||||||
<mkdir dir="${output}/classes/compiler"/>
|
<mkdir dir="${output}/classes/compiler"/>
|
||||||
<javac destdir="${output}/classes/compiler">
|
<javac destdir="${output}/classes/compiler" debug="true" debuglevel="lines,vars,source">
|
||||||
<src refid="sourcepath"/>
|
<src refid="sourcepath"/>
|
||||||
<classpath refid="classpath"/>
|
<classpath refid="classpath"/>
|
||||||
</javac>
|
</javac>
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import org.objectweb.asm.commons.InstructionAdapter;
|
|||||||
|
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.LinkedHashMap;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @author max
|
* @author max
|
||||||
@@ -38,6 +39,8 @@ public abstract class CodegenContext {
|
|||||||
public final ObjectOrClosureCodegen closure;
|
public final ObjectOrClosureCodegen closure;
|
||||||
|
|
||||||
HashMap<JetType,Integer> typeInfoConstants;
|
HashMap<JetType,Integer> typeInfoConstants;
|
||||||
|
HashMap<Integer,JetType> reverseTypeInfoConstants;
|
||||||
|
int typeInfoConstantsCount;
|
||||||
HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors;
|
HashMap<DeclarationDescriptor, DeclarationDescriptor> accessors;
|
||||||
|
|
||||||
protected StackValue outerExpression;
|
protected StackValue outerExpression;
|
||||||
@@ -177,13 +180,16 @@ public abstract class CodegenContext {
|
|||||||
if(parentContext != STATIC)
|
if(parentContext != STATIC)
|
||||||
return parentContext.getTypeInfoConstantIndex(type);
|
return parentContext.getTypeInfoConstantIndex(type);
|
||||||
|
|
||||||
if(typeInfoConstants == null)
|
if(typeInfoConstants == null) {
|
||||||
typeInfoConstants = new HashMap<JetType, Integer>();
|
typeInfoConstants = new LinkedHashMap<JetType, Integer>();
|
||||||
|
reverseTypeInfoConstants = new LinkedHashMap<Integer, JetType>();
|
||||||
|
}
|
||||||
|
|
||||||
Integer index = typeInfoConstants.get(type);
|
Integer index = typeInfoConstants.get(type);
|
||||||
if(index == null) {
|
if(index == null) {
|
||||||
index = typeInfoConstants.size();
|
index = typeInfoConstantsCount++;
|
||||||
typeInfoConstants.put(type, index);
|
typeInfoConstants.put(type, index);
|
||||||
|
reverseTypeInfoConstants.put(index, type);
|
||||||
}
|
}
|
||||||
return index;
|
return index;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2068,14 +2068,14 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
|
|||||||
return type;
|
return type;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void generateNewArray(JetCallExpression expression, JetType arrayType) {
|
public void generateNewArray(JetCallExpression expression, JetType arrayType) {
|
||||||
List<? extends ValueArgument> args = expression.getValueArguments();
|
List<? extends ValueArgument> args = expression.getValueArguments();
|
||||||
|
|
||||||
boolean isArray = state.getStandardLibrary().getArray().equals(arrayType.getConstructor().getDeclarationDescriptor());
|
boolean isArray = state.getStandardLibrary().getArray().equals(arrayType.getConstructor().getDeclarationDescriptor());
|
||||||
if(isArray) {
|
if(isArray) {
|
||||||
if (args.size() != 2 && !arrayType.getArguments().get(0).getType().isNullable()) {
|
// if (args.size() != 2 && !arrayType.getArguments().get(0).getType().isNullable()) {
|
||||||
throw new CompilationException("array constructor of non-nullable type requires two arguments");
|
// throw new CompilationException("array constructor of non-nullable type requires two arguments");
|
||||||
}
|
// }
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (args.size() != 1) {
|
if (args.size() != 1) {
|
||||||
@@ -2445,18 +2445,28 @@ If finally block is present, its last expression is the value of try expression.
|
|||||||
return StackValue.onStack(Type.BOOLEAN_TYPE);
|
return StackValue.onStack(Type.BOOLEAN_TYPE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean hasTypeInfoForInstanceOf(JetType type) {
|
||||||
|
DeclarationDescriptor declarationDescriptor = type.getConstructor().getDeclarationDescriptor();
|
||||||
|
if(declarationDescriptor instanceof TypeParameterDescriptor)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
ClassDescriptor classDescriptor = (ClassDescriptor) declarationDescriptor.getOriginal();
|
||||||
|
if(classDescriptor.equals(state.getStandardLibrary().getArray())) {
|
||||||
|
return hasTypeInfoForInstanceOf(type.getArguments().get(0).getType());
|
||||||
|
}
|
||||||
|
|
||||||
|
for(TypeParameterDescriptor proj : classDescriptor.getTypeConstructor().getParameters()) {
|
||||||
|
if(proj.isReified()) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private void generateInstanceOf(StackValue expressionToGen, JetType jetType, boolean leaveExpressionOnStack) {
|
private void generateInstanceOf(StackValue expressionToGen, JetType jetType, boolean leaveExpressionOnStack) {
|
||||||
DeclarationDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor();
|
DeclarationDescriptor descriptor = jetType.getConstructor().getDeclarationDescriptor();
|
||||||
boolean javaClass = bindingContext.get(BindingContext.DESCRIPTOR_TO_DECLARATION, descriptor) instanceof PsiClass;
|
if (!hasTypeInfoForInstanceOf(jetType)) {
|
||||||
if (!javaClass && (jetType.getArguments().size() > 0 || !(descriptor instanceof ClassDescriptor))) {
|
|
||||||
generateTypeInfo(jetType);
|
|
||||||
expressionToGen.put(OBJECT_TYPE, v);
|
|
||||||
if (leaveExpressionOnStack) {
|
|
||||||
v.dupX1();
|
|
||||||
}
|
|
||||||
v.invokevirtual("jet/typeinfo/TypeInfo", "isInstance", "(Ljava/lang/Object;)Z");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
expressionToGen.put(OBJECT_TYPE, v);
|
expressionToGen.put(OBJECT_TYPE, v);
|
||||||
if (leaveExpressionOnStack) {
|
if (leaveExpressionOnStack) {
|
||||||
v.dup();
|
v.dup();
|
||||||
@@ -2479,6 +2489,14 @@ If finally block is present, its last expression is the value of try expression.
|
|||||||
v.instanceOf(type);
|
v.instanceOf(type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
generateTypeInfo(jetType);
|
||||||
|
expressionToGen.put(OBJECT_TYPE, v);
|
||||||
|
if (leaveExpressionOnStack) {
|
||||||
|
v.dupX1();
|
||||||
|
}
|
||||||
|
v.invokevirtual("jet/typeinfo/TypeInfo", "isInstance", "(Ljava/lang/Object;)Z");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void generateTypeInfo(JetType jetType) {
|
public void generateTypeInfo(JetType jetType) {
|
||||||
@@ -2656,30 +2674,6 @@ If finally block is present, its last expression is the value of try expression.
|
|||||||
conditionValue = generatePatternMatch(pattern, patternCondition.isNegated(),
|
conditionValue = generatePatternMatch(pattern, patternCondition.isNegated(),
|
||||||
StackValue.local(subjectLocal, subjectType), nextEntry);
|
StackValue.local(subjectLocal, subjectType), nextEntry);
|
||||||
}
|
}
|
||||||
else if (condition instanceof JetWhenConditionCall) {
|
|
||||||
final JetExpression call = ((JetWhenConditionCall) condition).getCallSuffixExpression();
|
|
||||||
if (call instanceof JetCallExpression) {
|
|
||||||
v.load(subjectLocal, subjectType);
|
|
||||||
final DeclarationDescriptor declarationDescriptor = resolveCalleeDescriptor((JetCallExpression) call);
|
|
||||||
if (!(declarationDescriptor instanceof FunctionDescriptor)) {
|
|
||||||
throw new UnsupportedOperationException("expected function descriptor in when condition with call, found " + declarationDescriptor);
|
|
||||||
}
|
|
||||||
conditionValue = invokeFunction((JetCallExpression) call, declarationDescriptor, StackValue.onStack(subjectType));
|
|
||||||
}
|
|
||||||
else if (call instanceof JetSimpleNameExpression) {
|
|
||||||
final DeclarationDescriptor descriptor = bindingContext.get(BindingContext.REFERENCE_TARGET, (JetSimpleNameExpression) call);
|
|
||||||
if (descriptor instanceof PropertyDescriptor) {
|
|
||||||
v.load(subjectLocal, subjectType);
|
|
||||||
conditionValue = intermediateValueForProperty((PropertyDescriptor) descriptor, false, null);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new UnsupportedOperationException("unknown simple name resolve result: " + descriptor);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new UnsupportedOperationException("unsupported kind of call suffix");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
throw new UnsupportedOperationException("unsupported kind of when condition");
|
throw new UnsupportedOperationException("unsupported kind of when condition");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,9 +14,7 @@ import org.objectweb.asm.MethodVisitor;
|
|||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
import org.objectweb.asm.commons.InstructionAdapter;
|
||||||
|
|
||||||
import java.util.Collections;
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
|
||||||
|
|
||||||
import static org.objectweb.asm.Opcodes.*;
|
import static org.objectweb.asm.Opcodes.*;
|
||||||
|
|
||||||
@@ -114,11 +112,12 @@ public class NamespaceCodegen {
|
|||||||
private void generateTypeInfoFields(JetNamespace namespace, CodegenContext context) {
|
private void generateTypeInfoFields(JetNamespace namespace, CodegenContext context) {
|
||||||
if(context.typeInfoConstants != null) {
|
if(context.typeInfoConstants != null) {
|
||||||
String jvmClassName = getJVMClassName(namespace.getName());
|
String jvmClassName = getJVMClassName(namespace.getName());
|
||||||
for(Map.Entry<JetType,Integer> e : (context.typeInfoConstants != null ? context.typeInfoConstants : Collections.<JetType,Integer>emptyMap()).entrySet()) {
|
for(int index = 0; index != context.typeInfoConstantsCount; index++) {
|
||||||
String fieldName = "$typeInfoCache$" + e.getValue();
|
JetType type = context.reverseTypeInfoConstants.get(index);
|
||||||
|
String fieldName = "$typeInfoCache$" + index;
|
||||||
v.newField(null, ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC, fieldName, "Ljet/typeinfo/TypeInfo;", null, null);
|
v.newField(null, ACC_PRIVATE | ACC_STATIC | ACC_SYNTHETIC, fieldName, "Ljet/typeinfo/TypeInfo;", null, null);
|
||||||
|
|
||||||
MethodVisitor mmv = v.newMethod(null, ACC_PUBLIC | ACC_STATIC | ACC_SYNTHETIC, "$getCachedTypeInfo$" + e.getValue(), "()Ljet/typeinfo/TypeInfo;", null, null);
|
MethodVisitor mmv = v.newMethod(null, ACC_PUBLIC | ACC_STATIC | ACC_SYNTHETIC, "$getCachedTypeInfo$" + index, "()Ljet/typeinfo/TypeInfo;", null, null);
|
||||||
InstructionAdapter v = new InstructionAdapter(mmv);
|
InstructionAdapter v = new InstructionAdapter(mmv);
|
||||||
v.visitFieldInsn(GETSTATIC, jvmClassName, fieldName, "Ljet/typeinfo/TypeInfo;");
|
v.visitFieldInsn(GETSTATIC, jvmClassName, fieldName, "Ljet/typeinfo/TypeInfo;");
|
||||||
v.visitInsn(DUP);
|
v.visitInsn(DUP);
|
||||||
@@ -126,7 +125,7 @@ public class NamespaceCodegen {
|
|||||||
v.visitJumpInsn(IFNONNULL, end);
|
v.visitJumpInsn(IFNONNULL, end);
|
||||||
|
|
||||||
v.pop();
|
v.pop();
|
||||||
generateTypeInfo(context, v, e.getKey(), state.getTypeMapper(), e.getKey());
|
generateTypeInfo(context, v, type, state.getTypeMapper(), type);
|
||||||
v.dup();
|
v.dup();
|
||||||
|
|
||||||
v.visitFieldInsn(PUTSTATIC, jvmClassName, fieldName, "Ljet/typeinfo/TypeInfo;");
|
v.visitFieldInsn(PUTSTATIC, jvmClassName, fieldName, "Ljet/typeinfo/TypeInfo;");
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import org.jetbrains.jet.codegen.ExpressionCodegen;
|
|||||||
import org.jetbrains.jet.codegen.JetTypeMapper;
|
import org.jetbrains.jet.codegen.JetTypeMapper;
|
||||||
import org.jetbrains.jet.codegen.StackValue;
|
import org.jetbrains.jet.codegen.StackValue;
|
||||||
import org.jetbrains.jet.lang.psi.JetExpression;
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetParenthesizedExpression;
|
||||||
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
|
import org.jetbrains.jet.lang.psi.JetReferenceExpression;
|
||||||
import org.objectweb.asm.Type;
|
import org.objectweb.asm.Type;
|
||||||
import org.objectweb.asm.commons.InstructionAdapter;
|
import org.objectweb.asm.commons.InstructionAdapter;
|
||||||
@@ -23,7 +24,10 @@ public class Increment implements IntrinsicMethod {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
|
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
|
||||||
final JetExpression operand = arguments.get(0);
|
JetExpression operand = arguments.get(0);
|
||||||
|
while(operand instanceof JetParenthesizedExpression) {
|
||||||
|
operand = ((JetParenthesizedExpression)operand).getExpression();
|
||||||
|
}
|
||||||
if (operand instanceof JetReferenceExpression) {
|
if (operand instanceof JetReferenceExpression) {
|
||||||
final int index = codegen.indexOfLocal((JetReferenceExpression) operand);
|
final int index = codegen.indexOfLocal((JetReferenceExpression) operand);
|
||||||
if (index >= 0 && JetTypeMapper.isIntPrimitive(expectedType)) {
|
if (index >= 0 && JetTypeMapper.isIntPrimitive(expectedType)) {
|
||||||
@@ -33,6 +37,7 @@ public class Increment implements IntrinsicMethod {
|
|||||||
}
|
}
|
||||||
StackValue value = codegen.genQualified(receiver, operand);
|
StackValue value = codegen.genQualified(receiver, operand);
|
||||||
value. dupReceiver(v);
|
value. dupReceiver(v);
|
||||||
|
value. dupReceiver(v);
|
||||||
value.put(expectedType, v);
|
value.put(expectedType, v);
|
||||||
if (expectedType == Type.LONG_TYPE) {
|
if (expectedType == Type.LONG_TYPE) {
|
||||||
v.lconst(myDelta);
|
v.lconst(myDelta);
|
||||||
@@ -44,10 +49,11 @@ public class Increment implements IntrinsicMethod {
|
|||||||
v.dconst(myDelta);
|
v.dconst(myDelta);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
v.aconst(myDelta);
|
v.iconst(myDelta);
|
||||||
}
|
}
|
||||||
v.add(expectedType);
|
v.add(expectedType);
|
||||||
value.store(v);
|
value.store(v);
|
||||||
return value;
|
value.put(expectedType, v);
|
||||||
|
return StackValue.onStack(expectedType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import org.jetbrains.jet.lang.types.JetStandardLibrary;
|
|||||||
import org.jetbrains.jet.lang.types.TypeProjection;
|
import org.jetbrains.jet.lang.types.TypeProjection;
|
||||||
import org.jetbrains.jet.plugin.JetFileType;
|
import org.jetbrains.jet.plugin.JetFileType;
|
||||||
import org.objectweb.asm.Opcodes;
|
import org.objectweb.asm.Opcodes;
|
||||||
|
import sun.tools.tree.NewArrayExpression;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@@ -85,6 +86,7 @@ public class IntrinsicMethods {
|
|||||||
declareOverload(myStdLib.getLibraryScope().getFunctions("equals"), 1, EQUALS);
|
declareOverload(myStdLib.getLibraryScope().getFunctions("equals"), 1, EQUALS);
|
||||||
declareOverload(myStdLib.getLibraryScope().getFunctions("identityEquals"), 1, EQUALS);
|
declareOverload(myStdLib.getLibraryScope().getFunctions("identityEquals"), 1, EQUALS);
|
||||||
declareOverload(myStdLib.getLibraryScope().getFunctions("plus"), 1, new StringPlus());
|
declareOverload(myStdLib.getLibraryScope().getFunctions("plus"), 1, new StringPlus());
|
||||||
|
declareOverload(myStdLib.getLibraryScope().getFunctions("Array"), 1, new NewArray());
|
||||||
|
|
||||||
declareIntrinsicFunction("ByteIterator", "next", 0, ITERATOR_NEXT);
|
declareIntrinsicFunction("ByteIterator", "next", 0, ITERATOR_NEXT);
|
||||||
declareIntrinsicFunction("ShortIterator", "next", 0, ITERATOR_NEXT);
|
declareIntrinsicFunction("ShortIterator", "next", 0, ITERATOR_NEXT);
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
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.JetCallExpression;
|
||||||
|
import org.jetbrains.jet.lang.psi.JetExpression;
|
||||||
|
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||||
|
import org.objectweb.asm.Type;
|
||||||
|
import org.objectweb.asm.commons.InstructionAdapter;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author alex.tkachman
|
||||||
|
*/
|
||||||
|
public class NewArray implements IntrinsicMethod {
|
||||||
|
@Override
|
||||||
|
public StackValue generate(ExpressionCodegen codegen, InstructionAdapter v, Type expectedType, PsiElement element, List<JetExpression> arguments, StackValue receiver) {
|
||||||
|
codegen.generateNewArray((JetCallExpression) element, codegen.getBindingContext().get(BindingContext.EXPRESSION_TYPE, (JetExpression) element));
|
||||||
|
return StackValue.onStack(expectedType);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -105,7 +105,9 @@ trait Iterable<out T> {
|
|||||||
fun iterator() : Iterator<T>
|
fun iterator() : Iterator<T>
|
||||||
}
|
}
|
||||||
|
|
||||||
class Array<T>(val size : Int, init : fun(Int) : T = null ) {
|
fun Array<T>(val size : Int) : Array<T?>
|
||||||
|
|
||||||
|
class Array<T>(val size : Int, init : fun(Int) : T) {
|
||||||
fun get(index : Int) : T
|
fun get(index : Int) : T
|
||||||
fun set(index : Int, value : T) : Unit
|
fun set(index : Int, value : T) : Unit
|
||||||
|
|
||||||
|
|||||||
@@ -141,7 +141,6 @@ public interface JetNodeTypes {
|
|||||||
|
|
||||||
JetNodeType WHEN_CONDITION_IN_RANGE = new JetNodeType("WHEN_CONDITION_IN_RANGE", JetWhenConditionInRange.class);
|
JetNodeType WHEN_CONDITION_IN_RANGE = new JetNodeType("WHEN_CONDITION_IN_RANGE", JetWhenConditionInRange.class);
|
||||||
JetNodeType WHEN_CONDITION_IS_PATTERN = new JetNodeType("WHEN_CONDITION_IS_PATTERN", JetWhenConditionIsPattern.class);
|
JetNodeType WHEN_CONDITION_IS_PATTERN = new JetNodeType("WHEN_CONDITION_IS_PATTERN", JetWhenConditionIsPattern.class);
|
||||||
JetNodeType WHEN_CONDITION_CALL = new JetNodeType("WHEN_CONDITION_CALL", JetWhenConditionCall.class);
|
|
||||||
|
|
||||||
JetNodeType NAMESPACE_NAME = new JetNodeType("NAMESPACE_NAME", JetContainerNode.class);
|
JetNodeType NAMESPACE_NAME = new JetNodeType("NAMESPACE_NAME", JetContainerNode.class);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -62,10 +62,6 @@ public class JetControlFlowProcessor {
|
|||||||
private class CFPVisitor extends JetVisitorVoid {
|
private class CFPVisitor extends JetVisitorVoid {
|
||||||
private final boolean inCondition;
|
private final boolean inCondition;
|
||||||
private final JetVisitorVoid conditionVisitor = new JetVisitorVoid() {
|
private final JetVisitorVoid conditionVisitor = new JetVisitorVoid() {
|
||||||
@Override
|
|
||||||
public void visitWhenConditionCall(JetWhenConditionCall condition) {
|
|
||||||
value(condition.getCallSuffixExpression(), CFPVisitor.this.inCondition); // TODO : inCondition?
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitWhenConditionInRange(JetWhenConditionInRange condition) {
|
public void visitWhenConditionInRange(JetWhenConditionInRange condition) {
|
||||||
|
|||||||
@@ -21,7 +21,9 @@ public interface CallableDescriptor extends DeclarationDescriptor {
|
|||||||
@NotNull
|
@NotNull
|
||||||
List<TypeParameterDescriptor> getTypeParameters();
|
List<TypeParameterDescriptor> getTypeParameters();
|
||||||
|
|
||||||
@NotNull
|
/**
|
||||||
|
* Method may return null for not yet fully initialized object or if error occurred.
|
||||||
|
*/
|
||||||
JetType getReturnType();
|
JetType getReturnType();
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
@@ -120,7 +120,6 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@NotNull
|
|
||||||
public JetType getReturnType() {
|
public JetType getReturnType() {
|
||||||
return unsubstitutedReturnType;
|
return unsubstitutedReturnType;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -113,7 +113,6 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
|
|||||||
return expectedThisObject;
|
return expectedThisObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
@Override
|
||||||
public JetType getReturnType() {
|
public JetType getReturnType() {
|
||||||
return getOutType();
|
return getOutType();
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ public class PropertyGetterDescriptor extends PropertyAccessorDescriptor {
|
|||||||
return Collections.emptyList();
|
return Collections.emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
@Override
|
||||||
public JetType getReturnType() {
|
public JetType getReturnType() {
|
||||||
return returnType;
|
return returnType;
|
||||||
|
|||||||
@@ -84,7 +84,6 @@ public abstract class VariableDescriptorImpl extends DeclarationDescriptorImpl i
|
|||||||
return ReceiverDescriptor.NO_RECEIVER;
|
return ReceiverDescriptor.NO_RECEIVER;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
|
||||||
@Override
|
@Override
|
||||||
public JetType getReturnType() {
|
public JetType getReturnType() {
|
||||||
return getOutType();
|
return getOutType();
|
||||||
|
|||||||
@@ -288,7 +288,10 @@ public interface Errors {
|
|||||||
ParameterizedDiagnosticFactory2<JetType, Integer> TYPE_MISMATCH_IN_TUPLE_PATTERN = ParameterizedDiagnosticFactory2.create(ERROR, "Type mismatch: subject is of type {0} but the pattern is of type Tuple{1}"); // TODO: message
|
ParameterizedDiagnosticFactory2<JetType, Integer> TYPE_MISMATCH_IN_TUPLE_PATTERN = ParameterizedDiagnosticFactory2.create(ERROR, "Type mismatch: subject is of type {0} but the pattern is of type Tuple{1}"); // TODO: message
|
||||||
ParameterizedDiagnosticFactory2<JetType, JetType> TYPE_MISMATCH_IN_BINDING_PATTERN = ParameterizedDiagnosticFactory2.create(ERROR, "{0} must be a supertype of {1}. Use 'is' to match against {0}");
|
ParameterizedDiagnosticFactory2<JetType, JetType> TYPE_MISMATCH_IN_BINDING_PATTERN = ParameterizedDiagnosticFactory2.create(ERROR, "{0} must be a supertype of {1}. Use 'is' to match against {0}");
|
||||||
ParameterizedDiagnosticFactory2<JetType, JetType> INCOMPATIBLE_TYPES = ParameterizedDiagnosticFactory2.create(ERROR, "Incompatible types: {0} and {1}");
|
ParameterizedDiagnosticFactory2<JetType, JetType> INCOMPATIBLE_TYPES = ParameterizedDiagnosticFactory2.create(ERROR, "Incompatible types: {0} and {1}");
|
||||||
|
|
||||||
|
ParameterizedDiagnosticFactory1<JetType> CANNOT_CHECK_FOR_ERASED = ParameterizedDiagnosticFactory1.create(ERROR, "Cannot check for instance of erased type: {0}");
|
||||||
|
ParameterizedDiagnosticFactory2<JetType, JetType> UNCHECKED_CAST = ParameterizedDiagnosticFactory2.create(WARNING, "Unchecked cast: {0} to {1}");
|
||||||
|
|
||||||
ParameterizedDiagnosticFactory3<TypeParameterDescriptor, ClassDescriptor, Collection<JetType>> INCONSISTENT_TYPE_PARAMETER_VALUES = new ParameterizedDiagnosticFactory3<TypeParameterDescriptor, ClassDescriptor, Collection<JetType>>(ERROR, "Type parameter {0} of {1} has inconsistent values: {2}") {
|
ParameterizedDiagnosticFactory3<TypeParameterDescriptor, ClassDescriptor, Collection<JetType>> INCONSISTENT_TYPE_PARAMETER_VALUES = new ParameterizedDiagnosticFactory3<TypeParameterDescriptor, ClassDescriptor, Collection<JetType>>(ERROR, "Type parameter {0} of {1} has inconsistent values: {2}") {
|
||||||
@Override
|
@Override
|
||||||
protected String makeMessageForA(@NotNull TypeParameterDescriptor typeParameterDescriptor) {
|
protected String makeMessageForA(@NotNull TypeParameterDescriptor typeParameterDescriptor) {
|
||||||
@@ -370,7 +373,7 @@ public interface Errors {
|
|||||||
ParameterizedDiagnosticFactory2<JetClassOrObject, CallableMemberDescriptor> ABSTRACT_MEMBER_NOT_IMPLEMENTED = new ParameterizedDiagnosticFactory2<JetClassOrObject, CallableMemberDescriptor>(ERROR, "Class ''{0}'' must be declared abstract or implement abstract member {1}") {
|
ParameterizedDiagnosticFactory2<JetClassOrObject, CallableMemberDescriptor> ABSTRACT_MEMBER_NOT_IMPLEMENTED = new ParameterizedDiagnosticFactory2<JetClassOrObject, CallableMemberDescriptor>(ERROR, "Class ''{0}'' must be declared abstract or implement abstract member {1}") {
|
||||||
@Override
|
@Override
|
||||||
protected String makeMessageForA(@NotNull JetClassOrObject jetClassOrObject) {
|
protected String makeMessageForA(@NotNull JetClassOrObject jetClassOrObject) {
|
||||||
return jetClassOrObject.getName();
|
return JetPsiUtil.safeName(jetClassOrObject.getName());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -419,7 +419,10 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
}
|
}
|
||||||
else return false;
|
else return false;
|
||||||
}
|
}
|
||||||
else return false;
|
else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -764,7 +767,6 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
/*
|
/*
|
||||||
* whenCondition
|
* whenCondition
|
||||||
* : expression
|
* : expression
|
||||||
* : ("." | "?." postfixExpression typeArguments? valueArguments?
|
|
||||||
* : ("in" | "!in") expression
|
* : ("in" | "!in") expression
|
||||||
* : ("is" | "!is") isRHS
|
* : ("is" | "!is") isRHS
|
||||||
* ;
|
* ;
|
||||||
@@ -793,21 +795,10 @@ public class JetExpressionParsing extends AbstractJetParsing {
|
|||||||
parsePattern();
|
parsePattern();
|
||||||
}
|
}
|
||||||
condition.done(WHEN_CONDITION_IS_PATTERN);
|
condition.done(WHEN_CONDITION_IS_PATTERN);
|
||||||
} else if (at(DOT) || at(SAFE_ACCESS)) {
|
|
||||||
advance(); // DOT or SAFE_ACCESS
|
|
||||||
PsiBuilder.Marker mark = mark();
|
|
||||||
parsePostfixExpression();
|
|
||||||
if (parseCallSuffix()) {
|
|
||||||
mark.done(CALL_EXPRESSION);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
mark.drop();
|
|
||||||
}
|
|
||||||
condition.done(WHEN_CONDITION_CALL);
|
|
||||||
} else {
|
} else {
|
||||||
PsiBuilder.Marker expressionPattern = mark();
|
PsiBuilder.Marker expressionPattern = mark();
|
||||||
if (atSet(WHEN_CONDITION_RECOVERY_SET_WITH_DOUBLE_ARROW)) {
|
if (atSet(WHEN_CONDITION_RECOVERY_SET_WITH_DOUBLE_ARROW)) {
|
||||||
error("Expecting an element, is-condition or in-condition");
|
error("Expecting an expression, is-condition or in-condition");
|
||||||
} else {
|
} else {
|
||||||
parseExpression();
|
parseExpression();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -356,10 +356,6 @@ public class JetVisitor<R, D> extends PsiElementVisitor {
|
|||||||
return visitExpression(expression, data);
|
return visitExpression(expression, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
public R visitWhenConditionCall(JetWhenConditionCall condition, D data) {
|
|
||||||
return visitJetElement(condition, data);
|
|
||||||
}
|
|
||||||
|
|
||||||
public R visitWhenConditionIsPattern(JetWhenConditionIsPattern condition, D data) {
|
public R visitWhenConditionIsPattern(JetWhenConditionIsPattern condition, D data) {
|
||||||
return visitJetElement(condition, data);
|
return visitJetElement(condition, data);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -354,10 +354,6 @@ public class JetVisitorVoid extends PsiElementVisitor {
|
|||||||
visitExpression(expression);
|
visitExpression(expression);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void visitWhenConditionCall(JetWhenConditionCall condition) {
|
|
||||||
visitJetElement(condition);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void visitWhenConditionIsPattern(JetWhenConditionIsPattern condition) {
|
public void visitWhenConditionIsPattern(JetWhenConditionIsPattern condition) {
|
||||||
visitJetElement(condition);
|
visitJetElement(condition);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
package org.jetbrains.jet.lang.psi;
|
|
||||||
|
|
||||||
import com.intellij.lang.ASTNode;
|
|
||||||
import com.intellij.psi.tree.TokenSet;
|
|
||||||
import org.jetbrains.annotations.NotNull;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.jetbrains.jet.lexer.JetTokens;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @author abreslav
|
|
||||||
*/
|
|
||||||
public class JetWhenConditionCall extends JetWhenCondition {
|
|
||||||
public JetWhenConditionCall(@NotNull ASTNode node) {
|
|
||||||
super(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isSafeCall() {
|
|
||||||
return getNode().findChildByType(JetTokens.SAFE_ACCESS) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@NotNull
|
|
||||||
public ASTNode getOperationTokenNode() {
|
|
||||||
return getNode().findChildByType(TokenSet.create(JetTokens.SAFE_ACCESS, JetTokens.DOT));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Nullable @IfNotParsed
|
|
||||||
public JetExpression getCallSuffixExpression() {
|
|
||||||
return findChildByClass(JetExpression.class);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void accept(@NotNull JetVisitorVoid visitor) {
|
|
||||||
visitor.visitWhenConditionCall(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public <R, D> R accept(@NotNull JetVisitor<R, D> visitor, D data) {
|
|
||||||
return visitor.visitWhenConditionCall(this, data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -39,6 +39,8 @@ import static org.jetbrains.jet.lang.types.TypeUtils.NO_EXPECTED_TYPE;
|
|||||||
* @author abreslav
|
* @author abreslav
|
||||||
*/
|
*/
|
||||||
public class CallResolver {
|
public class CallResolver {
|
||||||
|
private static final JetType DONT_CARE = ErrorUtils.createErrorTypeWithCustomDebugName("DONT_CARE");
|
||||||
|
|
||||||
private final JetSemanticServices semanticServices;
|
private final JetSemanticServices semanticServices;
|
||||||
private final OverloadingConflictResolver overloadingConflictResolver;
|
private final OverloadingConflictResolver overloadingConflictResolver;
|
||||||
private final DataFlowInfo dataFlowInfo;
|
private final DataFlowInfo dataFlowInfo;
|
||||||
@@ -412,7 +414,7 @@ public class CallResolver {
|
|||||||
constraintSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT); // TODO
|
constraintSystem.registerTypeVariable(typeParameterDescriptor, Variance.INVARIANT); // TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeSubstitutor substituteUnknown = ConstraintSystemImpl.makeConstantSubstitutor(candidate.getTypeParameters(), ErrorUtils.createErrorType("Unknown"));
|
TypeSubstitutor substituteDontCare = ConstraintSystemImpl.makeConstantSubstitutor(candidate.getTypeParameters(), DONT_CARE);
|
||||||
|
|
||||||
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : candidateCall.getValueArguments().entrySet()) {
|
for (Map.Entry<ValueParameterDescriptor, ResolvedValueArgument> entry : candidateCall.getValueArguments().entrySet()) {
|
||||||
ResolvedValueArgument valueArgument = entry.getValue();
|
ResolvedValueArgument valueArgument = entry.getValue();
|
||||||
@@ -428,7 +430,7 @@ public class CallResolver {
|
|||||||
// We'll type check the arguments later, with the inferred types expected
|
// We'll type check the arguments later, with the inferred types expected
|
||||||
TemporaryBindingTrace traceForUnknown = TemporaryBindingTrace.create(temporaryTrace);
|
TemporaryBindingTrace traceForUnknown = TemporaryBindingTrace.create(temporaryTrace);
|
||||||
ExpressionTypingServices temporaryServices = new ExpressionTypingServices(semanticServices, traceForUnknown);
|
ExpressionTypingServices temporaryServices = new ExpressionTypingServices(semanticServices, traceForUnknown);
|
||||||
JetType type = temporaryServices.getType(scope, expression, substituteUnknown.substitute(valueParameterDescriptor.getOutType(), Variance.INVARIANT));
|
JetType type = temporaryServices.getType(scope, expression, substituteDontCare.substitute(valueParameterDescriptor.getOutType(), Variance.INVARIANT));
|
||||||
if (type != null) {
|
if (type != null) {
|
||||||
constraintSystem.addSubtypingConstraint(type, effectiveExpectedType);
|
constraintSystem.addSubtypingConstraint(type, effectiveExpectedType);
|
||||||
}
|
}
|
||||||
@@ -439,10 +441,10 @@ public class CallResolver {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Error is already reported if something is missing
|
// Error is already reported if something is missing
|
||||||
ReceiverDescriptor receiverParameter = candidateCall.getReceiverArgument();
|
ReceiverDescriptor receiverArgument = candidateCall.getReceiverArgument();
|
||||||
ReceiverDescriptor candidateReceiver = candidate.getReceiverParameter();
|
ReceiverDescriptor receiverParameter = candidate.getReceiverParameter();
|
||||||
if (receiverParameter.exists() && candidateReceiver.exists()) {
|
if (receiverArgument.exists() && receiverParameter.exists()) {
|
||||||
constraintSystem.addSubtypingConstraint(receiverParameter.getType(), candidateReceiver.getType());
|
constraintSystem.addSubtypingConstraint(receiverArgument.getType(), receiverParameter.getType());
|
||||||
}
|
}
|
||||||
|
|
||||||
if (expectedType != NO_EXPECTED_TYPE) {
|
if (expectedType != NO_EXPECTED_TYPE) {
|
||||||
|
|||||||
@@ -171,11 +171,20 @@ public class ErrorUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static JetType createErrorType(String debugMessage, JetScope memberScope) {
|
private static JetType createErrorType(String debugMessage, JetScope memberScope) {
|
||||||
return new ErrorTypeImpl(new TypeConstructorImpl(ERROR_CLASS, Collections.<AnnotationDescriptor>emptyList(), false, "[ERROR : " + debugMessage + "]", Collections.<TypeParameterDescriptor>emptyList(), Collections.singleton(JetStandardClasses.getAnyType())), memberScope);
|
return createErrorTypeWithCustomDebugName(memberScope, "[ERROR : " + debugMessage + "]");
|
||||||
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
|
public static JetType createErrorTypeWithCustomDebugName(String debugName) {
|
||||||
|
return createErrorTypeWithCustomDebugName(ERROR_SCOPE, debugName);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static JetType createErrorTypeWithCustomDebugName(JetScope memberScope, String debugName) {
|
||||||
|
return new ErrorTypeImpl(new TypeConstructorImpl(ERROR_CLASS, Collections.<AnnotationDescriptor>emptyList(), false, debugName, Collections.<TypeParameterDescriptor>emptyList(), Collections.singleton(JetStandardClasses.getAnyType())), memberScope);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static JetType createWrongVarianceErrorType(TypeProjection value) {
|
public static JetType createWrongVarianceErrorType(TypeProjection value) {
|
||||||
return createErrorType(value + " is not allowed here]", value.getType().getMemberScope());
|
return createErrorType(value + " is not allowed here", value.getType().getMemberScope());
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ClassifierDescriptor getErrorClass() {
|
public static ClassifierDescriptor getErrorClass() {
|
||||||
|
|||||||
@@ -284,7 +284,7 @@ public class JetStandardLibrary {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public ClassDescriptor getArray() {
|
public ClassDescriptor getArray() {
|
||||||
initStdClasses();
|
initStdClasses();
|
||||||
return arrayClass;
|
return arrayClass;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -110,54 +110,65 @@ public class TypeUtils {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static JetType intersect(JetTypeChecker typeChecker, Set<JetType> types) {
|
public static JetType intersect(@NotNull JetTypeChecker typeChecker, @NotNull Set<JetType> types) {
|
||||||
assert !types.isEmpty();
|
assert !types.isEmpty();
|
||||||
|
|
||||||
if (types.size() == 1) {
|
if (types.size() == 1) {
|
||||||
return types.iterator().next();
|
return types.iterator().next();
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder debugName = new StringBuilder();
|
// Intersection of T1..Tn is an intersection of their non-null versions,
|
||||||
boolean nullable = false;
|
// made nullable is they all were nullable
|
||||||
Set<JetType> resultingTypes = Sets.newHashSet();
|
boolean allNullable = true;
|
||||||
|
boolean nothingTypePresent = false;
|
||||||
|
List<JetType> nullabilityStripped = Lists.newArrayList();
|
||||||
|
for (JetType type : types) {
|
||||||
|
nothingTypePresent |= JetStandardClasses.isNothingOrNullableNothing(type);
|
||||||
|
allNullable &= type.isNullable();
|
||||||
|
nullabilityStripped.add(makeNotNullable(type));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (nothingTypePresent) {
|
||||||
|
return allNullable ? JetStandardClasses.getNullableNothingType() : JetStandardClasses.getNothingType();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now we remove types that have subtypes in the list
|
||||||
|
List<JetType> resultingTypes = Lists.newArrayList();
|
||||||
outer:
|
outer:
|
||||||
for (Iterator<JetType> iterator = types.iterator(); iterator.hasNext();) {
|
for (JetType type : nullabilityStripped) {
|
||||||
JetType type = iterator.next();
|
|
||||||
|
|
||||||
if (!canHaveSubtypes(typeChecker, type)) {
|
if (!canHaveSubtypes(typeChecker, type)) {
|
||||||
for (JetType other : types) {
|
for (JetType other : nullabilityStripped) {
|
||||||
// It makes sense to check for subtyping of other <: type, despite that
|
// It makes sense to check for subtyping of other <: type, despite that
|
||||||
// type is not supposed to be open, for there're enums
|
// type is not supposed to be open, for there're enums
|
||||||
if (!type.equals(other) && !typeChecker.isSubtypeOf(type, other) && !typeChecker.isSubtypeOf(other, type)) {
|
if (!type.equals(other) && !typeChecker.isSubtypeOf(type, other) && !typeChecker.isSubtypeOf(other, type)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return type;
|
return makeNullableAsSpecified(type, allNullable);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
for (JetType other : types) {
|
for (JetType other : nullabilityStripped) {
|
||||||
if (!type.equals(other) && typeChecker.isSubtypeOf(other, type)) {
|
if (!type.equals(other) && typeChecker.isSubtypeOf(other, type)) {
|
||||||
continue outer;
|
continue outer;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nullable |= type.isNullable();
|
|
||||||
|
|
||||||
resultingTypes.add(type);
|
resultingTypes.add(type);
|
||||||
debugName.append(type.toString());
|
|
||||||
if (iterator.hasNext()) {
|
|
||||||
debugName.append(" & ");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (resultingTypes.size() == 1) {
|
||||||
|
return makeNullableAsSpecified(resultingTypes.get(0), allNullable);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
List<AnnotationDescriptor> noAnnotations = Collections.<AnnotationDescriptor>emptyList();
|
List<AnnotationDescriptor> noAnnotations = Collections.<AnnotationDescriptor>emptyList();
|
||||||
TypeConstructor constructor = new TypeConstructorImpl(
|
TypeConstructor constructor = new TypeConstructorImpl(
|
||||||
null,
|
null,
|
||||||
noAnnotations,
|
noAnnotations,
|
||||||
false,
|
false,
|
||||||
debugName.toString(),
|
makeDebugNameForIntersectionType(resultingTypes).toString(),
|
||||||
Collections.<TypeParameterDescriptor>emptyList(),
|
Collections.<TypeParameterDescriptor>emptyList(),
|
||||||
resultingTypes);
|
resultingTypes);
|
||||||
|
|
||||||
@@ -171,11 +182,25 @@ public class TypeUtils {
|
|||||||
return new JetTypeImpl(
|
return new JetTypeImpl(
|
||||||
noAnnotations,
|
noAnnotations,
|
||||||
constructor,
|
constructor,
|
||||||
nullable,
|
allNullable,
|
||||||
Collections.<TypeProjection>emptyList(),
|
Collections.<TypeProjection>emptyList(),
|
||||||
new ChainedScope(null, scopes)); // TODO : check intersectibility, don't use a chanied scope
|
new ChainedScope(null, scopes)); // TODO : check intersectibility, don't use a chanied scope
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static StringBuilder makeDebugNameForIntersectionType(Iterable<JetType> resultingTypes) {
|
||||||
|
StringBuilder debugName = new StringBuilder("{");
|
||||||
|
for (Iterator<JetType> iterator = resultingTypes.iterator(); iterator.hasNext(); ) {
|
||||||
|
JetType type = iterator.next();
|
||||||
|
|
||||||
|
debugName.append(type.toString());
|
||||||
|
if (iterator.hasNext()) {
|
||||||
|
debugName.append(" & ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
debugName.append("}");
|
||||||
|
return debugName;
|
||||||
|
}
|
||||||
|
|
||||||
public static boolean canHaveSubtypes(JetTypeChecker typeChecker, JetType type) {
|
public static boolean canHaveSubtypes(JetTypeChecker typeChecker, JetType type) {
|
||||||
if (type.isNullable()) {
|
if (type.isNullable()) {
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
+55
@@ -1,6 +1,7 @@
|
|||||||
package org.jetbrains.jet.lang.types.expressions;
|
package org.jetbrains.jet.lang.types.expressions;
|
||||||
|
|
||||||
import com.google.common.collect.Lists;
|
import com.google.common.collect.Lists;
|
||||||
|
import com.google.common.collect.Multimap;
|
||||||
import com.intellij.lang.ASTNode;
|
import com.intellij.lang.ASTNode;
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.tree.IElementType;
|
import com.intellij.psi.tree.IElementType;
|
||||||
@@ -8,6 +9,7 @@ import org.jetbrains.annotations.NotNull;
|
|||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.JetNodeTypes;
|
import org.jetbrains.jet.JetNodeTypes;
|
||||||
import org.jetbrains.jet.lang.descriptors.*;
|
import org.jetbrains.jet.lang.descriptors.*;
|
||||||
|
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.*;
|
import org.jetbrains.jet.lang.resolve.*;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
|
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
|
||||||
@@ -245,10 +247,63 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
else {
|
else {
|
||||||
if (typeChecker.isSubtypeOf(actualType, targetType)) {
|
if (typeChecker.isSubtypeOf(actualType, targetType)) {
|
||||||
context.trace.report(USELESS_CAST.on(expression, expression.getOperationSign()));
|
context.trace.report(USELESS_CAST.on(expression, expression.getOperationSign()));
|
||||||
|
} else {
|
||||||
|
if (isCastErased(actualType, targetType)) {
|
||||||
|
context.trace.report(Errors.UNCHECKED_CAST.on(expression, actualType, targetType));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if assignment from ActualType to TargetType is erased.
|
||||||
|
* It is an error in "is" statement and warning in "as".
|
||||||
|
*/
|
||||||
|
public static boolean isCastErased(JetType actualType, JetType targetType) {
|
||||||
|
|
||||||
|
if (!(targetType.getConstructor().getDeclarationDescriptor() instanceof ClassDescriptor)) {
|
||||||
|
// TODO: what if it is TypeParameterDescriptor?
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
JetType targetTypeClerared = TypeUtils.makeUnsubstitutedType(
|
||||||
|
(ClassDescriptor) targetType.getConstructor().getDeclarationDescriptor(), null);
|
||||||
|
|
||||||
|
Multimap<TypeConstructor, TypeProjection> clearTypeSubstitutionMap =
|
||||||
|
TypeUtils.buildDeepSubstitutionMultimap(targetTypeClerared);
|
||||||
|
|
||||||
|
Set<JetType> clearSubstituted = new HashSet<JetType>();
|
||||||
|
|
||||||
|
for (int i = 0; i < actualType.getConstructor().getParameters().size(); ++i) {
|
||||||
|
TypeParameterDescriptor subjectTypeParameterDescriptor = actualType.getConstructor().getParameters().get(i);
|
||||||
|
|
||||||
|
Collection<TypeProjection> subst = clearTypeSubstitutionMap.get(subjectTypeParameterDescriptor.getTypeConstructor());
|
||||||
|
for (TypeProjection proj : subst) {
|
||||||
|
clearSubstituted.add(proj.getType());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i < targetType.getConstructor().getParameters().size(); ++i) {
|
||||||
|
TypeParameterDescriptor typeParameter = targetType.getConstructor().getParameters().get(i);
|
||||||
|
TypeProjection typeProjection = targetType.getArguments().get(i);
|
||||||
|
|
||||||
|
if (typeParameter.isReified()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// "is List<*>"
|
||||||
|
if (typeProjection.equals(TypeUtils.makeStarProjection(typeParameter))) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// if parameter is mapped to nothing then it is erased
|
||||||
|
if (!clearSubstituted.contains(typeParameter.getDefaultType())) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public JetType visitTupleExpression(JetTupleExpression expression, ExpressionTypingContext context) {
|
public JetType visitTupleExpression(JetTupleExpression expression, ExpressionTypingContext context) {
|
||||||
List<JetExpression> entries = expression.getEntries();
|
List<JetExpression> entries = expression.getEntries();
|
||||||
|
|||||||
+10
-15
@@ -6,6 +6,7 @@ import com.intellij.openapi.util.Ref;
|
|||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
import org.jetbrains.jet.lang.descriptors.VariableDescriptor;
|
||||||
|
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||||
import org.jetbrains.jet.lang.psi.*;
|
import org.jetbrains.jet.lang.psi.*;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
|
||||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValue;
|
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValue;
|
||||||
@@ -17,8 +18,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
|||||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.TransientReceiver;
|
import org.jetbrains.jet.lang.resolve.scopes.receivers.TransientReceiver;
|
||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.*;
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||||
import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.ensureBooleanResultWithCustomSubject;
|
import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.ensureBooleanResultWithCustomSubject;
|
||||||
@@ -113,19 +113,6 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
final DataFlowInfo[] newDataFlowInfo = new DataFlowInfo[]{context.dataFlowInfo};
|
final DataFlowInfo[] newDataFlowInfo = new DataFlowInfo[]{context.dataFlowInfo};
|
||||||
condition.accept(new JetVisitorVoid() {
|
condition.accept(new JetVisitorVoid() {
|
||||||
|
|
||||||
@Override
|
|
||||||
public void visitWhenConditionCall(JetWhenConditionCall condition) {
|
|
||||||
JetExpression callSuffixExpression = condition.getCallSuffixExpression();
|
|
||||||
// JetScope compositeScope = new ScopeWithReceiver(context.scope, subjectType, semanticServices.getTypeChecker());
|
|
||||||
if (callSuffixExpression != null) {
|
|
||||||
// JetType selectorReturnType = getType(compositeScope, callSuffixExpression, false, context);
|
|
||||||
assert subjectExpression != null;
|
|
||||||
JetType selectorReturnType = facade.getSelectorReturnType(new ExpressionReceiver(subjectExpression, subjectType), condition.getOperationTokenNode(), callSuffixExpression, context);//getType(compositeScope, callSuffixExpression, false, context);
|
|
||||||
ensureBooleanResultWithCustomSubject(callSuffixExpression, selectorReturnType, "This expression", context);
|
|
||||||
// context.getServices().checkNullSafety(subjectType, condition.getOperationTokenNode(), getCalleeFunctionDescriptor(callSuffixExpression, context), condition);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void visitWhenConditionInRange(JetWhenConditionInRange condition) {
|
public void visitWhenConditionInRange(JetWhenConditionInRange condition) {
|
||||||
JetExpression rangeExpression = condition.getRangeExpression();
|
JetExpression rangeExpression = condition.getRangeExpression();
|
||||||
@@ -245,6 +232,9 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (a: SubjectType) is Type
|
||||||
|
*/
|
||||||
private void checkTypeCompatibility(@Nullable JetType type, @NotNull JetType subjectType, @NotNull JetElement reportErrorOn) {
|
private void checkTypeCompatibility(@Nullable JetType type, @NotNull JetType subjectType, @NotNull JetElement reportErrorOn) {
|
||||||
// TODO : Take auto casts into account?
|
// TODO : Take auto casts into account?
|
||||||
if (type == null) {
|
if (type == null) {
|
||||||
@@ -253,6 +243,11 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
|||||||
if (TypeUtils.intersect(context.semanticServices.getTypeChecker(), Sets.newHashSet(type, subjectType)) == null) {
|
if (TypeUtils.intersect(context.semanticServices.getTypeChecker(), Sets.newHashSet(type, subjectType)) == null) {
|
||||||
// context.trace.getErrorHandler().genericError(reportErrorOn.getNode(), "Incompatible types: " + type + " and " + subjectType);
|
// context.trace.getErrorHandler().genericError(reportErrorOn.getNode(), "Incompatible types: " + type + " and " + subjectType);
|
||||||
context.trace.report(INCOMPATIBLE_TYPES.on(reportErrorOn, type, subjectType));
|
context.trace.report(INCOMPATIBLE_TYPES.on(reportErrorOn, type, subjectType));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (BasicExpressionTypingVisitor.isCastErased(subjectType, type)) {
|
||||||
|
context.trace.report(Errors.CANNOT_CHECK_FOR_ERASED.on(reportErrorOn, type));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+40
-9
@@ -9,6 +9,7 @@ import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
|||||||
import org.jetbrains.jet.lang.types.*;
|
import org.jetbrains.jet.lang.types.*;
|
||||||
|
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
@@ -46,8 +47,19 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static abstract class TypeValue {
|
public static abstract class TypeValue {
|
||||||
private final Set<TypeValue> upperBounds = Sets.newHashSet();
|
private final Set<TypeValue> mutableUpperBounds = Sets.newHashSet();
|
||||||
private final Set<TypeValue> lowerBounds = Sets.newHashSet();
|
private final Set<TypeValue> upperBounds = Collections.unmodifiableSet(mutableUpperBounds);
|
||||||
|
|
||||||
|
private final Set<TypeValue> mutableLowerBounds = Sets.newHashSet();
|
||||||
|
private final Set<TypeValue> lowerBounds = Collections.unmodifiableSet(mutableLowerBounds);
|
||||||
|
|
||||||
|
public void addUpperBound(@NotNull TypeValue bound) {
|
||||||
|
mutableUpperBounds.add(bound);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addLowerBound(@NotNull TypeValue bound) {
|
||||||
|
mutableLowerBounds.add(bound);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public Set<TypeValue> getUpperBounds() {
|
public Set<TypeValue> getUpperBounds() {
|
||||||
@@ -86,8 +98,8 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
|||||||
throw new LoopInTypeVariableConstraintsException();
|
throw new LoopInTypeVariableConstraintsException();
|
||||||
}
|
}
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
JetTypeChecker typeChecker = JetTypeChecker.INSTANCE;
|
|
||||||
beingComputed = true;
|
beingComputed = true;
|
||||||
|
JetTypeChecker typeChecker = JetTypeChecker.INSTANCE;
|
||||||
try {
|
try {
|
||||||
if (positionVariance == Variance.IN_VARIANCE) {
|
if (positionVariance == Variance.IN_VARIANCE) {
|
||||||
// maximal solution
|
// maximal solution
|
||||||
@@ -320,8 +332,8 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
|||||||
private void addSubtypingConstraintOnTypeValues(TypeValue typeValueForLower, TypeValue typeValueForUpper) {
|
private void addSubtypingConstraintOnTypeValues(TypeValue typeValueForLower, TypeValue typeValueForUpper) {
|
||||||
println(typeValueForLower + " :< " + typeValueForUpper);
|
println(typeValueForLower + " :< " + typeValueForUpper);
|
||||||
if (typeValueForLower != typeValueForUpper) {
|
if (typeValueForLower != typeValueForUpper) {
|
||||||
typeValueForLower.getUpperBounds().add(typeValueForUpper);
|
typeValueForLower.addUpperBound(typeValueForUpper);
|
||||||
typeValueForUpper.getLowerBounds().add(typeValueForLower);
|
typeValueForUpper.addLowerBound(typeValueForLower);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -358,13 +370,20 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
|||||||
|
|
||||||
// effective bounds for each node
|
// effective bounds for each node
|
||||||
Set<TypeValue> visited = Sets.newHashSet();
|
Set<TypeValue> visited = Sets.newHashSet();
|
||||||
for (KnownType knownType : knownTypes.values()) {
|
|
||||||
transitiveClosure(knownType, visited);
|
|
||||||
}
|
|
||||||
for (UnknownType unknownType : unknownTypes.values()) {
|
for (UnknownType unknownType : unknownTypes.values()) {
|
||||||
transitiveClosure(unknownType, visited);
|
transitiveClosure(unknownType, visited);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (UnknownType unknownType : unknownTypes.values()) {
|
||||||
|
println("Constraints for " + unknownType.getTypeParameterDescriptor());
|
||||||
|
printTypeValue(unknownType);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (KnownType knownType : knownTypes.values()) {
|
||||||
|
println("Constraints for " + knownType.getType());
|
||||||
|
printTypeValue(knownType);
|
||||||
|
}
|
||||||
|
|
||||||
// Find inconsistencies
|
// Find inconsistencies
|
||||||
Solution solution = new Solution();
|
Solution solution = new Solution();
|
||||||
|
|
||||||
@@ -382,6 +401,15 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
|||||||
return solution;
|
return solution;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void printTypeValue(TypeValue typeValue) {
|
||||||
|
for (TypeValue bound : typeValue.getUpperBounds()) {
|
||||||
|
println(" :< " + bound);
|
||||||
|
}
|
||||||
|
for (TypeValue bound : typeValue.getLowerBounds()) {
|
||||||
|
println(" :> " + bound);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void check(TypeValue typeValue, Solution solution) {
|
private void check(TypeValue typeValue, Solution solution) {
|
||||||
try {
|
try {
|
||||||
KnownType resultingValue = typeValue.getValue();
|
KnownType resultingValue = typeValue.getValue();
|
||||||
@@ -416,7 +444,7 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
solution.registerError("[TODO] Loop in constraints");
|
solution.registerError("[TODO] Loop in constraints");
|
||||||
e.printStackTrace();
|
// e.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -426,6 +454,9 @@ public class ConstraintSystemImpl implements ConstraintSystem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (TypeValue upperBound : Sets.newHashSet(current.getUpperBounds())) {
|
for (TypeValue upperBound : Sets.newHashSet(current.getUpperBounds())) {
|
||||||
|
if (upperBound instanceof KnownType) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
transitiveClosure(upperBound, visited);
|
transitiveClosure(upperBound, visited);
|
||||||
Set<TypeValue> upperBounds = upperBound.getUpperBounds();
|
Set<TypeValue> upperBounds = upperBound.getUpperBounds();
|
||||||
for (TypeValue transitiveBound : upperBounds) {
|
for (TypeValue transitiveBound : upperBounds) {
|
||||||
|
|||||||
@@ -73,7 +73,11 @@ public class DescriptorRenderer implements Renderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String renderType(JetType type) {
|
public String renderType(JetType type) {
|
||||||
return escape(type.toString());
|
if (type == null) {
|
||||||
|
return escape("[NULL]");
|
||||||
|
} else {
|
||||||
|
return escape(type.toString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected String escape(String s) {
|
protected String escape(String s) {
|
||||||
@@ -222,7 +226,6 @@ public class DescriptorRenderer implements Renderer {
|
|||||||
|
|
||||||
renderName(descriptor, builder);
|
renderName(descriptor, builder);
|
||||||
renderValueParameters(descriptor, builder);
|
renderValueParameters(descriptor, builder);
|
||||||
// TODO: getReturnType may be uninitialized and throw IllegalStateException // stepan.koltsov@ 2011-11-21
|
|
||||||
builder.append(" : ").append(escape(renderType(descriptor.getReturnType())));
|
builder.append(" : ").append(escape(renderType(descriptor.getReturnType())));
|
||||||
return super.visitFunctionDescriptor(descriptor, builder);
|
return super.visitFunctionDescriptor(descriptor, builder);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +0,0 @@
|
|||||||
import java.util.Collections
|
|
||||||
import java.util.List
|
|
||||||
|
|
||||||
val ab = Collections.emptyList<Int>() : List<Int>?
|
|
||||||
+3
-1
@@ -1,3 +1,5 @@
|
|||||||
|
// +JDK
|
||||||
|
|
||||||
namespace abstract
|
namespace abstract
|
||||||
|
|
||||||
class MyClass() {
|
class MyClass() {
|
||||||
@@ -238,4 +240,4 @@ abstract class B3(i: Int) {
|
|||||||
fun foo(a: B3) {
|
fun foo(a: B3) {
|
||||||
val <!UNUSED_VARIABLE!>a<!> = <!CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS!>B3()<!>
|
val <!UNUSED_VARIABLE!>a<!> = <!CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS!>B3()<!>
|
||||||
val <!UNUSED_VARIABLE!>b<!> = <!CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS!>B1(2, "s")<!>
|
val <!UNUSED_VARIABLE!>b<!> = <!CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS!>B1(2, "s")<!>
|
||||||
}
|
}
|
||||||
@@ -88,4 +88,4 @@ open class C {
|
|||||||
t = <!UNUSED_VALUE!>this@C<!>
|
t = <!UNUSED_VALUE!>this@C<!>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+2
@@ -1,3 +1,5 @@
|
|||||||
|
// +JDK
|
||||||
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
namespace html {
|
namespace html {
|
||||||
+3
-1
@@ -1,3 +1,5 @@
|
|||||||
|
// +JDK
|
||||||
|
|
||||||
namespace Jet86
|
namespace Jet86
|
||||||
|
|
||||||
class A {
|
class A {
|
||||||
@@ -27,4 +29,4 @@ val s = <!NO_CLASS_OBJECT!>System<!> // error
|
|||||||
fun test() {
|
fun test() {
|
||||||
System.out?.println()
|
System.out?.println()
|
||||||
java.lang.System.out?.println()
|
java.lang.System.out?.println()
|
||||||
}
|
}
|
||||||
+2
@@ -1,3 +1,5 @@
|
|||||||
|
// +JDK
|
||||||
|
|
||||||
trait A {
|
trait A {
|
||||||
fun foo() : Int = 1
|
fun foo() : Int = 1
|
||||||
fun foo2() : Int = 1
|
fun foo2() : Int = 1
|
||||||
+3
-1
@@ -1,3 +1,5 @@
|
|||||||
|
// +JDK
|
||||||
|
|
||||||
fun Int?.optint() : Unit {}
|
fun Int?.optint() : Unit {}
|
||||||
val Int?.optval : Unit = ()
|
val Int?.optval : Unit = ()
|
||||||
|
|
||||||
@@ -68,4 +70,4 @@ namespace null_safety {
|
|||||||
if (command == null) 1
|
if (command == null) 1
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+2
@@ -1,3 +1,5 @@
|
|||||||
|
// +JDK
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
class NotRange1() {
|
class NotRange1() {
|
||||||
+3
-1
@@ -1,3 +1,5 @@
|
|||||||
|
// +JDK
|
||||||
|
|
||||||
fun none() {}
|
fun none() {}
|
||||||
|
|
||||||
fun unitEmptyInfer() {}
|
fun unitEmptyInfer() {}
|
||||||
@@ -209,4 +211,4 @@ fun testFunctionLiterals() {
|
|||||||
object A {}
|
object A {}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
+2
@@ -1,3 +1,5 @@
|
|||||||
|
// +JDK
|
||||||
|
|
||||||
namespace foo
|
namespace foo
|
||||||
|
|
||||||
class X {}
|
class X {}
|
||||||
+3
-1
@@ -1,3 +1,5 @@
|
|||||||
|
// +JDK
|
||||||
|
|
||||||
namespace foobar
|
namespace foobar
|
||||||
|
|
||||||
namespace a {
|
namespace a {
|
||||||
@@ -60,4 +62,4 @@ abstract class Collection<E> : Iterable<E> {
|
|||||||
}
|
}
|
||||||
return iteratee.done()
|
return iteratee.done()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+3
-1
@@ -1,3 +1,5 @@
|
|||||||
|
// +JDK
|
||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
val a : Int? = 0
|
val a : Int? = 0
|
||||||
if (a != null) {
|
if (a != null) {
|
||||||
@@ -277,4 +279,4 @@ fun f9(a : Int?) : Int {
|
|||||||
if (a != null)
|
if (a != null)
|
||||||
return a
|
return a
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
+3
-1
@@ -1,3 +1,5 @@
|
|||||||
|
// +JDK
|
||||||
|
|
||||||
// Fixpoint generic in Java: Enum<T extends Enum<T>>
|
// Fixpoint generic in Java: Enum<T extends Enum<T>>
|
||||||
fun test(a : annotation.RetentionPolicy) {
|
fun test(a : annotation.RetentionPolicy) {
|
||||||
|
|
||||||
@@ -17,4 +19,4 @@ fun test(a : java.util.ArrayList<Int>) {
|
|||||||
|
|
||||||
fun test(a : java.lang.Class<Int>) {
|
fun test(a : java.lang.Class<Int>) {
|
||||||
|
|
||||||
}
|
}
|
||||||
+3
-1
@@ -1,3 +1,5 @@
|
|||||||
|
// +JDK
|
||||||
|
|
||||||
import java.*
|
import java.*
|
||||||
import util.*
|
import util.*
|
||||||
import <!UNRESOLVED_REFERENCE!>utils<!>.*
|
import <!UNRESOLVED_REFERENCE!>utils<!>.*
|
||||||
@@ -49,4 +51,4 @@ fun test(l : java.util.List<Int>) {
|
|||||||
|
|
||||||
namespace xxx {
|
namespace xxx {
|
||||||
import java.lang.Class;
|
import java.lang.Class;
|
||||||
}
|
}
|
||||||
+2
@@ -1,3 +1,5 @@
|
|||||||
|
// +JDK
|
||||||
|
|
||||||
fun t1() : Int{
|
fun t1() : Int{
|
||||||
return 0
|
return 0
|
||||||
<!UNREACHABLE_CODE!>1<!>
|
<!UNREACHABLE_CODE!>1<!>
|
||||||
@@ -50,7 +50,7 @@ class MyTest() {
|
|||||||
i = <!UNUSED_VALUE!>456<!>;
|
i = <!UNUSED_VALUE!>456<!>;
|
||||||
}
|
}
|
||||||
|
|
||||||
fun testWhile(a : Any?, b : Any?) {
|
fun testWhile() {
|
||||||
var a : Any? = true
|
var a : Any? = true
|
||||||
var b : Any? = 34
|
var b : Any? = 34
|
||||||
while (a is Any) {
|
while (a is Any) {
|
||||||
@@ -139,4 +139,4 @@ fun testBackingFieldsNotMarked() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun doSmth(i : Int) {}
|
fun doSmth(i : Int) {}
|
||||||
|
|||||||
+2
@@ -1,3 +1,5 @@
|
|||||||
|
// +JDK
|
||||||
|
|
||||||
class Foo1() : java.util.ArrayList<Int>()
|
class Foo1() : java.util.ArrayList<Int>()
|
||||||
|
|
||||||
open class Bar() {
|
open class Bar() {
|
||||||
+2
-1
@@ -1,4 +1,5 @@
|
|||||||
// KT-389 Wrong type inference for varargs etc.
|
// KT-389 Wrong type inference for varargs etc.
|
||||||
|
// +JDK
|
||||||
|
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -23,4 +24,4 @@ fun test() {
|
|||||||
fool(1, 2, 3)
|
fool(1, 2, 3)
|
||||||
food(1.0, 2.0, 3.0)
|
food(1.0, 2.0, 3.0)
|
||||||
foof(1.0.flt, 2.0.flt, 3.0.flt)
|
foof(1.0.flt, 2.0.flt, 3.0.flt)
|
||||||
}
|
}
|
||||||
+11
-8
@@ -13,16 +13,19 @@ fun foo() : Int {
|
|||||||
1 + <!UNRESOLVED_REFERENCE!>a<!> => 1
|
1 + <!UNRESOLVED_REFERENCE!>a<!> => 1
|
||||||
in 1..<!UNRESOLVED_REFERENCE!>a<!> => 1
|
in 1..<!UNRESOLVED_REFERENCE!>a<!> => 1
|
||||||
!in 1..<!UNRESOLVED_REFERENCE!>a<!> => 1
|
!in 1..<!UNRESOLVED_REFERENCE!>a<!> => 1
|
||||||
.<!UNRESOLVED_REFERENCE!>a<!> => 1
|
// Commented for KT-621 .<!!UNRESOLVED_REFERENCE!>a<!!> => 1
|
||||||
.equals(1).<!UNRESOLVED_REFERENCE!>a<!> => 1
|
// Commented for KT-621 .equals(1).<!!UNRESOLVED_REFERENCE!>a<!!> => 1
|
||||||
<!UNNECESSARY_SAFE_CALL!>?.<!>equals(1) => 1
|
// Commented for KT-621 <!UNNECESSARY_SAFE_CALL!!>?.<!!>equals(1) => 1
|
||||||
else => 1
|
else => 1
|
||||||
}
|
}
|
||||||
return when (<!USELESS_ELVIS!>x<!>?:null) {
|
|
||||||
<!UNSAFE_CALL!>.<!>foo() => 1
|
// Commented for KT-621
|
||||||
.equals(1) => 1
|
// return when (<!!USELESS_ELVIS!>x<!!>?:null) {
|
||||||
?.equals(1).equals(2) => 1
|
// <!!UNSAFE_CALL!!>.<!!>foo() => 1
|
||||||
}
|
// .equals(1) => 1
|
||||||
|
// ?.equals(1).equals(2) => 1
|
||||||
|
// }
|
||||||
|
return 0
|
||||||
}
|
}
|
||||||
|
|
||||||
val _type_test : Int = foo() // this is needed to ensure the inferred return type of foo()
|
val _type_test : Int = foo() // this is needed to ensure the inferred return type of foo()
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// +JDK
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
fun ff(c: Collection<String>) = c <!CAST_NEVER_SUCCEEDS!>as<!> List<Int>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// +JDK
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Collection;
|
||||||
|
|
||||||
|
fun ff(c: Collection<String>) = c as List<String>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// +JDK
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
fun ff(l: Any) = l as List<*>
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
// +JDK
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
fun ff(a: Any) = <!UNCHECKED_CAST!>a as List<String><!>
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
// +JDK
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
fun ff(l: Collection<String>) = l is List<String>
|
||||||
|
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
// +JDK
|
||||||
|
|
||||||
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
open class A
|
||||||
|
|
||||||
|
class B : A
|
||||||
|
|
||||||
|
fun ff(l: Collection<B>) = l is List<out A>
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
// +JDK
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
fun ff(l: Any) = l is <!CANNOT_CHECK_FOR_ERASED!>List<String><!>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
// +JDK
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
fun ff(l: Any) = l is List<*>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
class MyList<T>
|
||||||
|
|
||||||
|
fun ff(a: Any) = a is MyList<String>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
trait Aaa
|
||||||
|
trait Bbb
|
||||||
|
|
||||||
|
fun f(a: Aaa) = a is Bbb
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// +JDK
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
fun ff(l: Any) = when(l) {
|
||||||
|
is <!CANNOT_CHECK_FOR_ERASED!>List<String><!> => 1
|
||||||
|
else 2
|
||||||
|
}
|
||||||
+3
-1
@@ -1,3 +1,5 @@
|
|||||||
|
// +JDK
|
||||||
|
|
||||||
import java.*
|
import java.*
|
||||||
import util.*
|
import util.*
|
||||||
|
|
||||||
@@ -63,4 +65,4 @@ fun main(args: Array<String>) {
|
|||||||
catch(e: Throwable) {
|
catch(e: Throwable) {
|
||||||
System.out?.println(e.getMessage())
|
System.out?.println(e.getMessage())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user