From 4f3158abb359f3535f0750ac217f80dde4697b40 Mon Sep 17 00:00:00 2001 From: Andrey Breslav Date: Thu, 13 Nov 2014 21:03:37 +0300 Subject: [PATCH] Mark dynamic calls in tests --- .../jet/checkers/CheckerTestUtil.java | 24 ++++++++++-- .../jetbrains/jet/checkers/DebugInfoUtil.java | 13 +++++++ .../tests/dynamicTypes/extensions.kt | 38 +++++++++++++++++++ .../tests/dynamicTypes/extensions.txt | 16 ++++++++ .../jet/checkers/BaseDiagnosticsTest.java | 6 ++- .../jet/checkers/CheckerTestUtilTest.java | 4 +- .../checkers/JetDiagnosticsTestGenerated.java | 6 +++ .../internal/CopyAsDiagnosticTestAction.java | 2 +- 8 files changed, 102 insertions(+), 7 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/dynamicTypes/extensions.kt create mode 100644 compiler/testData/diagnostics/tests/dynamicTypes/extensions.txt diff --git a/compiler/frontend/src/org/jetbrains/jet/checkers/CheckerTestUtil.java b/compiler/frontend/src/org/jetbrains/jet/checkers/CheckerTestUtil.java index 125a0414b99..97b3cfadde3 100644 --- a/compiler/frontend/src/org/jetbrains/jet/checkers/CheckerTestUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/checkers/CheckerTestUtil.java @@ -82,7 +82,12 @@ public class CheckerTestUtil { private static final Pattern INDIVIDUAL_DIAGNOSTIC_PATTERN = Pattern.compile(INDIVIDUAL_DIAGNOSTIC); private static final Pattern INDIVIDUAL_PARAMETER_PATTERN = Pattern.compile(DIAGNOSTIC_PARAMETER); - public static List getDiagnosticsIncludingSyntaxErrors(BindingContext bindingContext, final PsiElement root) { + @NotNull + public static List getDiagnosticsIncludingSyntaxErrors( + @NotNull BindingContext bindingContext, + @NotNull final PsiElement root, + boolean markDynamicCalls + ) { List diagnostics = new ArrayList(); diagnostics.addAll(Collections2.filter(bindingContext.getDiagnostics().all(), new Predicate() { @@ -94,12 +99,17 @@ public class CheckerTestUtil { for (PsiErrorElement errorElement : AnalyzingUtils.getSyntaxErrorRanges(root)) { diagnostics.add(new SyntaxErrorDiagnostic(errorElement)); } - List debugAnnotations = getDebugInfoDiagnostics(root, bindingContext); + List debugAnnotations = getDebugInfoDiagnostics(root, bindingContext, markDynamicCalls); diagnostics.addAll(debugAnnotations); return diagnostics; } - public static List getDebugInfoDiagnostics(@NotNull PsiElement root, @NotNull BindingContext bindingContext) { + @NotNull + public static List getDebugInfoDiagnostics( + @NotNull PsiElement root, + @NotNull BindingContext bindingContext, + final boolean markDynamicCalls + ) { final List debugAnnotations = Lists.newArrayList(); DebugInfoUtil.markDebugAnnotations(root, bindingContext, new DebugInfoUtil.DebugInfoReporter() { @Override @@ -117,6 +127,13 @@ public class CheckerTestUtil { newDiagnostic(expression, DebugInfoDiagnosticFactory.UNRESOLVED_WITH_TARGET); } + @Override + public void reportDynamicCall(@NotNull JetReferenceExpression expression) { + if (markDynamicCalls) { + newDiagnostic(expression, DebugInfoDiagnosticFactory.DYNAMIC); + } + } + private void newDiagnostic(JetReferenceExpression expression, DebugInfoDiagnosticFactory factory) { debugAnnotations.add(new DebugInfoDiagnostic(expression, factory)); } @@ -486,6 +503,7 @@ public class CheckerTestUtil { public static final DebugInfoDiagnosticFactory ELEMENT_WITH_ERROR_TYPE = new DebugInfoDiagnosticFactory("ELEMENT_WITH_ERROR_TYPE"); public static final DebugInfoDiagnosticFactory UNRESOLVED_WITH_TARGET = new DebugInfoDiagnosticFactory("UNRESOLVED_WITH_TARGET"); public static final DebugInfoDiagnosticFactory MISSING_UNRESOLVED = new DebugInfoDiagnosticFactory("MISSING_UNRESOLVED"); + public static final DebugInfoDiagnosticFactory DYNAMIC = new DebugInfoDiagnosticFactory("DYNAMIC"); private final String name; private DebugInfoDiagnosticFactory(String name, Severity severity) { diff --git a/compiler/frontend/src/org/jetbrains/jet/checkers/DebugInfoUtil.java b/compiler/frontend/src/org/jetbrains/jet/checkers/DebugInfoUtil.java index 022d1420358..1931e7c7950 100644 --- a/compiler/frontend/src/org/jetbrains/jet/checkers/DebugInfoUtil.java +++ b/compiler/frontend/src/org/jetbrains/jet/checkers/DebugInfoUtil.java @@ -23,7 +23,9 @@ import com.intellij.psi.tree.TokenSet; import com.intellij.psi.util.PsiTreeUtil; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.JetNodeTypes; +import org.jetbrains.jet.lang.descriptors.CallableDescriptor; import org.jetbrains.jet.lang.descriptors.DeclarationDescriptor; +import org.jetbrains.jet.lang.descriptors.ReceiverParameterDescriptor; import org.jetbrains.jet.lang.diagnostics.Diagnostic; import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory; import org.jetbrains.jet.lang.diagnostics.Errors; @@ -32,6 +34,7 @@ import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingContextUtils; import org.jetbrains.jet.lang.types.ErrorUtils; import org.jetbrains.jet.lang.types.JetType; +import org.jetbrains.jet.lang.types.TypesPackage; import org.jetbrains.jet.lexer.JetTokens; import java.util.Collection; @@ -55,6 +58,8 @@ public class DebugInfoUtil { public abstract void reportMissingUnresolved(@NotNull JetReferenceExpression expression); public abstract void reportUnresolvedWithTarget(@NotNull JetReferenceExpression expression, @NotNull String target); + + public void reportDynamicCall(@NotNull JetReferenceExpression expression) { } } public static void markDebugAnnotations( @@ -113,6 +118,14 @@ public class DebugInfoUtil { DeclarationDescriptor declarationDescriptor = bindingContext.get(REFERENCE_TARGET, expression); if (declarationDescriptor != null) { target = declarationDescriptor.toString(); + + if (declarationDescriptor instanceof CallableDescriptor) { + CallableDescriptor callableDescriptor = (CallableDescriptor) declarationDescriptor; + ReceiverParameterDescriptor dispatchReceiverParameter = callableDescriptor.getDispatchReceiverParameter(); + if (dispatchReceiverParameter != null && TypesPackage.isDynamic(dispatchReceiverParameter.getReturnType())) { + debugInfoReporter.reportDynamicCall(expression); + } + } } if (target == null) { PsiElement labelTarget = bindingContext.get(LABEL_TARGET, expression); diff --git a/compiler/testData/diagnostics/tests/dynamicTypes/extensions.kt b/compiler/testData/diagnostics/tests/dynamicTypes/extensions.kt new file mode 100644 index 00000000000..6ea31c946bf --- /dev/null +++ b/compiler/testData/diagnostics/tests/dynamicTypes/extensions.kt @@ -0,0 +1,38 @@ +// !MARK_DYNAMIC_CALLS + +// MODULE[js]: m1 +// FILE: k.kt + +fun test(d: dynamic) { + d.foo() + d.foo(1) + + d.bar() + d.baz() + + d == 1 + + d.equals(1) + d?.equals(1) + + d.hashCode() + d?.hashCode() + + d.toString() + d?.toString() +} + +fun Any.foo() {} +fun Any?.bar() {} + +fun String.baz() {} + +class C { + fun test(d: dynamic) { + d.member() + d.memberExtension() + } + + fun member() {} + fun Any.memberExtension() {} +} \ No newline at end of file diff --git a/compiler/testData/diagnostics/tests/dynamicTypes/extensions.txt b/compiler/testData/diagnostics/tests/dynamicTypes/extensions.txt new file mode 100644 index 00000000000..2ba12ae16d3 --- /dev/null +++ b/compiler/testData/diagnostics/tests/dynamicTypes/extensions.txt @@ -0,0 +1,16 @@ +package + +internal fun test(/*0*/ d: dynamic): kotlin.Unit +internal fun kotlin.Any?.bar(): kotlin.Unit +internal fun kotlin.String.baz(): kotlin.Unit +internal fun kotlin.Any.foo(): kotlin.Unit + +internal final class C { + public constructor C() + public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean + public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int + internal final fun member(): kotlin.Unit + internal final fun test(/*0*/ d: dynamic): kotlin.Unit + public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String + internal final fun kotlin.Any.memberExtension(): kotlin.Unit +} diff --git a/compiler/tests/org/jetbrains/jet/checkers/BaseDiagnosticsTest.java b/compiler/tests/org/jetbrains/jet/checkers/BaseDiagnosticsTest.java index 996c0e3861a..0cb515ed99f 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/BaseDiagnosticsTest.java +++ b/compiler/tests/org/jetbrains/jet/checkers/BaseDiagnosticsTest.java @@ -78,6 +78,8 @@ public abstract class BaseDiagnosticsTest extends public static final String CHECK_LAZY_LOG_DIRECTIVE = "CHECK_LAZY_LOG"; public static final boolean CHECK_LAZY_LOG_DEFAULT = "true".equals(System.getProperty("check.lazy.logs", "false")); + public static final String MARK_DYNAMIC_CALLS_DIRECTIVE = "MARK_DYNAMIC_CALLS"; + @Override protected TestModule createTestModule(@NotNull String name) { return new TestModule(name); @@ -240,6 +242,7 @@ public abstract class BaseDiagnosticsTest extends private final boolean declareCheckType; private final boolean declareFlexibleType; public final boolean checkLazyLog; + private final boolean markDynamicCalls; public TestFile( @Nullable TestModule module, @@ -252,6 +255,7 @@ public abstract class BaseDiagnosticsTest extends this.checkLazyLog = directives.containsKey(CHECK_LAZY_LOG_DIRECTIVE) || CHECK_LAZY_LOG_DEFAULT; this.declareCheckType = directives.containsKey(CHECK_TYPE_DIRECTIVE); this.declareFlexibleType = directives.containsKey(EXPLICIT_FLEXIBLE_TYPES_DIRECTIVE); + this.markDynamicCalls = directives.containsKey(MARK_DYNAMIC_CALLS_DIRECTIVE); if (fileName.endsWith(".java")) { PsiFileFactory.getInstance(getProject()).createFileFromText(fileName, JavaLanguage.INSTANCE, textWithMarkers); // TODO: check there's not syntax errors @@ -334,7 +338,7 @@ public abstract class BaseDiagnosticsTest extends final boolean[] ok = { true }; List diagnostics = ContainerUtil.filter( - KotlinPackage.plus(CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, jetFile), + KotlinPackage.plus(CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, jetFile, markDynamicCalls), jvmSignatureDiagnostics), whatDiagnosticsToConsider ); diff --git a/compiler/tests/org/jetbrains/jet/checkers/CheckerTestUtilTest.java b/compiler/tests/org/jetbrains/jet/checkers/CheckerTestUtilTest.java index c3cccc0c20f..e54142d10f6 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/CheckerTestUtilTest.java +++ b/compiler/tests/org/jetbrains/jet/checkers/CheckerTestUtilTest.java @@ -147,7 +147,7 @@ public class CheckerTestUtilTest extends JetLiteFixture { (JetFile) psiFile) .getBindingContext(); - String expectedText = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile)).toString(); + String expectedText = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile, false)).toString(); List diagnosedRanges = Lists.newArrayList(); CheckerTestUtil.parseDiagnosedRanges(expectedText, diagnosedRanges); @@ -155,7 +155,7 @@ public class CheckerTestUtilTest extends JetLiteFixture { diagnosedRange.setFile(psiFile); } - List diagnostics = CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile); + List diagnostics = CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile, false); Collections.sort(diagnostics, CheckerTestUtil.DIAGNOSTIC_COMPARATOR); makeTestData(diagnostics, diagnosedRanges); diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index f293d794ae7..36966474466 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -3746,6 +3746,12 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest { doTest(fileName); } + @TestMetadata("extensions.kt") + public void testExtensions() throws Exception { + String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/dynamicTypes/extensions.kt"); + doTest(fileName); + } + @TestMetadata("implicitDynamicReceiver.kt") public void testImplicitDynamicReceiver() throws Exception { String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/dynamicTypes/implicitDynamicReceiver.kt"); diff --git a/idea/src/org/jetbrains/jet/plugin/actions/internal/CopyAsDiagnosticTestAction.java b/idea/src/org/jetbrains/jet/plugin/actions/internal/CopyAsDiagnosticTestAction.java index 4fbbb68be4e..3822cd9ce0b 100644 --- a/idea/src/org/jetbrains/jet/plugin/actions/internal/CopyAsDiagnosticTestAction.java +++ b/idea/src/org/jetbrains/jet/plugin/actions/internal/CopyAsDiagnosticTestAction.java @@ -42,7 +42,7 @@ public class CopyAsDiagnosticTestAction extends AnAction { BindingContext bindingContext = ResolvePackage.analyzeFully((JetFile) psiFile); - List diagnostics = CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile); + List diagnostics = CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile, false); String result = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, diagnostics).toString(); Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();