Kotlinify AbstractOutOfBlockModificationTest, p2

This commit is contained in:
Vladimir Dolzhenko
2019-11-27 11:51:26 +01:00
parent 8f8ed4dbcf
commit 144f721a44
@@ -3,121 +3,122 @@
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/ */
package org.jetbrains.kotlin.idea.codeInsight; package org.jetbrains.kotlin.idea.codeInsight
import com.intellij.openapi.application.ApplicationManager; import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.util.io.FileUtil; import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil; import com.intellij.openapi.util.text.StringUtil
import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiElement; import com.intellij.psi.PsiManager
import com.intellij.psi.PsiManager; import com.intellij.psi.impl.PsiModificationTrackerImpl
import com.intellij.psi.impl.PsiModificationTrackerImpl; import com.intellij.psi.util.PsiTreeUtil
import com.intellij.psi.util.PsiTreeUtil; import junit.framework.TestCase
import org.jetbrains.kotlin.idea.caches.resolve.ResolutionUtils; import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
import org.jetbrains.kotlin.idea.caches.trackers.KotlinCodeBlockModificationListenerKt; import org.jetbrains.kotlin.idea.caches.trackers.outOfBlockModificationCount
import org.jetbrains.kotlin.idea.resolve.ResolutionFacade; import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase; import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.*; import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.lazy.ResolveSession
import org.jetbrains.kotlin.resolve.lazy.ResolveSession; import org.jetbrains.kotlin.test.InTextDirectivesUtils
import org.jetbrains.kotlin.test.InTextDirectivesUtils;
import java.io.IOException; abstract class AbstractOutOfBlockModificationTest : KotlinLightCodeInsightFixtureTestCase() {
protected fun doTest(unused: String?) {
public abstract class AbstractOutOfBlockModificationTest extends KotlinLightCodeInsightFixtureTestCase { val ktFile = myFixture.configureByFile(fileName()) as KtFile
val expectedOutOfBlock = expectedOutOfBlockResult
public static final String OUT_OF_CODE_BLOCK_DIRECTIVE = "OUT_OF_CODE_BLOCK:"; val isSkipCheckDefined = InTextDirectivesUtils.isDirectiveDefined(
public static final String SKIP_ANALYZE_CHECK_DIRECTIVE = "SKIP_ANALYZE_CHECK"; ktFile.text,
public static final String TYPE_DIRECTIVE = "TYPE:"; SKIP_ANALYZE_CHECK_DIRECTIVE
)
protected void doTest(String unused) throws IOException { TestCase.assertTrue(
myFixture.configureByFile(fileName()); "It's allowed to skip check with analyze only for tests where out-of-block is expected",
!isSkipCheckDefined || expectedOutOfBlock
boolean expectedOutOfBlock = getExpectedOutOfBlockResult(); )
boolean isSkipCheckDefined = InTextDirectivesUtils.isDirectiveDefined(myFixture.getFile().getText(), SKIP_ANALYZE_CHECK_DIRECTIVE); val tracker =
PsiManager.getInstance(myFixture.project).modificationTracker as PsiModificationTrackerImpl
assertTrue("It's allowed to skip check with analyze only for tests where out-of-block is expected", val element = ktFile.findElementAt(myFixture.caretOffset)
!isSkipCheckDefined || expectedOutOfBlock); TestCase.assertNotNull("Should be valid element", element)
val oobBeforeType = ktFile.outOfBlockModificationCount
val modificationCountBeforeType = tracker.modificationCount
PsiModificationTrackerImpl tracker = myFixture.type(stringToType)
(PsiModificationTrackerImpl) PsiManager.getInstance(myFixture.getProject()).getModificationTracker(); PsiDocumentManager.getInstance(myFixture.project).commitDocument(myFixture.getDocument(myFixture.file))
val oobAfterCount = ktFile.outOfBlockModificationCount
PsiElement element = myFixture.getFile().findElementAt(myFixture.getCaretOffset()); val modificationCountAfterType = tracker.modificationCount
assertNotNull("Should be valid element", element); TestCase.assertTrue(
"Modification tracker should always be changed after type",
KtFile file = (KtFile) getFile(); modificationCountBeforeType != modificationCountAfterType
)
long oobBeforeType = KotlinCodeBlockModificationListenerKt.getOutOfBlockModificationCount(file); TestCase.assertEquals(
long modificationCountBeforeType = tracker.getModificationCount(); "Result for out of block test is differs from expected on element in file:\n"
myFixture.type(getStringToType());
PsiDocumentManager.getInstance(myFixture.getProject()).commitDocument(myFixture.getDocument(myFixture.getFile()));
long oobAfterCount = KotlinCodeBlockModificationListenerKt.getOutOfBlockModificationCount(file);
long modificationCountAfterType = tracker.getModificationCount();
assertTrue("Modification tracker should always be changed after type", modificationCountBeforeType != modificationCountAfterType);
assertEquals("Result for out of block test is differs from expected on element in file:\n"
+ FileUtil.loadFile(testDataFile()), + FileUtil.loadFile(testDataFile()),
expectedOutOfBlock, oobBeforeType != oobAfterCount); expectedOutOfBlock, oobBeforeType != oobAfterCount
)
if (!isSkipCheckDefined) { if (!isSkipCheckDefined) {
checkOOBWithDescriptorsResolve(expectedOutOfBlock); checkOOBWithDescriptorsResolve(expectedOutOfBlock)
} }
} }
private void checkOOBWithDescriptorsResolve(boolean expectedOutOfBlock) { private fun checkOOBWithDescriptorsResolve(expectedOutOfBlock: Boolean) {
ApplicationManager.getApplication().runReadAction( ApplicationManager.getApplication().runReadAction {
() -> ((PsiModificationTrackerImpl) PsiManager.getInstance(myFixture.getProject()).getModificationTracker()) (PsiManager.getInstance(myFixture.project).modificationTracker as PsiModificationTrackerImpl)
.incOutOfCodeBlockModificationCounter()); .incOutOfCodeBlockModificationCounter()
}
PsiElement updateElement = myFixture.getFile().findElementAt(myFixture.getCaretOffset() - 1); val updateElement = myFixture.file.findElementAt(myFixture.caretOffset - 1)
KtExpression ktExpression = PsiTreeUtil.getParentOfType(updateElement, KtExpression.class, false); val ktExpression: KtExpression? = PsiTreeUtil.getParentOfType(updateElement, KtExpression::class.java, false)
KtDeclaration ktDeclaration = PsiTreeUtil.getParentOfType(updateElement, KtDeclaration.class, false); val ktDeclaration: KtDeclaration? = PsiTreeUtil.getParentOfType(updateElement, KtDeclaration::class.java, false)
KtElement ktElement = ktExpression != null ? ktExpression : ktDeclaration; val ktElement = ktExpression ?: ktDeclaration ?: return
val facade = ktElement.containingKtFile.getResolutionFacade()
if (ktElement == null) return; val session = facade.getFrontendService(ResolveSession::class.java)
session.forceResolveAll()
ResolutionFacade facade = ResolutionUtils.getResolutionFacade(ktElement.getContainingKtFile()); val context = session.bindingContext
ResolveSession session = facade.getFrontendService(ResolveSession.class); if (ktExpression != null && ktExpression !== ktDeclaration) {
session.forceResolveAll(); val expressionProcessed = context.get(
BindingContext context = session.getBindingContext();
if (ktExpression != null && ktExpression != ktDeclaration) {
@SuppressWarnings("ConstantConditions")
boolean expressionProcessed = context.get(
BindingContext.PROCESSED, BindingContext.PROCESSED,
ktExpression instanceof KtFunctionLiteral ? (KtLambdaExpression) ktExpression.getParent() : ktExpression) == Boolean.TRUE; if (ktExpression is KtFunctionLiteral) ktExpression.getParent() as KtLambdaExpression else ktExpression
) === java.lang.Boolean.TRUE
assertEquals("Expected out-of-block should result expression analyzed and vise versa", expectedOutOfBlock, TestCase.assertEquals(
expressionProcessed); "Expected out-of-block should result expression analyzed and vise versa", expectedOutOfBlock,
} expressionProcessed
else { )
boolean declarationProcessed = context.get(BindingContext.DECLARATION_TO_DESCRIPTOR, ktDeclaration) != null; } else {
assertEquals("Expected out-of-block should result declaration analyzed and vise versa", expectedOutOfBlock, val declarationProcessed =
declarationProcessed); context.get(
BindingContext.DECLARATION_TO_DESCRIPTOR,
ktDeclaration
) != null
TestCase.assertEquals(
"Expected out-of-block should result declaration analyzed and vise versa", expectedOutOfBlock,
declarationProcessed
)
} }
} }
private String getStringToType() { private val stringToType: String
String text = myFixture.getDocument(myFixture.getFile()).getText(); get() {
String typeDirectives = InTextDirectivesUtils.findStringWithPrefixes(text, TYPE_DIRECTIVE); val text = myFixture.getDocument(myFixture.file).text
val typeDirectives =
return typeDirectives != null ? StringUtil.unescapeStringCharacters(typeDirectives) : "a"; InTextDirectivesUtils.findStringWithPrefixes(text, TYPE_DIRECTIVE)
return if (typeDirectives != null) StringUtil.unescapeStringCharacters(typeDirectives) else "a"
} }
private boolean getExpectedOutOfBlockResult() { private val expectedOutOfBlockResult: Boolean
String text = myFixture.getDocument(myFixture.getFile()).getText(); get() {
val text = myFixture.getDocument(myFixture.file).text
String outOfCodeBlockDirective = InTextDirectivesUtils.findStringWithPrefixes(text, OUT_OF_CODE_BLOCK_DIRECTIVE); val outOfCodeBlockDirective = InTextDirectivesUtils.findStringWithPrefixes(
assertNotNull(fileName() + text,
": Expectation of code block result test should be configured with " + OUT_OF_CODE_BLOCK_DIRECTIVE
)
assertNotNull(
"${fileName()}: Expectation of code block result test should be configured with " +
"\"// " + OUT_OF_CODE_BLOCK_DIRECTIVE + " TRUE\" or " + "\"// " + OUT_OF_CODE_BLOCK_DIRECTIVE + " TRUE\" or " +
"\"// " + OUT_OF_CODE_BLOCK_DIRECTIVE + " FALSE\" directive in the file", "\"// " + OUT_OF_CODE_BLOCK_DIRECTIVE + " FALSE\" directive in the file",
outOfCodeBlockDirective); outOfCodeBlockDirective
return Boolean.parseBoolean(outOfCodeBlockDirective); )
return outOfCodeBlockDirective?.toBoolean() ?: false
}
companion object {
const val OUT_OF_CODE_BLOCK_DIRECTIVE = "OUT_OF_CODE_BLOCK:"
const val SKIP_ANALYZE_CHECK_DIRECTIVE = "SKIP_ANALYZE_CHECK"
const val TYPE_DIRECTIVE = "TYPE:"
} }
} }