Moved classes into separate files
This commit is contained in:
+57
@@ -0,0 +1,57 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 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.completion.handlers
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.completion.InsertionContext
|
||||||
|
import com.intellij.codeInsight.lookup.LookupElement
|
||||||
|
import com.intellij.psi.PsiDocumentManager
|
||||||
|
import com.intellij.psi.util.PsiTreeUtil
|
||||||
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.core.completion.DeclarationDescriptorLookupObject
|
||||||
|
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||||
|
import org.jetbrains.kotlin.idea.util.ShortenReferences
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
|
||||||
|
object CastReceiverInsertHandler : KotlinCallableInsertHandler() {
|
||||||
|
override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
||||||
|
super.handleInsert(context, item)
|
||||||
|
|
||||||
|
val expression = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), javaClass<JetSimpleNameExpression>(), false)
|
||||||
|
val qualifiedExpression = PsiTreeUtil.getParentOfType(expression, javaClass<JetQualifiedExpression>(), true)
|
||||||
|
if (qualifiedExpression != null) {
|
||||||
|
val receiver = qualifiedExpression.getReceiverExpression()
|
||||||
|
|
||||||
|
val descriptor = (item.getObject() as? DeclarationDescriptorLookupObject)?.descriptor as CallableDescriptor
|
||||||
|
val project = context.getProject()
|
||||||
|
|
||||||
|
val thisObj = if (descriptor.getExtensionReceiverParameter() != null) descriptor.getExtensionReceiverParameter() else descriptor.getDispatchReceiverParameter()
|
||||||
|
val fqName = IdeDescriptorRenderers.SOURCE_CODE.renderClassifierName(thisObj.getType().getConstructor().getDeclarationDescriptor())
|
||||||
|
|
||||||
|
val parentCast = JetPsiFactory(project).createExpression("(expr as $fqName)") as JetParenthesizedExpression
|
||||||
|
val cast = parentCast.getExpression() as JetBinaryExpressionWithTypeRHS
|
||||||
|
cast.getLeft().replace(receiver)
|
||||||
|
|
||||||
|
val psiDocumentManager = PsiDocumentManager.getInstance(project)
|
||||||
|
psiDocumentManager.commitAllDocuments()
|
||||||
|
psiDocumentManager.doPostponedOperationsAndUnblockDocument(context.getDocument())
|
||||||
|
|
||||||
|
val expr = receiver.replace(parentCast) as JetParenthesizedExpression
|
||||||
|
|
||||||
|
ShortenReferences.DEFAULT.process((expr.getExpression() as JetBinaryExpressionWithTypeRHS).getRight())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-206
@@ -16,32 +16,18 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.completion.handlers
|
package org.jetbrains.kotlin.idea.completion.handlers
|
||||||
|
|
||||||
import com.intellij.codeInsight.AutoPopupController
|
|
||||||
import com.intellij.codeInsight.completion.InsertionContext
|
import com.intellij.codeInsight.completion.InsertionContext
|
||||||
import com.intellij.codeInsight.lookup.Lookup
|
|
||||||
import com.intellij.codeInsight.lookup.LookupElement
|
import com.intellij.codeInsight.lookup.LookupElement
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.openapi.util.TextRange
|
|
||||||
import com.intellij.psi.PsiDocumentManager
|
import com.intellij.psi.PsiDocumentManager
|
||||||
import com.intellij.psi.PsiElement
|
|
||||||
import com.intellij.psi.codeStyle.CodeStyleSettingsManager
|
|
||||||
import com.intellij.psi.util.PsiTreeUtil
|
|
||||||
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableDescriptor
|
||||||
import org.jetbrains.kotlin.idea.completion.isAfterDot
|
import org.jetbrains.kotlin.idea.completion.isAfterDot
|
||||||
import org.jetbrains.kotlin.idea.core.completion.DeclarationDescriptorLookupObject
|
import org.jetbrains.kotlin.idea.core.completion.DeclarationDescriptorLookupObject
|
||||||
import org.jetbrains.kotlin.idea.core.formatter.JetCodeStyleSettings
|
|
||||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
|
||||||
import org.jetbrains.kotlin.idea.util.ImportInsertHelper
|
import org.jetbrains.kotlin.idea.util.ImportInsertHelper
|
||||||
import org.jetbrains.kotlin.idea.util.ShortenReferences
|
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
||||||
import org.jetbrains.kotlin.lexer.JetTokens
|
import org.jetbrains.kotlin.psi.JetFile
|
||||||
import org.jetbrains.kotlin.psi.*
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.types.JetType
|
|
||||||
|
|
||||||
public abstract class KotlinCallableInsertHandler : BaseDeclarationInsertHandler() {
|
abstract class KotlinCallableInsertHandler : BaseDeclarationInsertHandler() {
|
||||||
public override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
public override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
||||||
super.handleInsert(context, item)
|
super.handleInsert(context, item)
|
||||||
|
|
||||||
@@ -71,193 +57,3 @@ public abstract class KotlinCallableInsertHandler : BaseDeclarationInsertHandler
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public object KotlinPropertyInsertHandler : KotlinCallableInsertHandler() {
|
|
||||||
public override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
|
||||||
super.handleInsert(context, item)
|
|
||||||
|
|
||||||
if (context.getCompletionChar() == Lookup.REPLACE_SELECT_CHAR) {
|
|
||||||
deleteEmptyParenthesis(context)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun deleteEmptyParenthesis(context: InsertionContext) {
|
|
||||||
val psiDocumentManager = PsiDocumentManager.getInstance(context.getProject())
|
|
||||||
psiDocumentManager.commitAllDocuments()
|
|
||||||
psiDocumentManager.doPostponedOperationsAndUnblockDocument(context.getDocument())
|
|
||||||
|
|
||||||
val offset = context.getTailOffset()
|
|
||||||
val document = context.getDocument()
|
|
||||||
val chars = document.getCharsSequence()
|
|
||||||
|
|
||||||
val lParenOffset = chars.indexOfSkippingSpace('(', offset) ?: return
|
|
||||||
val rParenOffset = chars.indexOfSkippingSpace(')', lParenOffset + 1) ?: return
|
|
||||||
|
|
||||||
document.deleteString(offset, rParenOffset + 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public enum class CaretPosition {
|
|
||||||
IN_BRACKETS
|
|
||||||
AFTER_BRACKETS
|
|
||||||
}
|
|
||||||
|
|
||||||
public data class GenerateLambdaInfo(val lambdaType: JetType, val explicitParameters: Boolean)
|
|
||||||
|
|
||||||
public class KotlinFunctionInsertHandler(val caretPosition : CaretPosition, val lambdaInfo: GenerateLambdaInfo?) : KotlinCallableInsertHandler() {
|
|
||||||
init {
|
|
||||||
if (caretPosition == CaretPosition.AFTER_BRACKETS && lambdaInfo != null) {
|
|
||||||
throw IllegalArgumentException("CaretPosition.AFTER_BRACKETS with lambdaInfo != null combination is not supported")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
|
||||||
super.handleInsert(context, item)
|
|
||||||
|
|
||||||
val psiDocumentManager = PsiDocumentManager.getInstance(context.getProject())
|
|
||||||
psiDocumentManager.commitAllDocuments()
|
|
||||||
psiDocumentManager.doPostponedOperationsAndUnblockDocument(context.getDocument())
|
|
||||||
|
|
||||||
val startOffset = context.getStartOffset()
|
|
||||||
val element = context.getFile().findElementAt(startOffset) ?: return
|
|
||||||
|
|
||||||
when {
|
|
||||||
element.getStrictParentOfType<JetImportDirective>() != null -> return
|
|
||||||
|
|
||||||
isInfixCall(element) -> {
|
|
||||||
if (context.getCompletionChar() == ' ') {
|
|
||||||
context.setAddCompletionChar(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
val tailOffset = context.getTailOffset()
|
|
||||||
context.getDocument().insertString(tailOffset, " ")
|
|
||||||
context.getEditor().getCaretModel().moveToOffset(tailOffset + 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
else -> addBrackets(context, element)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun isInfixCall(context: PsiElement): Boolean {
|
|
||||||
val parent = context.getParent()
|
|
||||||
val grandParent = parent?.getParent()
|
|
||||||
return parent is JetSimpleNameExpression && grandParent is JetBinaryExpression && parent == grandParent.getOperationReference()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun addBrackets(context : InsertionContext, offsetElement : PsiElement) {
|
|
||||||
val completionChar = context.getCompletionChar()
|
|
||||||
if (completionChar == '(') { //TODO: more correct behavior related to braces type
|
|
||||||
context.setAddCompletionChar(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
var offset = context.getTailOffset()
|
|
||||||
val document = context.getDocument()
|
|
||||||
val chars = document.getCharsSequence()
|
|
||||||
|
|
||||||
val forceParenthesis = lambdaInfo != null && completionChar == '\t' && chars.charAt(offset) == '('
|
|
||||||
val braces = lambdaInfo != null && completionChar != '(' && !forceParenthesis
|
|
||||||
|
|
||||||
val openingBracket = if (braces) '{' else '('
|
|
||||||
val closingBracket = if (braces) '}' else ')'
|
|
||||||
|
|
||||||
if (completionChar == Lookup.REPLACE_SELECT_CHAR) {
|
|
||||||
val offset1 = chars.skipSpaces(offset)
|
|
||||||
if (offset1 < chars.length()) {
|
|
||||||
if (chars[offset1] == '<') {
|
|
||||||
PsiDocumentManager.getInstance(context.getProject()).commitDocument(document)
|
|
||||||
val token = context.getFile().findElementAt(offset1)!!
|
|
||||||
if (token.getNode().getElementType() == JetTokens.LT) {
|
|
||||||
val parent = token.getParent()
|
|
||||||
if (parent is JetTypeArgumentList && parent.getText().indexOf('\n') < 0/* if type argument list is on multiple lines this is more likely wrong parsing*/) {
|
|
||||||
offset = parent.endOffset
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var openingBracketOffset = chars.indexOfSkippingSpace(openingBracket, offset)
|
|
||||||
var inBracketsShift = 0
|
|
||||||
if (openingBracketOffset == null) {
|
|
||||||
if (braces) {
|
|
||||||
if (completionChar == ' ' || completionChar == '{') {
|
|
||||||
context.setAddCompletionChar(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isInsertSpacesInOneLineFunctionEnabled(context.getProject())) {
|
|
||||||
document.insertString(offset, " { }")
|
|
||||||
inBracketsShift = 1
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
document.insertString(offset, " {}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
document.insertString(offset, "()")
|
|
||||||
}
|
|
||||||
PsiDocumentManager.getInstance(context.getProject()).commitDocument(document)
|
|
||||||
}
|
|
||||||
|
|
||||||
openingBracketOffset = chars.indexOfSkippingSpace(openingBracket, offset)!!
|
|
||||||
|
|
||||||
val closeBracketOffset = chars.indexOfSkippingSpace(closingBracket, openingBracketOffset + 1)
|
|
||||||
|
|
||||||
val editor = context.getEditor()
|
|
||||||
if (shouldPlaceCaretInBrackets(completionChar) || closeBracketOffset == null) {
|
|
||||||
editor.getCaretModel().moveToOffset(openingBracketOffset + 1 + inBracketsShift)
|
|
||||||
AutoPopupController.getInstance(context.getProject())?.autoPopupParameterInfo(editor, offsetElement)
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
editor.getCaretModel().moveToOffset(closeBracketOffset + 1)
|
|
||||||
}
|
|
||||||
|
|
||||||
PsiDocumentManager.getInstance(context.getProject()).commitDocument(document)
|
|
||||||
|
|
||||||
if (lambdaInfo != null && lambdaInfo.explicitParameters) {
|
|
||||||
insertLambdaTemplate(context, TextRange(openingBracketOffset, closeBracketOffset!! + 1), lambdaInfo.lambdaType)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun shouldPlaceCaretInBrackets(completionChar: Char): Boolean {
|
|
||||||
if (completionChar == ',' || completionChar == '.' || completionChar == '=') return false
|
|
||||||
if (completionChar == '(') return true
|
|
||||||
return caretPosition == CaretPosition.IN_BRACKETS
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
public val NO_PARAMETERS_HANDLER: KotlinFunctionInsertHandler = KotlinFunctionInsertHandler(CaretPosition.AFTER_BRACKETS, null)
|
|
||||||
public val WITH_PARAMETERS_HANDLER: KotlinFunctionInsertHandler = KotlinFunctionInsertHandler(CaretPosition.IN_BRACKETS, null)
|
|
||||||
|
|
||||||
private fun isInsertSpacesInOneLineFunctionEnabled(project: Project)
|
|
||||||
= CodeStyleSettingsManager.getSettings(project).getCustomSettings(javaClass<JetCodeStyleSettings>())!!.INSERT_WHITESPACES_IN_SIMPLE_ONE_LINE_METHOD
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object CastReceiverInsertHandler : KotlinCallableInsertHandler() {
|
|
||||||
override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
|
||||||
super.handleInsert(context, item)
|
|
||||||
|
|
||||||
val expression = PsiTreeUtil.findElementOfClassAtOffset(context.getFile(), context.getStartOffset(), javaClass<JetSimpleNameExpression>(), false)
|
|
||||||
val qualifiedExpression = PsiTreeUtil.getParentOfType(expression, javaClass<JetQualifiedExpression>(), true)
|
|
||||||
if (qualifiedExpression != null) {
|
|
||||||
val receiver = qualifiedExpression.getReceiverExpression()
|
|
||||||
|
|
||||||
val descriptor = (item.getObject() as? DeclarationDescriptorLookupObject)?.descriptor as CallableDescriptor
|
|
||||||
val project = context.getProject()
|
|
||||||
|
|
||||||
val thisObj = if (descriptor.getExtensionReceiverParameter() != null) descriptor.getExtensionReceiverParameter() else descriptor.getDispatchReceiverParameter()
|
|
||||||
val fqName = IdeDescriptorRenderers.SOURCE_CODE.renderClassifierName(thisObj.getType().getConstructor().getDeclarationDescriptor())
|
|
||||||
|
|
||||||
val parentCast = JetPsiFactory(project).createExpression("(expr as $fqName)") as JetParenthesizedExpression
|
|
||||||
val cast = parentCast.getExpression() as JetBinaryExpressionWithTypeRHS
|
|
||||||
cast.getLeft().replace(receiver)
|
|
||||||
|
|
||||||
val psiDocumentManager = PsiDocumentManager.getInstance(project)
|
|
||||||
psiDocumentManager.commitAllDocuments()
|
|
||||||
psiDocumentManager.doPostponedOperationsAndUnblockDocument(context.getDocument())
|
|
||||||
|
|
||||||
val expr = receiver.replace(parentCast) as JetParenthesizedExpression
|
|
||||||
|
|
||||||
ShortenReferences.DEFAULT.process((expr.getExpression() as JetBinaryExpressionWithTypeRHS).getRight())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
+1
-1
@@ -31,7 +31,7 @@ import org.jetbrains.kotlin.psi.JetNameReferenceExpression
|
|||||||
import org.jetbrains.kotlin.resolve.BindingContext
|
import org.jetbrains.kotlin.resolve.BindingContext
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
|
|
||||||
public object KotlinClassInsertHandler : BaseDeclarationInsertHandler() {
|
object KotlinClassInsertHandler : BaseDeclarationInsertHandler() {
|
||||||
override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
||||||
super.handleInsert(context, item)
|
super.handleInsert(context, item)
|
||||||
|
|
||||||
|
|||||||
+172
@@ -0,0 +1,172 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 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.completion.handlers
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.AutoPopupController
|
||||||
|
import com.intellij.codeInsight.completion.InsertionContext
|
||||||
|
import com.intellij.codeInsight.lookup.Lookup
|
||||||
|
import com.intellij.codeInsight.lookup.LookupElement
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.util.TextRange
|
||||||
|
import com.intellij.psi.PsiDocumentManager
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.codeStyle.CodeStyleSettingsManager
|
||||||
|
import org.jetbrains.kotlin.idea.core.formatter.JetCodeStyleSettings
|
||||||
|
import org.jetbrains.kotlin.lexer.JetTokens
|
||||||
|
import org.jetbrains.kotlin.psi.JetBinaryExpression
|
||||||
|
import org.jetbrains.kotlin.psi.JetImportDirective
|
||||||
|
import org.jetbrains.kotlin.psi.JetSimpleNameExpression
|
||||||
|
import org.jetbrains.kotlin.psi.JetTypeArgumentList
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
|
import org.jetbrains.kotlin.types.JetType
|
||||||
|
|
||||||
|
enum class CaretPosition {
|
||||||
|
IN_BRACKETS
|
||||||
|
AFTER_BRACKETS
|
||||||
|
}
|
||||||
|
|
||||||
|
data class GenerateLambdaInfo(val lambdaType: JetType, val explicitParameters: Boolean)
|
||||||
|
|
||||||
|
class KotlinFunctionInsertHandler(val caretPosition : CaretPosition, val lambdaInfo: GenerateLambdaInfo?) : KotlinCallableInsertHandler() {
|
||||||
|
init {
|
||||||
|
if (caretPosition == CaretPosition.AFTER_BRACKETS && lambdaInfo != null) {
|
||||||
|
throw IllegalArgumentException("CaretPosition.AFTER_BRACKETS with lambdaInfo != null combination is not supported")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
||||||
|
super.handleInsert(context, item)
|
||||||
|
|
||||||
|
val psiDocumentManager = PsiDocumentManager.getInstance(context.getProject())
|
||||||
|
psiDocumentManager.commitAllDocuments()
|
||||||
|
psiDocumentManager.doPostponedOperationsAndUnblockDocument(context.getDocument())
|
||||||
|
|
||||||
|
val startOffset = context.getStartOffset()
|
||||||
|
val element = context.getFile().findElementAt(startOffset) ?: return
|
||||||
|
|
||||||
|
when {
|
||||||
|
element.getStrictParentOfType<JetImportDirective>() != null -> return
|
||||||
|
|
||||||
|
isInfixCall(element) -> {
|
||||||
|
if (context.getCompletionChar() == ' ') {
|
||||||
|
context.setAddCompletionChar(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
val tailOffset = context.getTailOffset()
|
||||||
|
context.getDocument().insertString(tailOffset, " ")
|
||||||
|
context.getEditor().getCaretModel().moveToOffset(tailOffset + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
else -> addBrackets(context, element)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun isInfixCall(context: PsiElement): Boolean {
|
||||||
|
val parent = context.getParent()
|
||||||
|
val grandParent = parent?.getParent()
|
||||||
|
return parent is JetSimpleNameExpression && grandParent is JetBinaryExpression && parent == grandParent.getOperationReference()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addBrackets(context : InsertionContext, offsetElement : PsiElement) {
|
||||||
|
val completionChar = context.getCompletionChar()
|
||||||
|
if (completionChar == '(') { //TODO: more correct behavior related to braces type
|
||||||
|
context.setAddCompletionChar(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
var offset = context.getTailOffset()
|
||||||
|
val document = context.getDocument()
|
||||||
|
val chars = document.getCharsSequence()
|
||||||
|
|
||||||
|
val forceParenthesis = lambdaInfo != null && completionChar == '\t' && chars.charAt(offset) == '('
|
||||||
|
val braces = lambdaInfo != null && completionChar != '(' && !forceParenthesis
|
||||||
|
|
||||||
|
val openingBracket = if (braces) '{' else '('
|
||||||
|
val closingBracket = if (braces) '}' else ')'
|
||||||
|
|
||||||
|
if (completionChar == Lookup.REPLACE_SELECT_CHAR) {
|
||||||
|
val offset1 = chars.skipSpaces(offset)
|
||||||
|
if (offset1 < chars.length()) {
|
||||||
|
if (chars[offset1] == '<') {
|
||||||
|
PsiDocumentManager.getInstance(context.getProject()).commitDocument(document)
|
||||||
|
val token = context.getFile().findElementAt(offset1)!!
|
||||||
|
if (token.getNode().getElementType() == JetTokens.LT) {
|
||||||
|
val parent = token.getParent()
|
||||||
|
if (parent is JetTypeArgumentList && parent.getText().indexOf('\n') < 0/* if type argument list is on multiple lines this is more likely wrong parsing*/) {
|
||||||
|
offset = parent.endOffset
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var openingBracketOffset = chars.indexOfSkippingSpace(openingBracket, offset)
|
||||||
|
var inBracketsShift = 0
|
||||||
|
if (openingBracketOffset == null) {
|
||||||
|
if (braces) {
|
||||||
|
if (completionChar == ' ' || completionChar == '{') {
|
||||||
|
context.setAddCompletionChar(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isInsertSpacesInOneLineFunctionEnabled(context.getProject())) {
|
||||||
|
document.insertString(offset, " { }")
|
||||||
|
inBracketsShift = 1
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
document.insertString(offset, " {}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
document.insertString(offset, "()")
|
||||||
|
}
|
||||||
|
PsiDocumentManager.getInstance(context.getProject()).commitDocument(document)
|
||||||
|
}
|
||||||
|
|
||||||
|
openingBracketOffset = chars.indexOfSkippingSpace(openingBracket, offset)!!
|
||||||
|
|
||||||
|
val closeBracketOffset = chars.indexOfSkippingSpace(closingBracket, openingBracketOffset + 1)
|
||||||
|
|
||||||
|
val editor = context.getEditor()
|
||||||
|
if (shouldPlaceCaretInBrackets(completionChar) || closeBracketOffset == null) {
|
||||||
|
editor.getCaretModel().moveToOffset(openingBracketOffset + 1 + inBracketsShift)
|
||||||
|
AutoPopupController.getInstance(context.getProject())?.autoPopupParameterInfo(editor, offsetElement)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
editor.getCaretModel().moveToOffset(closeBracketOffset + 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
PsiDocumentManager.getInstance(context.getProject()).commitDocument(document)
|
||||||
|
|
||||||
|
if (lambdaInfo != null && lambdaInfo.explicitParameters) {
|
||||||
|
insertLambdaTemplate(context, TextRange(openingBracketOffset, closeBracketOffset!! + 1), lambdaInfo.lambdaType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun shouldPlaceCaretInBrackets(completionChar: Char): Boolean {
|
||||||
|
if (completionChar == ',' || completionChar == '.' || completionChar == '=') return false
|
||||||
|
if (completionChar == '(') return true
|
||||||
|
return caretPosition == CaretPosition.IN_BRACKETS
|
||||||
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
public val NO_PARAMETERS_HANDLER: KotlinFunctionInsertHandler = KotlinFunctionInsertHandler(CaretPosition.AFTER_BRACKETS, null)
|
||||||
|
public val WITH_PARAMETERS_HANDLER: KotlinFunctionInsertHandler = KotlinFunctionInsertHandler(CaretPosition.IN_BRACKETS, null)
|
||||||
|
|
||||||
|
private fun isInsertSpacesInOneLineFunctionEnabled(project: Project)
|
||||||
|
= CodeStyleSettingsManager.getSettings(project).getCustomSettings(javaClass<JetCodeStyleSettings>())!!.INSERT_WHITESPACES_IN_SIMPLE_ONE_LINE_METHOD
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-1
@@ -21,7 +21,7 @@ import com.intellij.codeInsight.completion.InsertionContext
|
|||||||
import com.intellij.codeInsight.lookup.LookupElement
|
import com.intellij.codeInsight.lookup.LookupElement
|
||||||
import org.jetbrains.kotlin.lexer.JetTokens.*
|
import org.jetbrains.kotlin.lexer.JetTokens.*
|
||||||
|
|
||||||
public object KotlinKeywordInsertHandler : InsertHandler<LookupElement> {
|
object KotlinKeywordInsertHandler : InsertHandler<LookupElement> {
|
||||||
private val NO_SPACE_AFTER = listOf(THIS_KEYWORD,
|
private val NO_SPACE_AFTER = listOf(THIS_KEYWORD,
|
||||||
SUPER_KEYWORD,
|
SUPER_KEYWORD,
|
||||||
FOR_KEYWORD,
|
FOR_KEYWORD,
|
||||||
|
|||||||
+47
@@ -0,0 +1,47 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2015 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.completion.handlers
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.completion.InsertionContext
|
||||||
|
import com.intellij.codeInsight.lookup.Lookup
|
||||||
|
import com.intellij.codeInsight.lookup.LookupElement
|
||||||
|
import com.intellij.psi.PsiDocumentManager
|
||||||
|
|
||||||
|
object KotlinPropertyInsertHandler : KotlinCallableInsertHandler() {
|
||||||
|
public override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
||||||
|
super.handleInsert(context, item)
|
||||||
|
|
||||||
|
if (context.getCompletionChar() == Lookup.REPLACE_SELECT_CHAR) {
|
||||||
|
deleteEmptyParenthesis(context)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun deleteEmptyParenthesis(context: InsertionContext) {
|
||||||
|
val psiDocumentManager = PsiDocumentManager.getInstance(context.getProject())
|
||||||
|
psiDocumentManager.commitAllDocuments()
|
||||||
|
psiDocumentManager.doPostponedOperationsAndUnblockDocument(context.getDocument())
|
||||||
|
|
||||||
|
val offset = context.getTailOffset()
|
||||||
|
val document = context.getDocument()
|
||||||
|
val chars = document.getCharsSequence()
|
||||||
|
|
||||||
|
val lParenOffset = chars.indexOfSkippingSpace('(', offset) ?: return
|
||||||
|
val rParenOffset = chars.indexOfSkippingSpace(')', lParenOffset + 1) ?: return
|
||||||
|
|
||||||
|
document.deleteString(offset, rParenOffset + 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user