KT-2606 Filter java.util.* import
#KT-2606 fixed added FilteringScope
This commit is contained in:
+3
-3
@@ -91,9 +91,9 @@ public class JavaBridgeConfiguration implements ModuleConfiguration {
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<ClassDescriptor> getKotlinAnalogs(@NotNull FqNameUnsafe className) {
|
||||
if (className.isSafe()) {
|
||||
return JavaToKotlinTypesMap.getInstance().getAllKotlinAnalogs(className.toSafe());
|
||||
public Collection<ClassDescriptor> getKotlinAnalogs(@NotNull FqNameUnsafe classOrPackageName) {
|
||||
if (classOrPackageName.isSafe()) {
|
||||
return JavaToKotlinTypesMap.getInstance().getAllKotlinAnalogs(classOrPackageName.toSafe());
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
|
||||
+6
-8
@@ -16,9 +16,7 @@
|
||||
|
||||
package org.jetbrains.jet.lang.resolve.java;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.google.common.collect.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.ClassDescriptor;
|
||||
@@ -48,7 +46,7 @@ public class JavaToKotlinTypesMap {
|
||||
private final Map<FqName, ClassDescriptor> classDescriptorMap = Maps.newHashMap();
|
||||
private final Map<FqName, ClassDescriptor> classDescriptorMapForCovariantPositions = Maps.newHashMap();
|
||||
private final Map<String, JetType> primitiveTypesMap = Maps.newHashMap();
|
||||
private final Set<String> mappedTypeNames = Sets.newHashSet();
|
||||
private final Multimap<FqName, ClassDescriptor> packagesWithMappedClasses = HashMultimap.create();
|
||||
|
||||
private JavaToKotlinTypesMap() {
|
||||
init();
|
||||
@@ -111,8 +109,8 @@ public class JavaToKotlinTypesMap {
|
||||
}
|
||||
|
||||
private void register(@NotNull FqName javaClassName, @NotNull ClassDescriptor kotlinDescriptor) {
|
||||
mappedTypeNames.add(javaClassName.getFqName());
|
||||
classDescriptorMap.put(javaClassName, kotlinDescriptor);
|
||||
packagesWithMappedClasses.put(javaClassName.parent(), kotlinDescriptor);
|
||||
}
|
||||
|
||||
private void registerCovariant(@NotNull Class<?> javaClass, @NotNull ClassDescriptor kotlinDescriptor) {
|
||||
@@ -120,16 +118,16 @@ public class JavaToKotlinTypesMap {
|
||||
}
|
||||
|
||||
private void registerCovariant(@NotNull FqName javaClassName, @NotNull ClassDescriptor kotlinDescriptor) {
|
||||
mappedTypeNames.add(javaClassName.getFqName());
|
||||
classDescriptorMapForCovariantPositions.put(javaClassName, kotlinDescriptor);
|
||||
packagesWithMappedClasses.put(javaClassName.parent(), kotlinDescriptor);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<ClassDescriptor> getAllKotlinAnalogs(@NotNull FqName fqName) {
|
||||
public Collection<ClassDescriptor> getAllKotlinAnalogs(@NotNull FqName fqName) {
|
||||
ClassDescriptor kotlinAnalog = classDescriptorMap.get(fqName);
|
||||
ClassDescriptor kotlinCovariantAnalog = classDescriptorMapForCovariantPositions.get(fqName);
|
||||
if (kotlinAnalog == null && kotlinCovariantAnalog == null) {
|
||||
return Collections.emptyList();
|
||||
return packagesWithMappedClasses.get(fqName);
|
||||
}
|
||||
ArrayList<ClassDescriptor> descriptors = Lists.newArrayList();
|
||||
if (kotlinAnalog != null) {
|
||||
|
||||
@@ -16,10 +16,12 @@
|
||||
|
||||
package org.jetbrains.jet.lang.resolve;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Maps;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.ModuleConfiguration;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
@@ -387,4 +389,26 @@ public class DescriptorUtils {
|
||||
Collections.sort(resultList);
|
||||
return resultList;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static Predicate<DeclarationDescriptor> createIsNotHiddenByKotlinAnalogPredicate(
|
||||
@NotNull DeclarationDescriptor descriptor,
|
||||
final @Nullable ModuleConfiguration moduleConfiguration
|
||||
) {
|
||||
if (moduleConfiguration == null || moduleConfiguration.getKotlinAnalogs(getFQName(descriptor)).isEmpty()) return null;
|
||||
return new Predicate<DeclarationDescriptor>() {
|
||||
@Override
|
||||
public boolean apply(@Nullable DeclarationDescriptor descriptor) {
|
||||
if (descriptor == null) return false;
|
||||
Collection<ClassDescriptor> kotlinAnalogs =
|
||||
moduleConfiguration.getKotlinAnalogs(getFQName(descriptor));
|
||||
for (ClassDescriptor kotlinAnalog : kotlinAnalogs) {
|
||||
if (kotlinAnalog.getName().equals(descriptor.getName())) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,11 +16,15 @@
|
||||
|
||||
package org.jetbrains.jet.lang.resolve;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.openapi.util.Pair;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.FilteringScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.JetScope;
|
||||
import org.jetbrains.jet.lang.resolve.scopes.WritableScope;
|
||||
|
||||
import java.util.List;
|
||||
@@ -30,13 +34,13 @@ import java.util.List;
|
||||
*/
|
||||
/*package*/ interface Importer {
|
||||
|
||||
void addAllUnderImport(@NotNull DeclarationDescriptor descriptor);
|
||||
void addAllUnderImport(@NotNull DeclarationDescriptor descriptor, @Nullable Predicate<DeclarationDescriptor> isNotHiddenByKotlinAnalog);
|
||||
|
||||
void addAliasImport(@NotNull DeclarationDescriptor descriptor, @NotNull Name aliasName);
|
||||
|
||||
Importer DO_NOTHING = new Importer() {
|
||||
@Override
|
||||
public void addAllUnderImport(@NotNull DeclarationDescriptor descriptor) {
|
||||
public void addAllUnderImport(@NotNull DeclarationDescriptor descriptor, Predicate<DeclarationDescriptor> isNotHiddenByKotlinAnalog) {
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -52,8 +56,8 @@ import java.util.List;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAllUnderImport(@NotNull DeclarationDescriptor descriptor) {
|
||||
importAllUnderDeclaration(descriptor);
|
||||
public void addAllUnderImport(@NotNull DeclarationDescriptor descriptor, @Nullable Predicate<DeclarationDescriptor> isNotHiddenByKotlinAnalog) {
|
||||
importAllUnderDeclaration(descriptor, isNotHiddenByKotlinAnalog);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -61,18 +65,25 @@ import java.util.List;
|
||||
importDeclarationAlias(descriptor, aliasName);
|
||||
}
|
||||
|
||||
protected void importAllUnderDeclaration(@NotNull DeclarationDescriptor descriptor) {
|
||||
protected void importAllUnderDeclaration(@NotNull DeclarationDescriptor descriptor, @Nullable Predicate<DeclarationDescriptor> isNotHiddenByKotlinAnalog) {
|
||||
JetScope scopeToImport = null;
|
||||
if (descriptor instanceof NamespaceDescriptor) {
|
||||
namespaceScope.importScope(((NamespaceDescriptor) descriptor).getMemberScope());
|
||||
scopeToImport = ((NamespaceDescriptor) descriptor).getMemberScope();
|
||||
}
|
||||
if (descriptor instanceof ClassDescriptor && ((ClassDescriptor) descriptor).getKind() != ClassKind.OBJECT) {
|
||||
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
|
||||
namespaceScope.importScope(classDescriptor.getUnsubstitutedInnerClassesScope());
|
||||
scopeToImport = classDescriptor.getUnsubstitutedInnerClassesScope();
|
||||
ClassDescriptor classObjectDescriptor = classDescriptor.getClassObjectDescriptor();
|
||||
if (classObjectDescriptor != null) {
|
||||
namespaceScope.importScope(classObjectDescriptor.getUnsubstitutedInnerClassesScope());
|
||||
scopeToImport = classObjectDescriptor.getUnsubstitutedInnerClassesScope();
|
||||
}
|
||||
}
|
||||
if (scopeToImport != null) {
|
||||
if (isNotHiddenByKotlinAnalog != null) {
|
||||
scopeToImport = new FilteringScope(scopeToImport, isNotHiddenByKotlinAnalog);
|
||||
}
|
||||
namespaceScope.importScope(scopeToImport);
|
||||
}
|
||||
}
|
||||
|
||||
protected void importDeclarationAlias(@NotNull DeclarationDescriptor descriptor, @NotNull Name aliasName) {
|
||||
@@ -93,32 +104,43 @@ import java.util.List;
|
||||
}
|
||||
|
||||
class DelayedImporter extends StandardImporter {
|
||||
private final List<Pair<DeclarationDescriptor, Name>> imports = Lists.newArrayList();
|
||||
private interface DelayedImportEntry {}
|
||||
private static class AllUnderImportEntry extends Pair<DeclarationDescriptor, Predicate<DeclarationDescriptor>> implements DelayedImportEntry {
|
||||
public AllUnderImportEntry(@NotNull DeclarationDescriptor first, @Nullable Predicate<DeclarationDescriptor> second) {
|
||||
super(first, second);
|
||||
}
|
||||
}
|
||||
private static class AliasImportEntry extends Pair<DeclarationDescriptor, Name> implements DelayedImportEntry {
|
||||
public AliasImportEntry(DeclarationDescriptor first, Name second) {
|
||||
super(first, second);
|
||||
}
|
||||
}
|
||||
|
||||
private final List<DelayedImportEntry> imports = Lists.newArrayList();
|
||||
|
||||
public DelayedImporter(@NotNull WritableScope namespaceScope) {
|
||||
super(namespaceScope);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAllUnderImport(@NotNull DeclarationDescriptor descriptor) {
|
||||
imports.add(Pair.<DeclarationDescriptor, Name>create(descriptor, null));
|
||||
public void addAllUnderImport(@NotNull DeclarationDescriptor descriptor, @Nullable Predicate<DeclarationDescriptor> isNotHiddenByKotlinAnalog) {
|
||||
imports.add(new AllUnderImportEntry(descriptor, isNotHiddenByKotlinAnalog));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void addAliasImport(@NotNull DeclarationDescriptor descriptor, @NotNull Name aliasName) {
|
||||
imports.add(Pair.create(descriptor, aliasName));
|
||||
imports.add(new AliasImportEntry(descriptor, aliasName));
|
||||
}
|
||||
|
||||
public void processImports() {
|
||||
for (Pair<DeclarationDescriptor, Name> anImport : imports) {
|
||||
DeclarationDescriptor descriptor = anImport.getFirst();
|
||||
Name aliasName = anImport.getSecond();
|
||||
boolean allUnderImport = aliasName == null;
|
||||
if (allUnderImport) {
|
||||
importAllUnderDeclaration(descriptor);
|
||||
for (DelayedImportEntry anImport : imports) {
|
||||
if (anImport instanceof AllUnderImportEntry) {
|
||||
AllUnderImportEntry allUnderImportEntry = (AllUnderImportEntry) anImport;
|
||||
importAllUnderDeclaration(allUnderImportEntry.getFirst(), allUnderImportEntry.getSecond());
|
||||
}
|
||||
else {
|
||||
importDeclarationAlias(descriptor, aliasName);
|
||||
AliasImportEntry aliasImportEntry = (AliasImportEntry) anImport;
|
||||
importDeclarationAlias(aliasImportEntry.getFirst(), aliasImportEntry.getSecond());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -112,12 +112,14 @@ public class ImportsResolver {
|
||||
configuration.addDefaultImports(defaultImportDirectives);
|
||||
for (JetImportDirective defaultImportDirective : defaultImportDirectives) {
|
||||
TemporaryBindingTrace temporaryTrace = TemporaryBindingTrace.create(trace); //not to trace errors of default imports
|
||||
qualifiedExpressionResolver.processImportReference(defaultImportDirective, rootScope, namespaceScope, delayedImporter, temporaryTrace, onlyClasses);
|
||||
qualifiedExpressionResolver.processImportReference(defaultImportDirective, rootScope, namespaceScope, delayedImporter,
|
||||
temporaryTrace, configuration, onlyClasses);
|
||||
}
|
||||
|
||||
for (JetImportDirective importDirective : importDirectives) {
|
||||
Collection<? extends DeclarationDescriptor> descriptors =
|
||||
qualifiedExpressionResolver.processImportReference(importDirective, rootScope, namespaceScope, delayedImporter, trace, onlyClasses);
|
||||
qualifiedExpressionResolver.processImportReference(importDirective, rootScope, namespaceScope, delayedImporter,
|
||||
trace, configuration, onlyClasses);
|
||||
if (descriptors.size() == 1) {
|
||||
resolvedDirectives.put(importDirective, descriptors.iterator().next());
|
||||
}
|
||||
|
||||
+19
-9
@@ -22,6 +22,7 @@ import com.google.common.collect.Lists;
|
||||
import com.google.common.collect.Sets;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.ModuleConfiguration;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.diagnostics.Errors;
|
||||
import org.jetbrains.jet.lang.psi.*;
|
||||
@@ -40,16 +41,24 @@ import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||
public class QualifiedExpressionResolver {
|
||||
|
||||
@NotNull
|
||||
public Collection<? extends DeclarationDescriptor> analyseImportReference(@NotNull JetImportDirective importDirective,
|
||||
@NotNull JetScope scope, @NotNull BindingTrace trace) {
|
||||
|
||||
return processImportReference(importDirective, scope, scope, Importer.DO_NOTHING, trace, false);
|
||||
public Collection<? extends DeclarationDescriptor> analyseImportReference(
|
||||
@NotNull JetImportDirective importDirective,
|
||||
@NotNull JetScope scope,
|
||||
@NotNull BindingTrace trace
|
||||
) {
|
||||
return processImportReference(importDirective, scope, scope, Importer.DO_NOTHING, trace, null, false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Collection<? extends DeclarationDescriptor> processImportReference(@NotNull JetImportDirective importDirective,
|
||||
@NotNull JetScope scope, @NotNull JetScope scopeToCheckVisibility, @NotNull Importer importer, @NotNull BindingTrace trace, boolean onlyClasses) {
|
||||
|
||||
public Collection<? extends DeclarationDescriptor> processImportReference(
|
||||
@NotNull JetImportDirective importDirective,
|
||||
@NotNull JetScope scope,
|
||||
@NotNull JetScope scopeToCheckVisibility,
|
||||
@NotNull Importer importer,
|
||||
@NotNull BindingTrace trace,
|
||||
@Nullable ModuleConfiguration moduleConfiguration,
|
||||
boolean onlyClasses
|
||||
) {
|
||||
if (importDirective.isAbsoluteInRootNamespace()) {
|
||||
trace.report(UNSUPPORTED.on(importDirective, "TypeHierarchyResolver")); // TODO
|
||||
return Collections.emptyList();
|
||||
@@ -76,7 +85,7 @@ public class QualifiedExpressionResolver {
|
||||
}
|
||||
|
||||
for (DeclarationDescriptor descriptor : descriptors) {
|
||||
importer.addAllUnderImport(descriptor);
|
||||
importer.addAllUnderImport(descriptor, DescriptorUtils.createIsNotHiddenByKotlinAnalogPredicate(descriptor, moduleConfiguration));
|
||||
}
|
||||
return Collections.emptyList();
|
||||
}
|
||||
@@ -311,7 +320,8 @@ public class QualifiedExpressionResolver {
|
||||
}
|
||||
}
|
||||
if (storeResult) {
|
||||
storeResolutionResult(descriptors, filteredDescriptors, referenceExpression, possibleResolutionScopes, trace, scopeToCheckVisibility);
|
||||
storeResolutionResult(descriptors, filteredDescriptors, referenceExpression, possibleResolutionScopes, trace,
|
||||
scopeToCheckVisibility);
|
||||
}
|
||||
return filteredDescriptors;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright 2010-2012 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.scopes;
|
||||
|
||||
import com.google.common.base.Predicate;
|
||||
import com.google.common.collect.Collections2;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.lang.descriptors.*;
|
||||
import org.jetbrains.jet.lang.resolve.name.LabelName;
|
||||
import org.jetbrains.jet.lang.resolve.name.Name;
|
||||
|
||||
import java.util.Collection;
|
||||
|
||||
/**
|
||||
* @author svtk
|
||||
*/
|
||||
public class FilteringScope extends JetScopeAdapter {
|
||||
private final Predicate<DeclarationDescriptor> predicate;
|
||||
|
||||
public FilteringScope(
|
||||
@NotNull JetScope workerScope,
|
||||
@NotNull Predicate<DeclarationDescriptor> predicate
|
||||
) {
|
||||
super(workerScope);
|
||||
this.predicate = predicate;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<FunctionDescriptor> getFunctions(@NotNull Name name) {
|
||||
return Collections2.filter(super.getFunctions(name), predicate);
|
||||
}
|
||||
|
||||
private <D extends DeclarationDescriptor> D filterDescriptor(@Nullable D descriptor) {
|
||||
if (predicate.apply(descriptor)) return descriptor;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public NamespaceDescriptor getNamespace(@NotNull Name name) {
|
||||
return filterDescriptor(super.getNamespace(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassifierDescriptor getClassifier(@NotNull Name name) {
|
||||
return filterDescriptor(super.getClassifier(name));
|
||||
}
|
||||
|
||||
@Override
|
||||
public ClassDescriptor getObjectDescriptor(@NotNull Name name) {
|
||||
return filterDescriptor(super.getObjectDescriptor(name));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<ClassDescriptor> getObjectDescriptors() {
|
||||
return Collections2.filter(super.getObjectDescriptors(), predicate);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<VariableDescriptor> getProperties(@NotNull Name name) {
|
||||
return Collections2.filter(super.getProperties(name), predicate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public VariableDescriptor getLocalVariable(@NotNull Name name) {
|
||||
return filterDescriptor(super.getLocalVariable(name));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<DeclarationDescriptor> getAllDescriptors() {
|
||||
return Collections2.filter(super.getAllDescriptors(), predicate);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<DeclarationDescriptor> getDeclarationsByLabel(LabelName labelName) {
|
||||
return Collections2.filter(super.getDeclarationsByLabel(labelName), predicate);
|
||||
}
|
||||
|
||||
@Override
|
||||
public PropertyDescriptor getPropertyByFieldReference(@NotNull Name fieldName) {
|
||||
return filterDescriptor(super.getPropertyByFieldReference(fieldName));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Collection<DeclarationDescriptor> getOwnDeclaredDescriptors() {
|
||||
return Collections2.filter(super.getOwnDeclaredDescriptors(), predicate);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
//KT-2606 Filter java.util.* import
|
||||
package n
|
||||
|
||||
import java.util.*
|
||||
import java.lang.annotation.*
|
||||
|
||||
fun bar() : Iterator<Int>? {
|
||||
val <!UNUSED_VARIABLE!>i<!> : Iterable<<!CLASS_HAS_KOTLIN_ANALOG!>Integer<!>>
|
||||
val <!UNUSED_VARIABLE!>a<!> : Annotation
|
||||
return null
|
||||
}
|
||||
@@ -1742,6 +1742,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
|
||||
doTest("compiler/testData/diagnostics/tests/j+k/kt2394.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt2606.kt")
|
||||
public void testKt2606() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/j+k/kt2606.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("kt2641.kt")
|
||||
public void testKt2641() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/j+k/kt2641.kt");
|
||||
|
||||
Reference in New Issue
Block a user