diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaBridgeConfiguration.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaBridgeConfiguration.java index 8b156136597..a513c5dfc5f 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaBridgeConfiguration.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaBridgeConfiguration.java @@ -91,9 +91,9 @@ public class JavaBridgeConfiguration implements ModuleConfiguration { @NotNull @Override - public Collection getKotlinAnalogs(@NotNull FqNameUnsafe className) { - if (className.isSafe()) { - return JavaToKotlinTypesMap.getInstance().getAllKotlinAnalogs(className.toSafe()); + public Collection getKotlinAnalogs(@NotNull FqNameUnsafe classOrPackageName) { + if (classOrPackageName.isSafe()) { + return JavaToKotlinTypesMap.getInstance().getAllKotlinAnalogs(classOrPackageName.toSafe()); } return Collections.emptyList(); } diff --git a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaToKotlinTypesMap.java b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaToKotlinTypesMap.java index 75d7dd2197f..d75ab0343ca 100644 --- a/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaToKotlinTypesMap.java +++ b/compiler/frontend.java/src/org/jetbrains/jet/lang/resolve/java/JavaToKotlinTypesMap.java @@ -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 classDescriptorMap = Maps.newHashMap(); private final Map classDescriptorMapForCovariantPositions = Maps.newHashMap(); private final Map primitiveTypesMap = Maps.newHashMap(); - private final Set mappedTypeNames = Sets.newHashSet(); + private final Multimap 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 getAllKotlinAnalogs(@NotNull FqName fqName) { + public Collection 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 descriptors = Lists.newArrayList(); if (kotlinAnalog != null) { diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java index d3aa33794c5..43567f8bd4b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -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 createIsNotHiddenByKotlinAnalogPredicate( + @NotNull DeclarationDescriptor descriptor, + final @Nullable ModuleConfiguration moduleConfiguration + ) { + if (moduleConfiguration == null || moduleConfiguration.getKotlinAnalogs(getFQName(descriptor)).isEmpty()) return null; + return new Predicate() { + @Override + public boolean apply(@Nullable DeclarationDescriptor descriptor) { + if (descriptor == null) return false; + Collection kotlinAnalogs = + moduleConfiguration.getKotlinAnalogs(getFQName(descriptor)); + for (ClassDescriptor kotlinAnalog : kotlinAnalogs) { + if (kotlinAnalog.getName().equals(descriptor.getName())) { + return false; + } + } + return true; + } + }; + } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/Importer.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/Importer.java index dcb1f6983a2..90a1c1bbb98 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/Importer.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/Importer.java @@ -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 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 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 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 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> imports = Lists.newArrayList(); + private interface DelayedImportEntry {} + private static class AllUnderImportEntry extends Pair> implements DelayedImportEntry { + public AllUnderImportEntry(@NotNull DeclarationDescriptor first, @Nullable Predicate second) { + super(first, second); + } + } + private static class AliasImportEntry extends Pair implements DelayedImportEntry { + public AliasImportEntry(DeclarationDescriptor first, Name second) { + super(first, second); + } + } + + private final List imports = Lists.newArrayList(); public DelayedImporter(@NotNull WritableScope namespaceScope) { super(namespaceScope); } @Override - public void addAllUnderImport(@NotNull DeclarationDescriptor descriptor) { - imports.add(Pair.create(descriptor, null)); + public void addAllUnderImport(@NotNull DeclarationDescriptor descriptor, @Nullable Predicate 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 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()); } } } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java index bac75d02b4f..7e1537cbb18 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ImportsResolver.java @@ -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 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()); } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/QualifiedExpressionResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/QualifiedExpressionResolver.java index aa43cdd006e..f8178d27572 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/QualifiedExpressionResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/QualifiedExpressionResolver.java @@ -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 analyseImportReference(@NotNull JetImportDirective importDirective, - @NotNull JetScope scope, @NotNull BindingTrace trace) { - - return processImportReference(importDirective, scope, scope, Importer.DO_NOTHING, trace, false); + public Collection analyseImportReference( + @NotNull JetImportDirective importDirective, + @NotNull JetScope scope, + @NotNull BindingTrace trace + ) { + return processImportReference(importDirective, scope, scope, Importer.DO_NOTHING, trace, null, false); } @NotNull - public Collection processImportReference(@NotNull JetImportDirective importDirective, - @NotNull JetScope scope, @NotNull JetScope scopeToCheckVisibility, @NotNull Importer importer, @NotNull BindingTrace trace, boolean onlyClasses) { - + public Collection 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; } diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/FilteringScope.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/FilteringScope.java new file mode 100644 index 00000000000..7429c7407f0 --- /dev/null +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/scopes/FilteringScope.java @@ -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 predicate; + + public FilteringScope( + @NotNull JetScope workerScope, + @NotNull Predicate predicate + ) { + super(workerScope); + this.predicate = predicate; + } + + @NotNull + @Override + public Collection getFunctions(@NotNull Name name) { + return Collections2.filter(super.getFunctions(name), predicate); + } + + private 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 getObjectDescriptors() { + return Collections2.filter(super.getObjectDescriptors(), predicate); + } + + @NotNull + @Override + public Collection 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 getAllDescriptors() { + return Collections2.filter(super.getAllDescriptors(), predicate); + } + + @NotNull + @Override + public Collection 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 getOwnDeclaredDescriptors() { + return Collections2.filter(super.getOwnDeclaredDescriptors(), predicate); + } +} diff --git a/compiler/testData/diagnostics/tests/j+k/kt2606.kt b/compiler/testData/diagnostics/tests/j+k/kt2606.kt new file mode 100644 index 00000000000..eea57095e04 --- /dev/null +++ b/compiler/testData/diagnostics/tests/j+k/kt2606.kt @@ -0,0 +1,11 @@ +//KT-2606 Filter java.util.* import +package n + +import java.util.* +import java.lang.annotation.* + +fun bar() : Iterator? { + val i : Iterable<Integer> + val a : Annotation + return null +} \ No newline at end of file diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index e8bc8b62243..816ad49871d 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -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");