KT-2606 Filter java.util.* import

#KT-2606 fixed
 added FilteringScope
This commit is contained in:
Svetlana Isakova
2012-08-29 14:45:42 +04:00
parent a04f6ee263
commit 726bcb5465
9 changed files with 221 additions and 41 deletions
@@ -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();
}
@@ -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());
}
@@ -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");