Add ability to reuse one diagnostic test file for old and new inference
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -80,23 +80,26 @@ public class CheckerTestUtil {
|
|||||||
private static final String IGNORE_DIAGNOSTIC_PARAMETER = "IGNORE";
|
private static final String IGNORE_DIAGNOSTIC_PARAMETER = "IGNORE";
|
||||||
private static final String SHOULD_BE_ESCAPED = "\\)\\(;";
|
private static final String SHOULD_BE_ESCAPED = "\\)\\(;";
|
||||||
private static final String DIAGNOSTIC_PARAMETER = "(?:(?:\\\\[" + SHOULD_BE_ESCAPED + "])|[^" + SHOULD_BE_ESCAPED + "])+";
|
private static final String DIAGNOSTIC_PARAMETER = "(?:(?:\\\\[" + SHOULD_BE_ESCAPED + "])|[^" + SHOULD_BE_ESCAPED + "])+";
|
||||||
private static final String INDIVIDUAL_DIAGNOSTIC = "(\\w+:)?(\\w+)(\\(" + DIAGNOSTIC_PARAMETER + "(;\\s*" + DIAGNOSTIC_PARAMETER + ")*\\))?";
|
private static final String INDIVIDUAL_DIAGNOSTIC = "(\\w+;)?(\\w+:)?(\\w+)(\\(" + DIAGNOSTIC_PARAMETER + "(;\\s*" + DIAGNOSTIC_PARAMETER + ")*\\))?";
|
||||||
private static final Pattern RANGE_START_OR_END_PATTERN = Pattern.compile("(<!" +
|
private static final Pattern RANGE_START_OR_END_PATTERN = Pattern.compile("(<!" +
|
||||||
INDIVIDUAL_DIAGNOSTIC + "(,\\s*" +
|
INDIVIDUAL_DIAGNOSTIC + "(,\\s*" +
|
||||||
INDIVIDUAL_DIAGNOSTIC + ")*!>)|(<!>)");
|
INDIVIDUAL_DIAGNOSTIC + ")*!>)|(<!>)");
|
||||||
private static final Pattern INDIVIDUAL_DIAGNOSTIC_PATTERN = Pattern.compile(INDIVIDUAL_DIAGNOSTIC);
|
private static final Pattern INDIVIDUAL_DIAGNOSTIC_PATTERN = Pattern.compile(INDIVIDUAL_DIAGNOSTIC);
|
||||||
private static final Pattern INDIVIDUAL_PARAMETER_PATTERN = Pattern.compile(DIAGNOSTIC_PARAMETER);
|
private static final Pattern INDIVIDUAL_PARAMETER_PATTERN = Pattern.compile(DIAGNOSTIC_PARAMETER);
|
||||||
|
|
||||||
|
private static final String NEW_INFERENCE_PREFIX = "NI";
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public static List<ActualDiagnostic> getDiagnosticsIncludingSyntaxErrors(
|
public static List<ActualDiagnostic> getDiagnosticsIncludingSyntaxErrors(
|
||||||
@NotNull BindingContext bindingContext,
|
@NotNull BindingContext bindingContext,
|
||||||
@NotNull List<Pair<MultiTargetPlatform, BindingContext>> implementingModulesBindings,
|
@NotNull List<Pair<MultiTargetPlatform, BindingContext>> implementingModulesBindings,
|
||||||
@NotNull PsiElement root,
|
@NotNull PsiElement root,
|
||||||
boolean markDynamicCalls,
|
boolean markDynamicCalls,
|
||||||
@Nullable List<DeclarationDescriptor> dynamicCallDescriptors
|
@Nullable List<DeclarationDescriptor> dynamicCallDescriptors,
|
||||||
|
boolean withNewInference
|
||||||
) {
|
) {
|
||||||
List<ActualDiagnostic> result =
|
List<ActualDiagnostic> result =
|
||||||
getDiagnosticsIncludingSyntaxErrors(bindingContext, root, markDynamicCalls, dynamicCallDescriptors, null);
|
getDiagnosticsIncludingSyntaxErrors(bindingContext, root, markDynamicCalls, dynamicCallDescriptors, null, withNewInference);
|
||||||
|
|
||||||
List<Pair<MultiTargetPlatform, BindingContext>> sortedBindings = CollectionsKt.sortedWith(
|
List<Pair<MultiTargetPlatform, BindingContext>> sortedBindings = CollectionsKt.sortedWith(
|
||||||
implementingModulesBindings,
|
implementingModulesBindings,
|
||||||
@@ -109,7 +112,7 @@ public class CheckerTestUtil {
|
|||||||
|
|
||||||
result.addAll(getDiagnosticsIncludingSyntaxErrors(
|
result.addAll(getDiagnosticsIncludingSyntaxErrors(
|
||||||
binding.getSecond(), root, markDynamicCalls, dynamicCallDescriptors,
|
binding.getSecond(), root, markDynamicCalls, dynamicCallDescriptors,
|
||||||
((MultiTargetPlatform.Specific) platform).getPlatform()
|
((MultiTargetPlatform.Specific) platform).getPlatform(), withNewInference
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,20 +125,21 @@ public class CheckerTestUtil {
|
|||||||
@NotNull PsiElement root,
|
@NotNull PsiElement root,
|
||||||
boolean markDynamicCalls,
|
boolean markDynamicCalls,
|
||||||
@Nullable List<DeclarationDescriptor> dynamicCallDescriptors,
|
@Nullable List<DeclarationDescriptor> dynamicCallDescriptors,
|
||||||
@Nullable String platform
|
@Nullable String platform,
|
||||||
|
boolean withNewInference
|
||||||
) {
|
) {
|
||||||
List<ActualDiagnostic> diagnostics = new ArrayList<>();
|
List<ActualDiagnostic> diagnostics = new ArrayList<>();
|
||||||
for (Diagnostic diagnostic : bindingContext.getDiagnostics().all()) {
|
for (Diagnostic diagnostic : bindingContext.getDiagnostics().all()) {
|
||||||
if (PsiTreeUtil.isAncestor(root, diagnostic.getPsiElement(), false)) {
|
if (PsiTreeUtil.isAncestor(root, diagnostic.getPsiElement(), false)) {
|
||||||
diagnostics.add(new ActualDiagnostic(diagnostic, platform));
|
diagnostics.add(new ActualDiagnostic(diagnostic, platform, withNewInference));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (PsiErrorElement errorElement : AnalyzingUtils.getSyntaxErrorRanges(root)) {
|
for (PsiErrorElement errorElement : AnalyzingUtils.getSyntaxErrorRanges(root)) {
|
||||||
diagnostics.add(new ActualDiagnostic(new SyntaxErrorDiagnostic(errorElement), platform));
|
diagnostics.add(new ActualDiagnostic(new SyntaxErrorDiagnostic(errorElement), platform, withNewInference));
|
||||||
}
|
}
|
||||||
|
|
||||||
diagnostics.addAll(getDebugInfoDiagnostics(root, bindingContext, markDynamicCalls, dynamicCallDescriptors, platform));
|
diagnostics.addAll(getDebugInfoDiagnostics(root, bindingContext, markDynamicCalls, dynamicCallDescriptors, platform, withNewInference));
|
||||||
return diagnostics;
|
return diagnostics;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,7 +150,8 @@ public class CheckerTestUtil {
|
|||||||
@NotNull BindingContext bindingContext,
|
@NotNull BindingContext bindingContext,
|
||||||
boolean markDynamicCalls,
|
boolean markDynamicCalls,
|
||||||
@Nullable List<DeclarationDescriptor> dynamicCallDescriptors,
|
@Nullable List<DeclarationDescriptor> dynamicCallDescriptors,
|
||||||
@Nullable String platform
|
@Nullable String platform,
|
||||||
|
boolean withNewInference
|
||||||
) {
|
) {
|
||||||
List<ActualDiagnostic> debugAnnotations = new ArrayList<>();
|
List<ActualDiagnostic> debugAnnotations = new ArrayList<>();
|
||||||
|
|
||||||
@@ -178,7 +183,7 @@ public class CheckerTestUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void newDiagnostic(KtElement element, DebugInfoDiagnosticFactory factory) {
|
private void newDiagnostic(KtElement element, DebugInfoDiagnosticFactory factory) {
|
||||||
debugAnnotations.add(new ActualDiagnostic(new DebugInfoDiagnostic(element, factory), platform));
|
debugAnnotations.add(new ActualDiagnostic(new DebugInfoDiagnostic(element, factory), platform, withNewInference));
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -193,7 +198,8 @@ public class CheckerTestUtil {
|
|||||||
)) {
|
)) {
|
||||||
for (KtExpression expression : bindingContext.getSliceContents(factory.getFirst()).keySet()) {
|
for (KtExpression expression : bindingContext.getSliceContents(factory.getFirst()).keySet()) {
|
||||||
if (PsiTreeUtil.isAncestor(root, expression, false)) {
|
if (PsiTreeUtil.isAncestor(root, expression, false)) {
|
||||||
debugAnnotations.add(new ActualDiagnostic(new DebugInfoDiagnostic(expression, factory.getSecond()), platform));
|
debugAnnotations.add(new ActualDiagnostic(new DebugInfoDiagnostic(expression, factory.getSecond()), platform,
|
||||||
|
withNewInference));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -207,6 +213,12 @@ public class CheckerTestUtil {
|
|||||||
void wrongParametersDiagnostic(TextDiagnostic expectedDiagnostic, TextDiagnostic actualDiagnostic, int start, int end);
|
void wrongParametersDiagnostic(TextDiagnostic expectedDiagnostic, TextDiagnostic actualDiagnostic, int start, int end);
|
||||||
|
|
||||||
void unexpectedDiagnostic(TextDiagnostic diagnostic, int actualStart, int actualEnd);
|
void unexpectedDiagnostic(TextDiagnostic diagnostic, int actualStart, int actualEnd);
|
||||||
|
|
||||||
|
void uncheckedDiagnostic(TextDiagnostic diagnostic, int expectedStart, int expectedEnd);
|
||||||
|
|
||||||
|
boolean shouldUseDiagnosticsForNI();
|
||||||
|
|
||||||
|
boolean isWithNewInferenceDirective();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Map<ActualDiagnostic, TextDiagnostic> diagnosticsDiff(
|
public static Map<ActualDiagnostic, TextDiagnostic> diagnosticsDiff(
|
||||||
@@ -219,13 +231,21 @@ public class CheckerTestUtil {
|
|||||||
assertSameFile(actual);
|
assertSameFile(actual);
|
||||||
|
|
||||||
Iterator<DiagnosedRange> expectedDiagnostics = expected.iterator();
|
Iterator<DiagnosedRange> expectedDiagnostics = expected.iterator();
|
||||||
List<DiagnosticDescriptor> sortedDiagnosticDescriptors = getSortedDiagnosticDescriptors(actual);
|
List<ActualDiagnosticDescriptor> sortedDiagnosticDescriptors =
|
||||||
Iterator<DiagnosticDescriptor> actualDiagnostics = sortedDiagnosticDescriptors.iterator();
|
getActualSortedDiagnosticDescriptors(actual, !callbacks.isWithNewInferenceDirective());
|
||||||
|
Iterator<ActualDiagnosticDescriptor> actualDiagnostics = sortedDiagnosticDescriptors.iterator();
|
||||||
|
|
||||||
DiagnosedRange currentExpected = safeAdvance(expectedDiagnostics);
|
DiagnosedRange currentExpected = safeAdvance(expectedDiagnostics);
|
||||||
DiagnosticDescriptor currentActual = safeAdvance(actualDiagnostics);
|
ActualDiagnosticDescriptor currentActual = safeAdvance(actualDiagnostics);
|
||||||
while (currentExpected != null || currentActual != null) {
|
while (currentExpected != null || currentActual != null) {
|
||||||
if (currentExpected != null) {
|
if (currentExpected != null) {
|
||||||
|
boolean currentDiagnosticsForNI = CollectionsKt.any(currentExpected.diagnostics, diagnostic -> diagnostic.withNewInference);
|
||||||
|
if (callbacks.shouldUseDiagnosticsForNI() != currentDiagnosticsForNI) {
|
||||||
|
uncheckedDiagnostics(callbacks, currentExpected);
|
||||||
|
currentExpected = safeAdvance(expectedDiagnostics);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (currentActual == null) {
|
if (currentActual == null) {
|
||||||
missingDiagnostics(callbacks, currentExpected);
|
missingDiagnostics(callbacks, currentExpected);
|
||||||
currentExpected = safeAdvance(expectedDiagnostics);
|
currentExpected = safeAdvance(expectedDiagnostics);
|
||||||
@@ -275,7 +295,7 @@ public class CheckerTestUtil {
|
|||||||
private static void compareDiagnostics(
|
private static void compareDiagnostics(
|
||||||
@NotNull DiagnosticDiffCallbacks callbacks,
|
@NotNull DiagnosticDiffCallbacks callbacks,
|
||||||
@NotNull DiagnosedRange currentExpected,
|
@NotNull DiagnosedRange currentExpected,
|
||||||
@NotNull DiagnosticDescriptor currentActual,
|
@NotNull ActualDiagnosticDescriptor currentActual,
|
||||||
@NotNull Map<ActualDiagnostic, TextDiagnostic> diagnosticToInput
|
@NotNull Map<ActualDiagnostic, TextDiagnostic> diagnosticToInput
|
||||||
) {
|
) {
|
||||||
int expectedStart = currentExpected.getStart();
|
int expectedStart = currentExpected.getStart();
|
||||||
@@ -339,9 +359,9 @@ public class CheckerTestUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void unexpectedDiagnostics(DiagnosticDescriptor descriptor, DiagnosticDiffCallbacks callbacks) {
|
private static void unexpectedDiagnostics(ActualDiagnosticDescriptor descriptor, DiagnosticDiffCallbacks callbacks) {
|
||||||
for (ActualDiagnostic diagnostic : descriptor.diagnostics) {
|
for (ActualDiagnostic diagnostic : descriptor.diagnostics) {
|
||||||
callbacks.unexpectedDiagnostic(TextDiagnostic.asTextDiagnostic(diagnostic), descriptor.start, descriptor.end);
|
callbacks.unexpectedDiagnostic(TextDiagnostic.asTextDiagnostic(diagnostic), descriptor.getStart(), descriptor.getEnd());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,6 +371,12 @@ public class CheckerTestUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void uncheckedDiagnostics(DiagnosticDiffCallbacks callbacks, DiagnosedRange currentExpected) {
|
||||||
|
for (TextDiagnostic diagnostic : currentExpected.getDiagnostics()) {
|
||||||
|
callbacks.uncheckedDiagnostic(diagnostic, currentExpected.getStart(), currentExpected.getEnd());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private static <T> T safeAdvance(Iterator<T> iterator) {
|
private static <T> T safeAdvance(Iterator<T> iterator) {
|
||||||
return iterator.hasNext() ? iterator.next() : null;
|
return iterator.hasNext() ? iterator.next() : null;
|
||||||
}
|
}
|
||||||
@@ -387,97 +413,114 @@ public class CheckerTestUtil {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public static StringBuffer addDiagnosticMarkersToText(@NotNull PsiFile psiFile, @NotNull Collection<ActualDiagnostic> diagnostics) {
|
public static StringBuffer addDiagnosticMarkersToText(@NotNull PsiFile psiFile, @NotNull Collection<ActualDiagnostic> diagnostics) {
|
||||||
return addDiagnosticMarkersToText(psiFile, diagnostics, Collections.emptyMap(), PsiElement::getText);
|
return addDiagnosticMarkersToText(psiFile, diagnostics, Collections.emptyMap(), PsiElement::getText, Collections.emptyList(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static StringBuffer addDiagnosticMarkersToText(
|
public static StringBuffer addDiagnosticMarkersToText(
|
||||||
@NotNull PsiFile psiFile,
|
@NotNull PsiFile psiFile,
|
||||||
@NotNull Collection<ActualDiagnostic> diagnostics,
|
@NotNull Collection<ActualDiagnostic> diagnostics,
|
||||||
@NotNull Map<ActualDiagnostic, TextDiagnostic> diagnosticToExpectedDiagnostic,
|
@NotNull Map<ActualDiagnostic, TextDiagnostic> diagnosticToExpectedDiagnostic,
|
||||||
@NotNull Function<PsiFile, String> getFileText
|
@NotNull Function<PsiFile, String> getFileText,
|
||||||
|
@NotNull Collection<PositionalTextDiagnostic> uncheckedDiagnostics,
|
||||||
|
boolean withNewInferenceDirective
|
||||||
) {
|
) {
|
||||||
String text = getFileText.fun(psiFile);
|
String text = getFileText.fun(psiFile);
|
||||||
StringBuffer result = new StringBuffer();
|
StringBuffer result = new StringBuffer();
|
||||||
diagnostics = CollectionsKt.filter(diagnostics, actualDiagnostic -> psiFile.equals(actualDiagnostic.getFile()));
|
diagnostics = CollectionsKt.filter(diagnostics, actualDiagnostic -> psiFile.equals(actualDiagnostic.getFile()));
|
||||||
if (!diagnostics.isEmpty()) {
|
if (diagnostics.isEmpty() && uncheckedDiagnostics.isEmpty()) {
|
||||||
List<DiagnosticDescriptor> diagnosticDescriptors = getSortedDiagnosticDescriptors(diagnostics);
|
result.append(text);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
Stack<DiagnosticDescriptor> opened = new Stack<>();
|
List<AbstractDiagnosticDescriptor> diagnosticDescriptors = getSortedDiagnosticDescriptors(diagnostics, uncheckedDiagnostics, !withNewInferenceDirective);
|
||||||
ListIterator<DiagnosticDescriptor> iterator = diagnosticDescriptors.listIterator();
|
|
||||||
DiagnosticDescriptor currentDescriptor = iterator.next();
|
|
||||||
|
|
||||||
for (int i = 0; i < text.length(); i++) {
|
Stack<AbstractDiagnosticDescriptor> opened = new Stack<>();
|
||||||
char c = text.charAt(i);
|
ListIterator<AbstractDiagnosticDescriptor> iterator = diagnosticDescriptors.listIterator();
|
||||||
while (!opened.isEmpty() && i == opened.peek().end) {
|
AbstractDiagnosticDescriptor currentDescriptor = iterator.next();
|
||||||
closeDiagnosticString(result);
|
|
||||||
opened.pop();
|
|
||||||
}
|
|
||||||
while (currentDescriptor != null && i == currentDescriptor.start) {
|
|
||||||
openDiagnosticsString(result, currentDescriptor, diagnosticToExpectedDiagnostic);
|
|
||||||
if (currentDescriptor.getEnd() == i) {
|
|
||||||
closeDiagnosticString(result);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
opened.push(currentDescriptor);
|
|
||||||
}
|
|
||||||
if (iterator.hasNext()) {
|
|
||||||
currentDescriptor = iterator.next();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
currentDescriptor = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.append(c);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (currentDescriptor != null) {
|
for (int i = 0; i < text.length(); i++) {
|
||||||
assert currentDescriptor.start == text.length();
|
char c = text.charAt(i);
|
||||||
assert currentDescriptor.end == text.length();
|
while (!opened.isEmpty() && i == opened.peek().end) {
|
||||||
openDiagnosticsString(result, currentDescriptor, diagnosticToExpectedDiagnostic);
|
|
||||||
opened.push(currentDescriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
while (!opened.isEmpty() && text.length() == opened.peek().end) {
|
|
||||||
closeDiagnosticString(result);
|
closeDiagnosticString(result);
|
||||||
opened.pop();
|
opened.pop();
|
||||||
}
|
}
|
||||||
|
while (currentDescriptor != null && i == currentDescriptor.start) {
|
||||||
|
openDiagnosticsString(result, currentDescriptor, diagnosticToExpectedDiagnostic);
|
||||||
|
if (currentDescriptor.getEnd() == i) {
|
||||||
|
closeDiagnosticString(result);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
opened.push(currentDescriptor);
|
||||||
|
}
|
||||||
|
if (iterator.hasNext()) {
|
||||||
|
currentDescriptor = iterator.next();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
currentDescriptor = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
result.append(c);
|
||||||
|
}
|
||||||
|
|
||||||
assert opened.isEmpty() : "Stack is not empty: " + opened;
|
if (currentDescriptor != null) {
|
||||||
|
assert currentDescriptor.start == text.length();
|
||||||
|
assert currentDescriptor.end == text.length();
|
||||||
|
openDiagnosticsString(result, currentDescriptor, diagnosticToExpectedDiagnostic);
|
||||||
|
opened.push(currentDescriptor);
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
result.append(text);
|
while (!opened.isEmpty() && text.length() == opened.peek().end) {
|
||||||
|
closeDiagnosticString(result);
|
||||||
|
opened.pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
assert opened.isEmpty() : "Stack is not empty: " + opened;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void openDiagnosticsString(
|
private static void openDiagnosticsString(
|
||||||
StringBuffer result,
|
StringBuffer result,
|
||||||
DiagnosticDescriptor currentDescriptor,
|
AbstractDiagnosticDescriptor currentDescriptor,
|
||||||
Map<ActualDiagnostic, TextDiagnostic> diagnosticToExpectedDiagnostic
|
Map<ActualDiagnostic, TextDiagnostic> diagnosticToExpectedDiagnostic
|
||||||
) {
|
) {
|
||||||
result.append("<!");
|
result.append("<!");
|
||||||
for (Iterator<ActualDiagnostic> iterator = currentDescriptor.diagnostics.iterator(); iterator.hasNext(); ) {
|
if (currentDescriptor instanceof TextDiagnosticDescriptor) {
|
||||||
ActualDiagnostic diagnostic = iterator.next();
|
TextDiagnostic diagnostic = ((TextDiagnosticDescriptor) currentDescriptor).getTextDiagnostic();
|
||||||
TextDiagnostic expectedDiagnostic = diagnosticToExpectedDiagnostic.get(diagnostic);
|
result.append(diagnostic.asString());
|
||||||
if (expectedDiagnostic != null) {
|
}
|
||||||
TextDiagnostic actualTextDiagnostic = TextDiagnostic.asTextDiagnostic(diagnostic);
|
else if (currentDescriptor instanceof ActualDiagnosticDescriptor) {
|
||||||
if (compareTextDiagnostic(expectedDiagnostic, actualTextDiagnostic)) {
|
List<ActualDiagnostic> diagnostics = ((ActualDiagnosticDescriptor) currentDescriptor).getDiagnostics();
|
||||||
result.append(expectedDiagnostic.asString());
|
for (Iterator<ActualDiagnostic> iterator = diagnostics.iterator(); iterator.hasNext(); ) {
|
||||||
|
ActualDiagnostic diagnostic = iterator.next();
|
||||||
|
TextDiagnostic expectedDiagnostic = diagnosticToExpectedDiagnostic.get(diagnostic);
|
||||||
|
if (expectedDiagnostic != null) {
|
||||||
|
TextDiagnostic actualTextDiagnostic = TextDiagnostic.asTextDiagnostic(diagnostic);
|
||||||
|
if (compareTextDiagnostic(expectedDiagnostic, actualTextDiagnostic)) {
|
||||||
|
result.append(expectedDiagnostic.asString());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result.append(actualTextDiagnostic.asString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
result.append(actualTextDiagnostic.asString());
|
if (diagnostic.withNewInference) {
|
||||||
|
result.append(NEW_INFERENCE_PREFIX);
|
||||||
|
result.append(";");
|
||||||
|
}
|
||||||
|
if (diagnostic.platform != null) {
|
||||||
|
result.append(diagnostic.platform);
|
||||||
|
result.append(":");
|
||||||
|
}
|
||||||
|
result.append(diagnostic.getName());
|
||||||
|
}
|
||||||
|
if (iterator.hasNext()) {
|
||||||
|
result.append(", ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
}
|
||||||
if (diagnostic.platform != null) {
|
else {
|
||||||
result.append(diagnostic.platform);
|
throw new IllegalStateException("Unknown diagnostic descriptor: " + currentDescriptor);
|
||||||
result.append(":");
|
|
||||||
}
|
|
||||||
result.append(diagnostic.getName());
|
|
||||||
}
|
|
||||||
if (iterator.hasNext()) {
|
|
||||||
result.append(", ");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
result.append("!>");
|
result.append("!>");
|
||||||
}
|
}
|
||||||
@@ -586,45 +629,80 @@ public class CheckerTestUtil {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static List<ActualDiagnosticDescriptor> getActualSortedDiagnosticDescriptors(
|
||||||
|
@NotNull Collection<ActualDiagnostic> diagnostics,
|
||||||
|
boolean groupDiagnosticsByRange
|
||||||
|
) {
|
||||||
|
return CollectionsKt.filterIsInstance(
|
||||||
|
getSortedDiagnosticDescriptors(diagnostics, Collections.emptyList(), groupDiagnosticsByRange),
|
||||||
|
ActualDiagnosticDescriptor.class
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static List<DiagnosticDescriptor> getSortedDiagnosticDescriptors(@NotNull Collection<ActualDiagnostic> diagnostics) {
|
private static List<AbstractDiagnosticDescriptor> getSortedDiagnosticDescriptors(
|
||||||
LinkedListMultimap<TextRange, ActualDiagnostic> diagnosticsGroupedByRanges = LinkedListMultimap.create();
|
@NotNull Collection<ActualDiagnostic> diagnostics,
|
||||||
for (ActualDiagnostic actualDiagnostic : diagnostics) {
|
@NotNull Collection<PositionalTextDiagnostic> uncheckedDiagnostics,
|
||||||
Diagnostic diagnostic = actualDiagnostic.diagnostic;
|
boolean groupDiagnosticsByRange
|
||||||
if (!diagnostic.isValid()) continue;
|
) {
|
||||||
for (TextRange textRange : diagnostic.getTextRanges()) {
|
List<ActualDiagnostic> validDiagnostics = CollectionsKt.filter(diagnostics, actualDiagnostic -> actualDiagnostic.diagnostic.isValid());
|
||||||
diagnosticsGroupedByRanges.put(textRange, actualDiagnostic);
|
List<AbstractDiagnosticDescriptor> diagnosticDescriptors = groupDiagnosticsByRange ?
|
||||||
}
|
groupDiagnosticsByTextRange(validDiagnostics) :
|
||||||
}
|
asPlainDiagnosticDescriptors(validDiagnostics);
|
||||||
List<DiagnosticDescriptor> diagnosticDescriptors = Lists.newArrayList();
|
for (PositionalTextDiagnostic diagnostic : uncheckedDiagnostics) {
|
||||||
for (TextRange range : diagnosticsGroupedByRanges.keySet()) {
|
diagnosticDescriptors.add(new TextDiagnosticDescriptor(diagnostic));
|
||||||
diagnosticDescriptors.add(
|
|
||||||
new DiagnosticDescriptor(range.getStartOffset(), range.getEndOffset(), diagnosticsGroupedByRanges.get(range)));
|
|
||||||
}
|
}
|
||||||
diagnosticDescriptors.sort((d1, d2) -> {
|
diagnosticDescriptors.sort((d1, d2) -> {
|
||||||
// Start early -- go first; start at the same offset, the one who end later is the outer, i.e. goes first
|
if (d1.start != d2.start) return d1.start - d2.start;
|
||||||
return (d1.start != d2.start) ? d1.start - d2.start : d2.end - d1.end;
|
if (d1.end != d2.end) return d2.end - d1.end;
|
||||||
|
if (d1.isWithNewInference() && !d2.isWithNewInference()) return -1;
|
||||||
|
if (!d1.isWithNewInference() && d2.isWithNewInference()) return 1;
|
||||||
|
return 0;
|
||||||
});
|
});
|
||||||
return diagnosticDescriptors;
|
return diagnosticDescriptors;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class DiagnosticDescriptor {
|
private static List<AbstractDiagnosticDescriptor> asPlainDiagnosticDescriptors(@NotNull Collection<ActualDiagnostic> diagnostics) {
|
||||||
private final int start;
|
List<AbstractDiagnosticDescriptor> diagnosticDescriptors = Lists.newArrayList();
|
||||||
private final int end;
|
for (ActualDiagnostic actualDiagnostic : diagnostics) {
|
||||||
private final List<ActualDiagnostic> diagnostics;
|
for (TextRange range : actualDiagnostic.diagnostic.getTextRanges()) {
|
||||||
|
diagnosticDescriptors.add(
|
||||||
DiagnosticDescriptor(int start, int end, List<ActualDiagnostic> diagnostics) {
|
new ActualDiagnosticDescriptor(
|
||||||
this.start = start;
|
range.getStartOffset(),
|
||||||
this.end = end;
|
range.getEndOffset(),
|
||||||
this.diagnostics = diagnostics;
|
Collections.singletonList(actualDiagnostic))
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<ActualDiagnostic, TextDiagnostic> getTextDiagnosticsMap() {
|
return diagnosticDescriptors;
|
||||||
Map<ActualDiagnostic, TextDiagnostic> diagnosticMap = new HashMap<>();
|
}
|
||||||
for (ActualDiagnostic diagnostic : diagnostics) {
|
|
||||||
diagnosticMap.put(diagnostic, TextDiagnostic.asTextDiagnostic(diagnostic));
|
@NotNull
|
||||||
|
private static List<AbstractDiagnosticDescriptor> groupDiagnosticsByTextRange(@NotNull Collection<ActualDiagnostic> diagnostics) {
|
||||||
|
LinkedListMultimap<TextRange, ActualDiagnostic> diagnosticsGroupedByRanges = LinkedListMultimap.create();
|
||||||
|
for (ActualDiagnostic actualDiagnostic : diagnostics) {
|
||||||
|
Diagnostic diagnostic = actualDiagnostic.diagnostic;
|
||||||
|
for (TextRange textRange : diagnostic.getTextRanges()) {
|
||||||
|
diagnosticsGroupedByRanges.put(textRange, actualDiagnostic);
|
||||||
}
|
}
|
||||||
return diagnosticMap;
|
}
|
||||||
|
|
||||||
|
return CollectionsKt.map(diagnosticsGroupedByRanges.keySet(), range ->
|
||||||
|
new ActualDiagnosticDescriptor(
|
||||||
|
range.getStartOffset(),
|
||||||
|
range.getEndOffset(),
|
||||||
|
diagnosticsGroupedByRanges.get(range))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static abstract class AbstractDiagnosticDescriptor {
|
||||||
|
private final int start;
|
||||||
|
private final int end;
|
||||||
|
|
||||||
|
AbstractDiagnosticDescriptor(int start, int end) {
|
||||||
|
this.start = start;
|
||||||
|
this.end = end;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getStart() {
|
public int getStart() {
|
||||||
@@ -638,15 +716,63 @@ public class CheckerTestUtil {
|
|||||||
public TextRange getTextRange() {
|
public TextRange getTextRange() {
|
||||||
return new TextRange(start, end);
|
return new TextRange(start, end);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract boolean isWithNewInference();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class ActualDiagnosticDescriptor extends AbstractDiagnosticDescriptor {
|
||||||
|
private final List<ActualDiagnostic> diagnostics;
|
||||||
|
|
||||||
|
ActualDiagnosticDescriptor(int start, int end, List<ActualDiagnostic> diagnostics) {
|
||||||
|
super(start, end);
|
||||||
|
this.diagnostics = diagnostics;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<ActualDiagnostic> getDiagnostics() {
|
||||||
|
return diagnostics;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<ActualDiagnostic, TextDiagnostic> getTextDiagnosticsMap() {
|
||||||
|
Map<ActualDiagnostic, TextDiagnostic> diagnosticMap = new HashMap<>();
|
||||||
|
for (ActualDiagnostic diagnostic : diagnostics) {
|
||||||
|
diagnosticMap.put(diagnostic, TextDiagnostic.asTextDiagnostic(diagnostic));
|
||||||
|
}
|
||||||
|
return diagnosticMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWithNewInference() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class TextDiagnosticDescriptor extends AbstractDiagnosticDescriptor {
|
||||||
|
private final PositionalTextDiagnostic positionalTextDiagnostic;
|
||||||
|
|
||||||
|
TextDiagnosticDescriptor(PositionalTextDiagnostic positionalTextDiagnostic) {
|
||||||
|
super(positionalTextDiagnostic.getStart(), positionalTextDiagnostic.getEnd());
|
||||||
|
this.positionalTextDiagnostic = positionalTextDiagnostic;
|
||||||
|
}
|
||||||
|
|
||||||
|
public TextDiagnostic getTextDiagnostic() {
|
||||||
|
return positionalTextDiagnostic.getDiagnostic();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWithNewInference() {
|
||||||
|
return positionalTextDiagnostic.getDiagnostic().withNewInference;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class ActualDiagnostic {
|
public static class ActualDiagnostic {
|
||||||
public final Diagnostic diagnostic;
|
public final Diagnostic diagnostic;
|
||||||
public final String platform;
|
public final String platform;
|
||||||
|
public final boolean withNewInference;
|
||||||
|
|
||||||
ActualDiagnostic(@NotNull Diagnostic diagnostic, @Nullable String platform) {
|
ActualDiagnostic(@NotNull Diagnostic diagnostic, @Nullable String platform, boolean withNewInference) {
|
||||||
this.diagnostic = diagnostic;
|
this.diagnostic = diagnostic;
|
||||||
this.platform = platform;
|
this.platform = platform;
|
||||||
|
this.withNewInference = withNewInference;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -666,17 +792,21 @@ public class CheckerTestUtil {
|
|||||||
ActualDiagnostic other = (ActualDiagnostic) obj;
|
ActualDiagnostic other = (ActualDiagnostic) obj;
|
||||||
// '==' on diagnostics is intentional here
|
// '==' on diagnostics is intentional here
|
||||||
return other.diagnostic == diagnostic &&
|
return other.diagnostic == diagnostic &&
|
||||||
(other.platform == null ? platform == null : other.platform.equals(platform));
|
(other.platform == null ? platform == null : other.platform.equals(platform)) &&
|
||||||
|
(other.withNewInference == withNewInference);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return System.identityHashCode(diagnostic) * 31 + (platform != null ? platform.hashCode() : 0);
|
int result = System.identityHashCode(diagnostic);
|
||||||
|
result = 31 * result + (platform != null ? platform.hashCode() : 0);
|
||||||
|
result = 31 * result + (withNewInference ? 0 : 1);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return (platform != null ? platform + ":" : "") + diagnostic.toString();
|
return (withNewInference ? NEW_INFERENCE_PREFIX + ";" : "") + (platform != null ? platform + ":" : "") + diagnostic.toString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -687,21 +817,25 @@ public class CheckerTestUtil {
|
|||||||
if (!matcher.find())
|
if (!matcher.find())
|
||||||
throw new IllegalArgumentException("Could not parse diagnostic: " + text);
|
throw new IllegalArgumentException("Could not parse diagnostic: " + text);
|
||||||
|
|
||||||
String platformPrefix = matcher.group(1);
|
boolean withNewInference = NEW_INFERENCE_PREFIX.equals(extractDataBefore(matcher.group(1), ";"));
|
||||||
assert platformPrefix == null || platformPrefix.endsWith(":") : platformPrefix;
|
String platform = extractDataBefore(matcher.group(2), ":");
|
||||||
String platform = platformPrefix == null ? null : StringsKt.substringBeforeLast(platformPrefix, ":", platformPrefix);
|
|
||||||
|
|
||||||
String name = matcher.group(2);
|
String name = matcher.group(3);
|
||||||
String parameters = matcher.group(3);
|
String parameters = matcher.group(4);
|
||||||
if (parameters == null) {
|
if (parameters == null) {
|
||||||
return new TextDiagnostic(name, platform, null);
|
return new TextDiagnostic(name, platform, null, withNewInference);
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> parsedParameters = new SmartList<>();
|
List<String> parsedParameters = new SmartList<>();
|
||||||
Matcher parametersMatcher = INDIVIDUAL_PARAMETER_PATTERN.matcher(parameters);
|
Matcher parametersMatcher = INDIVIDUAL_PARAMETER_PATTERN.matcher(parameters);
|
||||||
while (parametersMatcher.find())
|
while (parametersMatcher.find())
|
||||||
parsedParameters.add(unescape(parametersMatcher.group().trim()));
|
parsedParameters.add(unescape(parametersMatcher.group().trim()));
|
||||||
return new TextDiagnostic(name, platform, parsedParameters);
|
return new TextDiagnostic(name, platform, parsedParameters, withNewInference);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String extractDataBefore(@Nullable String prefix, @NotNull String anchor) {
|
||||||
|
assert prefix == null || prefix.endsWith(anchor) : prefix;
|
||||||
|
return prefix == null ? null : StringsKt.substringBeforeLast(prefix, anchor, prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static @NotNull String escape(@NotNull String s) {
|
private static @NotNull String escape(@NotNull String s) {
|
||||||
@@ -722,9 +856,9 @@ public class CheckerTestUtil {
|
|||||||
//noinspection unchecked
|
//noinspection unchecked
|
||||||
Object[] renderParameters = ((AbstractDiagnosticWithParametersRenderer) renderer).renderParameters(diagnostic);
|
Object[] renderParameters = ((AbstractDiagnosticWithParametersRenderer) renderer).renderParameters(diagnostic);
|
||||||
List<String> parameters = ContainerUtil.map(renderParameters, Object::toString);
|
List<String> parameters = ContainerUtil.map(renderParameters, Object::toString);
|
||||||
return new TextDiagnostic(diagnosticName, actualDiagnostic.platform, parameters);
|
return new TextDiagnostic(diagnosticName, actualDiagnostic.platform, parameters, actualDiagnostic.withNewInference);
|
||||||
}
|
}
|
||||||
return new TextDiagnostic(diagnosticName, actualDiagnostic.platform, null);
|
return new TextDiagnostic(diagnosticName, actualDiagnostic.platform, null, actualDiagnostic.withNewInference);
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
@@ -733,11 +867,13 @@ public class CheckerTestUtil {
|
|||||||
private final String platform;
|
private final String platform;
|
||||||
@Nullable
|
@Nullable
|
||||||
private final List<String> parameters;
|
private final List<String> parameters;
|
||||||
|
private final boolean withNewInference;
|
||||||
|
|
||||||
public TextDiagnostic(@NotNull String name, @Nullable String platform, @Nullable List<String> parameters) {
|
public TextDiagnostic(@NotNull String name, @Nullable String platform, @Nullable List<String> parameters, boolean withNewInference) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.platform = platform;
|
this.platform = platform;
|
||||||
this.parameters = parameters;
|
this.parameters = parameters;
|
||||||
|
this.withNewInference = withNewInference;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
@@ -765,6 +901,7 @@ public class CheckerTestUtil {
|
|||||||
if (!name.equals(that.name)) return false;
|
if (!name.equals(that.name)) return false;
|
||||||
if (platform != null ? !platform.equals(that.platform) : that.platform != null) return false;
|
if (platform != null ? !platform.equals(that.platform) : that.platform != null) return false;
|
||||||
if (parameters != null ? !parameters.equals(that.parameters) : that.parameters != null) return false;
|
if (parameters != null ? !parameters.equals(that.parameters) : that.parameters != null) return false;
|
||||||
|
if (withNewInference != that.withNewInference) return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -774,12 +911,17 @@ public class CheckerTestUtil {
|
|||||||
int result = name.hashCode();
|
int result = name.hashCode();
|
||||||
result = 31 * result + (platform != null ? platform.hashCode() : 0);
|
result = 31 * result + (platform != null ? platform.hashCode() : 0);
|
||||||
result = 31 * result + (parameters != null ? parameters.hashCode() : 0);
|
result = 31 * result + (parameters != null ? parameters.hashCode() : 0);
|
||||||
|
result = 31 * result + (withNewInference ? 0 : 1);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
public String asString() {
|
public String asString() {
|
||||||
StringBuilder result = new StringBuilder();
|
StringBuilder result = new StringBuilder();
|
||||||
|
if (withNewInference) {
|
||||||
|
result.append(NEW_INFERENCE_PREFIX);
|
||||||
|
result.append(";");
|
||||||
|
}
|
||||||
if (platform != null) {
|
if (platform != null) {
|
||||||
result.append(platform);
|
result.append(platform);
|
||||||
result.append(":");
|
result.append(":");
|
||||||
|
|||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2017 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.kotlin.checkers
|
||||||
|
|
||||||
|
data class PositionalTextDiagnostic(val diagnostic: CheckerTestUtil.TextDiagnostic, val start: Int, val end: Int)
|
||||||
+9
-5
@@ -140,13 +140,17 @@ abstract class AbstractDiagnosticsTest : BaseDiagnosticsTest() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var exceptionFromDescriptorValidation: Throwable? = null
|
var exceptionFromDescriptorValidation: Throwable? = null
|
||||||
|
val originalTestFile = testDataFile.readText()
|
||||||
try {
|
try {
|
||||||
val expectedFile = if (InTextDirectivesUtils.isDirectiveDefined(testDataFile.readText(), "// JAVAC_EXPECTED_FILE")
|
val isJavacExpectedFile = InTextDirectivesUtils.isDirectiveDefined(originalTestFile, "// JAVAC_EXPECTED_FILE")
|
||||||
&& environment.configuration.getBoolean(JVMConfigurationKeys.USE_JAVAC)) {
|
&& environment.configuration.getBoolean(JVMConfigurationKeys.USE_JAVAC)
|
||||||
File(FileUtil.getNameWithoutExtension(testDataFile.absolutePath) + ".javac.txt")
|
|
||||||
} else {
|
val postfix = when {
|
||||||
File(FileUtil.getNameWithoutExtension(testDataFile.absolutePath) + ".txt")
|
isJavacExpectedFile -> ".javac.txt"
|
||||||
|
files.all { it.withNewInferenceDirective && it.newInferenceEnabled } -> ".ni.txt"
|
||||||
|
else -> ".txt"
|
||||||
}
|
}
|
||||||
|
val expectedFile = File(FileUtil.getNameWithoutExtension(testDataFile.absolutePath) + postfix)
|
||||||
validateAndCompareDescriptorWithFile(expectedFile, files, modules)
|
validateAndCompareDescriptorWithFile(expectedFile, files, modules)
|
||||||
}
|
}
|
||||||
catch (e: Throwable) {
|
catch (e: Throwable) {
|
||||||
|
|||||||
@@ -130,6 +130,8 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
|||||||
val checkLazyLog: Boolean
|
val checkLazyLog: Boolean
|
||||||
private val markDynamicCalls: Boolean
|
private val markDynamicCalls: Boolean
|
||||||
val dynamicCallDescriptors: List<DeclarationDescriptor> = ArrayList()
|
val dynamicCallDescriptors: List<DeclarationDescriptor> = ArrayList()
|
||||||
|
val withNewInferenceDirective: Boolean
|
||||||
|
val newInferenceEnabled: Boolean
|
||||||
|
|
||||||
init {
|
init {
|
||||||
this.declareCheckType = CHECK_TYPE_DIRECTIVE in directives
|
this.declareCheckType = CHECK_TYPE_DIRECTIVE in directives
|
||||||
@@ -138,6 +140,8 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
|||||||
this.checkLazyLog = CHECK_LAZY_LOG_DIRECTIVE in directives || CHECK_LAZY_LOG_DEFAULT
|
this.checkLazyLog = CHECK_LAZY_LOG_DIRECTIVE in directives || CHECK_LAZY_LOG_DEFAULT
|
||||||
this.declareFlexibleType = EXPLICIT_FLEXIBLE_TYPES_DIRECTIVE in directives
|
this.declareFlexibleType = EXPLICIT_FLEXIBLE_TYPES_DIRECTIVE in directives
|
||||||
this.markDynamicCalls = MARK_DYNAMIC_CALLS_DIRECTIVE in directives
|
this.markDynamicCalls = MARK_DYNAMIC_CALLS_DIRECTIVE in directives
|
||||||
|
this.withNewInferenceDirective = WITH_NEW_INFERENCE_DIRECTIVE in directives
|
||||||
|
this.newInferenceEnabled = (customLanguageVersionSettings ?: LanguageVersionSettingsImpl.DEFAULT).supportsFeature(LanguageFeature.NewInference)
|
||||||
if (fileName.endsWith(".java")) {
|
if (fileName.endsWith(".java")) {
|
||||||
// TODO: check there are no syntax errors in .java sources
|
// TODO: check there are no syntax errors in .java sources
|
||||||
this.createKtFile = lazyOf(null)
|
this.createKtFile = lazyOf(null)
|
||||||
@@ -213,13 +217,16 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
|||||||
computeJvmSignatureDiagnostics(bindingContext)
|
computeJvmSignatureDiagnostics(bindingContext)
|
||||||
|
|
||||||
val ok = booleanArrayOf(true)
|
val ok = booleanArrayOf(true)
|
||||||
|
val withNewInference = newInferenceEnabled && withNewInferenceDirective
|
||||||
val diagnostics = ContainerUtil.filter(
|
val diagnostics = ContainerUtil.filter(
|
||||||
CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(
|
CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(
|
||||||
bindingContext, implementingModulesBindings, ktFile, markDynamicCalls, dynamicCallDescriptors
|
bindingContext, implementingModulesBindings, ktFile, markDynamicCalls, dynamicCallDescriptors, withNewInference
|
||||||
) + jvmSignatureDiagnostics,
|
) + jvmSignatureDiagnostics,
|
||||||
{ whatDiagnosticsToConsider.value(it.diagnostic) }
|
{ whatDiagnosticsToConsider.value(it.diagnostic) }
|
||||||
)
|
)
|
||||||
|
|
||||||
|
val uncheckedDiagnostics = mutableListOf<PositionalTextDiagnostic>()
|
||||||
|
|
||||||
val diagnosticToExpectedDiagnostic = CheckerTestUtil.diagnosticsDiff(diagnosedRanges, diagnostics, object : CheckerTestUtil.DiagnosticDiffCallbacks {
|
val diagnosticToExpectedDiagnostic = CheckerTestUtil.diagnosticsDiff(diagnosedRanges, diagnostics, object : CheckerTestUtil.DiagnosticDiffCallbacks {
|
||||||
override fun missingDiagnostic(diagnostic: CheckerTestUtil.TextDiagnostic, expectedStart: Int, expectedEnd: Int) {
|
override fun missingDiagnostic(diagnostic: CheckerTestUtil.TextDiagnostic, expectedStart: Int, expectedEnd: Int) {
|
||||||
val message = "Missing " + diagnostic.description + DiagnosticUtils.atLocation(ktFile, TextRange(expectedStart, expectedEnd))
|
val message = "Missing " + diagnostic.description + DiagnosticUtils.atLocation(ktFile, TextRange(expectedStart, expectedEnd))
|
||||||
@@ -245,10 +252,18 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
|||||||
System.err.println(message)
|
System.err.println(message)
|
||||||
ok[0] = false
|
ok[0] = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun uncheckedDiagnostic(diagnostic: CheckerTestUtil.TextDiagnostic, expectedStart: Int, expectedEnd: Int) {
|
||||||
|
uncheckedDiagnostics.add(PositionalTextDiagnostic(diagnostic, expectedStart, expectedEnd))
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun shouldUseDiagnosticsForNI(): Boolean = withNewInference
|
||||||
|
|
||||||
|
override fun isWithNewInferenceDirective(): Boolean = withNewInferenceDirective
|
||||||
})
|
})
|
||||||
|
|
||||||
actualText.append(
|
actualText.append(CheckerTestUtil.addDiagnosticMarkersToText(
|
||||||
CheckerTestUtil.addDiagnosticMarkersToText(ktFile, diagnostics, diagnosticToExpectedDiagnostic, { file -> file.text })
|
ktFile, diagnostics, diagnosticToExpectedDiagnostic, { file -> file.text }, uncheckedDiagnostics, withNewInferenceDirective)
|
||||||
)
|
)
|
||||||
|
|
||||||
stripExtras(actualText)
|
stripExtras(actualText)
|
||||||
@@ -262,7 +277,8 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
|||||||
for (declaration in declarations) {
|
for (declaration in declarations) {
|
||||||
val diagnostics = getJvmSignatureDiagnostics(declaration, bindingContext.diagnostics,
|
val diagnostics = getJvmSignatureDiagnostics(declaration, bindingContext.diagnostics,
|
||||||
GlobalSearchScope.allScope(project)) ?: continue
|
GlobalSearchScope.allScope(project)) ?: continue
|
||||||
jvmSignatureDiagnostics.addAll(diagnostics.forElement(declaration).map { ActualDiagnostic(it, null) })
|
val withNewInference = (customLanguageVersionSettings ?: LanguageVersionSettingsImpl.DEFAULT).supportsFeature(LanguageFeature.NewInference)
|
||||||
|
jvmSignatureDiagnostics.addAll(diagnostics.forElement(declaration).map { ActualDiagnostic(it, null, withNewInference) })
|
||||||
}
|
}
|
||||||
return jvmSignatureDiagnostics
|
return jvmSignatureDiagnostics
|
||||||
}
|
}
|
||||||
@@ -306,6 +322,8 @@ abstract class BaseDiagnosticsTest : KotlinMultiFileTestWithJava<TestModule, Tes
|
|||||||
|
|
||||||
val MARK_DYNAMIC_CALLS_DIRECTIVE = "MARK_DYNAMIC_CALLS"
|
val MARK_DYNAMIC_CALLS_DIRECTIVE = "MARK_DYNAMIC_CALLS"
|
||||||
|
|
||||||
|
val WITH_NEW_INFERENCE_DIRECTIVE = "WITH_NEW_INFERENCE"
|
||||||
|
|
||||||
private fun parseDiagnosticFilterDirective(directiveMap: Map<String, String>, allowUnderscoreUsage: Boolean): Condition<Diagnostic> {
|
private fun parseDiagnosticFilterDirective(directiveMap: Map<String, String>, allowUnderscoreUsage: Boolean): Condition<Diagnostic> {
|
||||||
val directives = directiveMap[DIAGNOSTICS_DIRECTIVE]
|
val directives = directiveMap[DIAGNOSTICS_DIRECTIVE]
|
||||||
val initialCondition =
|
val initialCondition =
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2016 JetBrains s.r.o.
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -79,7 +79,7 @@ import java.util.regex.Pattern;
|
|||||||
import static org.jetbrains.kotlin.checkers.CompilerTestLanguageVersionSettingsKt.parseLanguageVersionSettings;
|
import static org.jetbrains.kotlin.checkers.CompilerTestLanguageVersionSettingsKt.parseLanguageVersionSettings;
|
||||||
import static org.jetbrains.kotlin.cli.common.output.outputUtils.OutputUtilsKt.writeAllTo;
|
import static org.jetbrains.kotlin.cli.common.output.outputUtils.OutputUtilsKt.writeAllTo;
|
||||||
import static org.jetbrains.kotlin.codegen.CodegenTestUtil.*;
|
import static org.jetbrains.kotlin.codegen.CodegenTestUtil.*;
|
||||||
import static org.jetbrains.kotlin.codegen.TestUtilsKt.*;
|
import static org.jetbrains.kotlin.codegen.TestUtilsKt.extractUrls;
|
||||||
import static org.jetbrains.kotlin.test.KotlinTestUtils.getAnnotationsJar;
|
import static org.jetbrains.kotlin.test.KotlinTestUtils.getAnnotationsJar;
|
||||||
import static org.jetbrains.kotlin.test.clientserver.TestProcessServerKt.getBoxMethodOrNull;
|
import static org.jetbrains.kotlin.test.clientserver.TestProcessServerKt.getBoxMethodOrNull;
|
||||||
import static org.jetbrains.kotlin.test.clientserver.TestProcessServerKt.getGeneratedClass;
|
import static org.jetbrains.kotlin.test.clientserver.TestProcessServerKt.getGeneratedClass;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -146,14 +146,14 @@ public class CheckerTestUtilTest extends KotlinTestWithEnvironment {
|
|||||||
|
|
||||||
String expectedText = CheckerTestUtil.addDiagnosticMarkersToText(
|
String expectedText = CheckerTestUtil.addDiagnosticMarkersToText(
|
||||||
psiFile,
|
psiFile,
|
||||||
CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile, false, null, null)
|
CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile, false, null, null, false)
|
||||||
).toString();
|
).toString();
|
||||||
|
|
||||||
List<DiagnosedRange> diagnosedRanges = Lists.newArrayList();
|
List<DiagnosedRange> diagnosedRanges = Lists.newArrayList();
|
||||||
CheckerTestUtil.parseDiagnosedRanges(expectedText, diagnosedRanges);
|
CheckerTestUtil.parseDiagnosedRanges(expectedText, diagnosedRanges);
|
||||||
|
|
||||||
List<ActualDiagnostic> actualDiagnostics =
|
List<ActualDiagnostic> actualDiagnostics =
|
||||||
CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile, false, null, null);
|
CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile, false, null, null, false);
|
||||||
actualDiagnostics.sort(CheckerTestUtil.DIAGNOSTIC_COMPARATOR);
|
actualDiagnostics.sort(CheckerTestUtil.DIAGNOSTIC_COMPARATOR);
|
||||||
|
|
||||||
makeTestData(actualDiagnostics, diagnosedRanges);
|
makeTestData(actualDiagnostics, diagnosedRanges);
|
||||||
@@ -181,6 +181,20 @@ public class CheckerTestUtilTest extends KotlinTestWithEnvironment {
|
|||||||
public void unexpectedDiagnostic(CheckerTestUtil.TextDiagnostic diagnostic, int actualStart, int actualEnd) {
|
public void unexpectedDiagnostic(CheckerTestUtil.TextDiagnostic diagnostic, int actualStart, int actualEnd) {
|
||||||
actualMessages.add(unexpected(diagnostic.getDescription(), actualStart, actualEnd));
|
actualMessages.add(unexpected(diagnostic.getDescription(), actualStart, actualEnd));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void uncheckedDiagnostic(CheckerTestUtil.TextDiagnostic diagnostic, int expectedStart, int expectedEnd) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean shouldUseDiagnosticsForNI() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isWithNewInferenceDirective() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
assertEquals(listToString(expectedMessages), listToString(actualMessages));
|
assertEquals(listToString(expectedMessages), listToString(actualMessages));
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2010-2015 JetBrains s.r.o.
|
* Copyright 2010-2017 JetBrains s.r.o.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -44,7 +44,7 @@ public class CopyAsDiagnosticTestAction extends AnAction {
|
|||||||
BindingContext bindingContext = ResolutionUtils.analyzeFully((KtFile) psiFile);
|
BindingContext bindingContext = ResolutionUtils.analyzeFully((KtFile) psiFile);
|
||||||
|
|
||||||
List<CheckerTestUtil.ActualDiagnostic> diagnostics =
|
List<CheckerTestUtil.ActualDiagnostic> diagnostics =
|
||||||
CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile, false, null, null);
|
CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile, false, null, null, false);
|
||||||
String result = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, diagnostics).toString();
|
String result = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, diagnostics).toString();
|
||||||
|
|
||||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||||
|
|||||||
Reference in New Issue
Block a user