diff --git a/plugins/annotation-processing/testData/javaWrappers/Simple/Simple.txt b/plugins/annotation-processing/testData/javaWrappers/Simple/Simple.txt index d12fdcd50f6..c7215571bb8 100644 --- a/plugins/annotation-processing/testData/javaWrappers/Simple/Simple.txt +++ b/plugins/annotation-processing/testData/javaWrappers/Simple/Simple.txt @@ -13,4 +13,6 @@ public abstract class Simple { abstract void voidMethod() protected java.lang.String strMethod(int param) + + public void () } \ No newline at end of file diff --git a/plugins/annotation-processing/testData/javaWrappers/WithNested/WithNested.txt b/plugins/annotation-processing/testData/javaWrappers/WithNested/WithNested.txt index 4701d212eb0..45cfca8574f 100644 --- a/plugins/annotation-processing/testData/javaWrappers/WithNested/WithNested.txt +++ b/plugins/annotation-processing/testData/javaWrappers/WithNested/WithNested.txt @@ -3,6 +3,8 @@ class WithNested { static class NestedClass { void nestedClassFun() + + void () } class InnerClass { @@ -10,10 +12,16 @@ class WithNested { class InnerInnerClass { void innerInnerClassFun() + + void (WithNested.InnerClass $instance) } + + void (WithNested $instance) } static abstract interface NestedInterface { public abstract void nestedInterfaceFun() } + + void () } \ No newline at end of file diff --git a/plugins/annotation-processing/testData/kotlinWrappers/nestedClasses.txt b/plugins/annotation-processing/testData/kotlinWrappers/nestedClasses.txt index 0f0ce5534cd..eec19262b77 100644 --- a/plugins/annotation-processing/testData/kotlinWrappers/nestedClasses.txt +++ b/plugins/annotation-processing/testData/kotlinWrappers/nestedClasses.txt @@ -48,6 +48,8 @@ public final class MyClass { public static final class DefaultImpls { public static int innerInterfaceFunWithImpl(MyClass.InnerInterface $this) + + public void () } } } \ No newline at end of file diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeTypeElement.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeTypeElement.kt index 9654b5bada5..3eeca91af3c 100644 --- a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeTypeElement.kt +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeTypeElement.kt @@ -21,6 +21,7 @@ import com.intellij.psi.impl.source.PsiClassReferenceType import com.intellij.psi.util.ClassUtil import com.intellij.psi.util.PsiTypesUtil import org.jetbrains.kotlin.java.model.* +import org.jetbrains.kotlin.java.model.internal.DefaultConstructorPsiMethod import org.jetbrains.kotlin.java.model.types.JeNoneType import org.jetbrains.kotlin.java.model.types.toJeType import javax.lang.model.element.* @@ -75,9 +76,35 @@ class JeTypeElement(override val psi: PsiClass) : JeElement, TypeElement, JeAnno psi.fields.forEach { declarations += JeVariableElement(it) } psi.methods.forEach { declarations += JeMethodExecutableElement(it) } psi.innerClasses.forEach { declarations += JeTypeElement(it) } + + // Add default constructor if possible + if (!psi.isInterface && !psi.isAnnotationType && psi.constructors.isEmpty()) { + val superClass = psi.superClass + val canHaveDefaultConstructor = superClass == null || run { + val constructors = superClass.constructors + constructors.isEmpty() || constructors.any { + (it.hasModifierProperty(PsiModifier.PUBLIC) || it.hasModifierProperty(PsiModifier.PROTECTED) || run { + it.hasModifierProperty(PsiModifier.PACKAGE_LOCAL) && psi.packageName == superClass.packageName + }) && it.parameterList.parametersCount == 0 + } + } + + if (canHaveDefaultConstructor) { + declarations += JeMethodExecutableElement(DefaultConstructorPsiMethod(psi, psi.language).apply { + val containingClass = psi.containingClass + if (containingClass != null && !psi.hasModifierProperty(PsiModifier.STATIC)) { + addParameter("\$instance", PsiTypesUtil.getClassType(containingClass)) + } + }) + } + } + return declarations } + private val PsiClass.packageName: String + get() = (containingFile as? PsiJavaFile)?.packageName ?: "" + fun getAllMembers(): List { val declarations = mutableListOf() psi.allFields.forEach { declarations += JeVariableElement(it) } diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/internal/DefaultConstructorPsiMethod.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/internal/DefaultConstructorPsiMethod.kt new file mode 100644 index 00000000000..cb2935b2b74 --- /dev/null +++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/internal/DefaultConstructorPsiMethod.kt @@ -0,0 +1,38 @@ +/* + * Copyright 2010-2016 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.java.model.internal + +import com.intellij.lang.Language +import com.intellij.psi.PsiClass +import com.intellij.psi.PsiModifier.* +import com.intellij.psi.impl.light.LightMethodBuilder + +internal class DefaultConstructorPsiMethod( + clazz: PsiClass, + language: Language +) : LightMethodBuilder(clazz, language) { + init { + val modifier = when { + clazz.hasModifierProperty(PUBLIC) -> PUBLIC + clazz.hasModifierProperty(PRIVATE) -> PRIVATE + clazz.hasModifierProperty(PROTECTED) -> PROTECTED + else -> PACKAGE_LOCAL + } + setModifiers(modifier) + isConstructor = true + } +} \ No newline at end of file