Mark dynamic calls in tests
This commit is contained in:
@@ -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<Diagnostic> getDiagnosticsIncludingSyntaxErrors(BindingContext bindingContext, final PsiElement root) {
|
||||
@NotNull
|
||||
public static List<Diagnostic> getDiagnosticsIncludingSyntaxErrors(
|
||||
@NotNull BindingContext bindingContext,
|
||||
@NotNull final PsiElement root,
|
||||
boolean markDynamicCalls
|
||||
) {
|
||||
List<Diagnostic> diagnostics = new ArrayList<Diagnostic>();
|
||||
diagnostics.addAll(Collections2.filter(bindingContext.getDiagnostics().all(),
|
||||
new Predicate<Diagnostic>() {
|
||||
@@ -94,12 +99,17 @@ public class CheckerTestUtil {
|
||||
for (PsiErrorElement errorElement : AnalyzingUtils.getSyntaxErrorRanges(root)) {
|
||||
diagnostics.add(new SyntaxErrorDiagnostic(errorElement));
|
||||
}
|
||||
List<Diagnostic> debugAnnotations = getDebugInfoDiagnostics(root, bindingContext);
|
||||
List<Diagnostic> debugAnnotations = getDebugInfoDiagnostics(root, bindingContext, markDynamicCalls);
|
||||
diagnostics.addAll(debugAnnotations);
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
public static List<Diagnostic> getDebugInfoDiagnostics(@NotNull PsiElement root, @NotNull BindingContext bindingContext) {
|
||||
@NotNull
|
||||
public static List<Diagnostic> getDebugInfoDiagnostics(
|
||||
@NotNull PsiElement root,
|
||||
@NotNull BindingContext bindingContext,
|
||||
final boolean markDynamicCalls
|
||||
) {
|
||||
final List<Diagnostic> 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) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -0,0 +1,38 @@
|
||||
// !MARK_DYNAMIC_CALLS
|
||||
|
||||
// MODULE[js]: m1
|
||||
// FILE: k.kt
|
||||
|
||||
fun test(d: dynamic) {
|
||||
d.foo()
|
||||
d.<!DEBUG_INFO_DYNAMIC!>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.<!DEBUG_INFO_DYNAMIC!>member<!>()
|
||||
d.memberExtension()
|
||||
}
|
||||
|
||||
fun member() {}
|
||||
fun Any.memberExtension() {}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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<Diagnostic> diagnostics = ContainerUtil.filter(
|
||||
KotlinPackage.plus(CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, jetFile),
|
||||
KotlinPackage.plus(CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, jetFile, markDynamicCalls),
|
||||
jvmSignatureDiagnostics),
|
||||
whatDiagnosticsToConsider
|
||||
);
|
||||
|
||||
@@ -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<DiagnosedRange> diagnosedRanges = Lists.newArrayList();
|
||||
CheckerTestUtil.parseDiagnosedRanges(expectedText, diagnosedRanges);
|
||||
@@ -155,7 +155,7 @@ public class CheckerTestUtilTest extends JetLiteFixture {
|
||||
diagnosedRange.setFile(psiFile);
|
||||
}
|
||||
|
||||
List<Diagnostic> diagnostics = CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile);
|
||||
List<Diagnostic> diagnostics = CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile, false);
|
||||
Collections.sort(diagnostics, CheckerTestUtil.DIAGNOSTIC_COMPARATOR);
|
||||
|
||||
makeTestData(diagnostics, diagnosedRanges);
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -42,7 +42,7 @@ public class CopyAsDiagnosticTestAction extends AnAction {
|
||||
|
||||
BindingContext bindingContext = ResolvePackage.analyzeFully((JetFile) psiFile);
|
||||
|
||||
List<Diagnostic> diagnostics = CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile);
|
||||
List<Diagnostic> diagnostics = CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile, false);
|
||||
String result = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, diagnostics).toString();
|
||||
|
||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
|
||||
Reference in New Issue
Block a user