Scratch: get scratch expression using last commited version of document to avoid differences between PsiFile and Document

This commit is contained in:
Natalia Selezneva
2019-06-11 14:57:26 +03:00
parent 414f98aa29
commit a1564fe696
@@ -18,15 +18,14 @@ package org.jetbrains.kotlin.idea.scratch
import com.intellij.openapi.fileEditor.TextEditor import com.intellij.openapi.fileEditor.TextEditor
import com.intellij.openapi.project.Project import com.intellij.openapi.project.Project
import com.intellij.psi.PsiComment
import com.intellij.psi.PsiDocumentManager import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile import com.intellij.psi.PsiFile
import com.intellij.psi.PsiWhiteSpace import com.intellij.psi.PsiWhiteSpace
import com.intellij.psi.util.PsiUtil import com.intellij.psi.util.PsiTreeUtil
import org.jetbrains.kotlin.diagnostics.Severity import org.jetbrains.kotlin.diagnostics.Severity
import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithContent import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithContent
import org.jetbrains.kotlin.idea.core.util.CodeInsightUtils import org.jetbrains.kotlin.idea.core.util.CodeInsightUtils
import org.jetbrains.kotlin.idea.core.util.getLineStartOffset
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtFile import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtImportDirective import org.jetbrains.kotlin.psi.KtImportDirective
@@ -37,40 +36,48 @@ import org.jetbrains.kotlin.resolve.AnalyzingUtils
class KtScratchFile(project: Project, editor: TextEditor) : ScratchFile(project, editor) { class KtScratchFile(project: Project, editor: TextEditor) : ScratchFile(project, editor) {
override fun getExpressions(psiFile: PsiFile): List<ScratchExpression> { override fun getExpressions(psiFile: PsiFile): List<ScratchExpression> {
// todo multiple expressions at one line // todo multiple expressions at one line
val doc = PsiDocumentManager.getInstance(psiFile.project).getDocument(psiFile) ?: return emptyList() val doc = PsiDocumentManager.getInstance(psiFile.project).getLastCommittedDocument(psiFile) ?: return emptyList()
var line = 0 var line = 0
val result = arrayListOf<ScratchExpression>() val result = arrayListOf<ScratchExpression>()
while (line < doc.lineCount) { while (line < doc.lineCount) {
val start = psiFile.getLineStartOffset(line) ?: continue var start = doc.getLineStartOffset(line)
val elementAtOffset = CodeInsightUtils.getTopmostElementAtOffset( var element = psiFile.findElementAt(start)
PsiUtil.getElementAtOffset(psiFile, start), if (element is PsiWhiteSpace || element is PsiComment) {
start, start = PsiTreeUtil.skipSiblingsForward(
KtImportDirective::class.java, element,
KtDeclaration::class.java PsiWhiteSpace::class.java,
PsiComment::class.java
)?.startOffset ?: start
element = psiFile.findElementAt(start)
}
element = element?.let {
CodeInsightUtils.getTopmostElementAtOffset(
it,
start,
KtImportDirective::class.java,
KtDeclaration::class.java
)
}
if (element == null) {
line++
continue
}
val scratchExpression = ScratchExpression(
element,
doc.getLineNumber(element.startOffset),
doc.getLineNumber(element.endOffset)
) )
result.add(scratchExpression)
if (elementAtOffset is PsiWhiteSpace) { line = scratchExpression.lineEnd + 1
line = doc.getLineNumber(elementAtOffset.endOffset) + 1
continue
}
if (elementAtOffset == null) {
line += 1
continue
}
result.add(ScratchExpression(elementAtOffset, elementAtOffset.getLineNumber(true), elementAtOffset.getLineNumber(false)))
line = elementAtOffset.getLineNumber(false) + 1
} }
return result return result
} }
fun PsiElement.getLineNumber(start: Boolean = true): Int {
val document = PsiDocumentManager.getInstance(project).getLastCommittedDocument(containingFile)
return document?.getLineNumber(if (start) startOffset else endOffset) ?: 0
}
override fun hasErrors(): Boolean { override fun hasErrors(): Boolean {
val psiFile = getPsiFile() as? KtFile ?: return false val psiFile = getPsiFile() as? KtFile ?: return false
try { try {