[jvm-lang] use JvmElement Create method API from XMLs (IDEA-163124)

This commit is contained in:
Daniil Ovchinnikov
2018-03-26 21:29:00 +03:00
parent b4414c8ae0
commit 0b365efd34
4 changed files with 67 additions and 40 deletions
@@ -1,6 +1,19 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.lang.jvm.actions
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiType
import com.intellij.psi.codeStyle.JavaCodeStyleManager
import com.intellij.psi.codeStyle.SuggestedNameInfo
import com.intellij.psi.codeStyle.VariableKind
fun nameInfo(vararg names: String): SuggestedNameInfo = object : SuggestedNameInfo(names) {}
fun suggestJavaParamName(project: Project, type: PsiType, propertyName: String? = null): SuggestedNameInfo {
val codeStyleManager = JavaCodeStyleManager.getInstance(project)!!
return codeStyleManager.suggestVariableName(VariableKind.PARAMETER, propertyName, null, type)
}
fun SuggestedNameInfo.orDefault(defaultName: String): SuggestedNameInfo {
return if (names.isEmpty()) nameInfo(defaultName) else this
}
@@ -1,25 +1,10 @@
/*
* Copyright 2000-2017 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.
*/
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.psi.impl.beanProperties;
import com.intellij.codeInsight.intention.IntentionAction;
import com.intellij.codeInspection.IntentionWrapper;
import com.intellij.codeInspection.LocalQuickFix;
import com.intellij.lang.jvm.JvmModifier;
import com.intellij.lang.jvm.actions.MemberRequest;
import com.intellij.lang.java.beans.PropertyKind;
import com.intellij.openapi.project.Project;
import com.intellij.psi.*;
import com.intellij.psi.search.GlobalSearchScope;
@@ -27,9 +12,8 @@ import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import static com.intellij.lang.jvm.actions.JvmElementActionFactories.createPropertyActions;
import static com.intellij.lang.jvm.actions.JvmElementActionFactories.createMethodActions;
import static com.intellij.psi.CommonClassNames.JAVA_LANG_STRING;
import static com.intellij.util.ArrayUtil.toObjectArray;
@ApiStatus.Experimental
public class CreateBeanPropertyFixes {
@@ -46,14 +30,12 @@ public class CreateBeanPropertyFixes {
@Nullable PsiType type,
final boolean createSetter) {
if (psiClass instanceof PsiCompiledElement) return IntentionAction.EMPTY_ARRAY;
final Project project = psiClass.getProject();
if (type == null) {
final Project project = psiClass.getProject();
final JavaPsiFacade facade = JavaPsiFacade.getInstance(project);
final PsiClass aClass = facade.findClass(JAVA_LANG_STRING, GlobalSearchScope.allScope(project));
if (aClass == null) return IntentionAction.EMPTY_ARRAY;
type = facade.getElementFactory().createType(aClass);
type = JavaPsiFacade.getElementFactory(project).createTypeByFQClassName(JAVA_LANG_STRING, GlobalSearchScope.allScope(project));
}
MemberRequest.Property request = new MemberRequest.Property(propertyName, JvmModifier.PUBLIC, type, createSetter, !createSetter);
return toObjectArray(createPropertyActions(psiClass, request), IntentionAction.class);
PropertyKind propertyKind = createSetter ? PropertyKind.SETTER : PropertyKind.GETTER;
CreateBeanPropertyRequest request = new CreateBeanPropertyRequest(psiClass.getProject(), propertyName, propertyKind, type);
return createMethodActions(psiClass, request).toArray(IntentionAction.EMPTY_ARRAY);
}
}
@@ -0,0 +1,45 @@
// Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.intellij.psi.impl.beanProperties
import com.intellij.lang.java.beans.PropertyKind
import com.intellij.lang.jvm.JvmModifier
import com.intellij.lang.jvm.actions.AnnotationRequest
import com.intellij.lang.jvm.actions.CreateMethodRequest
import com.intellij.lang.jvm.actions.expectedTypes
import com.intellij.lang.jvm.actions.suggestJavaParamName
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiJvmSubstitutor
import com.intellij.psi.PsiSubstitutor
import com.intellij.psi.PsiType
import com.intellij.psi.util.PropertyUtilBase.getAccessorName
internal class CreateBeanPropertyRequest(
project: Project,
propertyName: String,
propertyKind: PropertyKind,
private val type: PsiType
) : CreateMethodRequest {
private val isSetter: Boolean = propertyKind == PropertyKind.SETTER
private val names = suggestJavaParamName(project, type, propertyName)
private val expectedTypes = expectedTypes(type)
private val myMethodName = getAccessorName(propertyName, propertyKind)
override fun getMethodName(): String = myMethodName
private val myReturnType = if (isSetter) expectedTypes(PsiType.VOID) else expectedTypes
override fun getReturnType() = myReturnType
private val myModifiers = listOf(JvmModifier.PUBLIC)
override fun getModifiers() = myModifiers
override fun getAnnotations() = emptyList<AnnotationRequest>()
private val myTargetSubstitutor = PsiJvmSubstitutor(project, PsiSubstitutor.EMPTY)
override fun getTargetSubstitutor() = myTargetSubstitutor
private val myParameters = if (isSetter) listOf(Pair(names, expectedTypes)) else emptyList()
override fun getParameters() = myParameters
override fun isValid() = type.isValid
}
@@ -10,10 +10,8 @@ import com.intellij.psi.PsiJvmSubstitutor
import com.intellij.psi.PsiModifier
import com.intellij.psi.PsiSubstitutor
import com.intellij.psi.PsiType
import com.intellij.psi.codeStyle.JavaCodeStyleManager
import com.intellij.psi.codeStyle.JavaCodeStyleSettings
import com.intellij.psi.codeStyle.SuggestedNameInfo
import com.intellij.psi.codeStyle.VariableKind
import com.intellij.psi.util.createSmartPointer
import com.intellij.psi.xml.XmlAttribute
import com.intellij.psi.xml.XmlAttributeValue
@@ -55,7 +53,7 @@ class CreateEventHandlerRequest(element: XmlAttributeValue) : CreateMethodReques
override fun getParameters(): List<Pair<SuggestedNameInfo, ExpectedTypes>> {
val eventType = getEventType(myElement)
val expectedType = expectedType(eventType, ExpectedType.Kind.EXACT)
val nameInfo = suggestParamName(myProject, eventType)
val nameInfo = suggestJavaParamName(myProject, eventType).orDefault("e")
val parameter = Pair(nameInfo, listOf(expectedType))
return listOf(parameter)
}
@@ -79,17 +77,6 @@ private fun getVisibility(project: Project): JvmModifier {
return JvmModifier.valueOf(visibility.toUpperCase())
}
private fun suggestParamName(project: Project, eventType: PsiType): SuggestedNameInfo {
val codeStyleManager = JavaCodeStyleManager.getInstance(project)!!
val suggestedNameInfo = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, null, null, eventType)
return if (suggestedNameInfo.names.isEmpty()) {
object : SuggestedNameInfo(arrayOf("e")) {}
}
else {
suggestedNameInfo
}
}
private fun getEventType(element: XmlAttributeValue): PsiType {
val parent = element.parent
if (parent is XmlAttribute) {