Support creating flexible types in tests
Flexible types can not be created in normal user code, but if there's a special classifier `kotlin.internal.flexible.ft` with two type parameters, its occurrences are replaced by flexible types, e.g. `ft<Int, Int?>` becomes `Int!`
This commit is contained in:
@@ -36,6 +36,7 @@ import org.jetbrains.jet.lang.resolve.java.resolver.PsiBasedMethodSignatureCheck
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.PsiBasedExternalAnnotationResolver;
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.impl.JavaPropertyInitializerEvaluatorImpl;
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.JavaSourceElementFactoryImpl;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaFlexibleTypeCapabilitiesProvider;
|
||||
import org.jetbrains.jet.lang.resolve.AdditionalCheckerProvider;
|
||||
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallResolver;
|
||||
@@ -92,6 +93,7 @@ public class InjectorForLazyResolveWithJava {
|
||||
private final PsiBasedExternalAnnotationResolver psiBasedExternalAnnotationResolver;
|
||||
private final JavaPropertyInitializerEvaluatorImpl javaPropertyInitializerEvaluator;
|
||||
private final JavaSourceElementFactoryImpl javaSourceElementFactory;
|
||||
private final JavaFlexibleTypeCapabilitiesProvider javaFlexibleTypeCapabilitiesProvider;
|
||||
private final AdditionalCheckerProvider additionalCheckerProvider;
|
||||
private final AnnotationResolver annotationResolver;
|
||||
private final CallResolver callResolver;
|
||||
@@ -154,6 +156,7 @@ public class InjectorForLazyResolveWithJava {
|
||||
this.globalJavaResolverContext = new GlobalJavaResolverContext(storageManager, javaClassFinder, virtualFileFinder, deserializedDescriptorResolver, psiBasedExternalAnnotationResolver, traceBasedExternalSignatureResolver, traceBasedErrorReporter, psiBasedMethodSignatureChecker, lazyResolveBasedCache, javaPropertyInitializerEvaluator, javaSourceElementFactory, moduleClassResolver);
|
||||
this.lazyJavaPackageFragmentProvider = new LazyJavaPackageFragmentProvider(globalJavaResolverContext, module);
|
||||
this.javaDescriptorResolver = new JavaDescriptorResolver(lazyJavaPackageFragmentProvider, module);
|
||||
this.javaFlexibleTypeCapabilitiesProvider = new JavaFlexibleTypeCapabilitiesProvider();
|
||||
this.additionalCheckerProvider = org.jetbrains.jet.lang.resolve.kotlin.JavaDeclarationCheckerProvider.INSTANCE$;
|
||||
this.annotationResolver = new AnnotationResolver();
|
||||
this.callResolver = new CallResolver();
|
||||
@@ -250,6 +253,7 @@ public class InjectorForLazyResolveWithJava {
|
||||
delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices);
|
||||
|
||||
typeResolver.setAnnotationResolver(annotationResolver);
|
||||
typeResolver.setFlexibleTypeCapabilitiesProvider(javaFlexibleTypeCapabilitiesProvider);
|
||||
typeResolver.setModuleDescriptor(module);
|
||||
typeResolver.setQualifiedExpressionResolver(qualifiedExpressionResolver);
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.jetbrains.jet.lang.resolve.java.resolver.PsiBasedExternalAnnotationRe
|
||||
import org.jetbrains.jet.lang.resolve.java.structure.impl.JavaPropertyInitializerEvaluatorImpl;
|
||||
import org.jetbrains.jet.lang.resolve.java.resolver.JavaSourceElementFactoryImpl;
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.SingleModuleClassResolver;
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaFlexibleTypeCapabilitiesProvider;
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileFinder;
|
||||
import org.jetbrains.jet.lang.resolve.BodyResolver;
|
||||
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
|
||||
@@ -105,6 +106,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
|
||||
private final JavaPropertyInitializerEvaluatorImpl javaPropertyInitializerEvaluator;
|
||||
private final JavaSourceElementFactoryImpl javaSourceElementFactory;
|
||||
private final SingleModuleClassResolver singleModuleClassResolver;
|
||||
private final JavaFlexibleTypeCapabilitiesProvider javaFlexibleTypeCapabilitiesProvider;
|
||||
private final VirtualFileFinder virtualFileFinder;
|
||||
private final BodyResolver bodyResolver;
|
||||
private final AnnotationResolver annotationResolver;
|
||||
@@ -179,6 +181,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
|
||||
this.deserializationGlobalContextForJava = new DeserializationGlobalContextForJava(storageManager, getModuleDescriptor(), javaClassDataFinder, annotationDescriptorLoader, constantDescriptorLoader, lazyJavaPackageFragmentProvider);
|
||||
this.additionalCheckerProvider = org.jetbrains.jet.lang.resolve.kotlin.JavaDeclarationCheckerProvider.INSTANCE$;
|
||||
this.globalSearchScope = com.intellij.psi.search.GlobalSearchScope.allScope(project);
|
||||
this.javaFlexibleTypeCapabilitiesProvider = new JavaFlexibleTypeCapabilitiesProvider();
|
||||
this.bodyResolver = new BodyResolver();
|
||||
this.annotationResolver = new AnnotationResolver();
|
||||
this.callResolver = new CallResolver();
|
||||
@@ -303,6 +306,7 @@ public class InjectorForTopDownAnalyzerForJvm implements InjectorForTopDownAnaly
|
||||
delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices);
|
||||
|
||||
typeResolver.setAnnotationResolver(annotationResolver);
|
||||
typeResolver.setFlexibleTypeCapabilitiesProvider(javaFlexibleTypeCapabilitiesProvider);
|
||||
typeResolver.setModuleDescriptor(moduleDescriptor);
|
||||
typeResolver.setQualifiedExpressionResolver(qualifiedExpressionResolver);
|
||||
|
||||
|
||||
+25
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* Copyright 2010-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.lang.resolve.java
|
||||
|
||||
import org.jetbrains.jet.lang.resolve.TypeResolver.FlexibleTypeCapabilitiesProvider
|
||||
import org.jetbrains.jet.lang.types.FlexibleTypeCapabilities
|
||||
import org.jetbrains.jet.lang.resolve.java.lazy.types.LazyJavaTypeResolver
|
||||
|
||||
public class JavaFlexibleTypeCapabilitiesProvider : FlexibleTypeCapabilitiesProvider() {
|
||||
override fun getCapabilities(): FlexibleTypeCapabilities = LazyJavaTypeResolver.FlexibleJavaClassifierTypeCapabilities
|
||||
}
|
||||
@@ -37,6 +37,7 @@ import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
|
||||
import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver;
|
||||
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
||||
import org.jetbrains.jet.lang.resolve.TypeResolver.FlexibleTypeCapabilitiesProvider;
|
||||
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallResolverExtensionProvider;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallCompleter;
|
||||
@@ -74,6 +75,7 @@ public class InjectorForBodyResolve {
|
||||
private final DescriptorResolver descriptorResolver;
|
||||
private final DelegatedPropertyResolver delegatedPropertyResolver;
|
||||
private final TypeResolver typeResolver;
|
||||
private final FlexibleTypeCapabilitiesProvider flexibleTypeCapabilitiesProvider;
|
||||
private final QualifiedExpressionResolver qualifiedExpressionResolver;
|
||||
private final CallResolverExtensionProvider callResolverExtensionProvider;
|
||||
private final CallCompleter callCompleter;
|
||||
@@ -112,6 +114,7 @@ public class InjectorForBodyResolve {
|
||||
this.descriptorResolver = new DescriptorResolver();
|
||||
this.delegatedPropertyResolver = new DelegatedPropertyResolver();
|
||||
this.typeResolver = new TypeResolver();
|
||||
this.flexibleTypeCapabilitiesProvider = new FlexibleTypeCapabilitiesProvider();
|
||||
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
|
||||
this.callResolverExtensionProvider = new CallResolverExtensionProvider();
|
||||
this.candidateResolver = new CandidateResolver();
|
||||
@@ -179,6 +182,7 @@ public class InjectorForBodyResolve {
|
||||
delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices);
|
||||
|
||||
typeResolver.setAnnotationResolver(annotationResolver);
|
||||
typeResolver.setFlexibleTypeCapabilitiesProvider(flexibleTypeCapabilitiesProvider);
|
||||
typeResolver.setModuleDescriptor(moduleDescriptor);
|
||||
typeResolver.setQualifiedExpressionResolver(qualifiedExpressionResolver);
|
||||
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
|
||||
import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver;
|
||||
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
||||
import org.jetbrains.jet.lang.resolve.TypeResolver.FlexibleTypeCapabilitiesProvider;
|
||||
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallResolverExtensionProvider;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallCompleter;
|
||||
@@ -74,6 +75,7 @@ public class InjectorForLazyResolve {
|
||||
private final DescriptorResolver descriptorResolver;
|
||||
private final DelegatedPropertyResolver delegatedPropertyResolver;
|
||||
private final TypeResolver typeResolver;
|
||||
private final FlexibleTypeCapabilitiesProvider flexibleTypeCapabilitiesProvider;
|
||||
private final QualifiedExpressionResolver qualifiedExpressionResolver;
|
||||
private final CallResolverExtensionProvider callResolverExtensionProvider;
|
||||
private final CallCompleter callCompleter;
|
||||
@@ -112,6 +114,7 @@ public class InjectorForLazyResolve {
|
||||
this.descriptorResolver = new DescriptorResolver();
|
||||
this.delegatedPropertyResolver = new DelegatedPropertyResolver();
|
||||
this.typeResolver = new TypeResolver();
|
||||
this.flexibleTypeCapabilitiesProvider = new FlexibleTypeCapabilitiesProvider();
|
||||
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
|
||||
this.callResolverExtensionProvider = new CallResolverExtensionProvider();
|
||||
this.candidateResolver = new CandidateResolver();
|
||||
@@ -175,6 +178,7 @@ public class InjectorForLazyResolve {
|
||||
delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices);
|
||||
|
||||
typeResolver.setAnnotationResolver(annotationResolver);
|
||||
typeResolver.setFlexibleTypeCapabilitiesProvider(flexibleTypeCapabilitiesProvider);
|
||||
typeResolver.setModuleDescriptor(moduleDescriptor);
|
||||
typeResolver.setQualifiedExpressionResolver(qualifiedExpressionResolver);
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ import org.jetbrains.jet.storage.StorageManager;
|
||||
import org.jetbrains.jet.lang.resolve.AdditionalCheckerProvider;
|
||||
import org.jetbrains.jet.lang.resolve.AnnotationResolver;
|
||||
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
||||
import org.jetbrains.jet.lang.resolve.TypeResolver.FlexibleTypeCapabilitiesProvider;
|
||||
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
|
||||
@@ -57,6 +58,7 @@ public class InjectorForMacros {
|
||||
private final AdditionalCheckerProvider additionalCheckerProvider;
|
||||
private final AnnotationResolver annotationResolver;
|
||||
private final TypeResolver typeResolver;
|
||||
private final FlexibleTypeCapabilitiesProvider flexibleTypeCapabilitiesProvider;
|
||||
private final QualifiedExpressionResolver qualifiedExpressionResolver;
|
||||
private final CallExpressionResolver callExpressionResolver;
|
||||
private final DescriptorResolver descriptorResolver;
|
||||
@@ -85,6 +87,7 @@ public class InjectorForMacros {
|
||||
this.additionalCheckerProvider = org.jetbrains.jet.lang.resolve.AdditionalCheckerProvider.Empty.INSTANCE$;
|
||||
this.annotationResolver = new AnnotationResolver();
|
||||
this.typeResolver = new TypeResolver();
|
||||
this.flexibleTypeCapabilitiesProvider = new FlexibleTypeCapabilitiesProvider();
|
||||
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
|
||||
this.callExpressionResolver = new CallExpressionResolver();
|
||||
this.descriptorResolver = new DescriptorResolver();
|
||||
@@ -127,6 +130,7 @@ public class InjectorForMacros {
|
||||
annotationResolver.setTypeResolver(typeResolver);
|
||||
|
||||
typeResolver.setAnnotationResolver(annotationResolver);
|
||||
typeResolver.setFlexibleTypeCapabilitiesProvider(flexibleTypeCapabilitiesProvider);
|
||||
typeResolver.setModuleDescriptor(moduleDescriptor);
|
||||
typeResolver.setQualifiedExpressionResolver(qualifiedExpressionResolver);
|
||||
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
|
||||
import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver;
|
||||
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
||||
import org.jetbrains.jet.lang.resolve.TypeResolver.FlexibleTypeCapabilitiesProvider;
|
||||
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallResolverExtensionProvider;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallCompleter;
|
||||
@@ -87,6 +88,7 @@ public class InjectorForTopDownAnalyzerBasic {
|
||||
private final DescriptorResolver descriptorResolver;
|
||||
private final DelegatedPropertyResolver delegatedPropertyResolver;
|
||||
private final TypeResolver typeResolver;
|
||||
private final FlexibleTypeCapabilitiesProvider flexibleTypeCapabilitiesProvider;
|
||||
private final QualifiedExpressionResolver qualifiedExpressionResolver;
|
||||
private final CallResolverExtensionProvider callResolverExtensionProvider;
|
||||
private final CallCompleter callCompleter;
|
||||
@@ -135,6 +137,7 @@ public class InjectorForTopDownAnalyzerBasic {
|
||||
this.descriptorResolver = new DescriptorResolver();
|
||||
this.delegatedPropertyResolver = new DelegatedPropertyResolver();
|
||||
this.typeResolver = new TypeResolver();
|
||||
this.flexibleTypeCapabilitiesProvider = new FlexibleTypeCapabilitiesProvider();
|
||||
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
|
||||
this.callResolverExtensionProvider = new CallResolverExtensionProvider();
|
||||
this.candidateResolver = new CandidateResolver();
|
||||
@@ -228,6 +231,7 @@ public class InjectorForTopDownAnalyzerBasic {
|
||||
delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices);
|
||||
|
||||
typeResolver.setAnnotationResolver(annotationResolver);
|
||||
typeResolver.setFlexibleTypeCapabilitiesProvider(flexibleTypeCapabilitiesProvider);
|
||||
typeResolver.setModuleDescriptor(moduleDescriptor);
|
||||
typeResolver.setQualifiedExpressionResolver(qualifiedExpressionResolver);
|
||||
|
||||
|
||||
@@ -1353,7 +1353,7 @@ public class DescriptorResolver {
|
||||
return propertyDescriptor;
|
||||
}
|
||||
|
||||
public static void checkBounds(@NotNull JetTypeReference typeReference, @NotNull JetType type, BindingTrace trace) {
|
||||
public static void checkBounds(@NotNull JetTypeReference typeReference, @NotNull JetType type, @NotNull BindingTrace trace) {
|
||||
if (type.isError()) return;
|
||||
|
||||
JetTypeElement typeElement = typeReference.getTypeElement();
|
||||
@@ -1364,7 +1364,20 @@ public class DescriptorResolver {
|
||||
assert parameters.size() == arguments.size();
|
||||
|
||||
List<JetTypeReference> jetTypeArguments = typeElement.getTypeArgumentsAsTypes();
|
||||
assert jetTypeArguments.size() == arguments.size() : typeElement.getText();
|
||||
|
||||
// A type reference from Kotlin code can yield a flexible type only if it's `ft<T1, T2>`, whose bounds should not be checked
|
||||
if (TypesPackage.isFlexible(type)) {
|
||||
assert jetTypeArguments.size() == 2
|
||||
: "Flexible type cannot be denoted in Kotlin otherwise than as ft<T1, T2>, but was: "
|
||||
+ JetPsiUtil.getElementTextWithContext(typeReference);
|
||||
// it's really ft<Foo, Bar>
|
||||
Flexibility flexibility = TypesPackage.flexibility(type);
|
||||
checkBounds(jetTypeArguments.get(0), flexibility.getLowerBound(), trace);
|
||||
checkBounds(jetTypeArguments.get(1), flexibility.getUpperBound(), trace);
|
||||
return;
|
||||
}
|
||||
|
||||
assert jetTypeArguments.size() == arguments.size() : typeElement.getText() + ": " + jetTypeArguments + " - " + arguments;
|
||||
|
||||
TypeSubstitutor substitutor = TypeSubstitutor.create(type);
|
||||
for (int i = 0; i < jetTypeArguments.size(); i++) {
|
||||
@@ -1384,7 +1397,8 @@ public class DescriptorResolver {
|
||||
@NotNull JetTypeReference jetTypeArgument,
|
||||
@NotNull JetType typeArgument,
|
||||
@NotNull TypeParameterDescriptor typeParameterDescriptor,
|
||||
@NotNull TypeSubstitutor substitutor, BindingTrace trace
|
||||
@NotNull TypeSubstitutor substitutor,
|
||||
@NotNull BindingTrace trace
|
||||
) {
|
||||
for (JetType bound : typeParameterDescriptor.getUpperBounds()) {
|
||||
JetType substitutedBound = substitutor.safeSubstitute(bound, Variance.INVARIANT);
|
||||
|
||||
@@ -39,9 +39,16 @@ import static org.jetbrains.jet.storage.LockBasedStorageManager.NO_LOCKS;
|
||||
|
||||
public class TypeResolver {
|
||||
|
||||
public static class FlexibleTypeCapabilitiesProvider {
|
||||
public FlexibleTypeCapabilities getCapabilities() {
|
||||
return FlexibleTypeCapabilities.NONE.INSTANCE$;
|
||||
}
|
||||
}
|
||||
|
||||
private AnnotationResolver annotationResolver;
|
||||
private QualifiedExpressionResolver qualifiedExpressionResolver;
|
||||
private ModuleDescriptor moduleDescriptor;
|
||||
private FlexibleTypeCapabilitiesProvider flexibleTypeCapabilitiesProvider;
|
||||
|
||||
@Inject
|
||||
public void setAnnotationResolver(AnnotationResolver annotationResolver) {
|
||||
@@ -58,6 +65,12 @@ public class TypeResolver {
|
||||
this.moduleDescriptor = moduleDescriptor;
|
||||
}
|
||||
|
||||
|
||||
@Inject
|
||||
public void setFlexibleTypeCapabilitiesProvider(@NotNull FlexibleTypeCapabilitiesProvider flexibleTypeCapabilitiesProvider) {
|
||||
this.flexibleTypeCapabilitiesProvider = flexibleTypeCapabilitiesProvider;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public JetType resolveType(@NotNull JetScope scope, @NotNull JetTypeReference typeReference, BindingTrace trace, boolean checkBounds) {
|
||||
// bare types are not allowed
|
||||
@@ -163,6 +176,17 @@ public class TypeResolver {
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (Flexibility.FLEXIBLE_TYPE_CLASSIFIER.asSingleFqName().equals(DescriptorUtils.getFqName(classifierDescriptor))
|
||||
&& classDescriptor.getTypeConstructor().getParameters().size() == 2) {
|
||||
// We create flexible types by convention here
|
||||
// This is not intended to be used in normal users' environments, only for tests and debugger etc
|
||||
result[0] = type(DelegatingFlexibleType.create(
|
||||
arguments.get(0).getType(),
|
||||
arguments.get(1).getType(),
|
||||
flexibleTypeCapabilitiesProvider.getCapabilities()
|
||||
));
|
||||
return;
|
||||
}
|
||||
JetTypeImpl resultingType = new JetTypeImpl(
|
||||
annotations,
|
||||
typeConstructor,
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// !EXPLICIT_FLEXIBLE_TYPES
|
||||
// !CHECK_TYPE
|
||||
|
||||
fun foo(f: ft<Int, Int?>) {
|
||||
f.checkType { it : _<Int> }
|
||||
f.checkType { it : _<Int?> }
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package
|
||||
|
||||
internal fun foo(/*0*/ f: kotlin.Int!): kotlin.Unit
|
||||
internal fun </*0*/ T> T.checkType(/*0*/ f: (_<T>) -> kotlin.Unit): (_<T>) -> kotlin.Unit
|
||||
|
||||
internal final class _</*0*/ T> {
|
||||
public constructor _</*0*/ T>()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
// !DIAGNOSTICS: -UNUSED_PARAMETER
|
||||
// !EXPLICIT_FLEXIBLE_TYPES
|
||||
// !CHECK_TYPE
|
||||
package ppp
|
||||
|
||||
fun foo(f: ft<Int, Int?>) {
|
||||
f.checkType { it : _<Int> }
|
||||
f.checkType { it : _<Int?> }
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
package
|
||||
|
||||
package ppp {
|
||||
internal fun foo(/*0*/ f: kotlin.Int!): kotlin.Unit
|
||||
internal fun </*0*/ T> T.checkType(/*0*/ f: (ppp._<T>) -> kotlin.Unit): (ppp._<T>) -> kotlin.Unit
|
||||
|
||||
internal final class _</*0*/ T> {
|
||||
public constructor _</*0*/ T>()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
}
|
||||
@@ -81,7 +81,7 @@ public abstract class AbstractJetDiagnosticsTest extends BaseDiagnosticsTest {
|
||||
TestModule testModule = entry.getKey();
|
||||
List<? extends TestFile> testFilesInModule = entry.getValue();
|
||||
|
||||
List<JetFile> jetFiles = getJetFiles(testFilesInModule);
|
||||
List<JetFile> jetFiles = getJetFiles(testFilesInModule, true);
|
||||
allJetFiles.addAll(jetFiles);
|
||||
|
||||
ModuleDescriptorImpl module = modules.get(testModule);
|
||||
@@ -194,8 +194,8 @@ public abstract class AbstractJetDiagnosticsTest extends BaseDiagnosticsTest {
|
||||
JetTestUtils.assertEqualsToFile(expectedFile, rootPackageText.toString());
|
||||
}
|
||||
|
||||
public static RecursiveDescriptorComparator.Configuration createdAffectedPackagesConfiguration(List<TestFile> testFiles) {
|
||||
final Set<Name> packagesNames = LazyResolveTestUtil.getTopLevelPackagesFromFileList(getJetFiles(testFiles));
|
||||
public RecursiveDescriptorComparator.Configuration createdAffectedPackagesConfiguration(List<TestFile> testFiles) {
|
||||
final Set<Name> packagesNames = LazyResolveTestUtil.getTopLevelPackagesFromFileList(getJetFiles(testFiles, false));
|
||||
|
||||
Predicate<DeclarationDescriptor> stepIntoFilter = new Predicate<DeclarationDescriptor>() {
|
||||
@Override
|
||||
|
||||
@@ -46,6 +46,7 @@ import org.jetbrains.jet.lang.psi.JetDeclaration;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.Diagnostics;
|
||||
import org.jetbrains.jet.lang.types.Flexibility;
|
||||
import org.jetbrains.jet.utils.UtilsPackage;
|
||||
import org.junit.Assert;
|
||||
|
||||
@@ -73,6 +74,14 @@ public abstract class BaseDiagnosticsTest extends JetLiteFixture {
|
||||
private static final String CHECK_TYPE_DECLARATIONS = "\nclass _<T>" +
|
||||
"\nfun <T> T.checkType(f: (_<T>) -> Unit) = f";
|
||||
|
||||
public static final String EXPLICIT_FLEXIBLE_TYPES_DIRECTIVE = "EXPLICIT_FLEXIBLE_TYPES";
|
||||
public static final String EXPLICIT_FLEXIBLE_PACKAGE = Flexibility.FLEXIBLE_TYPE_CLASSIFIER.getPackageFqName().asString();
|
||||
public static final String EXPLICIT_FLEXIBLE_CLASS_NAME = Flexibility.FLEXIBLE_TYPE_CLASSIFIER.getRelativeClassName().asString();
|
||||
private static final String EXPLICIT_FLEXIBLE_TYPES_DECLARATIONS
|
||||
= "\npackage " + EXPLICIT_FLEXIBLE_PACKAGE +
|
||||
"\npublic class " + EXPLICIT_FLEXIBLE_CLASS_NAME + "<L, U>";
|
||||
private static final String EXPLICIT_FLEXIBLE_TYPES_IMPORT = "import " + EXPLICIT_FLEXIBLE_PACKAGE + "." + EXPLICIT_FLEXIBLE_CLASS_NAME;
|
||||
|
||||
@Override
|
||||
protected JetCoreEnvironment createEnvironment() {
|
||||
File javaFilesDir = createJavaFilesDir();
|
||||
@@ -172,13 +181,20 @@ public abstract class BaseDiagnosticsTest extends JetLiteFixture {
|
||||
List<TestFile> files
|
||||
);
|
||||
|
||||
protected static List<JetFile> getJetFiles(List<? extends TestFile> testFiles) {
|
||||
protected List<JetFile> getJetFiles(List<? extends TestFile> testFiles, boolean includeExtras) {
|
||||
boolean declareFlexibleType = false;
|
||||
List<JetFile> jetFiles = Lists.newArrayList();
|
||||
for (TestFile testFile : testFiles) {
|
||||
if (testFile.getJetFile() != null) {
|
||||
jetFiles.add(testFile.getJetFile());
|
||||
}
|
||||
declareFlexibleType |= testFile.declareFlexibleType;
|
||||
}
|
||||
|
||||
if (declareFlexibleType && includeExtras) {
|
||||
jetFiles.add(createPsiFile(null, "EXPLICIT_FLEXIBLE_TYPES.kt", EXPLICIT_FLEXIBLE_TYPES_DECLARATIONS));
|
||||
}
|
||||
|
||||
return jetFiles;
|
||||
}
|
||||
|
||||
@@ -280,6 +296,7 @@ public abstract class BaseDiagnosticsTest extends JetLiteFixture {
|
||||
private final JetFile jetFile;
|
||||
private final Condition<Diagnostic> whatDiagnosticsToConsider;
|
||||
private final boolean declareCheckType;
|
||||
private final boolean declareFlexibleType;
|
||||
|
||||
public TestFile(
|
||||
@Nullable TestModule module,
|
||||
@@ -290,6 +307,7 @@ public abstract class BaseDiagnosticsTest extends JetLiteFixture {
|
||||
this.module = module;
|
||||
this.whatDiagnosticsToConsider = parseDiagnosticFilterDirective(directives);
|
||||
this.declareCheckType = directives.containsKey(CHECK_TYPE_DIRECTIVE);
|
||||
this.declareFlexibleType = directives.containsKey(EXPLICIT_FLEXIBLE_TYPES_DIRECTIVE);
|
||||
if (fileName.endsWith(".java")) {
|
||||
PsiFileFactory.getInstance(getProject()).createFileFromText(fileName, JavaLanguage.INSTANCE, textWithMarkers);
|
||||
// TODO: check there's not syntax errors
|
||||
@@ -299,14 +317,40 @@ public abstract class BaseDiagnosticsTest extends JetLiteFixture {
|
||||
else {
|
||||
expectedText = textWithMarkers;
|
||||
clearText = CheckerTestUtil.parseDiagnosedRanges(expectedText, diagnosedRanges);
|
||||
this.jetFile = createCheckAndReturnPsiFile(
|
||||
null, fileName, declareCheckType ? clearText + CHECK_TYPE_DECLARATIONS : clearText);
|
||||
this.jetFile = createCheckAndReturnPsiFile(null, fileName, makeText());
|
||||
for (CheckerTestUtil.DiagnosedRange diagnosedRange : diagnosedRanges) {
|
||||
diagnosedRange.setFile(jetFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String makeText() {
|
||||
String text = declareCheckType ? clearText + CHECK_TYPE_DECLARATIONS : clearText;
|
||||
if (declareFlexibleType) {
|
||||
Pattern pattern = Pattern.compile("^package [\\.\\w\\d]*\n", Pattern.MULTILINE);
|
||||
Matcher matcher = pattern.matcher(text);
|
||||
if (matcher.find()) {
|
||||
// add import after the package directive
|
||||
text = text.substring(0, matcher.end()) + EXPLICIT_FLEXIBLE_TYPES_IMPORT + "\n" + text.substring(matcher.end());
|
||||
}
|
||||
else {
|
||||
// add import at the beginning
|
||||
text = EXPLICIT_FLEXIBLE_TYPES_IMPORT + "\n" + text;
|
||||
}
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
||||
private void stripFlexibleTypes(StringBuilder actualText) {
|
||||
if (declareFlexibleType) {
|
||||
String pattern = EXPLICIT_FLEXIBLE_TYPES_IMPORT + "\n";
|
||||
int start = actualText.indexOf(pattern);
|
||||
if (start >= 0) {
|
||||
actualText.delete(start, start + pattern.length());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public TestModule getModule() {
|
||||
return module;
|
||||
@@ -358,6 +402,9 @@ public abstract class BaseDiagnosticsTest extends JetLiteFixture {
|
||||
return declareCheckType ? StringUtil.trimEnd(text, CHECK_TYPE_DECLARATIONS) : text;
|
||||
}
|
||||
}));
|
||||
|
||||
stripFlexibleTypes(actualText);
|
||||
|
||||
return ok[0];
|
||||
}
|
||||
|
||||
|
||||
@@ -7705,6 +7705,18 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("explicitFlexibleNoPackage.kt")
|
||||
public void testExplicitFlexibleNoPackage() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/explicitFlexibleNoPackage.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("explicitFlexibleWithPackage.kt")
|
||||
public void testExplicitFlexibleWithPackage() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/explicitFlexibleWithPackage.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("getParentOfType.kt")
|
||||
public void testGetParentOfType() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/platformTypes/getParentOfType.kt");
|
||||
|
||||
@@ -38,6 +38,7 @@ import org.jetbrains.jet.lang.types.expressions.ForLoopConventionsChecker;
|
||||
import org.jetbrains.jet.lang.reflect.ReflectionTypes;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallResolverExtensionProvider;
|
||||
import org.jetbrains.jet.lang.resolve.TypeResolver.FlexibleTypeCapabilitiesProvider;
|
||||
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import javax.annotation.PreDestroy;
|
||||
@@ -68,6 +69,7 @@ public class InjectorForTests {
|
||||
private final ReflectionTypes reflectionTypes;
|
||||
private final CallExpressionResolver callExpressionResolver;
|
||||
private final CallResolverExtensionProvider callResolverExtensionProvider;
|
||||
private final FlexibleTypeCapabilitiesProvider flexibleTypeCapabilitiesProvider;
|
||||
private final QualifiedExpressionResolver qualifiedExpressionResolver;
|
||||
|
||||
public InjectorForTests(
|
||||
@@ -96,6 +98,7 @@ public class InjectorForTests {
|
||||
this.reflectionTypes = new ReflectionTypes(moduleDescriptor);
|
||||
this.callExpressionResolver = new CallExpressionResolver();
|
||||
this.callResolverExtensionProvider = new CallResolverExtensionProvider();
|
||||
this.flexibleTypeCapabilitiesProvider = new FlexibleTypeCapabilitiesProvider();
|
||||
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
|
||||
|
||||
this.descriptorResolver.setAnnotationResolver(annotationResolver);
|
||||
@@ -113,6 +116,7 @@ public class InjectorForTests {
|
||||
this.expressionTypingServices.setTypeResolver(typeResolver);
|
||||
|
||||
this.typeResolver.setAnnotationResolver(annotationResolver);
|
||||
this.typeResolver.setFlexibleTypeCapabilitiesProvider(flexibleTypeCapabilitiesProvider);
|
||||
this.typeResolver.setModuleDescriptor(moduleDescriptor);
|
||||
this.typeResolver.setQualifiedExpressionResolver(qualifiedExpressionResolver);
|
||||
|
||||
|
||||
@@ -20,6 +20,9 @@ import org.jetbrains.jet.lang.types.checker.JetTypeChecker
|
||||
import org.jetbrains.jet.lang.types.Approximation.DataFlowExtras
|
||||
import org.jetbrains.jet.lang.resolve.name.FqName
|
||||
import kotlin.platform.platformStatic
|
||||
import org.jetbrains.jet.lang.resolve.name.ClassId
|
||||
import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe
|
||||
import org.jetbrains.jet.lang.resolve.name.Name
|
||||
|
||||
public trait FlexibleTypeCapabilities {
|
||||
fun <T: TypeCapability> getCapability(capabilityClass: Class<T>, jetType: JetType, flexibility: Flexibility): T?
|
||||
@@ -32,6 +35,14 @@ public trait FlexibleTypeCapabilities {
|
||||
}
|
||||
|
||||
public trait Flexibility : TypeCapability {
|
||||
class object {
|
||||
// This is a "magic" classifier: when type resolver sees it in the code, e.g. ft<Foo, Foo?>, instead of creating a normal type,
|
||||
// it creates a flexible type, e.g. (Foo..Foo?).
|
||||
// This is used in tests and Evaluate Expression to have flexible types in the code,
|
||||
// but normal users should not be referencing this classifier
|
||||
public val FLEXIBLE_TYPE_CLASSIFIER: ClassId = ClassId(FqName("kotlin.internal.flexible"), FqNameUnsafe.topLevel(Name.identifier("ft")))
|
||||
}
|
||||
|
||||
// lowerBound is a subtype of upperBound
|
||||
public val lowerBound: JetType
|
||||
public val upperBound: JetType
|
||||
|
||||
@@ -41,6 +41,7 @@ import org.jetbrains.jet.lang.resolve.java.lazy.SingleModuleClassResolver
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.VirtualFileFinderFactory
|
||||
import org.jetbrains.jet.lang.resolve.java.TopDownAnalyzerFacadeForJVM
|
||||
import org.jetbrains.jet.lang.resolve.kotlin.JavaDeclarationCheckerProvider
|
||||
import org.jetbrains.jet.lang.resolve.java.JavaFlexibleTypeCapabilitiesProvider
|
||||
|
||||
// NOTE: After making changes, you need to re-generate the injectors.
|
||||
// To do that, you can run main in this file.
|
||||
@@ -120,7 +121,8 @@ private fun generatorForTopDownAnalyzerForJvm() =
|
||||
javaClass<MutablePackageFragmentProvider>(),
|
||||
javaClass<JavaPropertyInitializerEvaluatorImpl>(),
|
||||
javaClass<JavaSourceElementFactoryImpl>(),
|
||||
javaClass<SingleModuleClassResolver>()
|
||||
javaClass<SingleModuleClassResolver>(),
|
||||
javaClass<JavaFlexibleTypeCapabilitiesProvider>()
|
||||
)
|
||||
field(javaClass<VirtualFileFinder>(), init = GivenExpression(javaClass<VirtualFileFinder>().getName() + ".SERVICE.getInstance(project)"))
|
||||
}
|
||||
@@ -185,7 +187,8 @@ private fun generatorForLazyResolveWithJava() =
|
||||
javaClass<PsiBasedMethodSignatureChecker>(),
|
||||
javaClass<PsiBasedExternalAnnotationResolver>(),
|
||||
javaClass<JavaPropertyInitializerEvaluatorImpl>(),
|
||||
javaClass<JavaSourceElementFactoryImpl>()
|
||||
javaClass<JavaSourceElementFactoryImpl>(),
|
||||
javaClass<JavaFlexibleTypeCapabilitiesProvider>()
|
||||
)
|
||||
field(javaClass<AdditionalCheckerProvider>(),
|
||||
init = GivenExpression(javaClass<JavaDeclarationCheckerProvider>().getName() + ".INSTANCE$"))
|
||||
|
||||
@@ -40,6 +40,7 @@ import org.jetbrains.jet.lang.resolve.calls.CallExpressionResolver;
|
||||
import org.jetbrains.jet.lang.resolve.DescriptorResolver;
|
||||
import org.jetbrains.jet.lang.resolve.DelegatedPropertyResolver;
|
||||
import org.jetbrains.jet.lang.resolve.TypeResolver;
|
||||
import org.jetbrains.jet.lang.resolve.TypeResolver.FlexibleTypeCapabilitiesProvider;
|
||||
import org.jetbrains.jet.lang.resolve.QualifiedExpressionResolver;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallResolverExtensionProvider;
|
||||
import org.jetbrains.jet.lang.resolve.calls.CallCompleter;
|
||||
@@ -87,6 +88,7 @@ public class InjectorForTopDownAnalyzerForJs {
|
||||
private final DescriptorResolver descriptorResolver;
|
||||
private final DelegatedPropertyResolver delegatedPropertyResolver;
|
||||
private final TypeResolver typeResolver;
|
||||
private final FlexibleTypeCapabilitiesProvider flexibleTypeCapabilitiesProvider;
|
||||
private final QualifiedExpressionResolver qualifiedExpressionResolver;
|
||||
private final CallResolverExtensionProvider callResolverExtensionProvider;
|
||||
private final CallCompleter callCompleter;
|
||||
@@ -134,6 +136,7 @@ public class InjectorForTopDownAnalyzerForJs {
|
||||
this.descriptorResolver = new DescriptorResolver();
|
||||
this.delegatedPropertyResolver = new DelegatedPropertyResolver();
|
||||
this.typeResolver = new TypeResolver();
|
||||
this.flexibleTypeCapabilitiesProvider = new FlexibleTypeCapabilitiesProvider();
|
||||
this.qualifiedExpressionResolver = new QualifiedExpressionResolver();
|
||||
this.callResolverExtensionProvider = new CallResolverExtensionProvider();
|
||||
this.candidateResolver = new CandidateResolver();
|
||||
@@ -227,6 +230,7 @@ public class InjectorForTopDownAnalyzerForJs {
|
||||
delegatedPropertyResolver.setExpressionTypingServices(expressionTypingServices);
|
||||
|
||||
typeResolver.setAnnotationResolver(annotationResolver);
|
||||
typeResolver.setFlexibleTypeCapabilitiesProvider(flexibleTypeCapabilitiesProvider);
|
||||
typeResolver.setModuleDescriptor(moduleDescriptor);
|
||||
typeResolver.setQualifiedExpressionResolver(qualifiedExpressionResolver);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user