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.editor.Document;
|
||||||
import com.intellij.openapi.util.TextRange;
|
import com.intellij.openapi.util.TextRange;
|
||||||
import com.intellij.openapi.vfs.VirtualFile;
|
import com.intellij.openapi.vfs.VirtualFile;
|
||||||
import com.intellij.psi.PsiDocumentManager;
|
|
||||||
import com.intellij.psi.PsiElement;
|
import com.intellij.psi.PsiElement;
|
||||||
import com.intellij.psi.PsiFile;
|
import com.intellij.psi.PsiFile;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
@@ -42,8 +41,14 @@ public class DiagnosticUtils {
|
|||||||
return closestPsiElement.getContainingFile();
|
return closestPsiElement.getContainingFile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@NotNull
|
||||||
public static String atLocation(@NotNull PsiFile file, @NotNull TextRange textRange) {
|
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();
|
int offset = textRange.getStartOffset();
|
||||||
VirtualFile virtualFile = file.getVirtualFile();
|
VirtualFile virtualFile = file.getVirtualFile();
|
||||||
String pathSuffix = virtualFile == null ? "" : " in " + virtualFile.getPath();
|
String pathSuffix = virtualFile == null ? "" : " in " + virtualFile.getPath();
|
||||||
|
|||||||
@@ -355,6 +355,7 @@ public class CallResolver {
|
|||||||
|
|
||||||
if (error) {
|
if (error) {
|
||||||
failedCandidates.add(candidate);
|
failedCandidates.add(candidate);
|
||||||
|
checkTypesWithNoCallee(temporaryTrace, scope, task.getTypeArguments(), task.getValueArguments(), task.getFunctionLiteralArguments());
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -19,6 +19,11 @@
|
|||||||
<keyboard-shortcut keymap="$default" first-keystroke="control shift Q"/>
|
<keyboard-shortcut keymap="$default" first-keystroke="control shift Q"/>
|
||||||
<add-to-group group-id="CodeMenu" anchor="last"/>
|
<add-to-group group-id="CodeMenu" anchor="last"/>
|
||||||
</action>
|
</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"
|
<action id="ToggleJetErrorReporting" class="org.jetbrains.jet.plugin.actions.ToggleErrorReportingAction"
|
||||||
text="Toggle Error Reporting">
|
text="Toggle Error Reporting">
|
||||||
<keyboard-shortcut keymap="$default" first-keystroke="control alt shift E"/>
|
<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();
|
return getTestDataPathBase();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected static String getTestDataPathBase() {
|
public static String getTestDataPathBase() {
|
||||||
return getHomeDirectory() + "/idea/testData";
|
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();
|
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);
|
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() {
|
public static Test suite() {
|
||||||
return JetTestCaseBase.suiteForDirectory(getHomeDirectory() + "/idea/testData/", "/resolve/", true, new JetTestCaseBase.NamedTestFactory() {
|
return JetTestCaseBase.suiteForDirectory(getHomeDirectory() + "/idea/testData/", "/resolve/", true, new JetTestCaseBase.NamedTestFactory() {
|
||||||
@NotNull
|
@NotNull
|
||||||
|
|||||||
Reference in New Issue
Block a user