Create from usage: Use separate editor for templates which should be placed in Java files
This commit is contained in:
@@ -31,6 +31,7 @@ import java.io.PrintWriter
|
|||||||
import java.io.StringWriter
|
import java.io.StringWriter
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
import com.intellij.psi.PsiComment
|
import com.intellij.psi.PsiComment
|
||||||
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
public fun JetPsiFactory(project: Project?): JetPsiFactory = JetPsiFactory(project!!)
|
public fun JetPsiFactory(project: Project?): JetPsiFactory = JetPsiFactory(project!!)
|
||||||
public fun JetPsiFactory(contextElement: JetElement): JetPsiFactory = JetPsiFactory(contextElement.getProject())
|
public fun JetPsiFactory(contextElement: JetElement): JetPsiFactory = JetPsiFactory(contextElement.getProject())
|
||||||
@@ -266,6 +267,10 @@ public class JetPsiFactory(private val project: Project) {
|
|||||||
return stringTemplateExpression.getEntries()[0] as JetStringTemplateEntryWithExpression
|
return stringTemplateExpression.getEntries()[0] as JetStringTemplateEntryWithExpression
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fun createPackageDirectiveIfNeeded(fqName: FqName): JetPackageDirective? {
|
||||||
|
return if (fqName.isRoot()) null else createFile("package ${fqName.asString()}").getPackageDirective()
|
||||||
|
}
|
||||||
|
|
||||||
public fun createImportDirective(path: String): JetImportDirective {
|
public fun createImportDirective(path: String): JetImportDirective {
|
||||||
return createImportDirective(ImportPath(path))
|
return createImportDirective(ImportPath(path))
|
||||||
}
|
}
|
||||||
|
|||||||
+130
-57
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder
|
|||||||
|
|
||||||
import com.intellij.codeInsight.navigation.NavigationUtil
|
import com.intellij.codeInsight.navigation.NavigationUtil
|
||||||
import com.intellij.codeInsight.template.*
|
import com.intellij.codeInsight.template.*
|
||||||
import com.intellij.codeInsight.template.impl.TemplateImpl
|
|
||||||
import com.intellij.ide.fileTemplates.FileTemplate
|
import com.intellij.ide.fileTemplates.FileTemplate
|
||||||
import com.intellij.ide.fileTemplates.FileTemplateManager
|
import com.intellij.ide.fileTemplates.FileTemplateManager
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
@@ -36,7 +35,6 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
import org.jetbrains.kotlin.resolve.scopes.JetScope
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
import org.jetbrains.kotlin.idea.util.ShortenReferences
|
|
||||||
import kotlin.properties.Delegates
|
import kotlin.properties.Delegates
|
||||||
import java.util.LinkedHashSet
|
import java.util.LinkedHashSet
|
||||||
import java.util.Collections
|
import java.util.Collections
|
||||||
@@ -48,7 +46,6 @@ import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
|||||||
import com.intellij.psi.PsiWhiteSpace
|
import com.intellij.psi.PsiWhiteSpace
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.lexer.JetTokens
|
import org.jetbrains.kotlin.lexer.JetTokens
|
||||||
import org.jetbrains.kotlin.idea.util.application.runWriteAction
|
|
||||||
import org.jetbrains.kotlin.types.checker.JetTypeChecker
|
import org.jetbrains.kotlin.types.checker.JetTypeChecker
|
||||||
import com.intellij.psi.SmartPointerManager
|
import com.intellij.psi.SmartPointerManager
|
||||||
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.SimpleFunctionDescriptorImpl
|
||||||
@@ -57,12 +54,9 @@ import org.jetbrains.kotlin.name.FqName
|
|||||||
import org.jetbrains.kotlin.descriptors.impl.MutablePackageFragmentDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.MutablePackageFragmentDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
|
||||||
import java.util.LinkedHashMap
|
import java.util.LinkedHashMap
|
||||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
|
||||||
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.ClassKind
|
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.createClass.ClassKind
|
||||||
import org.jetbrains.kotlin.idea.util.isAny
|
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
|
import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.siblings
|
import org.jetbrains.kotlin.psi.psiUtil.siblings
|
||||||
import org.jetbrains.kotlin.idea.util.isUnit
|
|
||||||
import com.intellij.openapi.editor.ScrollType
|
import com.intellij.openapi.editor.ScrollType
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
|
||||||
@@ -75,14 +69,17 @@ import com.intellij.psi.PsiModifier
|
|||||||
import com.intellij.psi.PsiField
|
import com.intellij.psi.PsiField
|
||||||
import com.intellij.psi.PsiMember
|
import com.intellij.psi.PsiMember
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.getJavaClassDescriptor
|
import org.jetbrains.kotlin.idea.caches.resolve.getJavaClassDescriptor
|
||||||
import com.intellij.psi.PsiNamedElement
|
|
||||||
import com.intellij.psi.PsiMethodCallExpression
|
|
||||||
import com.intellij.psi.PsiExpressionStatement
|
|
||||||
import org.jetbrains.kotlin.resolve.scopes.ChainedScope
|
import org.jetbrains.kotlin.resolve.scopes.ChainedScope
|
||||||
import org.jetbrains.kotlin.resolve.scopes.WritableScopeImpl
|
import org.jetbrains.kotlin.resolve.scopes.WritableScopeImpl
|
||||||
import org.jetbrains.kotlin.resolve.scopes.RedeclarationHandler
|
import org.jetbrains.kotlin.resolve.scopes.RedeclarationHandler
|
||||||
import org.jetbrains.kotlin.resolve.scopes.WritableScope
|
import org.jetbrains.kotlin.resolve.scopes.WritableScope
|
||||||
|
import com.intellij.psi.PsiMethodCallExpression
|
||||||
|
import com.intellij.psi.PsiExpressionStatement
|
||||||
import org.jetbrains.kotlin.idea.refactoring.*
|
import org.jetbrains.kotlin.idea.refactoring.*
|
||||||
|
import org.jetbrains.kotlin.idea.util.*
|
||||||
|
import com.intellij.openapi.ui.*
|
||||||
|
import com.intellij.codeInsight.template.impl.*
|
||||||
|
import org.jetbrains.kotlin.idea.util.application.*
|
||||||
|
|
||||||
private val TYPE_PARAMETER_LIST_VARIABLE_NAME = "typeParameterList"
|
private val TYPE_PARAMETER_LIST_VARIABLE_NAME = "typeParameterList"
|
||||||
private val TEMPLATE_FROM_USAGE_FUNCTION_BODY = "New Kotlin Function Body.kt"
|
private val TEMPLATE_FROM_USAGE_FUNCTION_BODY = "New Kotlin Function Body.kt"
|
||||||
@@ -201,6 +198,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
if (iterator.hasNext()) {
|
if (iterator.hasNext()) {
|
||||||
val context = Context(iterator.next())
|
val context = Context(iterator.next())
|
||||||
runWriteAction { context.buildAndRunTemplate { buildNext(iterator) } }
|
runWriteAction { context.buildAndRunTemplate { buildNext(iterator) } }
|
||||||
|
ApplicationManager.getApplication().invokeLater { context.showDialogIfNeeded() }
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
ShortenReferences.DEFAULT.process(elementsToShorten)
|
ShortenReferences.DEFAULT.process(elementsToShorten)
|
||||||
@@ -220,14 +218,16 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
|
|
||||||
private inner class Context(val callableInfo: CallableInfo) {
|
private inner class Context(val callableInfo: CallableInfo) {
|
||||||
val skipReturnType: Boolean
|
val skipReturnType: Boolean
|
||||||
val containingFile: JetFile
|
val jetFileToEdit: JetFile
|
||||||
val containingFileEditor: Editor
|
val containingFileEditor: Editor
|
||||||
val containingElement: JetElement
|
val containingElement: PsiElement
|
||||||
|
val dialogWithEditor: DialogWithEditor?
|
||||||
val receiverClassDescriptor: ClassDescriptor?
|
val receiverClassDescriptor: ClassDescriptor?
|
||||||
val typeParameterNameMap: Map<TypeParameterDescriptor, String>
|
val typeParameterNameMap: Map<TypeParameterDescriptor, String>
|
||||||
val receiverTypeCandidate: TypeCandidate?
|
val receiverTypeCandidate: TypeCandidate?
|
||||||
val mandatoryTypeParametersAsCandidates: List<TypeCandidate>
|
val mandatoryTypeParametersAsCandidates: List<TypeCandidate>
|
||||||
val substitutions: List<JetTypeSubstitution>
|
val substitutions: List<JetTypeSubstitution>
|
||||||
|
var released: Boolean = false
|
||||||
|
|
||||||
{
|
{
|
||||||
// gather relevant information
|
// gather relevant information
|
||||||
@@ -235,7 +235,7 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
val placement = placement
|
val placement = placement
|
||||||
when {
|
when {
|
||||||
placement is CallablePlacement.NoReceiver -> {
|
placement is CallablePlacement.NoReceiver -> {
|
||||||
containingElement = placement.containingElement as? JetElement ?: config.currentFile
|
containingElement = placement.containingElement
|
||||||
receiverClassDescriptor = with (placement.containingElement) {
|
receiverClassDescriptor = with (placement.containingElement) {
|
||||||
when (this) {
|
when (this) {
|
||||||
is JetClassOrObject -> currentFileContext[BindingContext.CLASS, this]
|
is JetClassOrObject -> currentFileContext[BindingContext.CLASS, this]
|
||||||
@@ -248,22 +248,44 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
receiverClassDescriptor =
|
receiverClassDescriptor =
|
||||||
placement.receiverTypeCandidate.theType.getConstructor().getDeclarationDescriptor() as? ClassDescriptor
|
placement.receiverTypeCandidate.theType.getConstructor().getDeclarationDescriptor() as? ClassDescriptor
|
||||||
val classDeclaration = receiverClassDescriptor?.let { DescriptorToSourceUtils.classDescriptorToDeclaration(it) }
|
val classDeclaration = receiverClassDescriptor?.let { DescriptorToSourceUtils.classDescriptorToDeclaration(it) }
|
||||||
containingElement = when {
|
containingElement = if (!config.isExtension && classDeclaration != null) classDeclaration else config.currentFile
|
||||||
!config.isExtension && classDeclaration is JetElement -> classDeclaration
|
|
||||||
else -> config.currentFile
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else -> throw IllegalArgumentException("Unexpected placement: $placement")
|
else -> throw IllegalArgumentException("Unexpected placement: $placement")
|
||||||
}
|
}
|
||||||
val receiverType = receiverClassDescriptor?.getDefaultType()
|
val receiverType = receiverClassDescriptor?.getDefaultType()
|
||||||
|
|
||||||
containingFile = containingElement.getContainingJetFile()
|
val project = config.currentFile.getProject()
|
||||||
if (containingFile != config.currentFile) {
|
|
||||||
|
if (containingElement.getContainingFile() != config.currentFile) {
|
||||||
NavigationUtil.activateFileWithPsiElement(containingElement)
|
NavigationUtil.activateFileWithPsiElement(containingElement)
|
||||||
containingFileEditor = FileEditorManager.getInstance(config.currentFile.getProject())!!.getSelectedTextEditor()!!
|
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
containingFileEditor = config.currentEditor!!
|
if (containingElement is JetElement) {
|
||||||
|
jetFileToEdit = containingElement.getContainingJetFile()
|
||||||
|
if (jetFileToEdit != config.currentFile) {
|
||||||
|
containingFileEditor = FileEditorManager.getInstance(project).getSelectedTextEditor()
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
containingFileEditor = config.currentEditor!!
|
||||||
|
}
|
||||||
|
dialogWithEditor = null
|
||||||
|
} else {
|
||||||
|
val dialog = object: DialogWithEditor(project, "Create from usage", "") {
|
||||||
|
override fun doOKAction() {
|
||||||
|
project.executeWriteCommand("Premature end of template") {
|
||||||
|
TemplateManagerImpl.getTemplateState(editor)?.gotoEnd(false)
|
||||||
|
}
|
||||||
|
super.doOKAction()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
containingFileEditor = dialog.editor
|
||||||
|
with(containingFileEditor.getSettings()) {
|
||||||
|
setAdditionalColumnsCount(config.currentEditor!!.getSettings().getRightMargin(project))
|
||||||
|
setAdditionalLinesCount(5)
|
||||||
|
}
|
||||||
|
jetFileToEdit = PsiDocumentManager.getInstance(project).getPsiFile(containingFileEditor.getDocument()) as JetFile
|
||||||
|
jetFileToEdit.analysisContext = config.currentFile
|
||||||
|
dialogWithEditor = dialog
|
||||||
}
|
}
|
||||||
|
|
||||||
val scope = getDeclarationScope()
|
val scope = getDeclarationScope()
|
||||||
@@ -510,6 +532,8 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
val declarationInPlace = when (containingElement) {
|
val declarationInPlace = when (containingElement) {
|
||||||
is JetFile -> containingElement.add(declaration) as JetNamedDeclaration
|
is JetFile -> containingElement.add(declaration) as JetNamedDeclaration
|
||||||
|
|
||||||
|
is PsiClass -> jetFileToEdit.add(declaration) as JetNamedDeclaration
|
||||||
|
|
||||||
is JetClassOrObject -> {
|
is JetClassOrObject -> {
|
||||||
var classBody = containingElement.getBody()
|
var classBody = containingElement.getBody()
|
||||||
if (classBody == null) {
|
if (classBody == null) {
|
||||||
@@ -779,6 +803,36 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun transformToJavaMemberIfApplicable(declaration: JetNamedDeclaration): Boolean {
|
private fun transformToJavaMemberIfApplicable(declaration: JetNamedDeclaration): Boolean {
|
||||||
|
fun convertToJava(targetClass: PsiClass): PsiMember? {
|
||||||
|
val psiFactory = JetPsiFactory(declaration)
|
||||||
|
|
||||||
|
psiFactory.createPackageDirectiveIfNeeded(config.currentFile.getPackageFqName())?.let {
|
||||||
|
declaration.getContainingFile().addBefore(it, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
val adjustedDeclaration = when (declaration) {
|
||||||
|
is JetNamedFunction, is JetProperty -> {
|
||||||
|
val klass = psiFactory.createClass("class Foo {}")
|
||||||
|
klass.getBody().add(declaration)
|
||||||
|
(declaration.replace(klass) as JetClass).getBody().getDeclarations().first()
|
||||||
|
}
|
||||||
|
else -> declaration
|
||||||
|
}
|
||||||
|
|
||||||
|
return when (adjustedDeclaration) {
|
||||||
|
is JetNamedFunction -> {
|
||||||
|
createJavaMethod(adjustedDeclaration, targetClass)
|
||||||
|
}
|
||||||
|
is JetProperty -> {
|
||||||
|
createJavaField(adjustedDeclaration, targetClass)
|
||||||
|
}
|
||||||
|
is JetClass -> {
|
||||||
|
createJavaClass(adjustedDeclaration, targetClass)
|
||||||
|
}
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (config.isExtension || receiverClassDescriptor !is JavaClassDescriptor) return false
|
if (config.isExtension || receiverClassDescriptor !is JavaClassDescriptor) return false
|
||||||
|
|
||||||
val targetClass = DescriptorToSourceUtils.classDescriptorToDeclaration(receiverClassDescriptor) as? PsiClass
|
val targetClass = DescriptorToSourceUtils.classDescriptorToDeclaration(receiverClassDescriptor) as? PsiClass
|
||||||
@@ -786,26 +840,13 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
|
|
||||||
val project = declaration.getProject()
|
val project = declaration.getProject()
|
||||||
|
|
||||||
val newJavaMember: PsiMember = when (declaration) {
|
val newJavaMember = convertToJava(targetClass) ?: return false
|
||||||
is JetNamedFunction -> {
|
|
||||||
createJavaMethod(declaration, targetClass)
|
|
||||||
}
|
|
||||||
is JetProperty -> {
|
|
||||||
createJavaField(declaration, targetClass)
|
|
||||||
}
|
|
||||||
is JetClass -> {
|
|
||||||
createJavaClass(declaration, targetClass)
|
|
||||||
}
|
|
||||||
else -> return false
|
|
||||||
}
|
|
||||||
|
|
||||||
val modifierList = newJavaMember.getModifierList()
|
val modifierList = newJavaMember.getModifierList()
|
||||||
if (newJavaMember is PsiMethod || newJavaMember is PsiClass) {
|
if (newJavaMember is PsiMethod || newJavaMember is PsiClass) {
|
||||||
modifierList.setModifierProperty(PsiModifier.FINAL, false)
|
modifierList.setModifierProperty(PsiModifier.FINAL, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
declaration.delete()
|
|
||||||
|
|
||||||
val needStatic = when (callableInfo) {
|
val needStatic = when (callableInfo) {
|
||||||
is ConstructorInfo -> with(callableInfo.classInfo) {
|
is ConstructorInfo -> with(callableInfo.classInfo) {
|
||||||
!inner && kind != ClassKind.ENUM_ENTRY && kind != ClassKind.ENUM_CLASS
|
!inner && kind != ClassKind.ENUM_ENTRY && kind != ClassKind.ENUM_CLASS
|
||||||
@@ -881,11 +922,11 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(containingFileEditor.getDocument())
|
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(containingFileEditor.getDocument())
|
||||||
|
|
||||||
val caretModel = containingFileEditor.getCaretModel()
|
val caretModel = containingFileEditor.getCaretModel()
|
||||||
caretModel.moveToOffset(containingFile.getNode().getStartOffset())
|
caretModel.moveToOffset(jetFileToEdit.getNode().getStartOffset())
|
||||||
|
|
||||||
val declaration = declarationPointer.getElement()
|
val declaration = declarationPointer.getElement()
|
||||||
|
|
||||||
val builder = TemplateBuilderImpl(containingFile)
|
val builder = TemplateBuilderImpl(jetFileToEdit)
|
||||||
if (declaration is JetProperty) {
|
if (declaration is JetProperty) {
|
||||||
setupValVarTemplate(builder, declaration)
|
setupValVarTemplate(builder, declaration)
|
||||||
}
|
}
|
||||||
@@ -918,38 +959,70 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
|
|
||||||
// run the template
|
// run the template
|
||||||
TemplateManager.getInstance(project).startTemplate(containingFileEditor, templateImpl, object : TemplateEditingAdapter() {
|
TemplateManager.getInstance(project).startTemplate(containingFileEditor, templateImpl, object : TemplateEditingAdapter() {
|
||||||
override fun templateFinished(template: Template?, brokenOff: Boolean) {
|
private fun finishTemplate(brokenOff: Boolean) {
|
||||||
PsiDocumentManager.getInstance(project).commitDocument(containingFileEditor.getDocument())
|
try {
|
||||||
|
PsiDocumentManager.getInstance(project).commitDocument(containingFileEditor.getDocument())
|
||||||
|
|
||||||
// file templates
|
dialogWithEditor?.close(DialogWrapper.OK_EXIT_CODE)
|
||||||
val newDeclaration = if (templateImpl.getSegmentsCount() > 0) {
|
if (brokenOff && !ApplicationManager.getApplication().isUnitTestMode()) {
|
||||||
PsiTreeUtil.findElementOfClassAtOffset(containingFile, templateImpl.getSegmentOffset(0), declaration.javaClass, false)!!
|
NavigationUtil.activateFileWithPsiElement(config.originalElement)
|
||||||
}
|
return
|
||||||
else declarationPointer.getElement()!!
|
}
|
||||||
|
|
||||||
ApplicationManager.getApplication()!!.runWriteAction {
|
|
||||||
// file templates
|
// file templates
|
||||||
if (newDeclaration is JetNamedFunction) {
|
val newDeclaration = if (templateImpl.getSegmentsCount() > 0) {
|
||||||
setupFunctionBody(newDeclaration)
|
PsiTreeUtil.findElementOfClassAtOffset(jetFileToEdit, templateImpl.getSegmentOffset(0), declaration.javaClass, false)!!
|
||||||
|
}
|
||||||
|
else declarationPointer.getElement()!!
|
||||||
|
|
||||||
|
runWriteAction {
|
||||||
|
// file templates
|
||||||
|
if (newDeclaration is JetNamedFunction) {
|
||||||
|
setupFunctionBody(newDeclaration)
|
||||||
|
}
|
||||||
|
|
||||||
|
val callElement = config.originalElement as? JetCallElement
|
||||||
|
if (callElement != null) {
|
||||||
|
setupCallTypeArguments(callElement, expression?.currentTypeParameters ?: Collections.emptyList())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val callElement = config.originalElement as? JetCallElement
|
// change short type names to fully qualified ones (to be shortened below)
|
||||||
if (callElement != null) {
|
val typeRefsToShorten = setupTypeReferencesForShortening(newDeclaration, parameterTypeExpressions)
|
||||||
setupCallTypeArguments(callElement, expression?.currentTypeParameters ?: Collections.emptyList())
|
if (!transformToJavaMemberIfApplicable(newDeclaration)) {
|
||||||
|
elementsToShorten.addAll(typeRefsToShorten)
|
||||||
|
setupEditor(newDeclaration)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
finally {
|
||||||
// change short type names to fully qualified ones (to be shortened below)
|
release()
|
||||||
val typeRefsToShorten = setupTypeReferencesForShortening(newDeclaration, parameterTypeExpressions)
|
onFinish()
|
||||||
if (!transformToJavaMemberIfApplicable(newDeclaration)) {
|
|
||||||
elementsToShorten.addAll(typeRefsToShorten)
|
|
||||||
setupEditor(newDeclaration)
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
onFinish()
|
override fun templateCancelled(template: Template?) {
|
||||||
|
finishTemplate(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun templateFinished(template: Template?, brokenOff: Boolean) {
|
||||||
|
finishTemplate(brokenOff)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun showDialogIfNeeded() {
|
||||||
|
if (!ApplicationManager.getApplication().isUnitTestMode() && dialogWithEditor != null && !released) {
|
||||||
|
dialogWithEditor.show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun release() {
|
||||||
|
if (released) return
|
||||||
|
dialogWithEditor?.let {
|
||||||
|
jetFileToEdit.delete()
|
||||||
|
released = true
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,82 @@
|
|||||||
|
/*
|
||||||
|
* 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.util
|
||||||
|
|
||||||
|
import com.intellij.openapi.ui.DialogWrapper
|
||||||
|
|
||||||
|
import javax.swing.*
|
||||||
|
import com.intellij.openapi.project.*
|
||||||
|
import com.intellij.openapi.editor.*
|
||||||
|
import java.awt.*
|
||||||
|
import com.intellij.testFramework.*
|
||||||
|
import org.jetbrains.kotlin.idea.*
|
||||||
|
import com.intellij.openapi.fileEditor.*
|
||||||
|
import com.intellij.openapi.editor.ex.*
|
||||||
|
import com.intellij.openapi.editor.colors.*
|
||||||
|
import java.awt.event.*
|
||||||
|
import com.intellij.psi.*
|
||||||
|
|
||||||
|
public open class DialogWithEditor(
|
||||||
|
val project: Project,
|
||||||
|
title: String,
|
||||||
|
val initialText: String
|
||||||
|
) : DialogWrapper(project, true) {
|
||||||
|
val editor: Editor = createEditor()
|
||||||
|
|
||||||
|
;{
|
||||||
|
init()
|
||||||
|
setTitle(title)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun createEditor(): Editor {
|
||||||
|
val editorFactory = EditorFactory.getInstance()!!
|
||||||
|
val virtualFile = LightVirtualFile("dummy.kt", JetFileType.INSTANCE, initialText)
|
||||||
|
val document = FileDocumentManager.getInstance().getDocument(virtualFile)!!
|
||||||
|
|
||||||
|
val editor = editorFactory.createEditor(document, project, JetFileType.INSTANCE, false)
|
||||||
|
val settings = editor.getSettings()
|
||||||
|
settings.setVirtualSpace(false)
|
||||||
|
settings.setLineMarkerAreaShown(false)
|
||||||
|
settings.setFoldingOutlineShown(false)
|
||||||
|
settings.setRightMarginShown(false)
|
||||||
|
settings.setAdditionalPageAtBottom(false)
|
||||||
|
settings.setAdditionalLinesCount(2)
|
||||||
|
settings.setAdditionalColumnsCount(12)
|
||||||
|
|
||||||
|
assert(editor is EditorEx)
|
||||||
|
(editor as EditorEx).setEmbeddedIntoDialogWrapper(true)
|
||||||
|
|
||||||
|
editor.getColorsScheme().setColor(EditorColors.CARET_ROW_COLOR, editor.getColorsScheme().getDefaultBackground())
|
||||||
|
|
||||||
|
return editor
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createCenterPanel(): JComponent {
|
||||||
|
val panel = JPanel(BorderLayout())
|
||||||
|
panel.add(editor.getComponent(), BorderLayout.CENTER)
|
||||||
|
return panel
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getPreferredFocusedComponent(): JComponent {
|
||||||
|
return editor.getContentComponent()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dispose() {
|
||||||
|
super.dispose()
|
||||||
|
EditorFactory.getInstance()!!.releaseEditor(editor)
|
||||||
|
}
|
||||||
|
}
|
||||||
+1
-2
@@ -3,5 +3,4 @@
|
|||||||
|
|
||||||
J.foo(1, "2") fun test() {
|
J.foo(1, "2") fun test() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+1
-2
@@ -3,5 +3,4 @@
|
|||||||
|
|
||||||
J.foo(count = 1, name = "2") fun test() {
|
J.foo(count = 1, name = "2") fun test() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+1
-2
@@ -4,5 +4,4 @@
|
|||||||
|
|
||||||
[foo(1, "2", J.bar("3", 4))] fun test() {
|
[foo(1, "2", J.bar("3", 4))] fun test() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+1
-2
@@ -3,5 +3,4 @@
|
|||||||
|
|
||||||
class A(val n: Int)
|
class A(val n: Int)
|
||||||
|
|
||||||
fun test() = J.Foo(abc = 1, ghi = A(2), def = "s")
|
fun test() = J.Foo(abc = 1, ghi = A(2), def = "s")
|
||||||
|
|
||||||
+1
-2
@@ -3,5 +3,4 @@
|
|||||||
|
|
||||||
fun test<U>(u: U) {
|
fun test<U>(u: U) {
|
||||||
val a = J(u).Foo(u)
|
val a = J(u).Foo(u)
|
||||||
}
|
}
|
||||||
|
|
||||||
+1
-2
@@ -3,5 +3,4 @@
|
|||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
val a = J.Foo(2)
|
val a = J.Foo(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
+1
-2
@@ -3,5 +3,4 @@
|
|||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
val a = J().Foo(2)
|
val a = J().Foo(2)
|
||||||
}
|
}
|
||||||
|
|
||||||
-1
@@ -7,4 +7,3 @@ open class B
|
|||||||
class A<T>(val t: T) {
|
class A<T>(val t: T) {
|
||||||
val x: B by J.Foo(t, "")
|
val x: B by J.Foo(t, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -3,5 +3,4 @@
|
|||||||
|
|
||||||
open class A
|
open class A
|
||||||
|
|
||||||
fun test(): A = J.Foo(2, "2")
|
fun test(): A = J.Foo(2, "2")
|
||||||
|
|
||||||
+1
-2
@@ -3,5 +3,4 @@
|
|||||||
|
|
||||||
open class A(val n: Int)
|
open class A(val n: Int)
|
||||||
|
|
||||||
fun test(): A = J.Foo(2, "2")
|
fun test(): A = J.Foo(2, "2")
|
||||||
|
|
||||||
+1
-2
@@ -3,5 +3,4 @@
|
|||||||
|
|
||||||
trait T
|
trait T
|
||||||
|
|
||||||
fun test(): T = J.Foo(2, "2")
|
fun test(): T = J.Foo(2, "2")
|
||||||
|
|
||||||
+1
-2
@@ -3,5 +3,4 @@
|
|||||||
|
|
||||||
class A<T>(val b: B<T>) {
|
class A<T>(val b: B<T>) {
|
||||||
fun test() = B.Foo<Int, String>(2, "2")
|
fun test() = B.Foo<Int, String>(2, "2")
|
||||||
}
|
}
|
||||||
|
|
||||||
+1
-2
@@ -3,5 +3,4 @@
|
|||||||
|
|
||||||
class A<T>(val b: B<T>) {
|
class A<T>(val b: B<T>) {
|
||||||
fun test() = b.Foo<Int, String>(2, "2")
|
fun test() = b.Foo<Int, String>(2, "2")
|
||||||
}
|
}
|
||||||
|
|
||||||
+1
-2
@@ -3,5 +3,4 @@
|
|||||||
|
|
||||||
class A<T>(val b: B<T>) {
|
class A<T>(val b: B<T>) {
|
||||||
fun test() = b.Foo<String>(2, "2")
|
fun test() = b.Foo<String>(2, "2")
|
||||||
}
|
}
|
||||||
|
|
||||||
+1
-2
@@ -3,5 +3,4 @@
|
|||||||
|
|
||||||
class A<T>(val b: B<T>) {
|
class A<T>(val b: B<T>) {
|
||||||
fun test() = b.Foo<T, Int, String>(2, "2")
|
fun test() = b.Foo<T, Int, String>(2, "2")
|
||||||
}
|
}
|
||||||
|
|
||||||
+1
-2
@@ -3,5 +3,4 @@
|
|||||||
|
|
||||||
class A<T>(val b: B<T>) {
|
class A<T>(val b: B<T>) {
|
||||||
fun test() = B.Foo<String>(2, "2")
|
fun test() = B.Foo<String>(2, "2")
|
||||||
}
|
}
|
||||||
|
|
||||||
+1
-2
@@ -6,5 +6,4 @@ class B {
|
|||||||
|
|
||||||
class Foo: J.A(1, "2", B()) {
|
class Foo: J.A(1, "2", B()) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+1
-2
@@ -6,5 +6,4 @@ class B {
|
|||||||
|
|
||||||
class Foo: J.A(abc = 1, ghi = "2", def = B()) {
|
class Foo: J.A(abc = 1, ghi = "2", def = B()) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+1
-2
@@ -2,5 +2,4 @@
|
|||||||
// ERROR: Unresolved reference: A
|
// ERROR: Unresolved reference: A
|
||||||
class Foo: J.A {
|
class Foo: J.A {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+1
-2
@@ -4,5 +4,4 @@ import J.A
|
|||||||
|
|
||||||
class X {
|
class X {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+1
-2
@@ -4,5 +4,4 @@ import J.A
|
|||||||
|
|
||||||
class X {
|
class X {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+1
-2
@@ -4,5 +4,4 @@ import J.A
|
|||||||
|
|
||||||
class X {
|
class X {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
+1
-2
@@ -4,5 +4,4 @@ import J.A
|
|||||||
|
|
||||||
class X {
|
class X {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// "Create class 'A'" "true"
|
// "Create class 'A'" "true"
|
||||||
// ERROR: Unresolved reference: A
|
// ERROR: Unresolved reference: A
|
||||||
fun foo() = J.A.B
|
fun foo() = J.A.B
|
||||||
|
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// "Create enum 'A'" "true"
|
// "Create enum 'A'" "true"
|
||||||
// ERROR: Unresolved reference: A
|
// ERROR: Unresolved reference: A
|
||||||
fun foo() = J.A.B
|
fun foo() = J.A.B
|
||||||
|
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// "Create trait 'A'" "true"
|
// "Create trait 'A'" "true"
|
||||||
// ERROR: Unresolved reference: A
|
// ERROR: Unresolved reference: A
|
||||||
fun foo() = J.A.B
|
fun foo() = J.A.B
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -1,4 +1,3 @@
|
|||||||
// "Create annotation 'A'" "true"
|
// "Create annotation 'A'" "true"
|
||||||
// ERROR: Unresolved reference: A
|
// ERROR: Unresolved reference: A
|
||||||
fun foo(): J.A = throw Throwable("")
|
fun foo(): J.A = throw Throwable("")
|
||||||
|
|
||||||
+1
-2
@@ -1,4 +1,3 @@
|
|||||||
// "Create class 'A'" "true"
|
// "Create class 'A'" "true"
|
||||||
// ERROR: Unresolved reference: A
|
// ERROR: Unresolved reference: A
|
||||||
fun foo(): J.A = throw Throwable("")
|
fun foo(): J.A = throw Throwable("")
|
||||||
|
|
||||||
+1
-2
@@ -1,4 +1,3 @@
|
|||||||
// "Create enum 'A'" "true"
|
// "Create enum 'A'" "true"
|
||||||
// ERROR: Unresolved reference: A
|
// ERROR: Unresolved reference: A
|
||||||
fun foo(): J.A = throw Throwable("")
|
fun foo(): J.A = throw Throwable("")
|
||||||
|
|
||||||
+1
-2
@@ -1,4 +1,3 @@
|
|||||||
// "Create trait 'A'" "true"
|
// "Create trait 'A'" "true"
|
||||||
// ERROR: Unresolved reference: A
|
// ERROR: Unresolved reference: A
|
||||||
fun foo(): J.A = throw Throwable("")
|
fun foo(): J.A = throw Throwable("")
|
||||||
|
|
||||||
+1
-2
@@ -3,5 +3,4 @@
|
|||||||
|
|
||||||
fun test(a: A): Int? {
|
fun test(a: A): Int? {
|
||||||
return a.foo<String, Int>(1, "2")
|
return a.foo<String, Int>(1, "2")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3,5 +3,4 @@
|
|||||||
|
|
||||||
fun test(): Int? {
|
fun test(): Int? {
|
||||||
return A().foo(1, "2")
|
return A().foo(1, "2")
|
||||||
}
|
}
|
||||||
|
|
||||||
+1
-2
@@ -3,5 +3,4 @@
|
|||||||
|
|
||||||
fun test(): Int {
|
fun test(): Int {
|
||||||
return A().foo<String, Int>(1, "2")
|
return A().foo<String, Int>(1, "2")
|
||||||
}
|
}
|
||||||
|
|
||||||
+1
@@ -4,3 +4,4 @@
|
|||||||
fun test() {
|
fun test() {
|
||||||
val a: Int = J.<caret>foo("1", 2)
|
val a: Int = J.<caret>foo("1", 2)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
class B<T>{
|
class B<T>{
|
||||||
final T t;
|
final T t;
|
||||||
|
|
||||||
public <U, V, W> U foo(V v, W w) {
|
public <U, V> U foo(U u, V v) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
@@ -4,3 +4,4 @@
|
|||||||
fun test() {
|
fun test() {
|
||||||
val a: Int = J.<caret>foo
|
val a: Int = J.<caret>foo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
@@ -4,3 +4,4 @@
|
|||||||
fun test() {
|
fun test() {
|
||||||
val a: Int = J.<caret>foo
|
val a: Int = J.<caret>foo
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-2
@@ -3,5 +3,4 @@
|
|||||||
|
|
||||||
fun test(): String? {
|
fun test(): String? {
|
||||||
return A().foo
|
return A().foo
|
||||||
}
|
}
|
||||||
|
|
||||||
+1
-2
@@ -3,5 +3,4 @@
|
|||||||
|
|
||||||
fun test() {
|
fun test() {
|
||||||
A().foo = ""
|
A().foo = ""
|
||||||
}
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user