Create from usage: Support generation of nested Java classes from usages in Kotlin code

This commit is contained in:
Alexey Sedunov
2015-02-19 13:59:14 +03:00
parent 5cd477279b
commit 60d02dab0f
169 changed files with 1452 additions and 40 deletions
@@ -74,6 +74,10 @@ import com.intellij.psi.codeStyle.JavaCodeStyleManager
import com.intellij.psi.PsiModifier
import com.intellij.psi.PsiField
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.WritableScopeImpl
import org.jetbrains.kotlin.resolve.scopes.RedeclarationHandler
@@ -135,7 +139,7 @@ class CallableBuilderConfiguration(
trait CallablePlacement {
class WithReceiver(val receiverTypeCandidate: TypeCandidate): CallablePlacement
class NoReceiver(val containingElement: JetElement): CallablePlacement
class NoReceiver(val containingElement: PsiElement): CallablePlacement
}
class CallableBuilder(val config: CallableBuilderConfiguration) {
@@ -231,8 +235,14 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
val placement = placement
when {
placement is CallablePlacement.NoReceiver -> {
containingElement = placement.containingElement
receiverClassDescriptor = (containingElement as? JetClassOrObject)?.let { currentFileContext[BindingContext.CLASS, it] }
containingElement = placement.containingElement as? JetElement ?: config.currentFile
receiverClassDescriptor = with (placement.containingElement) {
when (this) {
is JetClassOrObject -> currentFileContext[BindingContext.CLASS, this]
is PsiClass -> getJavaClassDescriptor()
else -> null
}
}
}
placement is CallablePlacement.WithReceiver -> {
receiverClassDescriptor =
@@ -558,8 +568,9 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
}
private fun setupTypeReferencesForShortening(declaration: JetNamedDeclaration,
typeRefsToShorten: MutableList<JetElement>,
parameterTypeExpressions: List<TypeExpression>) {
parameterTypeExpressions: List<TypeExpression>): List<JetElement> {
val typeRefsToShorten = ArrayList<JetElement>()
if (config.isExtension) {
val receiverTypeRef = JetPsiFactory(declaration).createType(receiverTypeCandidate!!.theType.renderLong(typeParameterNameMap))
replaceWithLongerName(receiverTypeRef, receiverTypeCandidate.theType)
@@ -604,6 +615,8 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
parameterIndicesToShorten.stream()
.map { expandedValueParameters[it].getTypeReference() }
.filterNotNullTo(typeRefsToShorten)
return typeRefsToShorten
}
private fun setupFunctionBody(func: JetNamedFunction) {
@@ -768,19 +781,31 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
val newJavaMember: PsiMember = when (declaration) {
is JetNamedFunction -> {
val method = createJavaMethod(declaration, targetClass)
method.getModifierList().setModifierProperty(PsiModifier.FINAL, false)
method
createJavaMethod(declaration, targetClass)
}
is JetProperty -> {
createJavaField(declaration, targetClass)
}
is JetClass -> {
createJavaClass(declaration, targetClass)
}
else -> return false
}
val modifierList = newJavaMember.getModifierList()
if (newJavaMember is PsiMethod || newJavaMember is PsiClass) {
modifierList.setModifierProperty(PsiModifier.FINAL, false)
}
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);
@@ -790,6 +815,18 @@ class CallableBuilder(val config: CallableBuilderConfiguration) {
when (newJavaMember) {
is PsiMethod -> CreateFromUsageUtils.setupEditor(newJavaMember, targetEditor)
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)
@@ -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)) {
// change short type names to fully qualified ones (to be shortened below)
setupTypeReferencesForShortening(newDeclaration, elementsToShorten, parameterTypeExpressions)
elementsToShorten.addAll(typeRefsToShorten)
setupEditor(newDeclaration)
}
@@ -39,9 +39,19 @@ import org.jetbrains.kotlin.psi.JetReferenceExpression
import java.util.Arrays
import org.jetbrains.kotlin.psi.JetDotQualifiedExpression
import org.jetbrains.kotlin.psi.psiUtil.isDotReceiver
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiElement
public object CreateClassFromReferenceExpressionActionFactory : JetIntentionActionsFactory() {
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()
if (refExpr.getNonStrictParentOfType<JetTypeReference>() != null) return Collections.emptyList()
@@ -77,7 +87,7 @@ public object CreateClassFromReferenceExpressionActionFactory : JetIntentionActi
.filter {
when (it) {
ClassKind.ANNOTATION_CLASS -> inImport
ClassKind.ENUM_ENTRY -> inImport && targetParent is JetClass && targetParent.isEnum()
ClassKind.ENUM_ENTRY -> inImport && isEnum(targetParent)
else -> true
}
}
@@ -104,7 +114,7 @@ public object CreateClassFromReferenceExpressionActionFactory : JetIntentionActi
.filter {
filter(it) && when (it) {
ClassKind.OBJECT -> true
ClassKind.ENUM_ENTRY -> targetParent is JetClass && targetParent.isEnum()
ClassKind.ENUM_ENTRY -> isEnum(targetParent)
else -> false
}
}
@@ -42,6 +42,9 @@ import com.intellij.ide.util.DirectoryChooserUtil
import java.util.HashMap
import com.intellij.openapi.application.ApplicationManager
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) {
PLAIN_CLASS: ClassKind("class", "class")
@@ -70,6 +73,17 @@ public class CreateClassFromUsageFix(
override fun getText(): String =
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) {
fun createFileByPackage(psiPackage: PsiPackage): JetFile? {
val directories = psiPackage.getDirectories().filter { it.canRefactor() }
@@ -105,10 +119,10 @@ public class CreateClassFromUsageFix(
with (classInfo) {
val targetParent =
when (targetParent) {
is JetElement -> targetParent
is JetElement, is PsiClass -> targetParent
is PsiPackage -> createFileByPackage(targetParent)
else -> throw AssertionError("Unexpected element: " + targetParent.getText())
} as? JetElement ?: return
} ?: return
val constructorInfo = ConstructorInfo(classInfo, expectedTypeInfo)
val builder = CallableBuilderConfiguration(
@@ -45,6 +45,8 @@ import org.jetbrains.kotlin.idea.quickfix.DelegatingIntentionAction
import org.jetbrains.kotlin.idea.JetBundle
import com.intellij.psi.PsiPackage
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())
@@ -104,6 +106,8 @@ private fun JetExpression.getInheritableTypeInfo(
return TypeInfo.ByType(type, Variance.OUT_VARIANCE).noSubstitutions() to { classKind ->
when (classKind) {
ClassKind.ENUM_ENTRY -> isEnum && containingDeclaration == DescriptorToSourceUtils.descriptorToDeclaration(descriptor)
ClassKind.TRAIT -> containingDeclaration !is PsiClass
|| (descriptor as? ClassDescriptor)?.getKind() == ClassDescriptorKind.TRAIT
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.Kind
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.psi.PsiClass
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 {
val template = LightClassUtil.getLightClassMethod(function)
?: throw AssertionError("Can't generate light method: ${JetPsiUtil.getElementTextWithContext(function)}")
val factory = PsiElementFactory.SERVICE.getInstance(template.getProject())
val method = targetClass.add(factory.createMethod(template.getName(), template.getReturnType())) as PsiMethod
copyModifierListItems(template.getModifierList(), method.getModifierList())
val templateTypeParamList = template.getTypeParameterList()
if (templateTypeParamList != null) {
val targetTypeParamList = method.addAfter(factory.createTypeParameterList(), method.getModifierList()) as PsiTypeParameterList
val newTypeParams = templateTypeParamList.getTypeParameters()
.map { factory.createTypeParameter(it.getName(), it.getExtendsList().getReferencedTypes()) }
private fun copyTypeParameters<T: PsiTypeParameterListOwner>(
from: T,
to: T,
inserter: (T, PsiTypeParameterList) -> Unit
) where T : PsiNameIdentifierOwner {
val factory = PsiElementFactory.SERVICE.getInstance((from : PsiElement).getProject())
val templateTypeParams = from.getTypeParameterList()?.getTypeParameters() ?: PsiTypeParameter.EMPTY_ARRAY
if (templateTypeParams.isNotEmpty()) {
inserter(to, factory.createTypeParameterList())
val targetTypeParamList = to.getTypeParameterList()
val newTypeParams = templateTypeParams.map {
factory.createTypeParameter(it.getName(), it.getExtendsList().getReferencedTypes())
}
ChangeSignatureUtil.synchronizeList(
targetTypeParamList,
newTypeParams,
@@ -467,6 +474,29 @@ public fun createJavaMethod(function: JetNamedFunction, targetClass: PsiClass):
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 newParams = template.getParameterList().getParameters().map {
@@ -484,7 +514,7 @@ public fun createJavaMethod(function: JetNamedFunction, targetClass: PsiClass):
if (template.getModifierList().hasModifierProperty(PsiModifier.ABSTRACT) || targetClass.isInterface()) {
method.getBody().delete()
}
else {
else if (!template.isConstructor()) {
CreateFromUsageUtils.setupMethodBody(method)
}
@@ -509,3 +539,57 @@ fun createJavaField(property: JetProperty, targetClass: PsiClass): PsiField {
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
}
@@ -0,0 +1,6 @@
// "Create annotation 'foo'" "false"
// ERROR: Unresolved reference: foo
J.<caret>foo(1, "2") fun test() {
}
@@ -0,0 +1,8 @@
class J {
public static @interface foo {
int i();
String s();
}
}
@@ -0,0 +1,7 @@
// "Create annotation 'foo'" "true"
// ERROR: Unresolved reference: foo
J.foo(1, "2") fun test() {
}
@@ -0,0 +1,6 @@
// "Create annotation 'foo'" "true"
// ERROR: Unresolved reference: foo
J.<caret>foo(1, "2") fun test() {
}
@@ -0,0 +1,8 @@
class J {
public static @interface foo {
int count();
String name();
}
}
@@ -0,0 +1,7 @@
// "Create annotation 'foo'" "true"
// ERROR: Unresolved reference: foo
J.foo(count = 1, name = "2") fun test() {
}
@@ -0,0 +1,6 @@
// "Create annotation 'foo'" "true"
// ERROR: Unresolved reference: foo
J.<caret>foo(count = 1, name = "2") fun test() {
}
@@ -0,0 +1,8 @@
class J {
public static @interface bar {
String s();
int i();
}
}
@@ -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() {
}
@@ -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() {
}
@@ -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) {
}
}
}
@@ -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")
@@ -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")
@@ -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")
@@ -0,0 +1,10 @@
class J<T> {
public J(T n) {
}
public class Foo<U> {
public Foo(U u) {
}
}
}
@@ -0,0 +1,7 @@
// "Create class 'Foo'" "true"
// ERROR: Unresolved reference: Foo
fun test<U>(u: U) {
val a = J(u).Foo(u)
}
@@ -0,0 +1,6 @@
// "Create class 'Foo'" "true"
// ERROR: Unresolved reference: Foo
fun test<U>(u: U) {
val a = J(u).<caret>Foo(u)
}
@@ -0,0 +1,4 @@
// "Create class 'Foo'" "false"
// ERROR: Unresolved reference: Foo
fun test() = J.<caret>Foo(2, "2")
@@ -0,0 +1,7 @@
class J {
public static class Foo {
public Foo(int i) {
}
}
}
@@ -0,0 +1,7 @@
// "Create class 'Foo'" "true"
// ERROR: Unresolved reference: Foo
fun test() {
val a = J.Foo(2)
}
@@ -0,0 +1,6 @@
// "Create class 'Foo'" "true"
// ERROR: Unresolved reference: Foo
fun test() {
val a = J.<caret>Foo(2)
}
@@ -0,0 +1,7 @@
class J {
public class Foo {
public Foo(int i) {
}
}
}
@@ -0,0 +1,7 @@
// "Create class 'Foo'" "true"
// ERROR: Unresolved reference: Foo
fun test() {
val a = J().Foo(2)
}
@@ -1,9 +1,6 @@
// "Create class 'Foo'" "false"
// ACTION: Create extension function 'Foo'
// ACTION: Create function 'Foo'
// ACTION: Convert to expression body
// "Create class 'Foo'" "true"
// ERROR: Unresolved reference: Foo
fun test(): Int {
return A().<caret>Foo(1, "2")
fun test() {
val a = J().<caret>Foo(2)
}
@@ -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) {
}
}
}
@@ -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, "")
}
@@ -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, "")
}
@@ -0,0 +1,9 @@
import org.jetbrains.annotations.NotNull;
class J {
public static class Foo extends A {
public Foo(int i, @NotNull String s) {
}
}
}
@@ -0,0 +1,7 @@
// "Create class 'Foo'" "true"
// ERROR: Unresolved reference: Foo
open class A
fun test(): A = J.Foo(2, "2")
@@ -0,0 +1,6 @@
// "Create class 'Foo'" "true"
// ERROR: Unresolved reference: Foo
open class A
fun test(): A = J.<caret>Foo(2, "2")
@@ -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();
}
}
}
@@ -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")
@@ -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")
@@ -0,0 +1,9 @@
import org.jetbrains.annotations.NotNull;
class J {
public static class Foo implements T {
public Foo(int i, @NotNull String s) {
}
}
}
@@ -0,0 +1,7 @@
// "Create class 'Foo'" "true"
// ERROR: Unresolved reference: Foo
trait T
fun test(): T = J.Foo(2, "2")
@@ -0,0 +1,6 @@
// "Create class 'Foo'" "true"
// ERROR: Unresolved reference: Foo
trait T
fun test(): T = J.<caret>Foo(2, "2")
@@ -0,0 +1,8 @@
class B<T> {
final T t = null;
public static class Foo<U, V> {
public Foo(U u, V v) {
}
}
}
@@ -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")
}
@@ -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")
}
@@ -0,0 +1,8 @@
class B<T> {
final T t = null;
public class Foo<U, V> {
public Foo(U u, V v) {
}
}
}
@@ -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")
}
@@ -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")
}
@@ -0,0 +1,8 @@
class B<T> {
final T t = null;
public class Foo<U> {
public Foo(int i, U u) {
}
}
}
@@ -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")
}
@@ -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")
}
@@ -0,0 +1,8 @@
class B<T> {
final T t = null;
public class Foo<U, V, W> {
public Foo(V v, W w) {
}
}
}
@@ -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")
}
@@ -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")
}
@@ -0,0 +1,8 @@
class B<T> {
final T t = null;
public static class Foo<U> {
public Foo(int i, U u) {
}
}
}
@@ -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")
}
@@ -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")
}
@@ -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) {
}
}
}
@@ -0,0 +1,10 @@
// "Create class 'A'" "true"
// ERROR: Unresolved reference: A
class B {
}
class Foo: J.A(1, "2", B()) {
}
@@ -0,0 +1,9 @@
// "Create class 'A'" "true"
// ERROR: Unresolved reference: A
class B {
}
class Foo: J.<caret>A(1, "2", B()) {
}
@@ -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) {
}
}
}
@@ -0,0 +1,10 @@
// "Create class 'A'" "true"
// ERROR: Unresolved reference: A
class B {
}
class Foo: J.A(abc = 1, ghi = "2", def = B()) {
}
@@ -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()) {
}
@@ -0,0 +1,5 @@
// "Create trait 'A'" "false"
// ERROR: Unresolved reference: A
class Foo: J.<caret>A {
}
@@ -0,0 +1,6 @@
// "Create trait 'A'" "true"
// ERROR: Unresolved reference: A
class Foo: J.A {
}
@@ -0,0 +1,5 @@
// "Create trait 'A'" "true"
// ERROR: Unresolved reference: A
class Foo: J.<caret>A {
}
@@ -0,0 +1,5 @@
public class J {
public static @interface A {
}
}
@@ -0,0 +1,8 @@
// "Create annotation 'A'" "true"
// ERROR: Unresolved reference: A
import J.A
class X {
}
@@ -0,0 +1,7 @@
// "Create annotation 'A'" "true"
// ERROR: Unresolved reference: A
import J.<caret>A
class X {
}
@@ -0,0 +1,8 @@
// "Create class 'A'" "false"
// ERROR: Unresolved reference: A
// ACTION: Create property 'A'
import J.<caret>A
class X {
}
@@ -0,0 +1,5 @@
public class J {
public static class A {
}
}
@@ -0,0 +1,8 @@
// "Create class 'A'" "true"
// ERROR: Unresolved reference: A
import J.A
class X {
}
@@ -0,0 +1,7 @@
// "Create class 'A'" "true"
// ERROR: Unresolved reference: A
import J.<caret>A
class X {
}

Some files were not shown because too many files have changed in this diff Show More