mark syntax errors in QuickJetPsiCheckerTest
This commit is contained in:
@@ -2,8 +2,13 @@ package org.jetbrains.jet.checkers;
|
||||
|
||||
import com.google.common.collect.*;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticFactory;
|
||||
import org.jetbrains.jet.lang.diagnostics.Severity;
|
||||
import org.jetbrains.jet.lang.resolve.AnalyzingUtils;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
|
||||
import java.util.*;
|
||||
@@ -32,6 +37,15 @@ public class CheckerTestUtil {
|
||||
private static final Pattern RANGE_START_OR_END_PATTERN = Pattern.compile("(<!\\w+(,\\s*\\w+)*!>)|(<!>)");
|
||||
private static final Pattern INDIVIDUAL_DIAGNOSTIC_PATTERN = Pattern.compile("\\w+");
|
||||
|
||||
public static List<Diagnostic> getDiagnosticsIncludingSyntaxErrors(BindingContext bindingContext, PsiElement root) {
|
||||
ArrayList<Diagnostic> diagnostics = new ArrayList<Diagnostic>();
|
||||
diagnostics.addAll(bindingContext.getDiagnostics());
|
||||
for (TextRange textRange : AnalyzingUtils.getSyntaxErrorRanges(root)) {
|
||||
diagnostics.add(new SyntaxErrorDiagnostic(textRange));
|
||||
}
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
public interface DiagnosticDiffCallbacks {
|
||||
void missingDiagnostic(String type, int expectedStart, int expectedEnd);
|
||||
void unexpectedDiagnostic(String type, int actualStart, int actualEnd);
|
||||
@@ -144,7 +158,7 @@ public class CheckerTestUtil {
|
||||
Matcher diagnosticTypeMatcher = INDIVIDUAL_DIAGNOSTIC_PATTERN.matcher(matchedText);
|
||||
DiagnosedRange range = new DiagnosedRange(effectiveOffset);
|
||||
while (diagnosticTypeMatcher.find()) {
|
||||
range.addDiagnostic(diagnosticTypeMatcher.group());
|
||||
range.addDiagnostic(diagnosticTypeMatcher.group());
|
||||
}
|
||||
opened.push(range);
|
||||
result.add(range);
|
||||
@@ -158,9 +172,17 @@ public class CheckerTestUtil {
|
||||
return matcher.replaceAll("");
|
||||
}
|
||||
|
||||
public static StringBuffer addDiagnosticMarkersToText(PsiFile psiFile, BindingContext bindingContext) {
|
||||
Collection<Diagnostic> diagnostics = bindingContext.getDiagnostics();
|
||||
public static StringBuffer addDiagnosticMarkersToText(PsiFile psiFile, BindingContext bindingContext, List<TextRange> syntaxErrors) {
|
||||
Collection<Diagnostic> diagnostics = new ArrayList<Diagnostic>();
|
||||
diagnostics.addAll(bindingContext.getDiagnostics());
|
||||
for (TextRange syntaxError : syntaxErrors) {
|
||||
diagnostics.add(new SyntaxErrorDiagnostic(syntaxError));
|
||||
}
|
||||
|
||||
return addDiagnosticMarkersToText(psiFile, diagnostics);
|
||||
}
|
||||
|
||||
public static StringBuffer addDiagnosticMarkersToText(PsiFile psiFile, Collection<Diagnostic> diagnostics) {
|
||||
StringBuffer result = new StringBuffer();
|
||||
String text = psiFile.getText();
|
||||
if (!diagnostics.isEmpty()) {
|
||||
@@ -193,6 +215,14 @@ public class CheckerTestUtil {
|
||||
}
|
||||
result.append(c);
|
||||
}
|
||||
|
||||
if (currentDescriptor != null) {
|
||||
assert currentDescriptor.start == text.length();
|
||||
assert currentDescriptor.end == text.length();
|
||||
openDiagnosticsString(result, currentDescriptor);
|
||||
opened.push(currentDescriptor);
|
||||
}
|
||||
|
||||
while (!opened.isEmpty() && text.length() == opened.peek().end) {
|
||||
closeDiagnosticString(result);
|
||||
opened.pop();
|
||||
@@ -223,6 +253,55 @@ public class CheckerTestUtil {
|
||||
result.append("<!>");
|
||||
}
|
||||
|
||||
private static class SyntaxErrorDiagnosticFactory implements DiagnosticFactory {
|
||||
private static final SyntaxErrorDiagnosticFactory instance = new SyntaxErrorDiagnosticFactory();
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public TextRange getTextRange(@NotNull Diagnostic diagnostic) {
|
||||
return ((SyntaxErrorDiagnostic) diagnostic).textRange;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public PsiFile getPsiFile(@NotNull Diagnostic diagnostic) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getName() {
|
||||
return "SYNTAX";
|
||||
}
|
||||
}
|
||||
|
||||
public static class SyntaxErrorDiagnostic implements Diagnostic {
|
||||
|
||||
private final TextRange textRange;
|
||||
|
||||
public SyntaxErrorDiagnostic(TextRange textRange) {
|
||||
this.textRange = textRange;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public DiagnosticFactory getFactory() {
|
||||
return SyntaxErrorDiagnosticFactory.instance;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public String getMessage() {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Severity getSeverity() {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
}
|
||||
|
||||
private static List<DiagnosticDescriptor> getSortedDiagnosticDescriptors(Collection<Diagnostic> diagnostics) {
|
||||
List<Diagnostic> list = Lists.newArrayList(diagnostics);
|
||||
Collections.sort(list, DIAGNOSTIC_COMPARATOR);
|
||||
@@ -282,6 +361,10 @@ public class CheckerTestUtil {
|
||||
public List<Diagnostic> getDiagnostics() {
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
public TextRange getTextRange() {
|
||||
return new TextRange(start, end);
|
||||
}
|
||||
}
|
||||
|
||||
public static class DiagnosedRange {
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.google.common.base.Predicate;
|
||||
import com.google.common.base.Predicates;
|
||||
import com.google.common.collect.Maps;
|
||||
import com.intellij.openapi.project.Project;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiElementVisitor;
|
||||
import com.intellij.psi.PsiErrorElement;
|
||||
@@ -45,6 +46,22 @@ public class AnalyzingUtils {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public static List<TextRange> getSyntaxErrorRanges(@NotNull PsiElement root) {
|
||||
final ArrayList<TextRange> r = new ArrayList<TextRange>();
|
||||
root.acceptChildren(new PsiElementVisitor() {
|
||||
@Override
|
||||
public void visitElement(PsiElement element) {
|
||||
element.acceptChildren(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitErrorElement(PsiErrorElement element) {
|
||||
r.add(element.getTextRange());
|
||||
}
|
||||
});
|
||||
return r;
|
||||
}
|
||||
|
||||
public static void throwExceptionOnErrors(BindingContext bindingContext) {
|
||||
for (Diagnostic diagnostic : bindingContext.getDiagnostics()) {
|
||||
|
||||
@@ -28,7 +28,7 @@ class WithPC1(a : Int) {
|
||||
}
|
||||
|
||||
|
||||
class Foo() : <!SUPERTYPE_NOT_INITIALIZED, FINAL_SUPERTYPE!>WithPC0<!>, <!MANY_CLASSES_IN_SUPERTYPE_LIST!>this<!>() {
|
||||
class Foo() : <!SUPERTYPE_NOT_INITIALIZED, FINAL_SUPERTYPE!>WithPC0<!>, <!MANY_CLASSES_IN_SUPERTYPE_LIST, SYNTAX!>this<!>() {
|
||||
|
||||
}
|
||||
|
||||
@@ -47,4 +47,4 @@ class <!PRIMARY_CONSTRUCTOR_MISSING_STATEFUL_PROPERTY!>NoCPI<!> {
|
||||
var ab = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>1<!>
|
||||
get() = 1
|
||||
set(v) {}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
namespace return
|
||||
namespace <!SYNTAX!>return<!>
|
||||
|
||||
class A {
|
||||
fun outer() {
|
||||
@@ -14,4 +14,4 @@ class A {
|
||||
<!RETURN_NOT_ALLOWED!>return<!UNRESOLVED_REFERENCE!>@inner<!><!>
|
||||
return@outer
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ class A<E>() : C(), T {
|
||||
super<<!NOT_A_SUPERTYPE!>E<!>>.bar()
|
||||
super<<!NOT_A_SUPERTYPE!>E<!>>@A.bar()
|
||||
super<<!NOT_A_SUPERTYPE!>Int<!>>.foo()
|
||||
super<>.foo()
|
||||
super<<!SYNTAX!><!>>.foo()
|
||||
super<<!NOT_A_SUPERTYPE!>fun() : Unit<!>>.foo()
|
||||
super<<!NOT_A_SUPERTYPE!>()<!>>.foo()
|
||||
super<T><!UNRESOLVED_REFERENCE!>@B<!>.foo()
|
||||
@@ -86,4 +86,4 @@ class A1 {
|
||||
fun test() {
|
||||
<!SUPER_IS_NOT_AN_EXPRESSION!>super<!>.equals(null)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
// dummy test of syntax error highlighing in tests
|
||||
|
||||
fun get() {
|
||||
1 + 2 <!SYNTAX!>2 3 4<!>
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
fun f() {<!SYNTAX!><!>
|
||||
@@ -4,5 +4,5 @@ import java.util.List;
|
||||
|
||||
fun ff(l: Any) = when(l) {
|
||||
is <!CANNOT_CHECK_FOR_ERASED!>List<String><!> => 1
|
||||
else 2
|
||||
else <!SYNTAX!>2<!>
|
||||
}
|
||||
|
||||
+1
-2
@@ -3,5 +3,4 @@
|
||||
fun block(f : fun() : Unit) = f()
|
||||
|
||||
fun bar() = block{ <!UNRESOLVED_REFERENCE!>foo<!>() // <-- missing closing curly bracket
|
||||
fun foo() = block{ <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bar()<!> }
|
||||
|
||||
fun foo() = block{ <!TYPECHECKER_HAS_RUN_INTO_RECURSIVE_PROBLEM!>bar()<!> }<!SYNTAX!><!>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package org.jetbrains.jet.checkers;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.jet.JetLiteFixture;
|
||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||
@@ -82,12 +83,12 @@ public class CheckerTestUtilTest extends JetLiteFixture {
|
||||
|
||||
public void test(PsiFile psiFile) {
|
||||
BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache(AnalyzingUtils.getInstance(ImportingStrategy.NONE), (JetFile) psiFile, AnalyzerFacade.SINGLE_DECLARATION_PROVIDER);
|
||||
String expectedText = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, bindingContext).toString();
|
||||
String expectedText = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile)).toString();
|
||||
|
||||
List<CheckerTestUtil.DiagnosedRange> diagnosedRanges = Lists.newArrayList();
|
||||
CheckerTestUtil.parseDiagnosedRanges(expectedText, diagnosedRanges);
|
||||
|
||||
List<Diagnostic> diagnostics = Lists.newArrayList(bindingContext.getDiagnostics());
|
||||
List<Diagnostic> diagnostics = CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, psiFile);
|
||||
Collections.sort(diagnostics, CheckerTestUtil.DIAGNOSTIC_COMPARATOR);
|
||||
|
||||
makeTestData(diagnostics, diagnosedRanges);
|
||||
|
||||
@@ -47,7 +47,7 @@ public class QuickJetPsiCheckerTest extends JetLiteFixture {
|
||||
|
||||
BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache(AnalyzingUtils.getInstance(importingStrategy), jetFile, AnalyzerFacade.SINGLE_DECLARATION_PROVIDER);
|
||||
|
||||
CheckerTestUtil.diagnosticsDiff(diagnosedRanges, bindingContext.getDiagnostics(), new CheckerTestUtil.DiagnosticDiffCallbacks() {
|
||||
CheckerTestUtil.diagnosticsDiff(diagnosedRanges, CheckerTestUtil.getDiagnosticsIncludingSyntaxErrors(bindingContext, jetFile), new CheckerTestUtil.DiagnosticDiffCallbacks() {
|
||||
@Override
|
||||
public void missingDiagnostic(String type, int expectedStart, int expectedEnd) {
|
||||
String message = "Missing " + type + DiagnosticUtils.atLocation(myFile, new TextRange(expectedStart, expectedEnd));
|
||||
@@ -61,14 +61,14 @@ public class QuickJetPsiCheckerTest extends JetLiteFixture {
|
||||
}
|
||||
});
|
||||
|
||||
String actualText = CheckerTestUtil.addDiagnosticMarkersToText(jetFile, bindingContext).toString();
|
||||
String actualText = CheckerTestUtil.addDiagnosticMarkersToText(jetFile, bindingContext, AnalyzingUtils.getSyntaxErrorRanges(jetFile)).toString();
|
||||
|
||||
assertEquals(expectedText, actualText);
|
||||
|
||||
// convert(new File(myFullDataPath + "/../../checker/"), new File(myFullDataPath));
|
||||
}
|
||||
|
||||
// private void convert(File src, File dest) throws IOException {
|
||||
// private void convert(File src, File dest) throws IOException {
|
||||
// File[] files = src.listFiles();
|
||||
// for (File file : files) {
|
||||
// try {
|
||||
|
||||
@@ -6,11 +6,12 @@ import com.intellij.openapi.actionSystem.LangDataKeys;
|
||||
import com.intellij.openapi.actionSystem.PlatformDataKeys;
|
||||
import com.intellij.openapi.application.ApplicationManager;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.jet.checkers.CheckerTestUtil;
|
||||
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.java.AnalyzerFacade;
|
||||
import org.jetbrains.jet.plugin.compiler.WholeProjectAnalyzerFacade;
|
||||
|
||||
import java.awt.*;
|
||||
@@ -18,6 +19,7 @@ import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.ClipboardOwner;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
@@ -30,8 +32,9 @@ public class CopyAsDiagnosticTestAction extends AnAction {
|
||||
assert editor != null && psiFile != null;
|
||||
|
||||
BindingContext bindingContext = WholeProjectAnalyzerFacade.analyzeProjectWithCacheOnAFile((JetFile) psiFile);
|
||||
List<TextRange> syntaxError = AnalyzingUtils.getSyntaxErrorRanges(psiFile);
|
||||
|
||||
String result = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, bindingContext).toString();
|
||||
String result = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, bindingContext, syntaxError).toString();
|
||||
|
||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
clipboard.setContents(new StringSelection(result), new ClipboardOwner() {
|
||||
|
||||
Reference in New Issue
Block a user