diff --git a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CliLightClassGenerationSupport.java b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CliLightClassGenerationSupport.java index 3b8e0daee16..2b324b35d92 100644 --- a/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CliLightClassGenerationSupport.java +++ b/compiler/cli/src/org/jetbrains/jet/cli/jvm/compiler/CliLightClassGenerationSupport.java @@ -97,6 +97,12 @@ public class CliLightClassGenerationSupport extends LightClassGenerationSupport return module; } + @TestOnly + @Nullable + public ModuleDescriptorImpl getLightClassModule() { + return module; + } + @TestOnly public void setModule(@NotNull ModuleDescriptorImpl module) { assert this.module == null : "module already configured: " + module; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/MemberComparator.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/MemberComparator.java index efc39e710f9..21c14726324 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/MemberComparator.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/MemberComparator.java @@ -17,6 +17,7 @@ package org.jetbrains.jet.lang.resolve; import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.renderer.DescriptorRenderer; import org.jetbrains.jet.renderer.DescriptorRendererBuilder; @@ -69,66 +70,85 @@ public class MemberComparator implements Comparator { return namesCompareTo; } - if (!(o1 instanceof CallableDescriptor) || !(o2 instanceof CallableDescriptor)) { - assert false : "Descriptors must be callable:\n" + o1 + "\n" + o2; - } + if (o1 instanceof CallableDescriptor && o2 instanceof CallableDescriptor) { + CallableDescriptor c1 = (CallableDescriptor) o1; + CallableDescriptor c2 = (CallableDescriptor) o2; - CallableDescriptor c1 = (CallableDescriptor)o1; - CallableDescriptor c2 = (CallableDescriptor)o2; + ReceiverParameterDescriptor c1ReceiverParameter = c1.getReceiverParameter(); + ReceiverParameterDescriptor c2ReceiverParameter = c2.getReceiverParameter(); + assert (c1ReceiverParameter != null) == (c2ReceiverParameter != null); + if (c1ReceiverParameter != null) { + String r1 = RENDERER.renderType(c1ReceiverParameter.getType()); + String r2 = RENDERER.renderType(c2ReceiverParameter.getType()); + int receiversCompareTo = r1.compareTo(r2); + if (receiversCompareTo != 0) { + return receiversCompareTo; + } + } - ReceiverParameterDescriptor c1ReceiverParameter = c1.getReceiverParameter(); - ReceiverParameterDescriptor c2ReceiverParameter = c2.getReceiverParameter(); - assert (c1ReceiverParameter != null) == (c2ReceiverParameter != null); - if (c1ReceiverParameter != null) { - String r1 = RENDERER.renderType(c1ReceiverParameter.getType()); - String r2 = RENDERER.renderType(c2ReceiverParameter.getType()); - int receiversCompareTo = r1.compareTo(r2); - if (receiversCompareTo != 0) { - return receiversCompareTo; + List c1ValueParameters = c1.getValueParameters(); + List c2ValueParameters = c2.getValueParameters(); + for (int i = 0; i < Math.min(c1ValueParameters.size(), c2ValueParameters.size()); i++) { + String p1 = RENDERER.renderType(c1ValueParameters.get(i).getType()); + String p2 = RENDERER.renderType(c2ValueParameters.get(i).getType()); + int parametersCompareTo = p1.compareTo(p2); + if (parametersCompareTo != 0) { + return parametersCompareTo; + } + } + + int valueParametersNumberCompareTo = c1ValueParameters.size() - c2ValueParameters.size(); + if (valueParametersNumberCompareTo != 0) { + return valueParametersNumberCompareTo; + } + + List c1TypeParameters = c1.getTypeParameters(); + List c2TypeParameters = c2.getTypeParameters(); + for (int i = 0; i < Math.min(c1TypeParameters.size(), c2TypeParameters.size()); i++) { + String p1 = RENDERER.renderType(c1TypeParameters.get(i).getUpperBoundsAsType()); + String p2 = RENDERER.renderType(c2TypeParameters.get(i).getUpperBoundsAsType()); + int parametersCompareTo = p1.compareTo(p2); + if (parametersCompareTo != 0) { + return parametersCompareTo; + } + } + + int typeParametersCompareTo = c1TypeParameters.size() - c2TypeParameters.size(); + if (typeParametersCompareTo != 0) { + return typeParametersCompareTo; + } + + if (c1 instanceof CallableMemberDescriptor && c2 instanceof CallableMemberDescriptor) { + CallableMemberDescriptor.Kind c1Kind = ((CallableMemberDescriptor) c1).getKind(); + CallableMemberDescriptor.Kind c2Kind = ((CallableMemberDescriptor) c2).getKind(); + int kindsCompareTo = c1Kind.ordinal() - c2Kind.ordinal(); + if (kindsCompareTo != 0) { + return kindsCompareTo; + } } } + else if (o1 instanceof ClassDescriptor && o2 instanceof ClassDescriptor) { + ClassDescriptor class1 = (ClassDescriptor) o1; + ClassDescriptor class2 = (ClassDescriptor) o2; - List c1ValueParameters = c1.getValueParameters(); - List c2ValueParameters = c2.getValueParameters(); - for (int i = 0; i < Math.min(c1ValueParameters.size(), c2ValueParameters.size()); i++) { - String p1 = RENDERER.renderType(c1ValueParameters.get(i).getType()); - String p2 = RENDERER.renderType(c2ValueParameters.get(i).getType()); - int parametersCompareTo = p1.compareTo(p2); - if (parametersCompareTo != 0) { - return parametersCompareTo; + if (class1.getKind().ordinal() != class2.getKind().ordinal()) { + return class1.getKind().ordinal() - class2.getKind().ordinal(); } } - - int valueParametersNumberCompareTo = c1ValueParameters.size() - c2ValueParameters.size(); - if (valueParametersNumberCompareTo != 0) { - return valueParametersNumberCompareTo; + else { + throw new AssertionError(String.format( + "Unsupported pair of descriptors:\n'" + + "%s' Class: %s\n" + + "%s' Class: %s", + o1, o1.getClass(), o2, o2.getClass())); } - List c1TypeParameters = c1.getTypeParameters(); - List c2TypeParameters = c2.getTypeParameters(); - for (int i = 0; i < Math.min(c1TypeParameters.size(), c2TypeParameters.size()); i++) { - String p1 = RENDERER.renderType(c1TypeParameters.get(i).getUpperBoundsAsType()); - String p2 = RENDERER.renderType(c2TypeParameters.get(i).getUpperBoundsAsType()); - int parametersCompareTo = p1.compareTo(p2); - if (parametersCompareTo != 0) { - return parametersCompareTo; - } - } + int renderDiff = RENDERER.render(o1).compareTo(RENDERER.render(o2)); + if (renderDiff != 0) return renderDiff; - int typeParametersCompareTo = c1TypeParameters.size() - c2TypeParameters.size(); - if (typeParametersCompareTo != 0) { - return typeParametersCompareTo; - } + Name firstModuleName = DescriptorUtils.getContainingModule(o1).getName(); + Name secondModuleName = DescriptorUtils.getContainingModule(o2).getName(); - if (c1 instanceof CallableMemberDescriptor && c2 instanceof CallableMemberDescriptor) { - CallableMemberDescriptor.Kind c1Kind = ((CallableMemberDescriptor) c1).getKind(); - CallableMemberDescriptor.Kind c2Kind = ((CallableMemberDescriptor) c2).getKind(); - int kindsCompareTo = c1Kind.ordinal() - c2Kind.ordinal(); - if (kindsCompareTo != 0) { - return kindsCompareTo; - } - } - - return RENDERER.render(o1).compareTo(RENDERER.render(o2)); + return firstModuleName.compareTo(secondModuleName); } } diff --git a/compiler/tests/org/jetbrains/jet/checkers/AbstractJetDiagnosticsTest.java b/compiler/tests/org/jetbrains/jet/checkers/AbstractJetDiagnosticsTest.java index 2197bce263e..ba20d698db0 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/AbstractJetDiagnosticsTest.java +++ b/compiler/tests/org/jetbrains/jet/checkers/AbstractJetDiagnosticsTest.java @@ -16,9 +16,11 @@ package org.jetbrains.jet.checkers; +import com.google.common.base.Predicate; import com.google.common.base.Predicates; import com.google.common.collect.ImmutableMap; import com.google.common.collect.Sets; +import com.intellij.openapi.util.io.FileUtil; import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import kotlin.Function1; @@ -26,6 +28,10 @@ import kotlin.KotlinPackage; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.cli.jvm.compiler.CliLightClassGenerationSupport; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.PackageFragmentDescriptor; +import org.jetbrains.jet.lang.descriptors.PackageFragmentProvider; +import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor; import org.jetbrains.jet.lang.descriptors.impl.ModuleDescriptorImpl; import org.jetbrains.jet.lang.diagnostics.*; import org.jetbrains.jet.lang.psi.Call; @@ -36,15 +42,20 @@ import org.jetbrains.jet.lang.resolve.*; import org.jetbrains.jet.lang.resolve.calls.model.MutableResolvedCall; import org.jetbrains.jet.lang.resolve.calls.model.ResolvedCall; import org.jetbrains.jet.lang.resolve.java.TopDownAnalyzerFacadeForJVM; +import org.jetbrains.jet.lang.resolve.lazy.LazyResolveTestUtil; +import org.jetbrains.jet.lang.resolve.name.FqName; +import org.jetbrains.jet.lang.resolve.name.Name; import org.jetbrains.jet.lang.types.lang.KotlinBuiltIns; +import org.jetbrains.jet.test.util.DescriptorValidator; +import org.jetbrains.jet.test.util.RecursiveDescriptorComparator; import java.io.File; import java.util.*; import static org.jetbrains.jet.lang.diagnostics.Errors.*; +import static org.jetbrains.jet.test.util.RecursiveDescriptorComparator.RECURSIVE; public abstract class AbstractJetDiagnosticsTest extends BaseDiagnosticsTest { - @Override protected void analyzeAndCheck(File testDataFile, List testFiles) { Map> groupedByModule = KotlinPackage.groupByTo( @@ -80,6 +91,7 @@ public abstract class AbstractJetDiagnosticsTest extends BaseDiagnosticsTest { if (module == null) { module = support.newModule(); + modules.put(entry.getKey(), module); } else { module.addDependencyOnModule(KotlinBuiltIns.getInstance().getBuiltInsModule()); @@ -97,6 +109,7 @@ public abstract class AbstractJetDiagnosticsTest extends BaseDiagnosticsTest { null, null ); + checkAllResolvedCallsAreCompleted(jetFiles, moduleTrace.getBindingContext()); } @@ -112,9 +125,83 @@ public abstract class AbstractJetDiagnosticsTest extends BaseDiagnosticsTest { assertTrue("Diagnostics mismatch. See the output above", ok); checkAllResolvedCallsAreCompleted(allJetFiles, supportTrace.getBindingContext()); + + File expectedFile = new File(FileUtil.getNameWithoutExtension(testDataFile.getAbsolutePath()) + ".txt"); + validateAndCompareDescriptorWithFile(expectedFile, testFiles, support, modules); } - private Map createModules(Map> groupedByModule) { + private void validateAndCompareDescriptorWithFile( + File expectedFile, + List testFiles, + CliLightClassGenerationSupport support, + Map modules + ) { + ModuleDescriptorImpl lightClassModule = support.getLightClassModule(); + if (lightClassModule == null) { + ModuleDescriptorImpl cliModule = support.newModule(); + cliModule.initialize(new PackageFragmentProvider() { + @NotNull + @Override + public List getPackageFragments(@NotNull FqName fqName) { + return Collections.emptyList(); + } + + @NotNull + @Override + public Collection getSubPackagesOf(@NotNull FqName fqName) { + return Collections.emptyList(); + } + }); + } + + RecursiveDescriptorComparator comparator = new RecursiveDescriptorComparator(createdAffectedPackagesConfiguration(testFiles)); + + boolean isMultiModuleTest = modules.size() != 1; + StringBuilder rootPackageText = new StringBuilder(); + + for (TestModule module : KotlinPackage.sort(modules.keySet())) { + ModuleDescriptorImpl moduleDescriptor = modules.get(module); + if (isMultiModuleTest) { + rootPackageText.append(String.format("// -- Module: %s --\n", moduleDescriptor.getName())); + } + + DeclarationDescriptor aPackage = moduleDescriptor.getPackage(FqName.ROOT); + assertNotNull(aPackage); + + String actualSerialized = comparator.serializeRecursively(aPackage); + rootPackageText.append(actualSerialized); + + if (isMultiModuleTest) { + rootPackageText.append("\n\n"); + } + } + + JetTestUtils.assertEqualsToFile(expectedFile, rootPackageText.toString()); + } + + public static RecursiveDescriptorComparator.Configuration createdAffectedPackagesConfiguration(List testFiles) { + final Set packagesNames = LazyResolveTestUtil.getTopLevelPackagesFromFileList(getJetFiles(testFiles)); + + Predicate stepIntoFilter = new Predicate() { + @Override + public boolean apply(DeclarationDescriptor descriptor) { + if (descriptor instanceof PackageViewDescriptor) { + FqName fqName = ((PackageViewDescriptor) descriptor).getFqName(); + + if (fqName.isRoot()) return true; + + Name firstName = fqName.pathSegments().get(0); + return packagesNames.contains(firstName); + } + + return true; + } + }; + + return RECURSIVE.filterRecursion(stepIntoFilter).withValidationStrategy(DescriptorValidator.ValidationVisitor.ALLOW_ERROR_TYPES); + } + + public static Map createModules(Map> groupedByModule) { Map modules = new HashMap(); for (TestModule testModule : groupedByModule.keySet()) { diff --git a/compiler/tests/org/jetbrains/jet/checkers/BaseDiagnosticsTest.java b/compiler/tests/org/jetbrains/jet/checkers/BaseDiagnosticsTest.java index 7f72be19170..df353d0ebce 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/BaseDiagnosticsTest.java +++ b/compiler/tests/org/jetbrains/jet/checkers/BaseDiagnosticsTest.java @@ -248,7 +248,7 @@ public abstract class BaseDiagnosticsTest extends JetLiteFixture { }); } - protected static class TestModule { + protected static class TestModule implements Comparable { private final String name; private final List dependencies = new ArrayList(); @@ -265,6 +265,11 @@ public abstract class BaseDiagnosticsTest extends JetLiteFixture { public List getDependencies() { return dependencies; } + + @Override + public int compareTo(@NotNull TestModule module) { + return name.compareTo(module.getName()); + } } protected class TestFile { diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveDiagnosticsTest.java b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveDiagnosticsTest.java index a2fbb258310..a826017f41e 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveDiagnosticsTest.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveDiagnosticsTest.java @@ -20,6 +20,7 @@ import com.google.common.base.Predicate; import com.intellij.openapi.util.io.FileUtil; import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.checkers.BaseDiagnosticsTest; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor; import org.jetbrains.jet.lang.psi.JetFile; @@ -55,13 +56,14 @@ public abstract class AbstractLazyResolveDiagnosticsTest extends BaseDiagnostics final Set names = LazyResolveTestUtil.getTopLevelPackagesFromFileList(jetFiles); validateAndCompareDescriptors( expected, actual, - RECURSIVE.filterRecursion(new Predicate() { + RECURSIVE.filterRecursion(new Predicate() { @Override - public boolean apply(FqName fqName) { - if (fqName.isRoot()) return true; - if (fqName.parent().isRoot()) { - return names.contains(fqName.shortName()); + public boolean apply(DeclarationDescriptor descriptor) { + if (descriptor instanceof PackageViewDescriptor) { + FqName fqName = ((PackageViewDescriptor) descriptor).getFqName(); + return fqName.isRoot() || !fqName.parent().isRoot() || names.contains(fqName.shortName()); } + return true; } }), diff --git a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveRecursiveComparingTest.java b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveRecursiveComparingTest.java index 9231bed2a82..482625cbc99 100644 --- a/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveRecursiveComparingTest.java +++ b/compiler/tests/org/jetbrains/jet/lang/resolve/lazy/AbstractLazyResolveRecursiveComparingTest.java @@ -22,6 +22,7 @@ import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.ConfigurationKind; import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.cli.jvm.compiler.JetCoreEnvironment; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor; import org.jetbrains.jet.lang.psi.JetFile; @@ -78,10 +79,13 @@ public abstract class AbstractLazyResolveRecursiveComparingTest extends KotlinTe RecursiveDescriptorComparator.validateAndCompareDescriptors( expected, actual, RecursiveDescriptorComparator.DONT_INCLUDE_METHODS_OF_OBJECT.filterRecursion( - new Predicate() { + new Predicate() { @Override - public boolean apply(FqName fqName) { - return !KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME.equals(fqName); + public boolean apply(DeclarationDescriptor descriptor) { + if (descriptor instanceof PackageViewDescriptor) { + return !KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME.equals(((PackageViewDescriptor) descriptor).getFqName()); + } + return true; } }) .checkPrimaryConstructors(checkPrimaryConstructors) diff --git a/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java b/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java index 5848a9a2024..122b9dd50da 100644 --- a/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java +++ b/compiler/tests/org/jetbrains/jet/test/util/DescriptorValidator.java @@ -16,6 +16,8 @@ package org.jetbrains.jet.test.util; +import com.google.common.base.Predicate; +import com.google.common.base.Predicates; import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -54,18 +56,29 @@ public class DescriptorValidator { } public static class ValidationVisitor implements DeclarationDescriptorVisitor { - public static final ValidationVisitor FORBID_ERROR_TYPES = new ValidationVisitor(false); - public static final ValidationVisitor ALLOW_ERROR_TYPES = new ValidationVisitor(true); + public static final ValidationVisitor FORBID_ERROR_TYPES = new ValidationVisitor( + false, Predicates.alwaysTrue()); + public static final ValidationVisitor ALLOW_ERROR_TYPES = new ValidationVisitor( + true, Predicates.alwaysTrue()); private final boolean allowErrorTypes; + private final Predicate recursiveFilter; - private ValidationVisitor(boolean allowErrorTypes) { + private ValidationVisitor(boolean allowErrorTypes, @NotNull Predicate recursiveFilter) { this.allowErrorTypes = allowErrorTypes; + this.recursiveFilter = recursiveFilter; } - private static void validateScope(@NotNull JetScope scope, @NotNull DiagnosticCollector collector) { + @NotNull + public ValidationVisitor withStepIntoFilter(@NotNull Predicate filter) { + return new ValidationVisitor(allowErrorTypes, filter); + } + + private void validateScope(@NotNull JetScope scope, @NotNull DiagnosticCollector collector) { for (DeclarationDescriptor descriptor : scope.getAllDescriptors()) { - descriptor.accept(new ScopeValidatorVisitor(collector), scope); + if (recursiveFilter.apply(descriptor)) { + descriptor.accept(new ScopeValidatorVisitor(collector), scope); + } } } @@ -173,9 +186,9 @@ public class DescriptorValidator { } @Override - public Boolean visitPackageViewDescriptor( - PackageViewDescriptor descriptor, DiagnosticCollector collector - ) { + public Boolean visitPackageViewDescriptor(PackageViewDescriptor descriptor, DiagnosticCollector collector) { + if (!recursiveFilter.apply(descriptor)) return false; + validateScope(descriptor.getMemberScope(), collector); return true; } @@ -259,9 +272,9 @@ public class DescriptorValidator { visitFunctionDescriptor(constructorDescriptor, collector); assertEqualTypes(constructorDescriptor, collector, - "return type", - constructorDescriptor.getContainingDeclaration().getDefaultType(), - constructorDescriptor.getReturnType()); + "return type", + constructorDescriptor.getContainingDeclaration().getDefaultType(), + constructorDescriptor.getReturnType()); return true; } diff --git a/compiler/tests/org/jetbrains/jet/test/util/RecursiveDescriptorComparator.java b/compiler/tests/org/jetbrains/jet/test/util/RecursiveDescriptorComparator.java index 6b6fada1dce..a96a0041d5e 100644 --- a/compiler/tests/org/jetbrains/jet/test/util/RecursiveDescriptorComparator.java +++ b/compiler/tests/org/jetbrains/jet/test/util/RecursiveDescriptorComparator.java @@ -26,6 +26,7 @@ import org.jetbrains.annotations.Nullable; import org.jetbrains.jet.JetTestUtils; import org.jetbrains.jet.jvm.compiler.ExpectedLoadErrorsUtil; import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.resolve.DescriptorUtils; import org.jetbrains.jet.lang.resolve.MemberComparator; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.scopes.JetScope; @@ -51,31 +52,36 @@ public class RecursiveDescriptorComparator { .setVerbose(true).build(); public static final Configuration DONT_INCLUDE_METHODS_OF_OBJECT = new Configuration(false, false, false, - Predicates.alwaysTrue(), + Predicates.alwaysTrue(), FORBID_ERROR_TYPES, DEFAULT_RENDERER); public static final Configuration RECURSIVE = new Configuration(false, false, true, - Predicates.alwaysTrue(), + Predicates.alwaysTrue(), FORBID_ERROR_TYPES, DEFAULT_RENDERER); public static final Configuration RECURSIVE_ALL = new Configuration(true, true, true, - Predicates.alwaysTrue(), + Predicates.alwaysTrue(), FORBID_ERROR_TYPES, DEFAULT_RENDERER); private static final ImmutableSet KOTLIN_ANY_METHOD_NAMES = ImmutableSet.of("equals", "hashCode", "toString"); private final Configuration conf; - private RecursiveDescriptorComparator(@NotNull Configuration conf) { + public RecursiveDescriptorComparator(@NotNull Configuration conf) { this.conf = conf; } - private String serializeRecursively(@NotNull DeclarationDescriptor declarationDescriptor) { + public String serializeRecursively(@NotNull DeclarationDescriptor declarationDescriptor) { StringBuilder result = new StringBuilder(); - appendDeclarationRecursively(declarationDescriptor, new Printer(result, 1), true); + appendDeclarationRecursively(declarationDescriptor, DescriptorUtils.getContainingModule(declarationDescriptor), new Printer(result, 1), true); return result.toString(); } - private void appendDeclarationRecursively(@NotNull DeclarationDescriptor descriptor, @NotNull Printer printer, boolean topLevel) { + private void appendDeclarationRecursively( + @NotNull DeclarationDescriptor descriptor, + @NotNull ModuleDescriptor module, + @NotNull Printer printer, + boolean topLevel + ) { if ((descriptor instanceof ClassOrPackageFragmentDescriptor || descriptor instanceof PackageViewDescriptor) && !topLevel) { printer.println(); } @@ -94,20 +100,23 @@ public class RecursiveDescriptorComparator { if (descriptor instanceof ClassDescriptor) { ClassDescriptor klass = (ClassDescriptor) descriptor; - appendSubDescriptors(klass.getDefaultType().getMemberScope(), getConstructorsAndClassObject(klass), printer); + appendSubDescriptors(descriptor, module, + klass.getDefaultType().getMemberScope(), getConstructorsAndClassObject(klass), printer); JetScope staticScope = klass.getStaticScope(); if (!staticScope.getAllDescriptors().isEmpty()) { printer.println(); printer.println("// Static members"); - appendSubDescriptors(staticScope, Collections.emptyList(), printer); + appendSubDescriptors(descriptor, module, staticScope, Collections.emptyList(), printer); } } else if (descriptor instanceof PackageFragmentDescriptor) { - appendSubDescriptors(((PackageFragmentDescriptor) descriptor).getMemberScope(), + appendSubDescriptors(descriptor, module, + ((PackageFragmentDescriptor) descriptor).getMemberScope(), Collections.emptyList(), printer); } else if (descriptor instanceof PackageViewDescriptor) { - appendSubDescriptors(((PackageViewDescriptor) descriptor).getMemberScope(), + appendSubDescriptors(descriptor, module, + ((PackageViewDescriptor) descriptor).getMemberScope(), Collections.emptyList(), printer); } @@ -145,20 +154,24 @@ public class RecursiveDescriptorComparator { } private boolean shouldSkip(@NotNull DeclarationDescriptor subDescriptor) { - return subDescriptor.getContainingDeclaration() instanceof ClassDescriptor - && subDescriptor instanceof FunctionDescriptor - && KOTLIN_ANY_METHOD_NAMES.contains(subDescriptor.getName().asString()) - && !conf.includeMethodsOfKotlinAny - || - subDescriptor instanceof PackageViewDescriptor - && !conf.recurseIntoPackage.apply(((PackageViewDescriptor) subDescriptor).getFqName()); + boolean isFunctionFromAny = subDescriptor.getContainingDeclaration() instanceof ClassDescriptor + && subDescriptor instanceof FunctionDescriptor + && KOTLIN_ANY_METHOD_NAMES.contains(subDescriptor.getName().asString()); + return (isFunctionFromAny && !conf.includeMethodsOfKotlinAny) || !conf.recursiveFilter.apply(subDescriptor); } private void appendSubDescriptors( + @NotNull DeclarationDescriptor descriptor, + @NotNull ModuleDescriptor module, @NotNull JetScope memberScope, @NotNull Collection extraSubDescriptors, @NotNull Printer printer ) { + if (!module.equals(DescriptorUtils.getContainingModule(descriptor))) { + printer.println(String.format("// -- Module: %s --", DescriptorUtils.getContainingModule(descriptor).getName())); + return; + } + List subDescriptors = Lists.newArrayList(); subDescriptors.addAll(memberScope.getAllDescriptors()); @@ -168,7 +181,7 @@ public class RecursiveDescriptorComparator { for (DeclarationDescriptor subDescriptor : subDescriptors) { if (!shouldSkip(subDescriptor)) { - appendDeclarationRecursively(subDescriptor, printer, false); + appendDeclarationRecursively(subDescriptor, module, printer, false); } } } @@ -239,7 +252,7 @@ public class RecursiveDescriptorComparator { private final boolean checkPrimaryConstructors; private final boolean checkPropertyAccessors; private final boolean includeMethodsOfKotlinAny; - private final Predicate recurseIntoPackage; + private final Predicate recursiveFilter; private final DescriptorRenderer renderer; private final DescriptorValidator.ValidationVisitor validationStrategy; @@ -248,45 +261,45 @@ public class RecursiveDescriptorComparator { boolean checkPrimaryConstructors, boolean checkPropertyAccessors, boolean includeMethodsOfKotlinAny, - Predicate recurseIntoPackage, + Predicate recursiveFilter, DescriptorValidator.ValidationVisitor validationStrategy, DescriptorRenderer renderer ) { this.checkPrimaryConstructors = checkPrimaryConstructors; this.checkPropertyAccessors = checkPropertyAccessors; this.includeMethodsOfKotlinAny = includeMethodsOfKotlinAny; - this.recurseIntoPackage = recurseIntoPackage; - this.validationStrategy = validationStrategy; + this.recursiveFilter = recursiveFilter; + this.validationStrategy = validationStrategy.withStepIntoFilter(recursiveFilter); this.renderer = renderer; } - public Configuration filterRecursion(@NotNull Predicate recurseIntoPackage) { - return new Configuration(checkPrimaryConstructors, checkPropertyAccessors, includeMethodsOfKotlinAny, recurseIntoPackage, + public Configuration filterRecursion(@NotNull Predicate stepIntoFilter) { + return new Configuration(checkPrimaryConstructors, checkPropertyAccessors, includeMethodsOfKotlinAny, stepIntoFilter, validationStrategy, renderer); } public Configuration checkPrimaryConstructors(boolean checkPrimaryConstructors) { - return new Configuration(checkPrimaryConstructors, checkPropertyAccessors, includeMethodsOfKotlinAny, recurseIntoPackage, + return new Configuration(checkPrimaryConstructors, checkPropertyAccessors, includeMethodsOfKotlinAny, recursiveFilter, validationStrategy, renderer); } public Configuration checkPropertyAccessors(boolean checkPropertyAccessors) { - return new Configuration(checkPrimaryConstructors, checkPropertyAccessors, includeMethodsOfKotlinAny, recurseIntoPackage, + return new Configuration(checkPrimaryConstructors, checkPropertyAccessors, includeMethodsOfKotlinAny, recursiveFilter, validationStrategy, renderer); } public Configuration includeMethodsOfKotlinAny(boolean includeMethodsOfKotlinAny) { - return new Configuration(checkPrimaryConstructors, checkPropertyAccessors, includeMethodsOfKotlinAny, recurseIntoPackage, + return new Configuration(checkPrimaryConstructors, checkPropertyAccessors, includeMethodsOfKotlinAny, recursiveFilter, validationStrategy, renderer); } public Configuration withValidationStrategy(@NotNull DescriptorValidator.ValidationVisitor validationStrategy) { - return new Configuration(checkPrimaryConstructors, checkPropertyAccessors, includeMethodsOfKotlinAny, recurseIntoPackage, + return new Configuration(checkPrimaryConstructors, checkPropertyAccessors, includeMethodsOfKotlinAny, recursiveFilter, validationStrategy, renderer); } public Configuration withRenderer(@NotNull DescriptorRenderer renderer) { - return new Configuration(checkPrimaryConstructors, checkPropertyAccessors, includeMethodsOfKotlinAny, recurseIntoPackage, + return new Configuration(checkPrimaryConstructors, checkPropertyAccessors, includeMethodsOfKotlinAny, recursiveFilter, validationStrategy, renderer); } } diff --git a/idea/tests/org/jetbrains/jet/plugin/stubs/AbstractLazyResolveByStubTest.java b/idea/tests/org/jetbrains/jet/plugin/stubs/AbstractLazyResolveByStubTest.java index 855e17aa37a..1f916ab22d9 100644 --- a/idea/tests/org/jetbrains/jet/plugin/stubs/AbstractLazyResolveByStubTest.java +++ b/idea/tests/org/jetbrains/jet/plugin/stubs/AbstractLazyResolveByStubTest.java @@ -26,6 +26,7 @@ import com.intellij.util.Consumer; import kotlin.Function0; import kotlin.Unit; import org.jetbrains.annotations.NotNull; +import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; import org.jetbrains.jet.lang.descriptors.ModuleDescriptor; import org.jetbrains.jet.lang.descriptors.PackageViewDescriptor; import org.jetbrains.jet.lang.psi.JetFile; @@ -77,10 +78,14 @@ public abstract class AbstractLazyResolveByStubTest extends KotlinCodeInsightTes RecursiveDescriptorComparator.validateAndCompareDescriptorWithFile( packageViewDescriptor, RecursiveDescriptorComparator.DONT_INCLUDE_METHODS_OF_OBJECT.filterRecursion( - new Predicate() { + new Predicate() { @Override - public boolean apply(FqName fqName) { - return !KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME.equals(fqName); + public boolean apply(DeclarationDescriptor descriptor) { + if (descriptor instanceof PackageViewDescriptor) { + return !KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME + .equals(((PackageViewDescriptor) descriptor).getFqName()); + } + return true; } } )