Partial body resolve: tests now support resolve to any element with selection in test data
This commit is contained in:
@@ -33,12 +33,14 @@ import org.jetbrains.jet.lang.types.JetType
|
|||||||
import org.jetbrains.jet.renderer.DescriptorRenderer
|
import org.jetbrains.jet.renderer.DescriptorRenderer
|
||||||
import org.jetbrains.jet.lang.descriptors.VariableDescriptor
|
import org.jetbrains.jet.lang.descriptors.VariableDescriptor
|
||||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression
|
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression
|
||||||
import org.jetbrains.jet.lang.psi.psiUtil.getReceiverExpression
|
|
||||||
import org.jetbrains.jet.plugin.caches.resolve.getResolutionFacade
|
import org.jetbrains.jet.plugin.caches.resolve.getResolutionFacade
|
||||||
import org.jetbrains.jet.lang.psi.psiUtil.parents
|
import org.jetbrains.jet.lang.psi.psiUtil.parents
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
import com.intellij.openapi.command.CommandProcessor
|
import com.intellij.openapi.command.CommandProcessor
|
||||||
import org.jetbrains.jet.lang.psi.JetPsiFactory
|
import org.jetbrains.jet.lang.psi.JetPsiFactory
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
|
import org.jetbrains.jet.lang.psi.JetReferenceExpression
|
||||||
|
import org.jetbrains.jet.lang.psi.psiUtil.getReceiverExpression
|
||||||
|
|
||||||
public abstract class AbstractPartialBodyResolveTest : JetLightCodeInsightFixtureTestCase() {
|
public abstract class AbstractPartialBodyResolveTest : JetLightCodeInsightFixtureTestCase() {
|
||||||
override fun getTestDataPath() = JetTestCaseBuilder.getHomeDirectory()
|
override fun getTestDataPath() = JetTestCaseBuilder.getHomeDirectory()
|
||||||
@@ -49,24 +51,37 @@ public abstract class AbstractPartialBodyResolveTest : JetLightCodeInsightFixtur
|
|||||||
|
|
||||||
val file = myFixture.getFile() as JetFile
|
val file = myFixture.getFile() as JetFile
|
||||||
val editor = myFixture.getEditor()
|
val editor = myFixture.getEditor()
|
||||||
val offset = editor.getCaretModel().getOffset()
|
val selectionModel = editor.getSelectionModel()
|
||||||
val element = file.findElementAt(offset)
|
val expression = if (selectionModel.hasSelection()) {
|
||||||
val refExpression = element.getParentByType(javaClass<JetSimpleNameExpression>()) ?: error("No JetSimpleNameExpression at caret")
|
PsiTreeUtil.findElementOfClassAtRange(file, selectionModel.getSelectionStart(), selectionModel.getSelectionEnd(), javaClass<JetExpression>())
|
||||||
|
?: error("No JetExpression at selection range")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val offset = editor.getCaretModel().getOffset()
|
||||||
|
val element = file.findElementAt(offset)
|
||||||
|
element.getParentByType(javaClass<JetSimpleNameExpression>()) ?: error("No JetSimpleNameExpression at caret")
|
||||||
|
}
|
||||||
|
|
||||||
val resolutionFacade = file.getResolutionFacade()
|
val resolutionFacade = file.getResolutionFacade()
|
||||||
|
|
||||||
// optimized resolve
|
// optimized resolve
|
||||||
val (target1, type1, processedStatements1) = doResolve(refExpression, resolutionFacade.analyzeWithPartialBodyResolve(refExpression))
|
val (target1, type1, processedStatements1) = doResolve(expression, resolutionFacade.analyzeWithPartialBodyResolve(expression))
|
||||||
|
|
||||||
// full body resolve
|
// full body resolve
|
||||||
val (target2, type2, processedStatements2) = doResolve(refExpression, resolutionFacade.analyze(refExpression))
|
val (target2, type2, processedStatements2) = doResolve(expression, resolutionFacade.analyze(expression))
|
||||||
|
|
||||||
val set = HashSet(processedStatements2)
|
val set = HashSet(processedStatements2)
|
||||||
assert (set.containsAll(processedStatements1))
|
assert (set.containsAll(processedStatements1))
|
||||||
set.removeAll(processedStatements1)
|
set.removeAll(processedStatements1)
|
||||||
|
|
||||||
val builder = StringBuilder()
|
val builder = StringBuilder()
|
||||||
builder.append("Resolve target: ${target2.presentation(type2)}\n")
|
|
||||||
|
if (expression is JetReferenceExpression) {
|
||||||
|
builder.append("Resolve target: ${target2.presentation(type2)}\n")
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
builder.append("Expression type:${type2.presentation()}\n")
|
||||||
|
}
|
||||||
builder.append("----------------------------------------------\n")
|
builder.append("----------------------------------------------\n")
|
||||||
|
|
||||||
val skippedStatements = set
|
val skippedStatements = set
|
||||||
@@ -85,14 +100,26 @@ public abstract class AbstractPartialBodyResolveTest : JetLightCodeInsightFixtur
|
|||||||
null
|
null
|
||||||
)
|
)
|
||||||
val fileText = file.getText()
|
val fileText = file.getText()
|
||||||
val newCaretOffset = editor.getCaretModel().getOffset()
|
if (selectionModel.hasSelection()) {
|
||||||
builder.append(fileText.substring(0, newCaretOffset))
|
val start = selectionModel.getSelectionStart()
|
||||||
builder.append("<caret>")
|
val end = selectionModel.getSelectionEnd()
|
||||||
builder.append(fileText.substring(newCaretOffset))
|
builder.append(fileText.substring(0, start))
|
||||||
|
builder.append("<selection>")
|
||||||
|
builder.append(fileText.substring(start, end))
|
||||||
|
builder.append("<selection>")
|
||||||
|
builder.append(fileText.substring(end))
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
val newCaretOffset = editor.getCaretModel().getOffset()
|
||||||
|
builder.append(fileText.substring(0, newCaretOffset))
|
||||||
|
builder.append("<caret>")
|
||||||
|
builder.append(fileText.substring(newCaretOffset))
|
||||||
|
}
|
||||||
|
|
||||||
JetTestUtils.assertEqualsToFile(File(testPath.substringBeforeLast('.') + ".dump"), builder.toString())
|
JetTestUtils.assertEqualsToFile(File(testPath.substringBeforeLast('.') + ".dump"), builder.toString())
|
||||||
|
|
||||||
Assert.assertEquals(target2.presentation(type2), target1.presentation(type1))
|
Assert.assertEquals(target2.presentation(null), target1.presentation(null))
|
||||||
|
Assert.assertEquals(type2.presentation(), type1.presentation())
|
||||||
}
|
}
|
||||||
|
|
||||||
private data class ResolveData(
|
private data class ResolveData(
|
||||||
@@ -101,20 +128,20 @@ public abstract class AbstractPartialBodyResolveTest : JetLightCodeInsightFixtur
|
|||||||
val processedStatements: Collection<JetExpression>
|
val processedStatements: Collection<JetExpression>
|
||||||
)
|
)
|
||||||
|
|
||||||
private fun doResolve(refExpression: JetSimpleNameExpression, bindingContext: BindingContext): ResolveData {
|
private fun doResolve(expression: JetExpression, bindingContext: BindingContext): ResolveData {
|
||||||
val target = bindingContext[BindingContext.REFERENCE_TARGET, refExpression]
|
val target = if (expression is JetReferenceExpression) bindingContext[BindingContext.REFERENCE_TARGET, expression] else null
|
||||||
|
|
||||||
val processedStatements = bindingContext.getSliceContents(BindingContext.PROCESSED)
|
val processedStatements = bindingContext.getSliceContents(BindingContext.PROCESSED)
|
||||||
.filter { it.value }
|
.filter { it.value }
|
||||||
.map { it.key }
|
.map { it.key }
|
||||||
.filter { it.getParent() is JetBlockExpression }
|
.filter { it.getParent() is JetBlockExpression }
|
||||||
|
|
||||||
val receiver = refExpression.getReceiverExpression()
|
val receiver = (expression as? JetSimpleNameExpression)?.getReceiverExpression()
|
||||||
val expressionWithType = if (receiver != null) {
|
val expressionWithType = if (receiver != null) {
|
||||||
refExpression.getParent() as? JetExpression ?: refExpression
|
expression.getParent() as? JetExpression ?: expression
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
refExpression
|
expression
|
||||||
}
|
}
|
||||||
val type = bindingContext[BindingContext.EXPRESSION_TYPE, expressionWithType]
|
val type = bindingContext[BindingContext.EXPRESSION_TYPE, expressionWithType]
|
||||||
|
|
||||||
@@ -128,9 +155,12 @@ public abstract class AbstractPartialBodyResolveTest : JetLightCodeInsightFixtur
|
|||||||
|
|
||||||
val renderType = this is VariableDescriptor && type != this.getReturnType()
|
val renderType = this is VariableDescriptor && type != this.getReturnType()
|
||||||
if (!renderType) return s
|
if (!renderType) return s
|
||||||
return s + " smart-cast to " + if (type != null) DescriptorRenderer.COMPACT.renderType(type) else "unknown type"
|
return "$s smart-cast to ${type.presentation()}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun JetType?.presentation()
|
||||||
|
= if (this != null) DescriptorRenderer.COMPACT.renderType(this) else "unknown type"
|
||||||
|
|
||||||
private fun JetExpression.compactPresentation(): String {
|
private fun JetExpression.compactPresentation(): String {
|
||||||
val text = getText()
|
val text = getText()
|
||||||
val builder = StringBuilder()
|
val builder = StringBuilder()
|
||||||
|
|||||||
Reference in New Issue
Block a user