Create from usage: Support generation of nested Java classes from usages in Kotlin code
This commit is contained in:
+49
-11
@@ -74,6 +74,10 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager
|
|||||||
import com.intellij.psi.PsiModifier
|
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 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
|
||||||
@@ -135,7 +139,7 @@ class CallableBuilderConfiguration(
|
|||||||
|
|
||||||
trait CallablePlacement {
|
trait CallablePlacement {
|
||||||
class WithReceiver(val receiverTypeCandidate: TypeCandidate): CallablePlacement
|
class WithReceiver(val receiverTypeCandidate: TypeCandidate): CallablePlacement
|
||||||
class NoReceiver(val containingElement: JetElement): CallablePlacement
|
class NoReceiver(val containingElement: PsiElement): CallablePlacement
|
||||||
}
|
}
|
||||||
|
|
||||||
class CallableBuilder(val config: CallableBuilderConfiguration) {
|
class CallableBuilder(val config: CallableBuilderConfiguration) {
|
||||||
@@ -231,8 +235,14 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
val placement = placement
|
val placement = placement
|
||||||
when {
|
when {
|
||||||
placement is CallablePlacement.NoReceiver -> {
|
placement is CallablePlacement.NoReceiver -> {
|
||||||
containingElement = placement.containingElement
|
containingElement = placement.containingElement as? JetElement ?: config.currentFile
|
||||||
receiverClassDescriptor = (containingElement as? JetClassOrObject)?.let { currentFileContext[BindingContext.CLASS, it] }
|
receiverClassDescriptor = with (placement.containingElement) {
|
||||||
|
when (this) {
|
||||||
|
is JetClassOrObject -> currentFileContext[BindingContext.CLASS, this]
|
||||||
|
is PsiClass -> getJavaClassDescriptor()
|
||||||
|
else -> null
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
placement is CallablePlacement.WithReceiver -> {
|
placement is CallablePlacement.WithReceiver -> {
|
||||||
receiverClassDescriptor =
|
receiverClassDescriptor =
|
||||||
@@ -558,8 +568,9 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun setupTypeReferencesForShortening(declaration: JetNamedDeclaration,
|
private fun setupTypeReferencesForShortening(declaration: JetNamedDeclaration,
|
||||||
typeRefsToShorten: MutableList<JetElement>,
|
parameterTypeExpressions: List<TypeExpression>): List<JetElement> {
|
||||||
parameterTypeExpressions: List<TypeExpression>) {
|
val typeRefsToShorten = ArrayList<JetElement>()
|
||||||
|
|
||||||
if (config.isExtension) {
|
if (config.isExtension) {
|
||||||
val receiverTypeRef = JetPsiFactory(declaration).createType(receiverTypeCandidate!!.theType.renderLong(typeParameterNameMap))
|
val receiverTypeRef = JetPsiFactory(declaration).createType(receiverTypeCandidate!!.theType.renderLong(typeParameterNameMap))
|
||||||
replaceWithLongerName(receiverTypeRef, receiverTypeCandidate.theType)
|
replaceWithLongerName(receiverTypeRef, receiverTypeCandidate.theType)
|
||||||
@@ -604,6 +615,8 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
parameterIndicesToShorten.stream()
|
parameterIndicesToShorten.stream()
|
||||||
.map { expandedValueParameters[it].getTypeReference() }
|
.map { expandedValueParameters[it].getTypeReference() }
|
||||||
.filterNotNullTo(typeRefsToShorten)
|
.filterNotNullTo(typeRefsToShorten)
|
||||||
|
|
||||||
|
return typeRefsToShorten
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupFunctionBody(func: JetNamedFunction) {
|
private fun setupFunctionBody(func: JetNamedFunction) {
|
||||||
@@ -768,19 +781,31 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
|
|
||||||
val newJavaMember: PsiMember = when (declaration) {
|
val newJavaMember: PsiMember = when (declaration) {
|
||||||
is JetNamedFunction -> {
|
is JetNamedFunction -> {
|
||||||
val method = createJavaMethod(declaration, targetClass)
|
createJavaMethod(declaration, targetClass)
|
||||||
method.getModifierList().setModifierProperty(PsiModifier.FINAL, false)
|
|
||||||
method
|
|
||||||
}
|
}
|
||||||
is JetProperty -> {
|
is JetProperty -> {
|
||||||
createJavaField(declaration, targetClass)
|
createJavaField(declaration, targetClass)
|
||||||
}
|
}
|
||||||
|
is JetClass -> {
|
||||||
|
createJavaClass(declaration, targetClass)
|
||||||
|
}
|
||||||
else -> return false
|
else -> return false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val modifierList = newJavaMember.getModifierList()
|
||||||
|
if (newJavaMember is PsiMethod || newJavaMember is PsiClass) {
|
||||||
|
modifierList.setModifierProperty(PsiModifier.FINAL, false)
|
||||||
|
}
|
||||||
|
|
||||||
declaration.delete()
|
declaration.delete()
|
||||||
|
|
||||||
newJavaMember.getModifierList().setModifierProperty(PsiModifier.STATIC, callableInfo.receiverTypeInfo.classObjectRequired)
|
val needStatic = when (callableInfo) {
|
||||||
|
is ConstructorInfo -> with(callableInfo.classInfo) {
|
||||||
|
!inner && kind != ClassKind.ENUM_ENTRY && kind != ClassKind.ENUM_CLASS
|
||||||
|
}
|
||||||
|
else -> callableInfo.receiverTypeInfo.classObjectRequired
|
||||||
|
}
|
||||||
|
modifierList.setModifierProperty(PsiModifier.STATIC, needStatic)
|
||||||
|
|
||||||
JavaCodeStyleManager.getInstance(project).shortenClassReferences(newJavaMember);
|
JavaCodeStyleManager.getInstance(project).shortenClassReferences(newJavaMember);
|
||||||
|
|
||||||
@@ -790,6 +815,18 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
when (newJavaMember) {
|
when (newJavaMember) {
|
||||||
is PsiMethod -> CreateFromUsageUtils.setupEditor(newJavaMember, targetEditor)
|
is PsiMethod -> CreateFromUsageUtils.setupEditor(newJavaMember, targetEditor)
|
||||||
is PsiField -> targetEditor.getCaretModel().moveToOffset(newJavaMember.getTextRange().getEndOffset() - 1)
|
is PsiField -> targetEditor.getCaretModel().moveToOffset(newJavaMember.getTextRange().getEndOffset() - 1)
|
||||||
|
is PsiClass -> {
|
||||||
|
val constructor = newJavaMember.getConstructors().firstOrNull()
|
||||||
|
val superStatement = constructor?.getBody()?.getStatements()?.firstOrNull() as? PsiExpressionStatement
|
||||||
|
val superCall = superStatement?.getExpression() as? PsiMethodCallExpression
|
||||||
|
if (superCall != null) {
|
||||||
|
val lParen = superCall.getArgumentList().getFirstChild()
|
||||||
|
targetEditor.getCaretModel().moveToOffset(lParen.getTextRange().getEndOffset())
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
targetEditor.getCaretModel().moveToOffset(newJavaMember.getTextRange().getStartOffset())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
targetEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE)
|
targetEditor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE)
|
||||||
|
|
||||||
@@ -895,9 +932,10 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// change short type names to fully qualified ones (to be shortened below)
|
||||||
|
val typeRefsToShorten = setupTypeReferencesForShortening(newDeclaration, parameterTypeExpressions)
|
||||||
if (!transformToJavaMemberIfApplicable(newDeclaration)) {
|
if (!transformToJavaMemberIfApplicable(newDeclaration)) {
|
||||||
// change short type names to fully qualified ones (to be shortened below)
|
elementsToShorten.addAll(typeRefsToShorten)
|
||||||
setupTypeReferencesForShortening(newDeclaration, elementsToShorten, parameterTypeExpressions)
|
|
||||||
setupEditor(newDeclaration)
|
setupEditor(newDeclaration)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+12
-2
@@ -39,9 +39,19 @@ import org.jetbrains.kotlin.psi.JetReferenceExpression
|
|||||||
import java.util.Arrays
|
import java.util.Arrays
|
||||||
import org.jetbrains.kotlin.psi.JetDotQualifiedExpression
|
import org.jetbrains.kotlin.psi.JetDotQualifiedExpression
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.isDotReceiver
|
import org.jetbrains.kotlin.psi.psiUtil.isDotReceiver
|
||||||
|
import com.intellij.psi.PsiClass
|
||||||
|
import com.intellij.psi.PsiElement
|
||||||
|
|
||||||
public object CreateClassFromReferenceExpressionActionFactory : JetIntentionActionsFactory() {
|
public object CreateClassFromReferenceExpressionActionFactory : JetIntentionActionsFactory() {
|
||||||
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction> {
|
override fun doCreateActions(diagnostic: Diagnostic): List<IntentionAction> {
|
||||||
|
fun isEnum(element: PsiElement): Boolean {
|
||||||
|
return when (element) {
|
||||||
|
is JetClass -> element.isEnum()
|
||||||
|
is PsiClass -> element.isEnum()
|
||||||
|
else -> false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val refExpr = diagnostic.getPsiElement() as? JetSimpleNameExpression ?: return Collections.emptyList()
|
val refExpr = diagnostic.getPsiElement() as? JetSimpleNameExpression ?: return Collections.emptyList()
|
||||||
if (refExpr.getNonStrictParentOfType<JetTypeReference>() != null) return Collections.emptyList()
|
if (refExpr.getNonStrictParentOfType<JetTypeReference>() != null) return Collections.emptyList()
|
||||||
|
|
||||||
@@ -77,7 +87,7 @@ public object CreateClassFromReferenceExpressionActionFactory : JetIntentionActi
|
|||||||
.filter {
|
.filter {
|
||||||
when (it) {
|
when (it) {
|
||||||
ClassKind.ANNOTATION_CLASS -> inImport
|
ClassKind.ANNOTATION_CLASS -> inImport
|
||||||
ClassKind.ENUM_ENTRY -> inImport && targetParent is JetClass && targetParent.isEnum()
|
ClassKind.ENUM_ENTRY -> inImport && isEnum(targetParent)
|
||||||
else -> true
|
else -> true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -104,7 +114,7 @@ public object CreateClassFromReferenceExpressionActionFactory : JetIntentionActi
|
|||||||
.filter {
|
.filter {
|
||||||
filter(it) && when (it) {
|
filter(it) && when (it) {
|
||||||
ClassKind.OBJECT -> true
|
ClassKind.OBJECT -> true
|
||||||
ClassKind.ENUM_ENTRY -> targetParent is JetClass && targetParent.isEnum()
|
ClassKind.ENUM_ENTRY -> isEnum(targetParent)
|
||||||
else -> false
|
else -> false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-2
@@ -42,6 +42,9 @@ import com.intellij.ide.util.DirectoryChooserUtil
|
|||||||
import java.util.HashMap
|
import java.util.HashMap
|
||||||
import com.intellij.openapi.application.ApplicationManager
|
import com.intellij.openapi.application.ApplicationManager
|
||||||
import org.jetbrains.kotlin.idea.refactoring.canRefactor
|
import org.jetbrains.kotlin.idea.refactoring.canRefactor
|
||||||
|
import com.intellij.psi.PsiMember
|
||||||
|
import com.intellij.psi.PsiClass
|
||||||
|
import com.intellij.psi.PsiFile
|
||||||
|
|
||||||
enum class ClassKind(val keyword: String, val description: String) {
|
enum class ClassKind(val keyword: String, val description: String) {
|
||||||
PLAIN_CLASS: ClassKind("class", "class")
|
PLAIN_CLASS: ClassKind("class", "class")
|
||||||
@@ -70,6 +73,17 @@ public class CreateClassFromUsageFix(
|
|||||||
override fun getText(): String =
|
override fun getText(): String =
|
||||||
JetBundle.message("create.0.from.usage", "${classInfo.kind.description} '${classInfo.name}'")
|
JetBundle.message("create.0.from.usage", "${classInfo.kind.description} '${classInfo.name}'")
|
||||||
|
|
||||||
|
override fun isAvailable(project: Project, editor: Editor?, file: PsiFile?): Boolean {
|
||||||
|
if (!super.isAvailable(project, editor, file)) return false
|
||||||
|
with(classInfo) {
|
||||||
|
if (targetParent is PsiClass) {
|
||||||
|
if (kind == OBJECT || kind == ENUM_ENTRY) return false
|
||||||
|
if (targetParent.isInterface() && inner) return false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
override fun invoke(project: Project, editor: Editor, file: JetFile) {
|
override fun invoke(project: Project, editor: Editor, file: JetFile) {
|
||||||
fun createFileByPackage(psiPackage: PsiPackage): JetFile? {
|
fun createFileByPackage(psiPackage: PsiPackage): JetFile? {
|
||||||
val directories = psiPackage.getDirectories().filter { it.canRefactor() }
|
val directories = psiPackage.getDirectories().filter { it.canRefactor() }
|
||||||
@@ -105,10 +119,10 @@ public class CreateClassFromUsageFix(
|
|||||||
with (classInfo) {
|
with (classInfo) {
|
||||||
val targetParent =
|
val targetParent =
|
||||||
when (targetParent) {
|
when (targetParent) {
|
||||||
is JetElement -> targetParent
|
is JetElement, is PsiClass -> targetParent
|
||||||
is PsiPackage -> createFileByPackage(targetParent)
|
is PsiPackage -> createFileByPackage(targetParent)
|
||||||
else -> throw AssertionError("Unexpected element: " + targetParent.getText())
|
else -> throw AssertionError("Unexpected element: " + targetParent.getText())
|
||||||
} as? JetElement ?: return
|
} ?: return
|
||||||
|
|
||||||
val constructorInfo = ConstructorInfo(classInfo, expectedTypeInfo)
|
val constructorInfo = ConstructorInfo(classInfo, expectedTypeInfo)
|
||||||
val builder = CallableBuilderConfiguration(
|
val builder = CallableBuilderConfiguration(
|
||||||
|
|||||||
+4
@@ -45,6 +45,8 @@ import org.jetbrains.kotlin.idea.quickfix.DelegatingIntentionAction
|
|||||||
import org.jetbrains.kotlin.idea.JetBundle
|
import org.jetbrains.kotlin.idea.JetBundle
|
||||||
import com.intellij.psi.PsiPackage
|
import com.intellij.psi.PsiPackage
|
||||||
import org.jetbrains.kotlin.idea.refactoring.canRefactor
|
import org.jetbrains.kotlin.idea.refactoring.canRefactor
|
||||||
|
import com.intellij.psi.PsiClass
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassKind as ClassDescriptorKind
|
||||||
|
|
||||||
private fun String.checkClassName(): Boolean = isNotEmpty() && Character.isUpperCase(first())
|
private fun String.checkClassName(): Boolean = isNotEmpty() && Character.isUpperCase(first())
|
||||||
|
|
||||||
@@ -104,6 +106,8 @@ private fun JetExpression.getInheritableTypeInfo(
|
|||||||
return TypeInfo.ByType(type, Variance.OUT_VARIANCE).noSubstitutions() to { classKind ->
|
return TypeInfo.ByType(type, Variance.OUT_VARIANCE).noSubstitutions() to { classKind ->
|
||||||
when (classKind) {
|
when (classKind) {
|
||||||
ClassKind.ENUM_ENTRY -> isEnum && containingDeclaration == DescriptorToSourceUtils.descriptorToDeclaration(descriptor)
|
ClassKind.ENUM_ENTRY -> isEnum && containingDeclaration == DescriptorToSourceUtils.descriptorToDeclaration(descriptor)
|
||||||
|
ClassKind.TRAIT -> containingDeclaration !is PsiClass
|
||||||
|
|| (descriptor as? ClassDescriptor)?.getKind() == ClassDescriptorKind.TRAIT
|
||||||
else -> canHaveSubtypes
|
else -> canHaveSubtypes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* 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.refactoring
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiReferenceList
|
||||||
|
import com.intellij.psi.PsiReferenceList.Role
|
||||||
|
import com.intellij.psi.PsiElementFactory
|
||||||
|
import com.intellij.psi.PsiJavaCodeReferenceElement
|
||||||
|
import org.jetbrains.kotlin.load.java.*
|
||||||
|
|
||||||
|
public fun PsiElementFactory.createReferenceListWithRole(
|
||||||
|
references: Array<PsiJavaCodeReferenceElement>,
|
||||||
|
role: Role
|
||||||
|
): PsiReferenceList? {
|
||||||
|
val filteredRefs = references.map { it.getCanonicalText() }.filter { it != JvmAbi.K_OBJECT.asString() }
|
||||||
|
val refListText = if (filteredRefs.isNotEmpty()) filteredRefs.joinToString() else return null
|
||||||
|
return when (role) {
|
||||||
|
Role.THROWS_LIST -> createMethodFromText("void foo() throws $refListText {}", null).getThrowsList()
|
||||||
|
Role.EXTENDS_LIST -> createClassFromText("class Foo extends $refListText {}", null).getInnerClasses()[0].getExtendsList()
|
||||||
|
Role.IMPLEMENTS_LIST -> createClassFromText("class Foo implements $refListText {}", null).getInnerClasses()[0].getImplementsList()
|
||||||
|
Role.EXTENDS_BOUNDS_LIST -> createTypeParameterFromText("T extends $refListText", null).getExtendsList()
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -86,6 +86,14 @@ import com.intellij.util.VisibilityUtil
|
|||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor.Kind
|
||||||
import org.jetbrains.kotlin.resolve.OverridingUtil
|
import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||||
|
import com.intellij.psi.PsiReferenceList
|
||||||
|
import com.intellij.psi.PsiTypeParameter
|
||||||
|
import com.intellij.psi.PsiTypeParameterListOwner
|
||||||
|
import com.intellij.psi.PsiNameIdentifierOwner
|
||||||
|
import com.intellij.psi.PsiJavaCodeReferenceElement
|
||||||
import com.intellij.lang.java.JavaLanguage
|
import com.intellij.lang.java.JavaLanguage
|
||||||
import com.intellij.psi.PsiClass
|
import com.intellij.psi.PsiClass
|
||||||
import com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageUtils
|
import com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageUtils
|
||||||
@@ -446,20 +454,19 @@ private fun copyModifierListItems(from: PsiModifierList, to: PsiModifierList, wi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun createJavaMethod(function: JetNamedFunction, targetClass: PsiClass): PsiMethod {
|
private fun copyTypeParameters<T: PsiTypeParameterListOwner>(
|
||||||
val template = LightClassUtil.getLightClassMethod(function)
|
from: T,
|
||||||
?: throw AssertionError("Can't generate light method: ${JetPsiUtil.getElementTextWithContext(function)}")
|
to: T,
|
||||||
|
inserter: (T, PsiTypeParameterList) -> Unit
|
||||||
val factory = PsiElementFactory.SERVICE.getInstance(template.getProject())
|
) where T : PsiNameIdentifierOwner {
|
||||||
val method = targetClass.add(factory.createMethod(template.getName(), template.getReturnType())) as PsiMethod
|
val factory = PsiElementFactory.SERVICE.getInstance((from : PsiElement).getProject())
|
||||||
|
val templateTypeParams = from.getTypeParameterList()?.getTypeParameters() ?: PsiTypeParameter.EMPTY_ARRAY
|
||||||
copyModifierListItems(template.getModifierList(), method.getModifierList())
|
if (templateTypeParams.isNotEmpty()) {
|
||||||
|
inserter(to, factory.createTypeParameterList())
|
||||||
val templateTypeParamList = template.getTypeParameterList()
|
val targetTypeParamList = to.getTypeParameterList()
|
||||||
if (templateTypeParamList != null) {
|
val newTypeParams = templateTypeParams.map {
|
||||||
val targetTypeParamList = method.addAfter(factory.createTypeParameterList(), method.getModifierList()) as PsiTypeParameterList
|
factory.createTypeParameter(it.getName(), it.getExtendsList().getReferencedTypes())
|
||||||
val newTypeParams = templateTypeParamList.getTypeParameters()
|
}
|
||||||
.map { factory.createTypeParameter(it.getName(), it.getExtendsList().getReferencedTypes()) }
|
|
||||||
ChangeSignatureUtil.synchronizeList(
|
ChangeSignatureUtil.synchronizeList(
|
||||||
targetTypeParamList,
|
targetTypeParamList,
|
||||||
newTypeParams,
|
newTypeParams,
|
||||||
@@ -467,6 +474,29 @@ public fun createJavaMethod(function: JetNamedFunction, targetClass: PsiClass):
|
|||||||
BooleanArray(newTypeParams.size())
|
BooleanArray(newTypeParams.size())
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun createJavaMethod(function: JetNamedFunction, targetClass: PsiClass): PsiMethod {
|
||||||
|
val template = LightClassUtil.getLightClassMethod(function)
|
||||||
|
?: throw AssertionError("Can't generate light method: ${JetPsiUtil.getElementTextWithContext(function)}")
|
||||||
|
return createJavaMethod(template, targetClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun createJavaMethod(template: PsiMethod, targetClass: PsiClass): PsiMethod {
|
||||||
|
val factory = PsiElementFactory.SERVICE.getInstance(template.getProject())
|
||||||
|
val methodToAdd = if (template.isConstructor()) {
|
||||||
|
factory.createConstructor(template.getName())
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
factory.createMethod(template.getName(), template.getReturnType())
|
||||||
|
}
|
||||||
|
val method = targetClass.add(methodToAdd) as PsiMethod
|
||||||
|
|
||||||
|
copyModifierListItems(template.getModifierList(), method.getModifierList())
|
||||||
|
|
||||||
|
copyTypeParameters(template, method) { (method, typeParameterList) ->
|
||||||
|
method.addAfter(typeParameterList, method.getModifierList())
|
||||||
|
}
|
||||||
|
|
||||||
val targetParamList = method.getParameterList()
|
val targetParamList = method.getParameterList()
|
||||||
val newParams = template.getParameterList().getParameters().map {
|
val newParams = template.getParameterList().getParameters().map {
|
||||||
@@ -484,7 +514,7 @@ public fun createJavaMethod(function: JetNamedFunction, targetClass: PsiClass):
|
|||||||
if (template.getModifierList().hasModifierProperty(PsiModifier.ABSTRACT) || targetClass.isInterface()) {
|
if (template.getModifierList().hasModifierProperty(PsiModifier.ABSTRACT) || targetClass.isInterface()) {
|
||||||
method.getBody().delete()
|
method.getBody().delete()
|
||||||
}
|
}
|
||||||
else {
|
else if (!template.isConstructor()) {
|
||||||
CreateFromUsageUtils.setupMethodBody(method)
|
CreateFromUsageUtils.setupMethodBody(method)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -509,3 +539,57 @@ fun createJavaField(property: JetProperty, targetClass: PsiClass): PsiField {
|
|||||||
|
|
||||||
return field
|
return field
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun createJavaClass(klass: JetClass, targetClass: PsiClass): PsiMember {
|
||||||
|
val kind = (klass.resolveToDescriptor() as ClassDescriptor).getKind()
|
||||||
|
|
||||||
|
val factory = PsiElementFactory.SERVICE.getInstance(klass.getProject())
|
||||||
|
val javaClassToAdd = when (kind) {
|
||||||
|
ClassKind.CLASS -> factory.createClass(klass.getName())
|
||||||
|
ClassKind.TRAIT -> factory.createInterface(klass.getName())
|
||||||
|
ClassKind.ANNOTATION_CLASS -> factory.createAnnotationType(klass.getName())
|
||||||
|
ClassKind.ENUM_CLASS -> factory.createEnum(klass.getName())
|
||||||
|
else -> throw AssertionError("Unexpected class kind: ${JetPsiUtil.getElementTextWithContext(klass)}")
|
||||||
|
}
|
||||||
|
val javaClass = targetClass.add(javaClassToAdd) as PsiClass
|
||||||
|
|
||||||
|
val template = LightClassUtil.getPsiClass(klass)
|
||||||
|
?: throw AssertionError("Can't generate light class: ${JetPsiUtil.getElementTextWithContext(klass)}")
|
||||||
|
|
||||||
|
copyModifierListItems(template.getModifierList(), javaClass.getModifierList())
|
||||||
|
if (template.isInterface()) {
|
||||||
|
javaClass.getModifierList().setModifierProperty(PsiModifier.ABSTRACT, false)
|
||||||
|
}
|
||||||
|
|
||||||
|
copyTypeParameters(template, javaClass) { (klass, typeParameterList) ->
|
||||||
|
klass.addAfter(typeParameterList, klass.getNameIdentifier())
|
||||||
|
}
|
||||||
|
|
||||||
|
val extendsList = factory.createReferenceListWithRole(
|
||||||
|
template.getExtendsList()?.getReferenceElements() ?: PsiJavaCodeReferenceElement.EMPTY_ARRAY,
|
||||||
|
PsiReferenceList.Role.EXTENDS_LIST
|
||||||
|
)
|
||||||
|
extendsList?.let { javaClass.getExtendsList()?.replace(it) }
|
||||||
|
|
||||||
|
val implementsList = factory.createReferenceListWithRole(
|
||||||
|
template.getImplementsList()?.getReferenceElements() ?: PsiJavaCodeReferenceElement.EMPTY_ARRAY,
|
||||||
|
PsiReferenceList.Role.IMPLEMENTS_LIST
|
||||||
|
)
|
||||||
|
implementsList?.let { javaClass.getImplementsList()?.replace(it) }
|
||||||
|
|
||||||
|
for (method in template.getMethods()) {
|
||||||
|
val hasParams = method.getParameterList().getParametersCount() > 0
|
||||||
|
val needSuperCall = !template.isEnum() &&
|
||||||
|
(template.getSuperClass()?.getConstructors() ?: PsiMethod.EMPTY_ARRAY).all {
|
||||||
|
it.getParameterList().getParametersCount() > 0
|
||||||
|
}
|
||||||
|
if (method.isConstructor() && !(hasParams || needSuperCall)) continue
|
||||||
|
with(createJavaMethod(method, javaClass)) {
|
||||||
|
if (isConstructor() && needSuperCall) {
|
||||||
|
getBody().add(factory.createStatementFromText("super();", this))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return javaClass
|
||||||
|
}
|
||||||
|
|||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// "Create annotation 'foo'" "false"
|
||||||
|
// ERROR: Unresolved reference: foo
|
||||||
|
|
||||||
|
J.<caret>foo(1, "2") fun test() {
|
||||||
|
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class J {
|
||||||
|
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
class J {
|
||||||
|
|
||||||
|
public static @interface foo {
|
||||||
|
int i();
|
||||||
|
|
||||||
|
String s();
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// "Create annotation 'foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: foo
|
||||||
|
|
||||||
|
J.foo(1, "2") fun test() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// "Create annotation 'foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: foo
|
||||||
|
|
||||||
|
J.<caret>foo(1, "2") fun test() {
|
||||||
|
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class J {
|
||||||
|
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
class J {
|
||||||
|
|
||||||
|
public static @interface foo {
|
||||||
|
int count();
|
||||||
|
|
||||||
|
String name();
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// "Create annotation 'foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: foo
|
||||||
|
|
||||||
|
J.foo(count = 1, name = "2") fun test() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// "Create annotation 'foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: foo
|
||||||
|
|
||||||
|
J.<caret>foo(count = 1, name = "2") fun test() {
|
||||||
|
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class J {
|
||||||
|
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
class J {
|
||||||
|
|
||||||
|
public static @interface bar {
|
||||||
|
String s();
|
||||||
|
|
||||||
|
int i();
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
// "Create annotation 'bar'" "true"
|
||||||
|
// ERROR: Unresolved reference: foo
|
||||||
|
// ERROR: Unresolved reference: bar
|
||||||
|
|
||||||
|
[foo(1, "2", J.bar("3", 4))] fun test() {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// "Create annotation 'bar'" "true"
|
||||||
|
// ERROR: Unresolved reference: foo
|
||||||
|
// ERROR: Unresolved reference: bar
|
||||||
|
|
||||||
|
[foo(1, "2", J.<caret>bar("3", 4))] fun test() {
|
||||||
|
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class J {
|
||||||
|
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
class J {
|
||||||
|
|
||||||
|
public static class Foo {
|
||||||
|
public Foo(int abc, @NotNull A ghi, @NotNull String def) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
class A(val n: Int)
|
||||||
|
|
||||||
|
fun test() = J.Foo(abc = 1, ghi = A(2), def = "s")
|
||||||
|
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
class A(val n: Int)
|
||||||
|
|
||||||
|
fun test() = J.<caret>Foo(abc = 1, ghi = A(2), def = "s")
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class J {
|
||||||
|
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// "Create class 'Foo'" "false"
|
||||||
|
// ACTION: Create function 'Foo'
|
||||||
|
// ACTION: Convert to block body
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
fun test(): A = <caret>Foo(2, "2")
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
final class A {
|
||||||
|
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
class J<T> {
|
||||||
|
public J(T n) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public class Foo<U> {
|
||||||
|
public Foo(U u) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
fun test<U>(u: U) {
|
||||||
|
val a = J(u).Foo(u)
|
||||||
|
}
|
||||||
|
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
fun test<U>(u: U) {
|
||||||
|
val a = J(u).<caret>Foo(u)
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
class J<T> {
|
||||||
|
public J(T n) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
+4
@@ -0,0 +1,4 @@
|
|||||||
|
// "Create class 'Foo'" "false"
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
fun test() = J.<caret>Foo(2, "2")
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class J {
|
||||||
|
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
class J {
|
||||||
|
|
||||||
|
public static class Foo {
|
||||||
|
public Foo(int i) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val a = J.Foo(2)
|
||||||
|
}
|
||||||
|
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val a = J.<caret>Foo(2)
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class J {
|
||||||
|
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
class J {
|
||||||
|
|
||||||
|
public class Foo {
|
||||||
|
public Foo(int i) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
val a = J().Foo(2)
|
||||||
|
}
|
||||||
|
|
||||||
+3
-6
@@ -1,9 +1,6 @@
|
|||||||
// "Create class 'Foo'" "false"
|
// "Create class 'Foo'" "true"
|
||||||
// ACTION: Create extension function 'Foo'
|
|
||||||
// ACTION: Create function 'Foo'
|
|
||||||
// ACTION: Convert to expression body
|
|
||||||
// ERROR: Unresolved reference: Foo
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
fun test(): Int {
|
fun test() {
|
||||||
return A().<caret>Foo(1, "2")
|
val a = J().<caret>Foo(2)
|
||||||
}
|
}
|
||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
class A {
|
class J {
|
||||||
|
|
||||||
}
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
import kotlin.properties.ReadOnlyProperty;
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
class J {
|
||||||
|
|
||||||
|
public static class Foo<T> implements ReadOnlyProperty<A<T>, B> {
|
||||||
|
public Foo(T t, @NotNull String s) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
open class B
|
||||||
|
|
||||||
|
class A<T>(val t: T) {
|
||||||
|
val x: B by J.Foo(t, "")
|
||||||
|
}
|
||||||
|
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// WITH_RUNTIME
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
open class B
|
||||||
|
|
||||||
|
class A<T>(val t: T) {
|
||||||
|
val x: B by J.<caret>Foo(t, "")
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class J {
|
||||||
|
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
class J {
|
||||||
|
|
||||||
|
public static class Foo extends A {
|
||||||
|
public Foo(int i, @NotNull String s) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
open class A
|
||||||
|
|
||||||
|
fun test(): A = J.Foo(2, "2")
|
||||||
|
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
open class A
|
||||||
|
|
||||||
|
fun test(): A = J.<caret>Foo(2, "2")
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class J {
|
||||||
|
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
class J {
|
||||||
|
|
||||||
|
public static class Foo extends A {
|
||||||
|
public Foo(int i, @NotNull String s) {
|
||||||
|
super();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
open class A(val n: Int)
|
||||||
|
|
||||||
|
fun test(): A = J.Foo(2, "2")
|
||||||
|
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
open class A(val n: Int)
|
||||||
|
|
||||||
|
fun test(): A = J.<caret>Foo(2, "2")
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class J {
|
||||||
|
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
class J {
|
||||||
|
|
||||||
|
public static class Foo implements T {
|
||||||
|
public Foo(int i, @NotNull String s) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
trait T
|
||||||
|
|
||||||
|
fun test(): T = J.Foo(2, "2")
|
||||||
|
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
trait T
|
||||||
|
|
||||||
|
fun test(): T = J.<caret>Foo(2, "2")
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class J {
|
||||||
|
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
class B<T> {
|
||||||
|
final T t = null;
|
||||||
|
|
||||||
|
public static class Foo<U, V> {
|
||||||
|
public Foo(U u, V v) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
class A<T>(val b: B<T>) {
|
||||||
|
fun test() = B.Foo<Int, String>(2, "2")
|
||||||
|
}
|
||||||
|
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
class A<T>(val b: B<T>) {
|
||||||
|
fun test() = B.<caret>Foo<Int, String>(2, "2")
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class B<T> {
|
||||||
|
final T t = null;
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
class B<T> {
|
||||||
|
final T t = null;
|
||||||
|
|
||||||
|
public class Foo<U, V> {
|
||||||
|
public Foo(U u, V v) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
class A<T>(val b: B<T>) {
|
||||||
|
fun test() = b.Foo<Int, String>(2, "2")
|
||||||
|
}
|
||||||
|
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
class A<T>(val b: B<T>) {
|
||||||
|
fun test() = b.<caret>Foo<Int, String>(2, "2")
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class B<T> {
|
||||||
|
final T t = null;
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
class B<T> {
|
||||||
|
final T t = null;
|
||||||
|
|
||||||
|
public class Foo<U> {
|
||||||
|
public Foo(int i, U u) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
class A<T>(val b: B<T>) {
|
||||||
|
fun test() = b.Foo<String>(2, "2")
|
||||||
|
}
|
||||||
|
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
class A<T>(val b: B<T>) {
|
||||||
|
fun test() = b.<caret>Foo<String>(2, "2")
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class B<T> {
|
||||||
|
final T t = null;
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
class B<T> {
|
||||||
|
final T t = null;
|
||||||
|
|
||||||
|
public class Foo<U, V, W> {
|
||||||
|
public Foo(V v, W w) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
class A<T>(val b: B<T>) {
|
||||||
|
fun test() = b.Foo<T, Int, String>(2, "2")
|
||||||
|
}
|
||||||
|
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
class A<T>(val b: B<T>) {
|
||||||
|
fun test() = b.<caret>Foo<T, Int, String>(2, "2")
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class B<T> {
|
||||||
|
final T t = null;
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
class B<T> {
|
||||||
|
final T t = null;
|
||||||
|
|
||||||
|
public static class Foo<U> {
|
||||||
|
public Foo(int i, U u) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
class A<T>(val b: B<T>) {
|
||||||
|
fun test() = B.Foo<String>(2, "2")
|
||||||
|
}
|
||||||
|
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// "Create class 'Foo'" "true"
|
||||||
|
// ERROR: Unresolved reference: Foo
|
||||||
|
|
||||||
|
class A<T>(val b: B<T>) {
|
||||||
|
fun test() = B.<caret>Foo<String>(2, "2")
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class B<T> {
|
||||||
|
final T t = null;
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
class J {
|
||||||
|
|
||||||
|
public static class A {
|
||||||
|
public A(int i, @NotNull String s, @NotNull B B) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
// "Create class 'A'" "true"
|
||||||
|
// ERROR: Unresolved reference: A
|
||||||
|
class B {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Foo: J.A(1, "2", B()) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// "Create class 'A'" "true"
|
||||||
|
// ERROR: Unresolved reference: A
|
||||||
|
class B {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Foo: J.<caret>A(1, "2", B()) {
|
||||||
|
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class J {
|
||||||
|
|
||||||
|
}
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
class J {
|
||||||
|
|
||||||
|
public static class A {
|
||||||
|
public A(int abc, @NotNull String ghi, @NotNull B def) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+10
@@ -0,0 +1,10 @@
|
|||||||
|
// "Create class 'A'" "true"
|
||||||
|
// ERROR: Unresolved reference: A
|
||||||
|
class B {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Foo: J.A(abc = 1, ghi = "2", def = B()) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
+9
@@ -0,0 +1,9 @@
|
|||||||
|
// "Create class 'A'" "true"
|
||||||
|
// ERROR: Unresolved reference: A
|
||||||
|
class B {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class Foo: J.<caret>A(abc = 1, ghi = "2", def = B()) {
|
||||||
|
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class J {
|
||||||
|
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
// "Create trait 'A'" "false"
|
||||||
|
// ERROR: Unresolved reference: A
|
||||||
|
class Foo: J.<caret>A {
|
||||||
|
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class J {
|
||||||
|
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
class J {
|
||||||
|
|
||||||
|
public static interface A {
|
||||||
|
}
|
||||||
|
}
|
||||||
+6
@@ -0,0 +1,6 @@
|
|||||||
|
// "Create trait 'A'" "true"
|
||||||
|
// ERROR: Unresolved reference: A
|
||||||
|
class Foo: J.A {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
// "Create trait 'A'" "true"
|
||||||
|
// ERROR: Unresolved reference: A
|
||||||
|
class Foo: J.<caret>A {
|
||||||
|
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
class J {
|
||||||
|
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
public class J {
|
||||||
|
|
||||||
|
public static @interface A {
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
// "Create annotation 'A'" "true"
|
||||||
|
// ERROR: Unresolved reference: A
|
||||||
|
import J.A
|
||||||
|
|
||||||
|
class X {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// "Create annotation 'A'" "true"
|
||||||
|
// ERROR: Unresolved reference: A
|
||||||
|
import J.<caret>A
|
||||||
|
|
||||||
|
class X {
|
||||||
|
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
public class J {
|
||||||
|
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
// "Create class 'A'" "false"
|
||||||
|
// ERROR: Unresolved reference: A
|
||||||
|
// ACTION: Create property 'A'
|
||||||
|
import J.<caret>A
|
||||||
|
|
||||||
|
class X {
|
||||||
|
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
public class J {
|
||||||
|
|
||||||
|
}
|
||||||
+5
@@ -0,0 +1,5 @@
|
|||||||
|
public class J {
|
||||||
|
|
||||||
|
public static class A {
|
||||||
|
}
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
// "Create class 'A'" "true"
|
||||||
|
// ERROR: Unresolved reference: A
|
||||||
|
import J.A
|
||||||
|
|
||||||
|
class X {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
// "Create class 'A'" "true"
|
||||||
|
// ERROR: Unresolved reference: A
|
||||||
|
import J.<caret>A
|
||||||
|
|
||||||
|
class X {
|
||||||
|
|
||||||
|
}
|
||||||
+3
@@ -0,0 +1,3 @@
|
|||||||
|
public class J {
|
||||||
|
|
||||||
|
}
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user