Fixed "Offset ... is not registered" exceptions when running under IDEA 2016.3

This commit is contained in:
Valentin Kipyatkov
2016-11-02 20:18:50 +03:00
parent 0af142edb3
commit eefa409a1d
5 changed files with 21 additions and 9 deletions

View File

@@ -17,6 +17,8 @@
package org.jetbrains.kotlin.idea.completion
import com.intellij.codeInsight.completion.InsertionContext
import com.intellij.codeInsight.completion.OffsetKey
import com.intellij.codeInsight.completion.OffsetMap
import com.intellij.codeInsight.completion.PrefixMatcher
import com.intellij.codeInsight.lookup.*
import com.intellij.openapi.util.Key
@@ -37,7 +39,6 @@ import org.jetbrains.kotlin.idea.util.*
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.renderer.render
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.DescriptorUtils
@@ -45,6 +46,7 @@ import org.jetbrains.kotlin.resolve.inline.InlineUtil
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.TypeNullability
import org.jetbrains.kotlin.types.typeUtil.nullability
import org.jetbrains.kotlin.utils.addToStdlib.check
import java.util.*
tailrec fun <T : Any> LookupElement.putUserDataDeep(key: Key<T>, value: T?) {
@@ -409,3 +411,11 @@ fun ImportableFqNameClassifier.isImportableDescriptorImported(descriptor: Declar
&& classification != ImportableFqNameClassifier.Classification.siblingImported
}
fun OffsetMap.tryGetOffset(key: OffsetKey): Int? {
try {
return getOffset(key).check { it != -1 } // prior to IDEA 2016.3 getOffset() returned -1 if not found, now it throws exception
}
catch(e: Exception) {
return null
}
}

View File

@@ -208,8 +208,8 @@ class ParameterNameAndTypeCompletion(
override fun handleInsert(context: InsertionContext) {
if (context.completionChar == Lookup.REPLACE_SELECT_CHAR) {
val replacementOffset = context.offsetMap.getOffset(REPLACEMENT_OFFSET)
if (replacementOffset != -1) {
val replacementOffset = context.offsetMap.tryGetOffset(REPLACEMENT_OFFSET)
if (replacementOffset != null) {
val tailOffset = context.tailOffset
context.document.deleteString(tailOffset, replacementOffset)

View File

@@ -25,6 +25,7 @@ import com.intellij.openapi.editor.Document
import com.intellij.psi.PsiDocumentManager
import org.jetbrains.kotlin.idea.completion.KEEP_OLD_ARGUMENT_LIST_ON_TAB_KEY
import org.jetbrains.kotlin.idea.completion.smart.SmartCompletion
import org.jetbrains.kotlin.idea.completion.tryGetOffset
class WithTailInsertHandler(val tailText: String,
val spaceBefore: Boolean,
@@ -47,8 +48,8 @@ class WithTailInsertHandler(val tailText: String,
var tailOffset = context.tailOffset
if (completionChar == Lookup.REPLACE_SELECT_CHAR && item.getUserData(KEEP_OLD_ARGUMENT_LIST_ON_TAB_KEY) != null) {
val offset = context.offsetMap.getOffset(SmartCompletion.OLD_ARGUMENTS_REPLACEMENT_OFFSET)
if (offset != -1) tailOffset = offset
context.offsetMap.tryGetOffset(SmartCompletion.OLD_ARGUMENTS_REPLACEMENT_OFFSET)
?.let { tailOffset = it }
}
val moveCaret = context.editor.caretModel.offset == tailOffset

View File

@@ -23,6 +23,7 @@ import com.intellij.ui.LayeredIcon
import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptor
import org.jetbrains.kotlin.idea.KotlinDescriptorIconProvider
import org.jetbrains.kotlin.idea.completion.tryGetOffset
import org.jetbrains.kotlin.idea.core.ArgumentPositionData
import org.jetbrains.kotlin.idea.core.ExpectedInfo
import org.jetbrains.kotlin.idea.core.SmartCastCalculator
@@ -90,8 +91,8 @@ class MultipleArgumentsItemProvider(
.create(variables.map { it.name.render() }.joinToString(", ")) //TODO: use code formatting settings
.withInsertHandler { context, lookupElement ->
if (context.completionChar == Lookup.REPLACE_SELECT_CHAR) {
val offset = context.offsetMap.getOffset(SmartCompletion.MULTIPLE_ARGUMENTS_REPLACEMENT_OFFSET)
if (offset != -1) {
val offset = context.offsetMap.tryGetOffset(SmartCompletion.MULTIPLE_ARGUMENTS_REPLACEMENT_OFFSET)
if (offset != null) {
context.document.deleteString(context.tailOffset, offset)
}
}

View File

@@ -265,8 +265,8 @@ class SmartCompletion(
object : LookupElementDecorator<LookupElement>(item) {
override fun handleInsert(context: InsertionContext) {
if (context.completionChar == Lookup.REPLACE_SELECT_CHAR) {
val offset = context.offsetMap.getOffset(OLD_ARGUMENTS_REPLACEMENT_OFFSET)
if (offset != -1) {
val offset = context.offsetMap.tryGetOffset(OLD_ARGUMENTS_REPLACEMENT_OFFSET)
if (offset != null) {
context.document.deleteString(context.tailOffset, offset)
}
}