Copy Current File As Diagnostic Test action added
Testing framework with error type support added
This commit is contained in:
@@ -4,7 +4,6 @@ import com.intellij.lang.ASTNode;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.openapi.vfs.VirtualFile;
|
||||
import com.intellij.psi.PsiDocumentManager;
|
||||
import com.intellij.psi.PsiElement;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
@@ -42,8 +41,14 @@ public class DiagnosticUtils {
|
||||
return closestPsiElement.getContainingFile();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String atLocation(@NotNull PsiFile file, @NotNull TextRange textRange) {
|
||||
Document document = PsiDocumentManager.getInstance(file.getProject()).getDocument(file);
|
||||
Document document = file.getViewProvider().getDocument();//PsiDocumentManager.getInstance(file.getProject()).getDocument(file);
|
||||
return atLocation(file, textRange, document);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static String atLocation(PsiFile file, TextRange textRange, Document document) {
|
||||
int offset = textRange.getStartOffset();
|
||||
VirtualFile virtualFile = file.getVirtualFile();
|
||||
String pathSuffix = virtualFile == null ? "" : " in " + virtualFile.getPath();
|
||||
|
||||
@@ -355,6 +355,7 @@ public class CallResolver {
|
||||
|
||||
if (error) {
|
||||
failedCandidates.add(candidate);
|
||||
checkTypesWithNoCallee(temporaryTrace, scope, task.getTypeArguments(), task.getValueArguments(), task.getFunctionLiteralArguments());
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
<keyboard-shortcut keymap="$default" first-keystroke="control shift Q"/>
|
||||
<add-to-group group-id="CodeMenu" anchor="last"/>
|
||||
</action>
|
||||
<action id="CopyAsDiagnosticTest" class="org.jetbrains.jet.plugin.actions.CopyAsDiagnosticTestAction"
|
||||
text="Copy Current File As Diagnostic Test">
|
||||
<keyboard-shortcut keymap="$default" first-keystroke="control alt shift T"/>
|
||||
<add-to-group group-id="CodeMenu" anchor="last"/>
|
||||
</action>
|
||||
<action id="ToggleJetErrorReporting" class="org.jetbrains.jet.plugin.actions.ToggleErrorReportingAction"
|
||||
text="Toggle Error Reporting">
|
||||
<keyboard-shortcut keymap="$default" first-keystroke="control alt shift E"/>
|
||||
|
||||
@@ -0,0 +1,302 @@
|
||||
package org.jetbrains.jet.checkers;
|
||||
|
||||
import com.google.common.collect.*;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class CheckerTestUtil {
|
||||
public static final Comparator<Diagnostic> DIAGNOSTIC_COMPARATOR = new Comparator<Diagnostic>() {
|
||||
@Override
|
||||
public int compare(Diagnostic o1, Diagnostic o2) {
|
||||
TextRange range1 = getTextRange(o1);
|
||||
TextRange range2 = getTextRange(o2);
|
||||
int startOffset1 = range1.getStartOffset();
|
||||
int startOffset2 = range2.getStartOffset();
|
||||
if (startOffset1 != startOffset2) {
|
||||
// Start early -- go first
|
||||
return startOffset1 - range2.getStartOffset();
|
||||
}
|
||||
// start at the same offset, the one who end later is the outer, i.e. goes first
|
||||
return range2.getEndOffset() - range1.getEndOffset();
|
||||
}
|
||||
};
|
||||
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 interface DiagnosticDiffCallbacks {
|
||||
void missingDiagnostic(String type, int expectedStart, int expectedEnd);
|
||||
void unexpectedDiagnostic(String type, int actualStart, int actualEnd);
|
||||
}
|
||||
|
||||
public static void diagnosticsDiff(List<DiagnosedRange> expected, Collection<Diagnostic> actual, DiagnosticDiffCallbacks callbacks) {
|
||||
Iterator<DiagnosedRange> expectedDiagnostics = expected.iterator();
|
||||
List<DiagnosticDescriptor> sortedDiagnosticDescriptors = getSortedDiagnosticDescriptors(actual);
|
||||
Iterator<DiagnosticDescriptor> actualDiagnostics = sortedDiagnosticDescriptors.iterator();
|
||||
|
||||
DiagnosedRange currentExpected = safeAdvance(expectedDiagnostics);
|
||||
DiagnosticDescriptor currentActual = safeAdvance(actualDiagnostics);
|
||||
while (currentExpected != null || currentActual != null) {
|
||||
if (currentExpected != null) {
|
||||
if (currentActual == null) {
|
||||
missingDiagnostics(callbacks, currentExpected);
|
||||
currentExpected = safeAdvance(expectedDiagnostics);
|
||||
}
|
||||
else {
|
||||
int expectedStart = currentExpected.getStart();
|
||||
int actualStart = currentActual.getStart();
|
||||
int expectedEnd = currentExpected.getEnd();
|
||||
int actualEnd = currentActual.getEnd();
|
||||
if (expectedStart < actualStart) {
|
||||
missingDiagnostics(callbacks, currentExpected);
|
||||
currentExpected = safeAdvance(expectedDiagnostics);
|
||||
}
|
||||
else if (expectedStart > actualStart) {
|
||||
unexpectedDiagnostics(currentActual.getDiagnostics(), callbacks);
|
||||
currentActual = safeAdvance(actualDiagnostics);
|
||||
}
|
||||
else if (expectedEnd > actualEnd) {
|
||||
assert expectedStart == actualStart;
|
||||
missingDiagnostics(callbacks, currentExpected);
|
||||
currentExpected = safeAdvance(expectedDiagnostics);
|
||||
}
|
||||
else if (expectedEnd < actualEnd) {
|
||||
assert expectedStart == actualStart;
|
||||
unexpectedDiagnostics(currentActual.getDiagnostics(), callbacks);
|
||||
currentActual = safeAdvance(actualDiagnostics);
|
||||
}
|
||||
else {
|
||||
assert expectedStart == actualStart && expectedEnd == actualEnd;
|
||||
Multiset<String> actualDiagnosticTypes = currentActual.getDiagnosticTypeStrings();
|
||||
Multiset<String> expectedDiagnosticTypes = currentExpected.getDiagnostics();
|
||||
if (!actualDiagnosticTypes.equals(expectedDiagnosticTypes)) {
|
||||
Multiset<String> expectedCopy = HashMultiset.create(expectedDiagnosticTypes);
|
||||
expectedCopy.removeAll(actualDiagnosticTypes);
|
||||
Multiset<String> actualCopy = HashMultiset.create(actualDiagnosticTypes);
|
||||
actualCopy.removeAll(expectedDiagnosticTypes);
|
||||
|
||||
for (String type : expectedCopy) {
|
||||
callbacks.missingDiagnostic(type, expectedStart, expectedEnd);
|
||||
}
|
||||
for (String type : actualCopy) {
|
||||
callbacks.unexpectedDiagnostic(type, actualStart, actualEnd);
|
||||
}
|
||||
}
|
||||
currentExpected = safeAdvance(expectedDiagnostics);
|
||||
currentActual = safeAdvance(actualDiagnostics);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (currentActual != null) {
|
||||
unexpectedDiagnostics(currentActual.getDiagnostics(), callbacks);
|
||||
currentActual = safeAdvance(actualDiagnostics);
|
||||
}
|
||||
else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// assert expectedDiagnostics.hasNext() || actualDiagnostics.hasNext();
|
||||
}
|
||||
}
|
||||
|
||||
private static void unexpectedDiagnostics(List<Diagnostic> actual, DiagnosticDiffCallbacks callbacks) {
|
||||
for (Diagnostic diagnostic : actual) {
|
||||
TextRange textRange = getTextRange(diagnostic);
|
||||
callbacks.unexpectedDiagnostic(diagnostic.getFactory().getName(), textRange.getStartOffset(), textRange.getEndOffset());
|
||||
}
|
||||
}
|
||||
|
||||
private static void missingDiagnostics(DiagnosticDiffCallbacks callbacks, DiagnosedRange currentExpected) {
|
||||
for (String type : currentExpected.getDiagnostics()) {
|
||||
callbacks.missingDiagnostic(type, currentExpected.getStart(), currentExpected.getEnd());
|
||||
}
|
||||
}
|
||||
|
||||
private static <T> T safeAdvance(Iterator<T> iterator) {
|
||||
return iterator.hasNext() ? iterator.next() : null;
|
||||
}
|
||||
|
||||
public static String parseDiagnosedRanges(String text, List<DiagnosedRange> result) {
|
||||
Matcher matcher = RANGE_START_OR_END_PATTERN.matcher(text);
|
||||
|
||||
Stack<DiagnosedRange> opened = new Stack<DiagnosedRange>();
|
||||
|
||||
int offsetCompensation = 0;
|
||||
|
||||
while (matcher.find()) {
|
||||
int effectiveOffset = matcher.start() - offsetCompensation;
|
||||
String matchedText = matcher.group();
|
||||
if ("<!>".equals(matchedText)) {
|
||||
opened.pop().setEnd(effectiveOffset);
|
||||
}
|
||||
else {
|
||||
Matcher diagnosticTypeMatcher = INDIVIDUAL_DIAGNOSTIC_PATTERN.matcher(matchedText);
|
||||
DiagnosedRange range = new DiagnosedRange(effectiveOffset);
|
||||
while (diagnosticTypeMatcher.find()) {
|
||||
range.addDiagnostic(diagnosticTypeMatcher.group());
|
||||
}
|
||||
opened.push(range);
|
||||
result.add(range);
|
||||
}
|
||||
offsetCompensation += matchedText.length();
|
||||
}
|
||||
|
||||
matcher.reset();
|
||||
return matcher.replaceAll("");
|
||||
}
|
||||
|
||||
public static StringBuffer addDiagnosticMarkersToText(PsiFile psiFile, BindingContext bindingContext) {
|
||||
Collection<Diagnostic> diagnostics = bindingContext.getDiagnostics();
|
||||
|
||||
StringBuffer result = new StringBuffer();
|
||||
String text = psiFile.getText();
|
||||
if (!diagnostics.isEmpty()) {
|
||||
List<DiagnosticDescriptor> diagnosticDescriptors = getSortedDiagnosticDescriptors(diagnostics);
|
||||
|
||||
Stack<DiagnosticDescriptor> opened = new Stack<DiagnosticDescriptor>();
|
||||
ListIterator<DiagnosticDescriptor> iterator = diagnosticDescriptors.listIterator();
|
||||
DiagnosticDescriptor currentDescriptor = iterator.next();
|
||||
|
||||
for (int i = 0; i < text.length(); i++) {
|
||||
char c = text.charAt(i);
|
||||
while (!opened.isEmpty() && i == opened.peek().end) {
|
||||
closeDiagnosticString(result);
|
||||
opened.pop();
|
||||
}
|
||||
if (currentDescriptor != null && i == currentDescriptor.start) {
|
||||
openDiagnosticsString(result, currentDescriptor);
|
||||
opened.push(currentDescriptor);
|
||||
if (iterator.hasNext()) {
|
||||
currentDescriptor = iterator.next();
|
||||
}
|
||||
else {
|
||||
currentDescriptor = null;
|
||||
}
|
||||
}
|
||||
result.append(c);
|
||||
}
|
||||
}
|
||||
else {
|
||||
result.append(text);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void openDiagnosticsString(StringBuffer result, DiagnosticDescriptor currentDescriptor) {
|
||||
result.append("<!");
|
||||
for (Iterator<Diagnostic> iterator = currentDescriptor.diagnostics.iterator(); iterator.hasNext(); ) {
|
||||
Diagnostic diagnostic = iterator.next();
|
||||
result.append(diagnostic.getFactory().getName());
|
||||
if (iterator.hasNext()) {
|
||||
result.append(", ");
|
||||
}
|
||||
}
|
||||
result.append("!>");
|
||||
}
|
||||
|
||||
private static void closeDiagnosticString(StringBuffer result) {
|
||||
result.append("<!>");
|
||||
}
|
||||
|
||||
private static List<DiagnosticDescriptor> getSortedDiagnosticDescriptors(Collection<Diagnostic> diagnostics) {
|
||||
List<Diagnostic> list = Lists.newArrayList(diagnostics);
|
||||
Collections.sort(list, DIAGNOSTIC_COMPARATOR);
|
||||
|
||||
List<DiagnosticDescriptor> diagnosticDescriptors = Lists.newArrayList();
|
||||
DiagnosticDescriptor currentDiagnosticDescriptor = null;
|
||||
for (Iterator<Diagnostic> iterator = list.iterator(); iterator.hasNext(); ) {
|
||||
Diagnostic diagnostic = iterator.next();
|
||||
|
||||
TextRange textRange = getTextRange(diagnostic);
|
||||
if (currentDiagnosticDescriptor != null && currentDiagnosticDescriptor.equalRange(textRange)) {
|
||||
currentDiagnosticDescriptor.diagnostics.add(diagnostic);
|
||||
}
|
||||
else {
|
||||
currentDiagnosticDescriptor = new DiagnosticDescriptor(textRange.getStartOffset(), textRange.getEndOffset(), diagnostic);
|
||||
diagnosticDescriptors.add(currentDiagnosticDescriptor);
|
||||
}
|
||||
}
|
||||
return diagnosticDescriptors;
|
||||
}
|
||||
|
||||
private static TextRange getTextRange(Diagnostic currentDiagnostic) {
|
||||
return currentDiagnostic.getFactory().getTextRange(currentDiagnostic);
|
||||
}
|
||||
|
||||
private static class DiagnosticDescriptor {
|
||||
private final int start;
|
||||
private final int end;
|
||||
private final List<Diagnostic> diagnostics = Lists.newArrayList();
|
||||
|
||||
DiagnosticDescriptor(int start, int end, Diagnostic diagnostic) {
|
||||
this.start = start;
|
||||
this.end = end;
|
||||
this.diagnostics.add(diagnostic);
|
||||
}
|
||||
|
||||
public boolean equalRange(TextRange textRange) {
|
||||
return start == textRange.getStartOffset() && end == textRange.getEndOffset();
|
||||
}
|
||||
|
||||
public Multiset<String> getDiagnosticTypeStrings() {
|
||||
Multiset<String> actualDiagnosticTypes = HashMultiset.create();
|
||||
for (Diagnostic diagnostic : diagnostics) {
|
||||
actualDiagnosticTypes.add(diagnostic.getFactory().getName());
|
||||
}
|
||||
return actualDiagnosticTypes;
|
||||
}
|
||||
|
||||
public int getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public int getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
public List<Diagnostic> getDiagnostics() {
|
||||
return diagnostics;
|
||||
}
|
||||
}
|
||||
|
||||
public static class DiagnosedRange {
|
||||
private final int start;
|
||||
private int end;
|
||||
private final Multiset<String> diagnostics = HashMultiset.create();
|
||||
|
||||
private DiagnosedRange(int start) {
|
||||
this.start = start;
|
||||
}
|
||||
|
||||
public int getStart() {
|
||||
return start;
|
||||
}
|
||||
|
||||
public int getEnd() {
|
||||
return end;
|
||||
}
|
||||
|
||||
public Multiset<String> getDiagnostics() {
|
||||
return diagnostics;
|
||||
}
|
||||
|
||||
public void setEnd(int end) {
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
public void addDiagnostic(String diagnostic) {
|
||||
diagnostics.add(diagnostic);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
package org.jetbrains.jet.plugin.actions;
|
||||
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.actionSystem.AnActionEvent;
|
||||
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.psi.PsiFile;
|
||||
import org.jetbrains.jet.checkers.CheckerTestUtil;
|
||||
import org.jetbrains.jet.lang.psi.JetFile;
|
||||
import org.jetbrains.jet.lang.resolve.BindingContext;
|
||||
import org.jetbrains.jet.plugin.AnalyzerFacade;
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.datatransfer.Clipboard;
|
||||
import java.awt.datatransfer.ClipboardOwner;
|
||||
import java.awt.datatransfer.StringSelection;
|
||||
import java.awt.datatransfer.Transferable;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class CopyAsDiagnosticTestAction extends AnAction {
|
||||
@Override
|
||||
public void actionPerformed(AnActionEvent e) {
|
||||
Editor editor = e.getData(PlatformDataKeys.EDITOR);
|
||||
PsiFile psiFile = e.getData(LangDataKeys.PSI_FILE);
|
||||
assert editor != null && psiFile != null;
|
||||
|
||||
BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache((JetFile) psiFile);
|
||||
|
||||
String result = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, bindingContext).toString();
|
||||
|
||||
Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
|
||||
clipboard.setContents(new StringSelection(result), new ClipboardOwner() {
|
||||
@Override
|
||||
public void lostOwnership(Clipboard clipboard, Transferable contents) {}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void update(AnActionEvent e) {
|
||||
Editor editor = e.getData(PlatformDataKeys.EDITOR);
|
||||
PsiFile psiFile = e.getData(LangDataKeys.PSI_FILE);
|
||||
e.getPresentation().setEnabled(editor != null && psiFile instanceof JetFile && ApplicationManager.getApplication().isInternal());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fun foo(u : Unit) : Int = 1
|
||||
|
||||
fun test() : Int {
|
||||
foo(1)
|
||||
val a : fun() : Unit = {
|
||||
foo(1)
|
||||
}
|
||||
return 1 - "1"
|
||||
}
|
||||
|
||||
class A() {
|
||||
val x : Int = foo1(xx)
|
||||
}
|
||||
|
||||
fun foo1() {}
|
||||
@@ -0,0 +1,241 @@
|
||||
namespace abstract
|
||||
|
||||
class MyClass() {
|
||||
//properties
|
||||
val <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>a<!>: Int
|
||||
val a1: Int = 1
|
||||
<!ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS!>abstract<!> val a2: Int
|
||||
<!ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS!>abstract<!> val a3: Int = 1
|
||||
|
||||
var <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>b<!>: Int private set
|
||||
var b1: Int = 0; private set
|
||||
<!ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS!>abstract<!> var b2: Int private set
|
||||
<!ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS!>abstract<!> var b3: Int = 0; private set
|
||||
|
||||
var <!MUST_BE_INITIALIZED!>c<!>: Int set(v: Int) { $c = v }
|
||||
var c1: Int = 0; set(v: Int) { $c1 = v }
|
||||
<!ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS!>abstract<!> var c2: Int set(v: Int) { $c2 = v }
|
||||
<!ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS!>abstract<!> var c3: Int = 0; set(v: Int) { $c3 = v }
|
||||
|
||||
val e: Int get() = a
|
||||
val e1: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>0<!>; get() = a
|
||||
<!ABSTRACT_PROPERTY_IN_NN_ABSTRACT_CLASS!>abstract<!> val e2: Int get() = a
|
||||
<!ABSTRACT_PROPERTY_IN_NON_ABSTRACT_CLASS!>abstract<!> val e3: Int = 0; get() = a
|
||||
|
||||
//methods
|
||||
fun <!NON_ABSTRACT_FUNCTION_WITH_NO_BODY!>f<!>()
|
||||
fun g() {}
|
||||
<!ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS!>abstract<!> fun h()
|
||||
<!ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS, ABSTRACT_FUNCTION_WITH_BODY!>abstract<!> fun j() {}
|
||||
|
||||
//property accessors
|
||||
var i: Int <!ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS!>abstract<!> get <!ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS!>abstract<!> set
|
||||
var i1: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>0<!>; <!ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS!>abstract<!> get <!ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS!>abstract<!> set
|
||||
|
||||
var j: Int get() = i; <!ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS!>abstract<!> set
|
||||
var j1: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>0<!>; get() = i; <!ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS!>abstract<!> set
|
||||
|
||||
var <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>k<!>: Int <!ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS!>abstract<!> set
|
||||
var k1: Int = 0; <!ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS!>abstract<!> set
|
||||
|
||||
var l: Int <!ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS!>abstract<!> get <!ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS!>abstract<!> set
|
||||
var l1: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>0<!>; <!ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS!>abstract<!> get <!ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS!>abstract<!> set
|
||||
|
||||
var n: Int <!ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS!>abstract<!> get <!ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS, ABSTRACT_FUNCTION_WITH_BODY!>abstract<!> set(v: Int) {}
|
||||
}
|
||||
|
||||
abstract class MyAbstractClass() {
|
||||
//properties
|
||||
val <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>a<!>: Int
|
||||
val a1: Int = 1
|
||||
abstract val a2: Int
|
||||
abstract val a3: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>1<!>
|
||||
|
||||
var <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>b<!>: Int private set
|
||||
var b1: Int = 0; private set
|
||||
abstract var b2: Int private set
|
||||
abstract var b3: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>0<!>; private set
|
||||
|
||||
var <!MUST_BE_INITIALIZED!>c<!>: Int set(v: Int) { $c = v }
|
||||
var c1: Int = 0; set(v: Int) { $c1 = v }
|
||||
abstract var c2: Int <!ABSTRACT_PROPERTY_WITH_SETTER!>set(v: Int) { $c2 = v }<!>
|
||||
abstract var c3: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>0<!>; <!ABSTRACT_PROPERTY_WITH_SETTER!>set(v: Int) { $c3 = v }<!>
|
||||
|
||||
val e: Int get() = a
|
||||
val e1: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>0<!>; get() = a
|
||||
abstract val e2: Int <!ABSTRACT_PROPERTY_WITH_GETTER!>get() = a<!>
|
||||
abstract val e3: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>0<!>; <!ABSTRACT_PROPERTY_WITH_GETTER!>get() = a<!>
|
||||
|
||||
//methods
|
||||
fun <!NON_ABSTRACT_FUNCTION_WITH_NO_BODY!>f<!>()
|
||||
fun g() {}
|
||||
abstract fun h()
|
||||
<!ABSTRACT_FUNCTION_WITH_BODY!>abstract<!> fun j() {}
|
||||
|
||||
//property accessors
|
||||
var i: Int abstract get abstract set
|
||||
var i1: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>0<!>; abstract get abstract set
|
||||
|
||||
var j: Int get() = i; abstract set
|
||||
var j1: Int get() = i; abstract set
|
||||
|
||||
var <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>k<!>: Int abstract set
|
||||
var k1: Int = 0; abstract set
|
||||
|
||||
var l: Int abstract get abstract set
|
||||
var l1: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>0<!>; abstract get abstract set
|
||||
|
||||
var n: Int abstract get <!ABSTRACT_FUNCTION_WITH_BODY!>abstract<!> set(v: Int) {}
|
||||
}
|
||||
|
||||
trait MyTrait {
|
||||
//properties
|
||||
val a: Int
|
||||
val a1: Int = <!PROPERTY_INITIALIZER_IN_TRAIT!>1<!>
|
||||
<!REDUNDANT_ABSTRACT!>abstract<!> val a2: Int
|
||||
<!REDUNDANT_ABSTRACT!>abstract<!> val a3: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>1<!>
|
||||
|
||||
var b: Int private set
|
||||
var b1: Int = <!PROPERTY_INITIALIZER_IN_TRAIT!>0<!>; private set
|
||||
<!REDUNDANT_ABSTRACT!>abstract<!> var b2: Int private set
|
||||
<!REDUNDANT_ABSTRACT!>abstract<!> var b3: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>0<!>; private set
|
||||
|
||||
var <!BACKING_FIELD_IN_TRAIT!>c<!>: Int set(v: Int) { $c = v }
|
||||
var <!BACKING_FIELD_IN_TRAIT!>c1<!>: Int = <!PROPERTY_INITIALIZER_IN_TRAIT!>0<!>; set(v: Int) { $c1 = v }
|
||||
<!REDUNDANT_ABSTRACT!>abstract<!> var c2: Int <!ABSTRACT_PROPERTY_WITH_SETTER!>set(v: Int) { $c2 = v }<!>
|
||||
<!REDUNDANT_ABSTRACT!>abstract<!> var c3: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>0<!>; <!ABSTRACT_PROPERTY_WITH_SETTER!>set(v: Int) { $c3 = v }<!>
|
||||
|
||||
val e: Int get() = a
|
||||
val e1: Int = <!PROPERTY_INITIALIZER_IN_TRAIT!>0<!>; get() = a
|
||||
<!REDUNDANT_ABSTRACT!>abstract<!> val e2: Int <!ABSTRACT_PROPERTY_WITH_GETTER!>get() = a<!>
|
||||
<!REDUNDANT_ABSTRACT!>abstract<!> val e3: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>0<!>; <!ABSTRACT_PROPERTY_WITH_GETTER!>get() = a<!>
|
||||
|
||||
//methods
|
||||
fun f()
|
||||
fun g() {}
|
||||
<!REDUNDANT_ABSTRACT!>abstract<!> fun h()
|
||||
<!REDUNDANT_ABSTRACT, ABSTRACT_FUNCTION_WITH_BODY!>abstract<!> fun j() {}
|
||||
|
||||
//property accessors
|
||||
var i: Int abstract get abstract set
|
||||
var i1: Int = <!PROPERTY_INITIALIZER_IN_TRAIT!>0<!>; abstract get abstract set
|
||||
|
||||
var j: Int get() = i; abstract set
|
||||
var j1: Int = <!PROPERTY_INITIALIZER_IN_TRAIT!>0<!>; get() = i; abstract set
|
||||
|
||||
var k: Int abstract set
|
||||
var k1: Int = <!PROPERTY_INITIALIZER_IN_TRAIT!>0<!>; abstract set
|
||||
|
||||
var l: Int abstract get abstract set
|
||||
var l1: Int = <!PROPERTY_INITIALIZER_IN_TRAIT!>0<!>; abstract get abstract set
|
||||
|
||||
var n: Int abstract get <!ABSTRACT_FUNCTION_WITH_BODY!>abstract<!> set(v: Int) {}
|
||||
}
|
||||
|
||||
enum class MyEnum() {
|
||||
//properties
|
||||
val <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>a<!>: Int
|
||||
val a1: Int = 1
|
||||
abstract val a2: Int
|
||||
abstract val a3: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>1<!>
|
||||
|
||||
var <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>b<!>: Int private set
|
||||
var b1: Int = 0; private set
|
||||
abstract var b2: Int private set
|
||||
abstract var b3: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>0<!>; private set
|
||||
|
||||
var <!MUST_BE_INITIALIZED!>c<!>: Int set(v: Int) { $c = v }
|
||||
var c1: Int = 0; set(v: Int) { $c1 = v }
|
||||
abstract var c2: Int <!ABSTRACT_PROPERTY_WITH_SETTER!>set(v: Int) { $c2 = v }<!>
|
||||
abstract var c3: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>0<!>; <!ABSTRACT_PROPERTY_WITH_SETTER!>set(v: Int) { $c3 = v }<!>
|
||||
|
||||
val e: Int get() = a
|
||||
val e1: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>0<!>; get() = a
|
||||
abstract val e2: Int <!ABSTRACT_PROPERTY_WITH_GETTER!>get() = a<!>
|
||||
abstract val e3: Int = <!ABSTRACT_PROPERTY_WITH_INITIALIZER!>0<!>; <!ABSTRACT_PROPERTY_WITH_GETTER!>get() = a<!>
|
||||
|
||||
//methods
|
||||
fun <!NON_ABSTRACT_FUNCTION_WITH_NO_BODY!>f<!>()
|
||||
fun g() {}
|
||||
abstract fun h()
|
||||
<!ABSTRACT_FUNCTION_WITH_BODY!>abstract<!> fun j() {}
|
||||
|
||||
//property accessors
|
||||
var i: Int abstract get abstract set
|
||||
var i1: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>0<!>; abstract get abstract set
|
||||
|
||||
var j: Int get() = i; abstract set
|
||||
var j1: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>0<!>; get() = i; abstract set
|
||||
|
||||
var <!MUST_BE_INITIALIZED_OR_BE_ABSTRACT!>k<!>: Int abstract set
|
||||
var k1: Int = 0; abstract set
|
||||
|
||||
var l: Int abstract get abstract set
|
||||
var l1: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>0<!>; abstract get abstract set
|
||||
|
||||
var n: Int abstract get <!ABSTRACT_FUNCTION_WITH_BODY!>abstract<!> set(v: Int) {}
|
||||
}
|
||||
|
||||
abstract enum class MyAbstractEnum() {}
|
||||
|
||||
namespace MyNamespace {
|
||||
//properties
|
||||
val <!MUST_BE_INITIALIZED!>a<!>: Int
|
||||
val a1: Int = 1
|
||||
<!ABSTRACT_PROPERTY_NOT_IN_CLASS!>abstract<!> val a2: Int
|
||||
<!ABSTRACT_PROPERTY_NOT_IN_CLASS!>abstract<!> val a3: Int = 1
|
||||
|
||||
var <!MUST_BE_INITIALIZED!>b<!>: Int private set
|
||||
var b1: Int = 0; private set
|
||||
<!ABSTRACT_PROPERTY_NOT_IN_CLASS!>abstract<!> var b2: Int private set
|
||||
<!ABSTRACT_PROPERTY_NOT_IN_CLASS!>abstract<!> var b3: Int = 0; private set
|
||||
|
||||
var <!MUST_BE_INITIALIZED!>c<!>: Int set(v: Int) { $c = v }
|
||||
var c1: Int = 0; set(v: Int) { $c1 = v }
|
||||
<!ABSTRACT_PROPERTY_NOT_IN_CLASS!>abstract<!> var c2: Int set(v: Int) { $c2 = v }
|
||||
<!ABSTRACT_PROPERTY_NOT_IN_CLASS!>abstract<!> var c3: Int = 0; set(v: Int) { $c3 = v }
|
||||
|
||||
val e: Int get() = a
|
||||
val e1: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>0<!>; get() = a
|
||||
<!ABSTRACT_PROPERTY_NOT_IN_CLASS!>abstract<!> val e2: Int get() = a
|
||||
<!ABSTRACT_PROPERTY_NOT_IN_CLASS!>abstract<!> val e3: Int = 0; get() = a
|
||||
|
||||
//methods
|
||||
fun <!NON_MEMBER_FUNCTION_NO_BODY!>f<!>()
|
||||
fun g() {}
|
||||
<!NON_MEMBER_ABSTRACT_FUNCTION!>abstract<!> fun h()
|
||||
<!NON_MEMBER_ABSTRACT_FUNCTION!>abstract<!> fun j() {}
|
||||
|
||||
//property accessors
|
||||
var i: Int <!NON_MEMBER_ABSTRACT_ACCESSOR!>abstract<!> get <!NON_MEMBER_ABSTRACT_ACCESSOR!>abstract<!> set
|
||||
var i1: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>0<!>; <!NON_MEMBER_ABSTRACT_ACCESSOR!>abstract<!> get <!NON_MEMBER_ABSTRACT_ACCESSOR!>abstract<!> set
|
||||
|
||||
var j: Int get() = i; <!NON_MEMBER_ABSTRACT_ACCESSOR!>abstract<!> set
|
||||
var j1: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>0<!>; get() = i; <!NON_MEMBER_ABSTRACT_ACCESSOR!>abstract<!> set
|
||||
|
||||
var <!MUST_BE_INITIALIZED!>k<!>: Int <!NON_MEMBER_ABSTRACT_ACCESSOR!>abstract<!> set
|
||||
var k1: Int = 0; <!NON_MEMBER_ABSTRACT_ACCESSOR!>abstract<!> set
|
||||
|
||||
var l: Int <!NON_MEMBER_ABSTRACT_ACCESSOR!>abstract<!> get <!NON_MEMBER_ABSTRACT_ACCESSOR!>abstract<!> set
|
||||
var l1: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>0<!>; <!NON_MEMBER_ABSTRACT_ACCESSOR!>abstract<!> get <!NON_MEMBER_ABSTRACT_ACCESSOR!>abstract<!> set
|
||||
|
||||
var n: Int <!NON_MEMBER_ABSTRACT_ACCESSOR!>abstract<!> get <!NON_MEMBER_ABSTRACT_ACCESSOR!>abstract<!> set(v: Int) {}
|
||||
}
|
||||
|
||||
//creating an instance
|
||||
abstract class B1(
|
||||
val i: Int,
|
||||
val s: String
|
||||
) {
|
||||
}
|
||||
|
||||
class B2() : B1(1, "r") {}
|
||||
|
||||
abstract class B3(i: Int) {
|
||||
this(): this(1)
|
||||
}
|
||||
|
||||
fun foo(a: B3) {
|
||||
val a = <!CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS!>B3()<!>
|
||||
val b = <!CREATING_AN_INSTANCE_OF_ABSTRACT_CLASS!>B1(2, "s")<!>
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
fun foo(u : Unit) : Int = 1
|
||||
|
||||
fun test() : Int {
|
||||
foo(<!TYPE_MISMATCH!>1<!>)
|
||||
val a : fun() : Unit = {
|
||||
foo(<!TYPE_MISMATCH!>1<!>)
|
||||
}
|
||||
return 1 <!NONE_APPLICABLE!>-<!> "1"
|
||||
}
|
||||
|
||||
class A() {
|
||||
val x : Int = <!TYPE_MISMATCH!>foo1(<!TOO_MANY_ARGUMENTS, UNRESOLVED_REFERENCE!>xx<!>)<!>
|
||||
}
|
||||
|
||||
fun foo1() {}
|
||||
@@ -0,0 +1,189 @@
|
||||
package org.jetbrains.jet;
|
||||
|
||||
import com.intellij.ide.startup.impl.StartupManagerImpl;
|
||||
import com.intellij.lang.*;
|
||||
import com.intellij.lang.impl.PsiBuilderFactoryImpl;
|
||||
import com.intellij.mock.*;
|
||||
import com.intellij.openapi.Disposable;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.EditorFactory;
|
||||
import com.intellij.openapi.fileEditor.FileDocumentManager;
|
||||
import com.intellij.openapi.fileEditor.impl.FileDocumentManagerImpl;
|
||||
import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
|
||||
import com.intellij.openapi.fileTypes.FileTypeFactory;
|
||||
import com.intellij.openapi.fileTypes.FileTypeManager;
|
||||
import com.intellij.openapi.options.SchemesManagerFactory;
|
||||
import com.intellij.openapi.progress.impl.ProgressManagerImpl;
|
||||
import com.intellij.openapi.startup.StartupManager;
|
||||
import com.intellij.openapi.util.Disposer;
|
||||
import com.intellij.openapi.util.io.FileUtil;
|
||||
import com.intellij.openapi.util.text.StringUtil;
|
||||
import com.intellij.openapi.vfs.CharsetToolkit;
|
||||
import com.intellij.psi.*;
|
||||
import com.intellij.psi.impl.PsiCachedValuesFactory;
|
||||
import com.intellij.psi.impl.PsiFileFactoryImpl;
|
||||
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
|
||||
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistryImpl;
|
||||
import com.intellij.psi.util.CachedValuesManager;
|
||||
import com.intellij.testFramework.LightVirtualFile;
|
||||
import com.intellij.testFramework.MockSchemesManagerFactory;
|
||||
import com.intellij.testFramework.PlatformLiteFixture;
|
||||
import com.intellij.testFramework.TestDataFile;
|
||||
import com.intellij.util.CachedValuesManagerImpl;
|
||||
import com.intellij.util.Function;
|
||||
import com.intellij.util.messages.MessageBus;
|
||||
import com.intellij.util.messages.MessageBusFactory;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.jet.lang.parsing.JetParserDefinition;
|
||||
import org.picocontainer.MutablePicoContainer;
|
||||
import org.picocontainer.PicoContainer;
|
||||
import org.picocontainer.PicoInitializationException;
|
||||
import org.picocontainer.PicoIntrospectionException;
|
||||
import org.picocontainer.defaults.AbstractComponentAdapter;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class JetLiteFixture extends PlatformLiteFixture {
|
||||
protected String myFileExt;
|
||||
@NonNls
|
||||
protected final String myFullDataPath;
|
||||
protected PsiFile myFile;
|
||||
private MockPsiManager myPsiManager;
|
||||
private PsiFileFactoryImpl myFileFactory;
|
||||
protected Language myLanguage;
|
||||
protected final ParserDefinition[] myDefinitions;
|
||||
|
||||
public JetLiteFixture(@NonNls String dataPath) {
|
||||
myFileExt = "jet";
|
||||
myFullDataPath = getTestDataPath() + "/" + dataPath;
|
||||
myDefinitions = new ParserDefinition[] {new JetParserDefinition()};
|
||||
}
|
||||
|
||||
protected String getTestDataPath() {
|
||||
return JetTestCaseBase.getTestDataPathBase();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setUp() throws Exception {
|
||||
super.setUp();
|
||||
initApplication();
|
||||
getApplication().getPicoContainer().registerComponent(new AbstractComponentAdapter("com.intellij.openapi.progress.ProgressManager", Object.class) {
|
||||
@Override
|
||||
public Object getComponentInstance(PicoContainer container) throws PicoInitializationException, PicoIntrospectionException {
|
||||
return new ProgressManagerImpl(getApplication());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void verify(PicoContainer container) throws PicoIntrospectionException {
|
||||
}
|
||||
});
|
||||
myProject = disposeOnTearDown(new MockProjectEx());
|
||||
myPsiManager = new MockPsiManager(myProject);
|
||||
myFileFactory = new PsiFileFactoryImpl(myPsiManager);
|
||||
final MutablePicoContainer appContainer = getApplication().getPicoContainer();
|
||||
registerComponentInstance(appContainer, MessageBus.class, MessageBusFactory.newMessageBus(getApplication()));
|
||||
registerComponentInstance(appContainer, SchemesManagerFactory.class, new MockSchemesManagerFactory());
|
||||
final MockEditorFactory editorFactory = new MockEditorFactory();
|
||||
registerComponentInstance(appContainer, EditorFactory.class, editorFactory);
|
||||
registerComponentInstance(appContainer, FileDocumentManager.class, new MockFileDocumentManagerImpl(new Function<CharSequence, Document>() {
|
||||
@Override
|
||||
public Document fun(CharSequence charSequence) {
|
||||
return editorFactory.createDocument(charSequence);
|
||||
}
|
||||
}, FileDocumentManagerImpl.DOCUMENT_KEY));
|
||||
registerComponentInstance(appContainer, PsiDocumentManager.class, new MockPsiDocumentManager());
|
||||
myLanguage = myLanguage == null && myDefinitions != null && myDefinitions.length > 0
|
||||
? myDefinitions[0].getFileNodeType().getLanguage()
|
||||
: myLanguage;
|
||||
registerComponentInstance(appContainer, FileTypeManager.class, new MockFileTypeManager(new MockLanguageFileType(myLanguage, myFileExt)));
|
||||
registerApplicationService(PsiBuilderFactory.class, new PsiBuilderFactoryImpl());
|
||||
registerApplicationService(DefaultASTFactory.class, new DefaultASTFactoryImpl());
|
||||
registerApplicationService(ReferenceProvidersRegistry.class, new ReferenceProvidersRegistryImpl());
|
||||
myProject.registerService(CachedValuesManager.class, new CachedValuesManagerImpl(myProject, new PsiCachedValuesFactory(myPsiManager)));
|
||||
myProject.registerService(PsiManager.class, myPsiManager);
|
||||
myProject.registerService(StartupManager.class, new StartupManagerImpl(myProject));
|
||||
myProject.registerService(PsiFileFactory.class, new PsiFileFactoryImpl(myPsiManager));
|
||||
|
||||
registerExtensionPoint(FileTypeFactory.FILE_TYPE_FACTORY_EP, FileTypeFactory.class);
|
||||
|
||||
for (ParserDefinition definition : myDefinitions) {
|
||||
addExplicitExtension(LanguageParserDefinitions.INSTANCE, definition.getFileNodeType().getLanguage(), definition);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void tearDown() throws Exception {
|
||||
super.tearDown();
|
||||
myFile = null;
|
||||
myProject = null;
|
||||
myPsiManager = null;
|
||||
}
|
||||
|
||||
protected String loadFile(@NonNls @TestDataFile String name) throws IOException {
|
||||
return doLoadFile(myFullDataPath, name);
|
||||
}
|
||||
|
||||
private static String doLoadFile(String myFullDataPath, String name) throws IOException {
|
||||
String fullName = myFullDataPath + File.separatorChar + name;
|
||||
String text = FileUtil.loadFile(new File(fullName), CharsetToolkit.UTF8).trim();
|
||||
text = StringUtil.convertLineSeparators(text);
|
||||
return text;
|
||||
}
|
||||
|
||||
protected PsiFile createPsiFile(String name, String text) {
|
||||
return createFile(name + "." + myFileExt, text);
|
||||
}
|
||||
|
||||
protected PsiFile createFile(@NonNls String name, String text) {
|
||||
LightVirtualFile virtualFile = new LightVirtualFile(name, myLanguage, text);
|
||||
virtualFile.setCharset(CharsetToolkit.UTF8_CHARSET);
|
||||
return myFileFactory.trySetupPsiForFile(virtualFile, myLanguage, true, false);
|
||||
}
|
||||
|
||||
protected static void ensureParsed(PsiFile file) {
|
||||
file.accept(new PsiElementVisitor() {
|
||||
@Override
|
||||
public void visitElement(PsiElement element) {
|
||||
element.acceptChildren(this);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected <T> void registerApplicationService(final Class<T> aClass, T object) {
|
||||
getApplication().registerService(aClass, object);
|
||||
Disposer.register(myProject, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
getApplication().getPicoContainer().unregisterComponent(aClass.getName());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected <T> void addExplicitExtension(final LanguageExtension<T> instance, final Language language, final T object) {
|
||||
instance.addExplicitExtension(language, object);
|
||||
Disposer.register(myProject, new Disposable() {
|
||||
@Override
|
||||
public void dispose() {
|
||||
instance.removeExplicitExtension(language, object);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
protected void prepareForTest(String name) throws IOException {
|
||||
String text = loadFile(name + "." + myFileExt);
|
||||
createAndCheckPsiFile(name, text);
|
||||
}
|
||||
|
||||
protected void createAndCheckPsiFile(String name, String text) {
|
||||
myFile = createPsiFile(name, text);
|
||||
ensureParsed(myFile);
|
||||
assertEquals("light virtual file text mismatch", text, ((LightVirtualFile) myFile.getVirtualFile()).getContent().toString());
|
||||
assertEquals("virtual file text mismatch", text, LoadTextUtil.loadText(myFile.getVirtualFile()));
|
||||
assertEquals("doc text mismatch", text, myFile.getViewProvider().getDocument().getText());
|
||||
assertEquals("psi text mismatch", text, myFile.getText());
|
||||
}
|
||||
}
|
||||
@@ -43,11 +43,11 @@ public abstract class JetTestCaseBase extends LightDaemonAnalyzerTestCase {
|
||||
return getTestDataPathBase();
|
||||
}
|
||||
|
||||
protected static String getTestDataPathBase() {
|
||||
public static String getTestDataPathBase() {
|
||||
return getHomeDirectory() + "/idea/testData";
|
||||
}
|
||||
|
||||
private static String getHomeDirectory() {
|
||||
public static String getHomeDirectory() {
|
||||
return new File(PathManager.getResourceRoot(JetTestCaseBase.class, "/org/jetbrains/jet/JetTestCaseBase.class")).getParentFile().getParentFile().getParent();
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,125 @@
|
||||
package org.jetbrains.jet.checkers;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.psi.PsiFile;
|
||||
import org.jetbrains.jet.JetLiteFixture;
|
||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic;
|
||||
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.ImportingStrategy;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class CheckerTestUtilTest extends JetLiteFixture {
|
||||
|
||||
public CheckerTestUtilTest() {
|
||||
super("checkerTestUtil");
|
||||
}
|
||||
|
||||
protected void doTest(TheTest theTest) throws Exception {
|
||||
prepareForTest("test");
|
||||
theTest.test(myFile);
|
||||
}
|
||||
|
||||
public void testEquals() throws Exception {
|
||||
doTest(new TheTest() {
|
||||
@Override
|
||||
protected void makeTestData(List<Diagnostic> diagnostics, List<CheckerTestUtil.DiagnosedRange> diagnosedRanges) {
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testMissing() throws Exception {
|
||||
doTest(new TheTest("Missing TYPE_MISMATCH at 56 to 57") {
|
||||
@Override
|
||||
protected void makeTestData(List<Diagnostic> diagnostics, List<CheckerTestUtil.DiagnosedRange> diagnosedRanges) {
|
||||
diagnostics.remove(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testUnexpected() throws Exception {
|
||||
doTest(new TheTest("Unexpected TYPE_MISMATCH at 56 to 57") {
|
||||
@Override
|
||||
protected void makeTestData(List<Diagnostic> diagnostics, List<CheckerTestUtil.DiagnosedRange> diagnosedRanges) {
|
||||
diagnosedRanges.remove(0);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testBoth() throws Exception {
|
||||
doTest(new TheTest("Unexpected TYPE_MISMATCH at 56 to 57", "Missing UNRESOLVED_REFERENCE at 166 to 168") {
|
||||
@Override
|
||||
protected void makeTestData(List<Diagnostic> diagnostics, List<CheckerTestUtil.DiagnosedRange> diagnosedRanges) {
|
||||
diagnosedRanges.remove(0);
|
||||
diagnostics.remove(diagnostics.size() - 1);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public void testMissingInTheMiddle() throws Exception {
|
||||
doTest(new TheTest("Unexpected NONE_APPLICABLE at 122 to 123", "Missing TYPE_MISMATCH at 161 to 169") {
|
||||
@Override
|
||||
protected void makeTestData(List<Diagnostic> diagnostics, List<CheckerTestUtil.DiagnosedRange> diagnosedRanges) {
|
||||
diagnosedRanges.remove(2);
|
||||
diagnostics.remove(diagnostics.size() - 3);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private static abstract class TheTest {
|
||||
private final String[] expected;
|
||||
|
||||
protected TheTest(String... expectedMessages) {
|
||||
this.expected = expectedMessages;
|
||||
}
|
||||
|
||||
public void test(PsiFile psiFile) {
|
||||
BindingContext bindingContext = AnalyzingUtils.getInstance(ImportingStrategy.NONE).analyzeFileWithCache((JetFile) psiFile);
|
||||
String expectedText = CheckerTestUtil.addDiagnosticMarkersToText(psiFile, bindingContext).toString();
|
||||
|
||||
List<CheckerTestUtil.DiagnosedRange> diagnosedRanges = Lists.newArrayList();
|
||||
CheckerTestUtil.parseDiagnosedRanges(expectedText, diagnosedRanges);
|
||||
|
||||
List<Diagnostic> diagnostics = Lists.newArrayList(bindingContext.getDiagnostics());
|
||||
Collections.sort(diagnostics, CheckerTestUtil.DIAGNOSTIC_COMPARATOR);
|
||||
|
||||
makeTestData(diagnostics, diagnosedRanges);
|
||||
|
||||
final List<String> expectedMessages = Lists.newArrayList(expected);
|
||||
final List<String> actualMessages = Lists.newArrayList();
|
||||
|
||||
CheckerTestUtil.diagnosticsDiff(diagnosedRanges, diagnostics, new CheckerTestUtil.DiagnosticDiffCallbacks() {
|
||||
@Override
|
||||
public void missingDiagnostic(String type, int expectedStart, int expectedEnd) {
|
||||
String message = "Missing " + type + " at " + expectedStart + " to " + expectedEnd;
|
||||
actualMessages.add(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unexpectedDiagnostic(String type, int actualStart, int actualEnd) {
|
||||
String message = "Unexpected " + type + " at " + actualStart + " to " + actualEnd;
|
||||
actualMessages.add(message);
|
||||
}
|
||||
});
|
||||
|
||||
assertEquals(listToString(expectedMessages), listToString(actualMessages));
|
||||
}
|
||||
|
||||
private String listToString(List<String> expectedMessages) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
for (String expectedMessage : expectedMessages) {
|
||||
stringBuilder.append(expectedMessage).append("\n");
|
||||
}
|
||||
return stringBuilder.toString();
|
||||
}
|
||||
|
||||
protected abstract void makeTestData(List<Diagnostic> diagnostics, List<CheckerTestUtil.DiagnosedRange> diagnosedRanges);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
package org.jetbrains.jet.checkers;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import junit.framework.Test;
|
||||
import org.jetbrains.annotations.NonNls;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.jet.JetLiteFixture;
|
||||
import org.jetbrains.jet.JetTestCaseBase;
|
||||
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
|
||||
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.ImportingStrategy;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* @author abreslav
|
||||
*/
|
||||
public class QuickJetPsiCheckerTest extends JetLiteFixture {
|
||||
private String name;
|
||||
|
||||
public QuickJetPsiCheckerTest(@NonNls String dataPath, String name) {
|
||||
super(dataPath);
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getName() {
|
||||
return "test" + name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void runTest() throws Exception {
|
||||
String expectedText = loadFile(name + ".jet");
|
||||
List<CheckerTestUtil.DiagnosedRange> diagnosedRanges = Lists.newArrayList();
|
||||
String clearText = CheckerTestUtil.parseDiagnosedRanges(expectedText, diagnosedRanges);
|
||||
|
||||
createAndCheckPsiFile(name, clearText);
|
||||
JetFile jetFile = (JetFile) myFile;
|
||||
BindingContext bindingContext = AnalyzingUtils.getInstance(ImportingStrategy.NONE).analyzeFileWithCache(jetFile);
|
||||
|
||||
CheckerTestUtil.diagnosticsDiff(diagnosedRanges, bindingContext.getDiagnostics(), new CheckerTestUtil.DiagnosticDiffCallbacks() {
|
||||
@Override
|
||||
public void missingDiagnostic(String type, int expectedStart, int expectedEnd) {
|
||||
String message = "Missing " + type + DiagnosticUtils.atLocation(myFile, new TextRange(expectedStart, expectedEnd));
|
||||
System.err.println(message);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void unexpectedDiagnostic(String type, int actualStart, int actualEnd) {
|
||||
String message = "Unexpected " + type + DiagnosticUtils.atLocation(myFile, new TextRange(actualStart, actualEnd));
|
||||
System.err.println(message);
|
||||
}
|
||||
});
|
||||
|
||||
String actualText = CheckerTestUtil.addDiagnosticMarkersToText(jetFile, bindingContext).toString();
|
||||
|
||||
assertEquals(expectedText, actualText);
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return JetTestCaseBase.suiteForDirectory(JetTestCaseBase.getTestDataPathBase(), "/checkerWithErrorTypes/quick", true, new JetTestCaseBase.NamedTestFactory() {
|
||||
@NotNull
|
||||
@Override
|
||||
public Test createTest(@NotNull String dataPath, @NotNull String name) {
|
||||
return new QuickJetPsiCheckerTest(dataPath, name);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -143,42 +143,6 @@ public class JetResolveTest extends ExtensibleResolveTestCase {
|
||||
doTest(path, true, false);
|
||||
}
|
||||
|
||||
// public void testBasic() throws Exception {
|
||||
// doTest("/resolve/Basic.jet", true, true);
|
||||
// }
|
||||
//
|
||||
// public void testResolveToJava() throws Exception {
|
||||
// doTest("/resolve/ResolveToJava.jet", true, true);
|
||||
// }
|
||||
//
|
||||
// public void testResolveOfInfixExpressions() throws Exception {
|
||||
// doTest("/resolve/ResolveOfInfixExpressions.jet", true, true);
|
||||
// }
|
||||
//
|
||||
// public void testProjections() throws Exception {
|
||||
// doTest("/resolve/Projections.jet", true, true);
|
||||
// }
|
||||
//
|
||||
// public void testPrimaryConstructors() throws Exception {
|
||||
// doTest("/resolve/PrimaryConstructors.jet", true, true);
|
||||
// }
|
||||
//
|
||||
// public void testClassifiers() throws Exception {
|
||||
// doTest("/resolve/Classifiers.jet", true, true);
|
||||
// }
|
||||
//
|
||||
// public void testConstructorsAndInitializers() throws Exception {
|
||||
// doTest("/resolve/ConstructorsAndInitializers.jet", true, true);
|
||||
// }
|
||||
//
|
||||
// public void testNamespaces() throws Exception {
|
||||
// doTest("/resolve/Namespaces.jet", true, true);
|
||||
// }
|
||||
//
|
||||
// public void testTryCatch() throws Exception {
|
||||
// doTest("/resolve/TryCatch.jet", true, true);
|
||||
// }
|
||||
|
||||
public static Test suite() {
|
||||
return JetTestCaseBase.suiteForDirectory(getHomeDirectory() + "/idea/testData/", "/resolve/", true, new JetTestCaseBase.NamedTestFactory() {
|
||||
@NotNull
|
||||
|
||||
Reference in New Issue
Block a user