Multi-module diagnostic tests supported
Test added for internal visibility
This commit is contained in:
@@ -0,0 +1,35 @@
|
||||
// !DIAGNOSTICS: -UNUSED_VARIABLE
|
||||
// MODULE: m1
|
||||
// FILE: a.kt
|
||||
|
||||
package p
|
||||
|
||||
public class A {
|
||||
val a = A()
|
||||
var v = A()
|
||||
fun a() = A()
|
||||
inner class B
|
||||
}
|
||||
|
||||
val a = A()
|
||||
var v = A()
|
||||
fun a() = A()
|
||||
class B
|
||||
|
||||
// MODULE: m2(m1)
|
||||
// FILE: b.kt
|
||||
|
||||
import p.*
|
||||
|
||||
fun test() {
|
||||
val _a = <!INVISIBLE_MEMBER!>a<!>
|
||||
val _v = <!INVISIBLE_MEMBER!>v<!>
|
||||
<!INVISIBLE_MEMBER!>a<!>()
|
||||
<!INVISIBLE_MEMBER!>B<!>()
|
||||
|
||||
val inst = A()
|
||||
val ia = inst.<!INVISIBLE_MEMBER!>a<!>
|
||||
val iv = inst.<!INVISIBLE_MEMBER!>v<!>
|
||||
inst.<!INVISIBLE_MEMBER!>a<!>()
|
||||
inst.<!INVISIBLE_MEMBER!>B<!>()
|
||||
}
|
||||
@@ -21,25 +21,27 @@ import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.Sets;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import kotlin.Function1;
|
||||
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.context.ContextPackage;
|
||||
import org.jetbrains.jet.context.GlobalContext;
|
||||
import org.jetbrains.jet.descriptors.serialization.descriptors.MemberFilter;
|
||||
import org.jetbrains.jet.di.InjectorForTopDownAnalyzerForJvm;
|
||||
import org.jetbrains.jet.lang.descriptors.DependencyKind;
|
||||
import org.jetbrains.jet.lang.descriptors.ModuleDescriptorImpl;
|
||||
import org.jetbrains.jet.lang.diagnostics.*;
|
||||
import org.jetbrains.jet.lang.psi.JetElement;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.lang.resolve.Diagnostics;
|
||||
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.AnalyzerFacadeForJVM;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
|
||||
|
||||
@@ -47,27 +49,91 @@ public abstract class AbstractJetDiagnosticsTest extends BaseDiagnosticsTest {
|
||||
|
||||
@Override
|
||||
protected void analyzeAndCheck(File testDataFile, List<TestFile> testFiles) {
|
||||
List<JetFile> jetFiles = getJetFiles(testFiles);
|
||||
Map<TestModule, List<TestFile>> groupedByModule = KotlinPackage.groupByTo(
|
||||
testFiles,
|
||||
new LinkedHashMap<TestModule, List<TestFile>>(),
|
||||
new Function1<TestFile, TestModule>() {
|
||||
@Override
|
||||
public TestModule invoke(TestFile file) {
|
||||
return file.getModule();
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
CliLightClassGenerationSupport support = CliLightClassGenerationSupport.getInstanceForCli(getProject());
|
||||
BindingTrace trace = support.getTrace();
|
||||
|
||||
BindingContext bindingContext = AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
|
||||
getProject(), jetFiles, support.getTrace(),
|
||||
Predicates.<PsiFile>alwaysTrue(), support.getModule(),
|
||||
MemberFilter.ALWAYS_TRUE).getBindingContext();
|
||||
List<JetFile> allJetFiles = new ArrayList<JetFile>();
|
||||
Map<TestModule, ModuleDescriptorImpl> modules = createModules(groupedByModule);
|
||||
|
||||
for (Map.Entry<TestModule, List<TestFile>> entry : groupedByModule.entrySet()) {
|
||||
TestModule testModule = entry.getKey();
|
||||
List<? extends TestFile> testFilesInModule = entry.getValue();
|
||||
|
||||
List<JetFile> jetFiles = getJetFiles(testFilesInModule);
|
||||
allJetFiles.addAll(jetFiles);
|
||||
|
||||
ModuleDescriptorImpl module = modules.get(testModule);
|
||||
analyzeModule(trace, module == null ? support.getModule() : module, jetFiles);
|
||||
}
|
||||
|
||||
boolean ok = true;
|
||||
|
||||
StringBuilder actualText = new StringBuilder();
|
||||
for (TestFile testFile : testFiles) {
|
||||
ok &= testFile.getActualText(bindingContext, actualText);
|
||||
ok &= testFile.getActualText(trace.getBindingContext(), actualText);
|
||||
}
|
||||
|
||||
JetTestUtils.assertEqualsToFile(testDataFile, actualText.toString());
|
||||
|
||||
assertTrue("Diagnostics mismatch. See the output above", ok);
|
||||
|
||||
checkAllResolvedCallsAreCompleted(jetFiles, bindingContext);
|
||||
checkAllResolvedCallsAreCompleted(allJetFiles, trace.getBindingContext());
|
||||
}
|
||||
|
||||
private Map<TestModule, ModuleDescriptorImpl> createModules(Map<TestModule, List<TestFile>> groupedByModule) {
|
||||
Map<TestModule, ModuleDescriptorImpl> modules = new HashMap<TestModule, ModuleDescriptorImpl>();
|
||||
|
||||
for (TestModule testModule : groupedByModule.keySet()) {
|
||||
if (testModule == null) continue;
|
||||
ModuleDescriptorImpl module = AnalyzerFacadeForJVM.createJavaModule("<" + testModule.getName() + ">");
|
||||
modules.put(testModule, module);
|
||||
}
|
||||
|
||||
for (TestModule testModule : groupedByModule.keySet()) {
|
||||
if (testModule == null) continue;
|
||||
|
||||
ModuleDescriptorImpl module = modules.get(testModule);
|
||||
for (TestModule dependency : testModule.getDependencies()) {
|
||||
// Adding other modules as BINARIES here, because in teh reduced dependency ordering model they are equal to binaries
|
||||
module.addFragmentProvider(DependencyKind.BINARIES, modules.get(dependency).getPackageFragmentProvider());
|
||||
}
|
||||
}
|
||||
return modules;
|
||||
}
|
||||
|
||||
private void analyzeModule(BindingTrace trace, ModuleDescriptorImpl module, List<JetFile> jetFiles) {
|
||||
GlobalContext globalContext = ContextPackage.GlobalContext();
|
||||
TopDownAnalysisParameters topDownAnalysisParameters = TopDownAnalysisParameters.create(
|
||||
globalContext.getStorageManager(),
|
||||
globalContext.getExceptionTracker(),
|
||||
Predicates.<PsiFile>alwaysTrue(),
|
||||
false,
|
||||
false
|
||||
);
|
||||
|
||||
// New JavaDescriptorResolver is created for each module, which is good because it emulates different Java libraries for each module,
|
||||
// albeit with same class names
|
||||
InjectorForTopDownAnalyzerForJvm
|
||||
injector = new InjectorForTopDownAnalyzerForJvm(getProject(), topDownAnalysisParameters, trace, module,
|
||||
MemberFilter.ALWAYS_TRUE);
|
||||
try {
|
||||
module.addFragmentProvider(DependencyKind.BINARIES, injector.getJavaDescriptorResolver().getPackageFragmentProvider());
|
||||
injector.getTopDownAnalyzer().analyzeFiles(topDownAnalysisParameters, jetFiles);
|
||||
}
|
||||
finally {
|
||||
injector.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
private static void checkAllResolvedCallsAreCompleted(@NotNull List<JetFile> jetFiles, @NotNull BindingContext bindingContext) {
|
||||
|
||||
@@ -29,6 +29,8 @@ import com.intellij.psi.PsiFile;
|
||||
import com.intellij.psi.PsiFileFactory;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.containers.ContainerUtil;
|
||||
import kotlin.Function1;
|
||||
import kotlin.KotlinPackage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
import org.jetbrains.jet.ConfigurationKind;
|
||||
@@ -45,9 +47,7 @@ import org.junit.Assert;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@@ -107,17 +107,54 @@ public abstract class BaseDiagnosticsTest extends JetLiteFixture {
|
||||
|
||||
String expectedText = JetTestUtils.doLoadFile(file);
|
||||
|
||||
class ModuleAndDependencies {
|
||||
final TestModule module;
|
||||
final List<String> dependencies;
|
||||
|
||||
ModuleAndDependencies(TestModule module, List<String> dependencies) {
|
||||
this.module = module;
|
||||
this.dependencies = dependencies;
|
||||
}
|
||||
}
|
||||
final Map<String, ModuleAndDependencies> modules = new HashMap<String, ModuleAndDependencies>();
|
||||
|
||||
List<TestFile> testFiles =
|
||||
JetTestUtils.createTestFiles(file.getName(), expectedText, new JetTestUtils.TestFileFactory<TestFile>() {
|
||||
JetTestUtils.createTestFiles(file.getName(), expectedText, new JetTestUtils.TestFileFactory<TestModule, TestFile>() {
|
||||
|
||||
@Override
|
||||
public TestFile create(String fileName, String text, Map<String, String> directives) {
|
||||
public TestFile createFile(@Nullable TestModule module, String fileName, String text, Map<String, String> directives) {
|
||||
if (fileName.endsWith(".java")) {
|
||||
writeJavaFile(fileName, text, javaFilesDir);
|
||||
}
|
||||
return new TestFile(fileName, text, directives);
|
||||
|
||||
return new TestFile(module, fileName, text, directives);
|
||||
}
|
||||
|
||||
@Override
|
||||
public TestModule createModule(String name, List<String> dependencies) {
|
||||
TestModule module = new TestModule(name);
|
||||
ModuleAndDependencies oldValue = modules.put(name, new ModuleAndDependencies(module, dependencies));
|
||||
assert oldValue == null : "Module " + name + " declared more than once";
|
||||
|
||||
return module;
|
||||
}
|
||||
});
|
||||
|
||||
for (final ModuleAndDependencies moduleAndDependencies : modules.values()) {
|
||||
List<TestModule> dependencies = KotlinPackage.map(
|
||||
moduleAndDependencies.dependencies,
|
||||
new Function1<String, TestModule>() {
|
||||
@Override
|
||||
public TestModule invoke(String name) {
|
||||
ModuleAndDependencies dependency = modules.get(name);
|
||||
assert dependency != null : "Dependency not found: " + name + " for module " + moduleAndDependencies.module.getName();
|
||||
return dependency.module;
|
||||
}
|
||||
}
|
||||
);
|
||||
moduleAndDependencies.module.getDependencies().addAll(dependencies);
|
||||
}
|
||||
|
||||
analyzeAndCheck(file, testFiles);
|
||||
}
|
||||
|
||||
@@ -126,7 +163,7 @@ public abstract class BaseDiagnosticsTest extends JetLiteFixture {
|
||||
List<TestFile> files
|
||||
);
|
||||
|
||||
protected static List<JetFile> getJetFiles(List<TestFile> testFiles) {
|
||||
protected static List<JetFile> getJetFiles(List<? extends TestFile> testFiles) {
|
||||
List<JetFile> jetFiles = Lists.newArrayList();
|
||||
for (TestFile testFile : testFiles) {
|
||||
if (testFile.getJetFile() != null) {
|
||||
@@ -202,19 +239,41 @@ public abstract class BaseDiagnosticsTest extends JetLiteFixture {
|
||||
});
|
||||
}
|
||||
|
||||
protected static class TestModule {
|
||||
private final String name;
|
||||
private final List<TestModule> dependencies = new ArrayList<TestModule>();
|
||||
|
||||
public TestModule(@NotNull String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public List<TestModule> getDependencies() {
|
||||
return dependencies;
|
||||
}
|
||||
}
|
||||
|
||||
protected class TestFile {
|
||||
private final List<CheckerTestUtil.DiagnosedRange> diagnosedRanges = Lists.newArrayList();
|
||||
private final String expectedText;
|
||||
private final TestModule module;
|
||||
private final String clearText;
|
||||
private final JetFile jetFile;
|
||||
private final Condition<Diagnostic> whatDiagnosticsToConsider;
|
||||
private final boolean declareCheckType;
|
||||
|
||||
public TestFile(
|
||||
@Nullable TestModule module,
|
||||
String fileName,
|
||||
String textWithMarkers,
|
||||
Map<String, String> directives
|
||||
) {
|
||||
this.module = module;
|
||||
this.whatDiagnosticsToConsider = parseDiagnosticFilterDirective(directives);
|
||||
this.declareCheckType = directives.containsKey(CHECK_TYPE_DIRECTIVE);
|
||||
if (fileName.endsWith(".java")) {
|
||||
@@ -234,6 +293,10 @@ public abstract class BaseDiagnosticsTest extends JetLiteFixture {
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public TestModule getModule() {
|
||||
return module;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public JetFile getJetFile() {
|
||||
|
||||
@@ -33,7 +33,7 @@ import org.jetbrains.jet.checkers.AbstractJetDiagnosticsTest;
|
||||
@InnerTestClasses({JetDiagnosticsTestGenerated.Tests.class, JetDiagnosticsTestGenerated.Script.class, JetDiagnosticsTestGenerated.TailRecursion.class})
|
||||
public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
@TestMetadata("compiler/testData/diagnostics/tests")
|
||||
@InnerTestClasses({Tests.Annotations.class, Tests.BackingField.class, Tests.CallableReference.class, Tests.Cast.class, Tests.CheckArguments.class, Tests.ClassObjects.class, Tests.ControlFlowAnalysis.class, Tests.ControlStructures.class, Tests.CyclicHierarchy.class, Tests.DataClasses.class, Tests.DataFlow.class, Tests.DataFlowInfoTraversal.class, Tests.DeclarationChecks.class, Tests.DelegatedProperty.class, Tests.Deparenthesize.class, Tests.Enum.class, Tests.Evaluate.class, Tests.Extensions.class, Tests.FunctionLiterals.class, Tests.Generics.class, Tests.Imports.class, Tests.IncompleteCode.class, Tests.Inference.class, Tests.Infos.class, Tests.Inline.class, Tests.Inner.class, Tests.J_k.class, Tests.Jdk_annotations.class, Tests.Library.class, Tests.NamedArguments.class, Tests.NullabilityAndAutoCasts.class, Tests.NullableTypes.class, Tests.Numbers.class, Tests.Objects.class, Tests.OperatorsOverloading.class, Tests.Overload.class, Tests.Override.class, Tests.Recovery.class, Tests.Redeclarations.class, Tests.Regressions.class, Tests.Resolve.class, Tests.Scopes.class, Tests.SenselessComparison.class, Tests.Shadowing.class, Tests.SmartCasts.class, Tests.Substitutions.class, Tests.Subtyping.class, Tests.Suppress.class, Tests.ThisAndSuper.class, Tests.Typedefs.class, Tests.Unit.class, Tests.Varargs.class, Tests.When.class})
|
||||
@InnerTestClasses({Tests.Annotations.class, Tests.BackingField.class, Tests.CallableReference.class, Tests.Cast.class, Tests.CheckArguments.class, Tests.ClassObjects.class, Tests.ControlFlowAnalysis.class, Tests.ControlStructures.class, Tests.CyclicHierarchy.class, Tests.DataClasses.class, Tests.DataFlow.class, Tests.DataFlowInfoTraversal.class, Tests.DeclarationChecks.class, Tests.DelegatedProperty.class, Tests.Deparenthesize.class, Tests.Enum.class, Tests.Evaluate.class, Tests.Extensions.class, Tests.FunctionLiterals.class, Tests.Generics.class, Tests.Imports.class, Tests.IncompleteCode.class, Tests.Inference.class, Tests.Infos.class, Tests.Inline.class, Tests.Inner.class, Tests.J_k.class, Tests.Jdk_annotations.class, Tests.Library.class, Tests.Multimodule.class, Tests.NamedArguments.class, Tests.NullabilityAndAutoCasts.class, Tests.NullableTypes.class, Tests.Numbers.class, Tests.Objects.class, Tests.OperatorsOverloading.class, Tests.Overload.class, Tests.Override.class, Tests.Recovery.class, Tests.Redeclarations.class, Tests.Regressions.class, Tests.Resolve.class, Tests.Scopes.class, Tests.SenselessComparison.class, Tests.Shadowing.class, Tests.SmartCasts.class, Tests.Substitutions.class, Tests.Subtyping.class, Tests.Suppress.class, Tests.ThisAndSuper.class, Tests.Typedefs.class, Tests.Unit.class, Tests.Varargs.class, Tests.When.class})
|
||||
public static class Tests extends AbstractJetDiagnosticsTest {
|
||||
@TestMetadata("Abstract.kt")
|
||||
public void testAbstract() throws Exception {
|
||||
@@ -4861,6 +4861,19 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/multimodule")
|
||||
public static class Multimodule extends AbstractJetDiagnosticsTest {
|
||||
public void testAllFilesPresentInMultimodule() throws Exception {
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("compiler/testData/diagnostics/tests/multimodule"), Pattern.compile("^(.+)\\.kt$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("internal.kt")
|
||||
public void testInternal() throws Exception {
|
||||
doTest("compiler/testData/diagnostics/tests/multimodule/internal.kt");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@TestMetadata("compiler/testData/diagnostics/tests/namedArguments")
|
||||
public static class NamedArguments extends AbstractJetDiagnosticsTest {
|
||||
public void testAllFilesPresentInNamedArguments() throws Exception {
|
||||
@@ -7251,6 +7264,7 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
suite.addTestSuite(J_k.class);
|
||||
suite.addTest(Jdk_annotations.innerSuite());
|
||||
suite.addTestSuite(Library.class);
|
||||
suite.addTestSuite(Multimodule.class);
|
||||
suite.addTestSuite(NamedArguments.class);
|
||||
suite.addTestSuite(NullabilityAndAutoCasts.class);
|
||||
suite.addTestSuite(NullableTypes.class);
|
||||
|
||||
Reference in New Issue
Block a user