Merge remote branch 'origin/master'
This commit is contained in:
@@ -30,7 +30,7 @@ public class GenerationState {
|
||||
|
||||
public GenerationState(Project project, ClassBuilderFactory builderFactory) {
|
||||
this.project = project;
|
||||
this.standardLibrary = JetStandardLibrary.getJetStandardLibrary(project);
|
||||
this.standardLibrary = JetStandardLibrary.getJetStandardLibrary(project, true);
|
||||
this.factory = new ClassFileFactory(builderFactory, this);
|
||||
this.intrinsics = new IntrinsicMethods(project, standardLibrary);
|
||||
}
|
||||
@@ -82,7 +82,7 @@ public class GenerationState {
|
||||
|
||||
public void compile(JetFile psiFile) {
|
||||
final JetNamespace namespace = psiFile.getRootNamespace();
|
||||
final BindingContext bindingContext = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS).analyzeNamespace(namespace, JetControlFlowDataTraceFactory.EMPTY);
|
||||
final BindingContext bindingContext = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS, true).analyzeNamespace(namespace, JetControlFlowDataTraceFactory.EMPTY);
|
||||
AnalyzingUtils.throwExceptionOnErrors(bindingContext);
|
||||
compileCorrectNamespaces(bindingContext, Collections.singletonList(namespace));
|
||||
// NamespaceCodegen codegen = forNamespace(namespace);
|
||||
|
||||
@@ -84,7 +84,7 @@ public class CompileSession {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
final AnalyzingUtils instance = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS);
|
||||
final AnalyzingUtils instance = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS, true);
|
||||
List<JetNamespace> allNamespaces = new ArrayList<JetNamespace>(mySourceFileNamespaces);
|
||||
allNamespaces.addAll(myLibrarySourceFileNamespaces);
|
||||
myBindingContext = instance.analyzeNamespaces(myEnvironment.getProject(), allNamespaces, Predicates.<PsiFile>alwaysTrue(), JetControlFlowDataTraceFactory.EMPTY);
|
||||
|
||||
@@ -34,7 +34,7 @@ public class AnalyzerFacade {
|
||||
}
|
||||
};
|
||||
|
||||
private static final AnalyzingUtils ANALYZING_UTILS = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS);
|
||||
private static final AnalyzingUtils ANALYZING_UTILS = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS, true);
|
||||
private final static Key<CachedValue<BindingContext>> BINDING_CONTEXT = Key.create("BINDING_CONTEXT");
|
||||
private static final Object lock = new Object();
|
||||
|
||||
|
||||
@@ -17,7 +17,11 @@ public class JetSemanticServices {
|
||||
}
|
||||
|
||||
public static JetSemanticServices createSemanticServices(Project project) {
|
||||
return new JetSemanticServices(JetStandardLibrary.getJetStandardLibrary(project));
|
||||
return createSemanticServices(project, true);
|
||||
}
|
||||
|
||||
public static JetSemanticServices createSemanticServices(Project project, boolean loadFullLibrary) {
|
||||
return new JetSemanticServices(JetStandardLibrary.getJetStandardLibrary(project, loadFullLibrary));
|
||||
}
|
||||
|
||||
private final JetStandardLibrary standardLibrary;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jet.lang.descriptors;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.types.JetType;
|
||||
import org.jetbrains.jet.lang.types.TypeSubstitutor;
|
||||
@@ -24,6 +25,9 @@ public interface CallableDescriptor extends DeclarationDescriptor {
|
||||
@NotNull
|
||||
JetType getReturnType();
|
||||
|
||||
@Nullable
|
||||
JetType getReturnTypeSafe();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
CallableDescriptor getOriginal();
|
||||
|
||||
@@ -125,6 +125,12 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
|
||||
return unsubstitutedReturnType;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public JetType getReturnTypeSafe() {
|
||||
return unsubstitutedReturnType;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public FunctionDescriptor getOriginal() {
|
||||
|
||||
@@ -118,6 +118,11 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Callab
|
||||
return getOutType();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public JetType getReturnTypeSafe() {
|
||||
return getOutType();
|
||||
}
|
||||
|
||||
public boolean isVar() {
|
||||
return isVar;
|
||||
|
||||
@@ -45,6 +45,12 @@ public class PropertyGetterDescriptor extends PropertyAccessorDescriptor {
|
||||
return returnType;
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public JetType getReturnTypeSafe() {
|
||||
return returnType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
|
||||
return visitor.visitPropertyGetterDescriptor(this, data);
|
||||
|
||||
@@ -53,6 +53,11 @@ public class PropertySetterDescriptor extends PropertyAccessorDescriptor {
|
||||
return JetStandardClasses.getUnitType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JetType getReturnTypeSafe() {
|
||||
return getReturnType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
|
||||
return visitor.visitPropertySetterDescriptor(this, data);
|
||||
|
||||
@@ -89,4 +89,10 @@ public abstract class VariableDescriptorImpl extends DeclarationDescriptorImpl i
|
||||
public JetType getReturnType() {
|
||||
return getOutType();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public JetType getReturnTypeSafe() {
|
||||
return getOutType();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,7 @@ import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import static org.jetbrains.jet.lang.diagnostics.Severity.ERROR;
|
||||
import static org.jetbrains.jet.lang.diagnostics.Severity.WARNING;
|
||||
@@ -275,7 +276,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, 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}");
|
||||
|
||||
|
||||
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}") {
|
||||
@Override
|
||||
protected String makeMessageForA(@NotNull TypeParameterDescriptor typeParameterDescriptor) {
|
||||
|
||||
@@ -28,8 +28,8 @@ import java.util.*;
|
||||
* @author abreslav
|
||||
*/
|
||||
public class AnalyzingUtils {
|
||||
public static AnalyzingUtils getInstance(@NotNull ImportingStrategy importingStrategy) {
|
||||
return new AnalyzingUtils(importingStrategy);
|
||||
public static AnalyzingUtils getInstance(@NotNull ImportingStrategy importingStrategy, boolean loadStdlib) {
|
||||
return new AnalyzingUtils(importingStrategy, loadStdlib);
|
||||
}
|
||||
|
||||
public static void checkForSyntacticErrors(@NotNull PsiElement root) {
|
||||
@@ -53,9 +53,11 @@ public class AnalyzingUtils {
|
||||
}
|
||||
|
||||
private final ImportingStrategy importingStrategy;
|
||||
private final boolean loadStdlib;
|
||||
|
||||
private AnalyzingUtils(ImportingStrategy importingStrategy) {
|
||||
private AnalyzingUtils(ImportingStrategy importingStrategy, boolean loadStdlib) {
|
||||
this.importingStrategy = importingStrategy;
|
||||
this.loadStdlib = loadStdlib;
|
||||
}
|
||||
|
||||
public BindingContext analyzeNamespace(@NotNull JetNamespace namespace, @NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
|
||||
@@ -71,7 +73,7 @@ public class AnalyzingUtils {
|
||||
@NotNull Predicate<PsiFile> filesToAnalyzeCompletely,
|
||||
@NotNull JetControlFlowDataTraceFactory flowDataTraceFactory) {
|
||||
BindingTraceContext bindingTraceContext = new BindingTraceContext();
|
||||
JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(project);
|
||||
JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(project, loadStdlib);
|
||||
|
||||
JetScope libraryScope = semanticServices.getStandardLibrary().getLibraryScope();
|
||||
ModuleDescriptor owner = new ModuleDescriptor("<module>");
|
||||
|
||||
@@ -82,7 +82,7 @@ public class BodyResolver {
|
||||
resolveSecondaryConstructorBodies();
|
||||
resolveFunctionBodies();
|
||||
|
||||
computeDeferredTypes();
|
||||
computeDeferredTypes();
|
||||
}
|
||||
|
||||
private void resolveDelegationSpecifierLists() {
|
||||
@@ -501,6 +501,18 @@ public class BodyResolver {
|
||||
for (Map.Entry<JetNamedFunction, FunctionDescriptorImpl> entry : this.context.getFunctions().entrySet()) {
|
||||
JetNamedFunction declaration = entry.getKey();
|
||||
FunctionDescriptor descriptor = entry.getValue();
|
||||
|
||||
if (descriptor.getReturnType() instanceof DeferredType) {
|
||||
// handle type inference loop: function body contains a closure that calls that function
|
||||
//
|
||||
// fun f() = { f() }
|
||||
//
|
||||
// function type resolution must be started before function body resolution
|
||||
//
|
||||
|
||||
DeferredType returnType = (DeferredType) descriptor.getReturnType();
|
||||
returnType.getActualType();
|
||||
}
|
||||
|
||||
JetScope declaringScope = this.context.getDeclaringScopes().get(declaration);
|
||||
assert declaringScope != null;
|
||||
@@ -545,7 +557,8 @@ public class BodyResolver {
|
||||
private void computeDeferredTypes() {
|
||||
Collection<Box<DeferredType>> deferredTypes = context.getTrace().getKeys(DEFERRED_TYPE);
|
||||
if (deferredTypes != null) {
|
||||
final Queue<DeferredType> queue = new Queue<DeferredType>(deferredTypes.size());
|
||||
// +1 is a work around agains new Queue(0).addLast(...) bug // stepan.koltsov@ 2011-11-21
|
||||
final Queue<DeferredType> queue = new Queue<DeferredType>(deferredTypes.size() + 1);
|
||||
context.getTrace().addHandler(DEFERRED_TYPE, new ObservableBindingTrace.RecordHandler<Box<DeferredType>, Boolean>() {
|
||||
@Override
|
||||
public void handleRecord(WritableSlice<Box<DeferredType>, Boolean> deferredTypeKeyDeferredTypeWritableSlice, Box<DeferredType> key, Boolean value) {
|
||||
|
||||
@@ -29,16 +29,24 @@ import java.util.Set;
|
||||
public class JetStandardLibrary {
|
||||
|
||||
// TODO : consider releasing this memory
|
||||
private static JetStandardLibrary cachedLibrary = null;
|
||||
private static JetStandardLibrary cachedFullLibrary = null;
|
||||
private static JetStandardLibrary cachedQuickLibrary = null;
|
||||
// private static final Map<Project, JetStandardLibrary> standardLibraryCache = new HashMap<Project, JetStandardLibrary>();
|
||||
|
||||
// TODO : double checked locking
|
||||
synchronized
|
||||
public static JetStandardLibrary getJetStandardLibrary(@NotNull Project project) {
|
||||
if (cachedLibrary == null) {
|
||||
cachedLibrary = new JetStandardLibrary(project);
|
||||
public static JetStandardLibrary getJetStandardLibrary(@NotNull Project project, boolean loadFullLibrary) {
|
||||
if (loadFullLibrary) {
|
||||
if (cachedFullLibrary == null) {
|
||||
cachedFullLibrary = new JetStandardLibrary(project, true);
|
||||
}
|
||||
return cachedFullLibrary;
|
||||
} else {
|
||||
if (cachedQuickLibrary == null) {
|
||||
cachedQuickLibrary = new JetStandardLibrary(project, false);
|
||||
}
|
||||
return cachedQuickLibrary;
|
||||
}
|
||||
return cachedLibrary;
|
||||
// JetStandardLibrary standardLibrary = standardLibraryCache.get(project);
|
||||
// if (standardLibrary == null) {
|
||||
// standardLibrary = new JetStandardLibrary(project);
|
||||
@@ -47,6 +55,12 @@ public class JetStandardLibrary {
|
||||
// return standardLibrary;
|
||||
}
|
||||
|
||||
public static JetStandardLibrary getJetStandardLibrary(@NotNull Project project) {
|
||||
return getJetStandardLibrary(project, true);
|
||||
}
|
||||
|
||||
private final boolean loadFullLibrary;
|
||||
|
||||
private JetScope libraryScope;
|
||||
|
||||
private ClassDescriptor numberClass;
|
||||
@@ -122,20 +136,27 @@ public class JetStandardLibrary {
|
||||
private NamespaceDescriptor typeInfoNamespace;
|
||||
private Set<FunctionDescriptor> typeInfoFunction;
|
||||
|
||||
private JetStandardLibrary(@NotNull Project project) {
|
||||
// TODO : review
|
||||
InputStream stream = JetStandardClasses.class.getClassLoader().getResourceAsStream("jet/Library.jet");
|
||||
private JetStandardLibrary(@NotNull Project project, boolean loadFullLibrary) {
|
||||
this.loadFullLibrary = loadFullLibrary;
|
||||
|
||||
try {
|
||||
//noinspection IOResourceOpenedButNotSafelyClosed
|
||||
JetFile file = (JetFile) PsiFileFactory.getInstance(project).createFileFromText("Library.jet",
|
||||
JetFileType.INSTANCE, FileUtil.loadTextAndClose(new InputStreamReader(stream)));
|
||||
JetFile file = null;
|
||||
if (loadFullLibrary) {
|
||||
// TODO : review
|
||||
InputStream stream = JetStandardClasses.class.getClassLoader().getResourceAsStream("jet/Library.jet");
|
||||
//noinspection IOResourceOpenedButNotSafelyClosed
|
||||
file = (JetFile) PsiFileFactory.getInstance(project).createFileFromText("Library.jet",
|
||||
JetFileType.INSTANCE, FileUtil.loadTextAndClose(new InputStreamReader(stream)));
|
||||
}
|
||||
|
||||
JetSemanticServices bootstrappingSemanticServices = JetSemanticServices.createSemanticServices(this);
|
||||
BindingTraceContext bindingTraceContext = new BindingTraceContext();
|
||||
WritableScopeImpl writableScope = new WritableScopeImpl(JetStandardClasses.STANDARD_CLASSES, JetStandardClasses.STANDARD_CLASSES_NAMESPACE, RedeclarationHandler.THROW_EXCEPTION).setDebugName("Root bootstrap scope");
|
||||
// this.libraryScope = bootstrappingTDA.process(JetStandardClasses.STANDARD_CLASSES, file.getRootNamespace().getDeclarations());
|
||||
// bootstrappingTDA.process(writableScope, JetStandardClasses.STANDARD_CLASSES_NAMESPACE, file.getRootNamespace().getDeclarations());
|
||||
TopDownAnalyzer.processStandardLibraryNamespace(bootstrappingSemanticServices, bindingTraceContext, writableScope, JetStandardClasses.STANDARD_CLASSES_NAMESPACE, file.getRootNamespace());
|
||||
if (loadFullLibrary) {
|
||||
TopDownAnalyzer.processStandardLibraryNamespace(bootstrappingSemanticServices, bindingTraceContext, writableScope, JetStandardClasses.STANDARD_CLASSES_NAMESPACE, file.getRootNamespace());
|
||||
}
|
||||
// this.libraryScope = JetStandardClasses.STANDARD_CLASSES_NAMESPACE.getMemberScope();
|
||||
|
||||
AnalyzingUtils.throwExceptionOnErrors(bindingTraceContext.getBindingContext());
|
||||
@@ -153,6 +174,11 @@ public class JetStandardLibrary {
|
||||
private void initStdClasses() {
|
||||
if(libraryScope == null) {
|
||||
this.libraryScope = JetStandardClasses.STANDARD_CLASSES_NAMESPACE.getMemberScope();
|
||||
|
||||
if (!loadFullLibrary) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.numberClass = (ClassDescriptor) libraryScope.getClassifier("Number");
|
||||
this.byteClass = (ClassDescriptor) libraryScope.getClassifier("Byte");
|
||||
this.charClass = (ClassDescriptor) libraryScope.getClassifier("Char");
|
||||
|
||||
+50
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jet.lang.types.expressions;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.tree.IElementType;
|
||||
@@ -8,6 +9,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.JetNodeTypes;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
import org.jetbrains.jet.lang.resolve.*;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallMaker;
|
||||
@@ -245,10 +247,58 @@ public class BasicExpressionTypingVisitor extends ExpressionTypingVisitor {
|
||||
else {
|
||||
if (typeChecker.isSubtypeOf(actualType, targetType)) {
|
||||
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) {
|
||||
|
||||
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
|
||||
public JetType visitTupleExpression(JetTupleExpression expression, ExpressionTypingContext context) {
|
||||
List<JetExpression> entries = expression.getEntries();
|
||||
|
||||
+30
-2
@@ -1,11 +1,14 @@
|
||||
package org.jetbrains.jet.lang.types.expressions;
|
||||
|
||||
import com.google.common.collect.Multimap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.util.Ref;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.TypeParameterDescriptor;
|
||||
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.resolve.calls.autocasts.DataFlowInfo;
|
||||
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowValue;
|
||||
@@ -17,8 +20,7 @@ import org.jetbrains.jet.lang.resolve.scopes.receivers.ReceiverDescriptor;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.receivers.TransientReceiver;
|
||||
import org.jetbrains.jet.lang.types.*;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||
import static org.jetbrains.jet.lang.types.expressions.ExpressionTypingUtils.ensureBooleanResultWithCustomSubject;
|
||||
@@ -245,6 +247,9 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* (a: SubjectType) is Type
|
||||
*/
|
||||
private void checkTypeCompatibility(@Nullable JetType type, @NotNull JetType subjectType, @NotNull JetElement reportErrorOn) {
|
||||
// TODO : Take auto casts into account?
|
||||
if (type == null) {
|
||||
@@ -253,6 +258,29 @@ public class PatternMatchingTypingVisitor extends ExpressionTypingVisitor {
|
||||
if (TypeUtils.intersect(context.semanticServices.getTypeChecker(), Sets.newHashSet(type, subjectType)) == null) {
|
||||
// context.trace.getErrorHandler().genericError(reportErrorOn.getNode(), "Incompatible types: " + type + " and " + subjectType);
|
||||
context.trace.report(INCOMPATIBLE_TYPES.on(reportErrorOn, type, subjectType));
|
||||
return;
|
||||
}
|
||||
|
||||
{
|
||||
// check parameters compatible
|
||||
Multimap<TypeConstructor, TypeProjection> typeSubstritutionMap = TypeUtils.buildDeepSubstitutionMultimap(type);
|
||||
|
||||
for (int i = 0; i < subjectType.getConstructor().getParameters().size(); ++i) {
|
||||
TypeParameterDescriptor subjectTypeParameterDescriptor = subjectType.getConstructor().getParameters().get(i);
|
||||
TypeProjection subjectParameterType = subjectType.getArguments().get(i);
|
||||
|
||||
Collection<TypeProjection> xxy = typeSubstritutionMap.get(subjectTypeParameterDescriptor.getTypeConstructor());
|
||||
for (TypeProjection proj : xxy) {
|
||||
if (!context.semanticServices.getTypeChecker().isSubtypeOf(subjectParameterType.getType(), proj.getType())) {
|
||||
context.trace.report(INCOMPATIBLE_TYPES.on(reportErrorOn, type, subjectType));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (BasicExpressionTypingVisitor.isCastErased(subjectType, type)) {
|
||||
context.trace.report(Errors.CANNOT_CHECK_FOR_ERASED.on(reportErrorOn, type));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,11 @@ public class DescriptorRenderer implements Renderer {
|
||||
}
|
||||
|
||||
public String renderType(JetType type) {
|
||||
return escape(type.toString());
|
||||
if (type == null) {
|
||||
return escape("<?>");
|
||||
} else {
|
||||
return escape(type.toString());
|
||||
}
|
||||
}
|
||||
|
||||
protected String escape(String s) {
|
||||
@@ -222,7 +226,7 @@ public class DescriptorRenderer implements Renderer {
|
||||
|
||||
renderName(descriptor, builder);
|
||||
renderValueParameters(descriptor, builder);
|
||||
builder.append(" : ").append(escape(renderType(descriptor.getReturnType())));
|
||||
builder.append(" : ").append(escape(renderType(descriptor.getReturnTypeSafe())));
|
||||
return super.visitFunctionDescriptor(descriptor, builder);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
// -JDK
|
||||
|
||||
fun test() : Unit {
|
||||
var x : Int? = 0
|
||||
var y : Int = 0
|
||||
@@ -13,4 +15,4 @@ fun test() : Unit {
|
||||
x <!USELESS_CAST!>as?<!> Int? : Int?
|
||||
y <!USELESS_CAST_STATIC_ASSERT_IS_FINE!>as?<!> Int? : Int?
|
||||
()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,15 +5,15 @@ namespace a {
|
||||
}
|
||||
|
||||
namespace b {
|
||||
fun foo() = <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bar()<!>
|
||||
fun foo() = bar()
|
||||
|
||||
fun bar() = foo()
|
||||
fun bar() = <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>foo()<!>
|
||||
}
|
||||
|
||||
namespace c {
|
||||
fun bazz() = <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bar()<!>
|
||||
fun bazz() = bar()
|
||||
|
||||
fun foo() = bazz()
|
||||
fun foo() = <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bazz()<!>
|
||||
|
||||
fun bar() = foo()
|
||||
}
|
||||
@@ -39,4 +39,4 @@ namespace ok {
|
||||
|
||||
fun bar() = foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
|
||||
fun ff(c: Collection<String>) = c <!CAST_NEVER_SUCCEEDS!>as<!> List<Int>
|
||||
@@ -0,0 +1,4 @@
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
|
||||
fun ff(c: Collection<String>) = c as List<String>
|
||||
@@ -0,0 +1,4 @@
|
||||
import java.util.List;
|
||||
|
||||
fun ff(l: Any) = l as List<*>
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
import java.util.List;
|
||||
|
||||
fun ff(a: Any) = <!UNCHECKED_CAST!>a as List<String><!>
|
||||
@@ -0,0 +1,5 @@
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
fun ff(l: Collection<String>) = l is List<String>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
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,3 @@
|
||||
import java.util.List;
|
||||
|
||||
fun ff(l: Any) = l is <!CANNOT_CHECK_FOR_ERASED!>List<String><!>
|
||||
@@ -0,0 +1,5 @@
|
||||
import java.util.List;
|
||||
import java.util.Collection;
|
||||
|
||||
fun ff(l: Collection<Int>) = l is <!INCOMPATIBLE_TYPES!>List<String><!>
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
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,3 @@
|
||||
class MyList<A>
|
||||
|
||||
fun ff(l: MyList<String>) = l is <!INCOMPATIBLE_TYPES!>MyList<Int><!>
|
||||
@@ -0,0 +1,4 @@
|
||||
trait Aaa
|
||||
trait Bbb
|
||||
|
||||
fun f(a: Aaa) = a is Bbb
|
||||
@@ -0,0 +1,6 @@
|
||||
import java.util.List;
|
||||
|
||||
fun ff(l: Any) = when(l) {
|
||||
is <!CANNOT_CHECK_FOR_ERASED!>List<String><!> => 1
|
||||
else 2
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun bar() = {
|
||||
<!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bar()<!>
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
fun bar() = {
|
||||
fun foo() = <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bar()<!>
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
// http://youtrack.jetbrains.net/issue/KT-329
|
||||
|
||||
fun block(f : fun() : Unit) = f()
|
||||
|
||||
fun bar() = block{ <!UNRESOLVED_REFERENCE!>foo<!>() // <-- missing closing curly bracket
|
||||
fun foo() = block{ <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bar()<!> }
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
fun typeName(a: Any?) : String {
|
||||
return when(a) {
|
||||
is java.util.ArrayList<Int> => "array list"
|
||||
is java.util.ArrayList<*> => "array list"
|
||||
else => "no idea"
|
||||
}
|
||||
}
|
||||
@@ -8,4 +8,4 @@ fun typeName(a: Any?) : String {
|
||||
fun box() : String {
|
||||
if(typeName(java.util.ArrayList<Int> ()) != "array list") return "array list failed"
|
||||
return "OK"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ public class CheckerTestUtilTest extends JetLiteFixture {
|
||||
}
|
||||
|
||||
public void test(PsiFile psiFile) {
|
||||
BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache(AnalyzingUtils.getInstance(ImportingStrategy.NONE), (JetFile) psiFile, AnalyzerFacade.SINGLE_DECLARATION_PROVIDER);
|
||||
BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache(AnalyzingUtils.getInstance(ImportingStrategy.NONE, true), (JetFile) psiFile, AnalyzerFacade.SINGLE_DECLARATION_PROVIDER);
|
||||
String expectedText = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, bindingContext).toString();
|
||||
|
||||
List<CheckerTestUtil.DiagnosedRange> diagnosedRanges = Lists.newArrayList();
|
||||
|
||||
@@ -8,8 +8,11 @@ import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.JetLiteFixture;
|
||||
import org.jetbrains.jet.JetTestCaseBuilder;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
|
||||
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.ImportingStrategy;
|
||||
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaDefaultImports;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -42,7 +45,13 @@ public class FullJetPsiCheckerTest extends JetLiteFixture {
|
||||
String clearText = CheckerTestUtil.parseDiagnosedRanges(expectedText, diagnosedRanges);
|
||||
|
||||
myFile = createPsiFile(myName, clearText);
|
||||
BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache(myFile, AnalyzerFacade.SINGLE_DECLARATION_PROVIDER);
|
||||
|
||||
boolean loadStdlib = !expectedText.contains("-STDLIB");
|
||||
boolean importJdk = !expectedText.contains("-JDK");
|
||||
|
||||
ImportingStrategy importingStrategy = importJdk ? JavaDefaultImports.JAVA_DEFAULT_IMPORTS : ImportingStrategy.NONE;
|
||||
|
||||
BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache(AnalyzingUtils.getInstance(importingStrategy, loadStdlib), myFile, AnalyzerFacade.SINGLE_DECLARATION_PROVIDER);
|
||||
|
||||
CheckerTestUtil.diagnosticsDiff(diagnosedRanges, bindingContext.getDiagnostics(), new CheckerTestUtil.DiagnosticDiffCallbacks() {
|
||||
@Override
|
||||
|
||||
@@ -13,6 +13,7 @@ import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.ImportingStrategy;
|
||||
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacade;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaDefaultImports;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@@ -40,7 +41,12 @@ public class QuickJetPsiCheckerTest extends JetLiteFixture {
|
||||
|
||||
createAndCheckPsiFile(name, clearText);
|
||||
JetFile jetFile = (JetFile) myFile;
|
||||
BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache(AnalyzingUtils.getInstance(ImportingStrategy.NONE), jetFile, AnalyzerFacade.SINGLE_DECLARATION_PROVIDER);
|
||||
boolean loadStdlib = !expectedText.contains("-STDLIB");
|
||||
boolean importJdk = expectedText.contains("+JDK");
|
||||
|
||||
ImportingStrategy importingStrategy = importJdk ? JavaDefaultImports.JAVA_DEFAULT_IMPORTS : ImportingStrategy.NONE;
|
||||
|
||||
BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache(AnalyzingUtils.getInstance(importingStrategy, loadStdlib), jetFile, AnalyzerFacade.SINGLE_DECLARATION_PROVIDER);
|
||||
|
||||
CheckerTestUtil.diagnosticsDiff(diagnosedRanges, bindingContext.getDiagnostics(), new CheckerTestUtil.DiagnosticDiffCallbacks() {
|
||||
@Override
|
||||
|
||||
@@ -44,7 +44,7 @@ public class JetResolveTest extends ExtensibleResolveTestCase {
|
||||
@Override
|
||||
protected ExpectedResolveData getExpectedResolveData() {
|
||||
Project project = getProject();
|
||||
JetStandardLibrary lib = JetStandardLibrary.getJetStandardLibrary(project);
|
||||
JetStandardLibrary lib = JetStandardLibrary.getJetStandardLibrary(project, true);
|
||||
Map<String, DeclarationDescriptor> nameToDescriptor = new HashMap<String, DeclarationDescriptor>();
|
||||
nameToDescriptor.put("std::Int.plus(Int)", standardFunction(lib.getInt(), "plus", lib.getIntType()));
|
||||
FunctionDescriptor descriptorForGet = standardFunction(lib.getArray(), Collections.singletonList(new TypeProjection(lib.getIntType())), "get", lib.getIntType());
|
||||
|
||||
@@ -80,7 +80,7 @@ public class JetCompiler implements TranslatingCompiler {
|
||||
}
|
||||
}
|
||||
|
||||
BindingContext bindingContext = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS).analyzeNamespaces(
|
||||
BindingContext bindingContext = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS, true).analyzeNamespaces(
|
||||
compileContext.getProject(), namespaces,
|
||||
Predicates.<PsiFile>alwaysTrue(),
|
||||
JetControlFlowDataTraceFactory.EMPTY);
|
||||
|
||||
@@ -211,7 +211,7 @@ public class JavaElementFinder extends PsiElementFinder {
|
||||
|
||||
|
||||
if (dirty.size() > 0) {
|
||||
final BindingContext context = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS).shallowAnalyzeFiles(dirty);
|
||||
final BindingContext context = AnalyzingUtils.getInstance(JavaDefaultImports.JAVA_DEFAULT_IMPORTS, true).shallowAnalyzeFiles(dirty);
|
||||
state.compileCorrectNamespaces(context, AnalyzingUtils.collectRootNamespaces(dirty));
|
||||
state.getFactory().files();
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
namespace a {
|
||||
val foo = <error>bar()</error>
|
||||
val foo = <error descr="[TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM] Type checking has run into a recursive problem">bar()</error>
|
||||
|
||||
fun bar() = foo
|
||||
}
|
||||
|
||||
namespace b {
|
||||
fun foo() = <error>bar()</error>
|
||||
fun foo() = bar()
|
||||
|
||||
fun bar() = foo()
|
||||
fun bar() = <error descr="[TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM] Type checking has run into a recursive problem">foo()</error>
|
||||
}
|
||||
|
||||
namespace c {
|
||||
fun bazz() = <error>bar()</error>
|
||||
fun bazz() = bar()
|
||||
|
||||
fun foo() = bazz()
|
||||
fun foo() = <error descr="[TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM] Type checking has run into a recursive problem">bazz()</error>
|
||||
|
||||
fun bar() = foo()
|
||||
}
|
||||
@@ -39,4 +39,4 @@ namespace ok {
|
||||
|
||||
fun bar() = foo()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user