From fa88fb74c4f980c9ca58cdc58023cef2aec64037 Mon Sep 17 00:00:00 2001 From: Simon Ogorodnik Date: Mon, 24 Jul 2017 01:41:46 +0300 Subject: [PATCH] Disable completion binding context caching by default Now it opt-in in internal mode, due duplication problems #KT-19191 fixed --- .../CompletionBindingContextProvider.kt | 11 ++ ...bstractCompletionIncrementalResolveTest.kt | 103 +++++++++--------- idea/src/META-INF/plugin.xml | 4 + ...letionBindingContextCachingToggleAction.kt | 35 ++++++ 4 files changed, 104 insertions(+), 49 deletions(-) create mode 100644 idea/src/org/jetbrains/kotlin/idea/actions/internal/CompletionBindingContextCachingToggleAction.kt diff --git a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionBindingContextProvider.kt b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionBindingContextProvider.kt index d329f87fffb..91b18a674c9 100644 --- a/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionBindingContextProvider.kt +++ b/idea/idea-completion/src/org/jetbrains/kotlin/idea/completion/CompletionBindingContextProvider.kt @@ -58,6 +58,8 @@ class CompletionBindingContextProvider(project: Project) { companion object { fun getInstance(project: Project): CompletionBindingContextProvider = project.getComponent(CompletionBindingContextProvider::class.java) + + var ENABLED = false } private class CompletionData( @@ -86,6 +88,15 @@ class CompletionBindingContextProvider(project: Project) { fun getBindingContext(position: PsiElement, resolutionFacade: ResolutionFacade): BindingContext { + return if (ENABLED) { + _getBindingContext(position, resolutionFacade) + } + else { + resolutionFacade.analyze(position.parentsWithSelf.firstIsInstance(), BodyResolveMode.PARTIAL_FOR_COMPLETION) + } + } + + private fun _getBindingContext(position: PsiElement, resolutionFacade: ResolutionFacade): BindingContext { assert(!position.isPhysical) // position is in synthetic file val inStatement = position.findStatementInBlock() diff --git a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/AbstractCompletionIncrementalResolveTest.kt b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/AbstractCompletionIncrementalResolveTest.kt index 67a4953f309..9604561b529 100644 --- a/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/AbstractCompletionIncrementalResolveTest.kt +++ b/idea/idea-completion/tests/org/jetbrains/kotlin/idea/completion/test/AbstractCompletionIncrementalResolveTest.kt @@ -37,64 +37,69 @@ abstract class AbstractCompletionIncrementalResolveTest : KotlinLightCodeInsight override fun getProjectDescriptor() = KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE protected fun doTest(testPath: String) { - val file = File(testPath) - val hasCaretMarker = FileUtil.loadFile(file, true).contains("") - myFixture.configureByFile(testPath) + CompletionBindingContextProvider.ENABLED = true + try { + val file = File(testPath) + val hasCaretMarker = FileUtil.loadFile(file, true).contains("") + myFixture.configureByFile(testPath) - val document = myFixture.editor.document - val beforeMarkerOffset = document.text.indexOf(BEFORE_MARKER) - assertTrue("\"$BEFORE_MARKER\" is missing in file \"$testPath\"", beforeMarkerOffset >= 0) + val document = myFixture.editor.document + val beforeMarkerOffset = document.text.indexOf(BEFORE_MARKER) + assertTrue("\"$BEFORE_MARKER\" is missing in file \"$testPath\"", beforeMarkerOffset >= 0) - val changeMarkerOffset = document.text.indexOf(CHANGE_MARKER) - assertTrue("\"$CHANGE_MARKER\" is missing in file \"$testPath\"", changeMarkerOffset >= 0) + val changeMarkerOffset = document.text.indexOf(CHANGE_MARKER) + assertTrue("\"$CHANGE_MARKER\" is missing in file \"$testPath\"", changeMarkerOffset >= 0) - val textToType = InTextDirectivesUtils.findArrayWithPrefixes(document.text, TYPE_DIRECTIVE_PREFIX).singleOrNull() - ?.let { StringUtil.unquoteString(it) } - val backspaceCount = InTextDirectivesUtils.getPrefixedInt(document.text, BACKSPACES_DIRECTIVE_PREFIX) - assertTrue("At least one of \"$TYPE_DIRECTIVE_PREFIX\" and \"$BACKSPACES_DIRECTIVE_PREFIX\" should be defined", - textToType != null || backspaceCount != null) + val textToType = InTextDirectivesUtils.findArrayWithPrefixes(document.text, TYPE_DIRECTIVE_PREFIX).singleOrNull() + ?.let { StringUtil.unquoteString(it) } + val backspaceCount = InTextDirectivesUtils.getPrefixedInt(document.text, BACKSPACES_DIRECTIVE_PREFIX) + assertTrue("At least one of \"$TYPE_DIRECTIVE_PREFIX\" and \"$BACKSPACES_DIRECTIVE_PREFIX\" should be defined", + textToType != null || backspaceCount != null) - val beforeMarker = document.createRangeMarker(beforeMarkerOffset, beforeMarkerOffset + BEFORE_MARKER.length) - val changeMarker = document.createRangeMarker(changeMarkerOffset, changeMarkerOffset + CHANGE_MARKER.length) - changeMarker.isGreedyToRight = true + val beforeMarker = document.createRangeMarker(beforeMarkerOffset, beforeMarkerOffset + BEFORE_MARKER.length) + val changeMarker = document.createRangeMarker(changeMarkerOffset, changeMarkerOffset + CHANGE_MARKER.length) + changeMarker.isGreedyToRight = true - project.executeWriteCommand("") { - document.deleteString(beforeMarker.startOffset, beforeMarker.endOffset) - document.deleteString(changeMarker.startOffset, changeMarker.endOffset) - } - - val caretMarker = if (hasCaretMarker) - document.createRangeMarker(editor.caretModel.offset, editor.caretModel.offset) - else - null - editor.caretModel.moveToOffset(beforeMarker.startOffset) - - val testLog = StringBuilder() - CompletionBindingContextProvider.getInstance(project).TEST_LOG = testLog - - myFixture.complete(CompletionType.BASIC) - - project.executeWriteCommand("") { - if (backspaceCount != null) { - document.deleteString(changeMarker.startOffset - backspaceCount, changeMarker.startOffset) + project.executeWriteCommand("") { + document.deleteString(beforeMarker.startOffset, beforeMarker.endOffset) + document.deleteString(changeMarker.startOffset, changeMarker.endOffset) } - if (textToType != null) { - document.insertString(changeMarker.startOffset, textToType) + + val caretMarker = if (hasCaretMarker) + document.createRangeMarker(editor.caretModel.offset, editor.caretModel.offset) + else + null + editor.caretModel.moveToOffset(beforeMarker.startOffset) + + val testLog = StringBuilder() + CompletionBindingContextProvider.getInstance(project).TEST_LOG = testLog + + myFixture.complete(CompletionType.BASIC) + + project.executeWriteCommand("") { + if (backspaceCount != null) { + document.deleteString(changeMarker.startOffset - backspaceCount, changeMarker.startOffset) + } + if (textToType != null) { + document.insertString(changeMarker.startOffset, textToType) + } } - } - if (caretMarker != null) { - editor.caretModel.moveToOffset(caretMarker.startOffset) - } - else { - editor.caretModel.moveToOffset(changeMarker.endOffset) - } + if (caretMarker != null) { + editor.caretModel.moveToOffset(caretMarker.startOffset) + } + else { + editor.caretModel.moveToOffset(changeMarker.endOffset) + } - testCompletion(FileUtil.loadFile(file, true), - JvmPlatform, - { completionType, count -> myFixture.complete(completionType, count) }, - additionalValidDirectives = listOf(TYPE_DIRECTIVE_PREFIX, BACKSPACES_DIRECTIVE_PREFIX)) + testCompletion(FileUtil.loadFile(file, true), + JvmPlatform, + { completionType, count -> myFixture.complete(completionType, count) }, + additionalValidDirectives = listOf(TYPE_DIRECTIVE_PREFIX, BACKSPACES_DIRECTIVE_PREFIX)) - KotlinTestUtils.assertEqualsToFile(File(file.parent, file.nameWithoutExtension + ".log"), testLog.toString()) + KotlinTestUtils.assertEqualsToFile(File(file.parent, file.nameWithoutExtension + ".log"), testLog.toString()) + } finally { + CompletionBindingContextProvider.ENABLED = false + } } } \ No newline at end of file diff --git a/idea/src/META-INF/plugin.xml b/idea/src/META-INF/plugin.xml index 8d63f0bf4ea..cc11d26b088 100644 --- a/idea/src/META-INF/plugin.xml +++ b/idea/src/META-INF/plugin.xml @@ -146,6 +146,10 @@ text="Local scenario"/> + + diff --git a/idea/src/org/jetbrains/kotlin/idea/actions/internal/CompletionBindingContextCachingToggleAction.kt b/idea/src/org/jetbrains/kotlin/idea/actions/internal/CompletionBindingContextCachingToggleAction.kt new file mode 100644 index 00000000000..7d3321e9326 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/actions/internal/CompletionBindingContextCachingToggleAction.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.idea.actions.internal + +import com.intellij.openapi.actionSystem.AnActionEvent +import com.intellij.openapi.actionSystem.ToggleAction +import org.jetbrains.kotlin.idea.completion.CompletionBindingContextProvider + +class CompletionBindingContextCachingToggleAction : ToggleAction() { + override fun isSelected(e: AnActionEvent?): Boolean = + CompletionBindingContextProvider.ENABLED + + + override fun setSelected(e: AnActionEvent?, state: Boolean) { + CompletionBindingContextProvider.ENABLED = state + } + + override fun update(e: AnActionEvent) { + e.presentation.isEnabledAndVisible = KotlinInternalMode.enabled + } +}