[jvm-lang] convert api interfaces to java step 3: implementations

This commit is contained in:
Daniil Ovchinnikov
2018-02-15 15:29:33 +03:00
parent e423613412
commit 39ffc13605
10 changed files with 103 additions and 140 deletions
@@ -1,20 +1,8 @@
/*
* 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.lang.jvm.actions
private data class SimpleAnnotationRequest(override val qualifiedName: String) : AnnotationRequest
private data class SimpleAnnotationRequest(private val qualifiedName: String) : AnnotationRequest {
override fun getQualifiedName() = qualifiedName
}
fun annotationRequest(fqn: String): AnnotationRequest = SimpleAnnotationRequest(fqn)
@@ -1,4 +1,4 @@
// Copyright 2000-2017 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.
// 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.lang.jvm.types.JvmType
@@ -9,7 +9,7 @@ fun expectedType(type: JvmType, kind: ExpectedType.Kind = ExpectedType.Kind.EXAC
fun expectedTypes(type: JvmType): ExpectedTypes = listOf(expectedType(type))
private class SimpleExpectedType(
override val theType: JvmType,
override val theKind: ExpectedType.Kind
) : ExpectedType
private class SimpleExpectedType(private val theType: JvmType, private val theKind: ExpectedType.Kind) : ExpectedType {
override fun getTheType(): JvmType = theType
override fun getTheKind(): ExpectedType.Kind = theKind
}
@@ -1,4 +1,4 @@
// Copyright 2000-2017 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.
// 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.lang.jvm.JvmModifier
@@ -11,23 +11,29 @@ import com.intellij.psi.PsiSubstitutor
import com.intellij.psi.PsiType
private class SimpleMethodRequest(
override val methodName: String,
override val modifiers: Collection<JvmModifier> = emptyList(),
override val returnType: ExpectedTypes = emptyList(),
override val annotations: Collection<AnnotationRequest> = emptyList(),
override val parameters: List<ExpectedParameter> = emptyList(),
override val targetSubstitutor: JvmSubstitutor
private val methodName: String,
private val modifiers: Collection<JvmModifier>,
private val returnType: ExpectedTypes,
private val targetSubstitutor: JvmSubstitutor
) : CreateMethodRequest {
override val isValid: Boolean = true
override fun isValid(): Boolean = true
override fun getMethodName() = methodName
override fun getModifiers() = modifiers
override fun getReturnType() = returnType
override fun getAnnotations() = emptyList<AnnotationRequest>()
override fun getParameters() = emptyList<ExpectedParameter>()
override fun getTargetSubstitutor() = targetSubstitutor
}
private class SimpleConstructorRequest(
override val parameters: ExpectedParameters,
override val targetSubstitutor: JvmSubstitutor
private val parameters: ExpectedParameters,
private val targetSubstitutor: JvmSubstitutor
) : CreateConstructorRequest {
override val isValid: Boolean get() = true
override val modifiers: List<JvmModifier> get() = emptyList()
override val annotations: Collection<AnnotationRequest> = emptyList()
override fun isValid(): Boolean = true
override fun getModifiers() = emptyList<JvmModifier>()
override fun getAnnotations() = emptyList<AnnotationRequest>()
override fun getTargetSubstitutor() = targetSubstitutor
override fun getParameters() = parameters
}
fun methodRequest(project: Project, methodName: String, modifier: JvmModifier, returnType: JvmType): CreateMethodRequest {
@@ -1,4 +1,4 @@
// Copyright 2000-2017 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.
// 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.java.request
import com.intellij.lang.jvm.JvmModifier
@@ -7,5 +7,5 @@ import com.intellij.psi.PsiConstructorCall
internal class CreateConstructorFromJavaUsageRequest(
call: PsiConstructorCall,
override val modifiers: Collection<JvmModifier>
) : CreateExecutableFromJavaUsageRequest<PsiConstructorCall>(call), CreateConstructorRequest
modifiers: Collection<JvmModifier>
) : CreateExecutableFromJavaUsageRequest<PsiConstructorCall>(call, modifiers), CreateConstructorRequest
@@ -1,9 +1,9 @@
// Copyright 2000-2017 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.
// 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.java.request
import com.intellij.codeInsight.daemon.impl.quickfix.CreateMethodFromUsageFix.getTargetSubstitutor
import com.intellij.lang.jvm.JvmModifier
import com.intellij.lang.jvm.actions.*
import com.intellij.lang.jvm.types.JvmSubstitutor
import com.intellij.openapi.components.service
import com.intellij.psi.*
import com.intellij.psi.codeStyle.JavaCodeStyleManager
@@ -12,41 +12,45 @@ import com.intellij.psi.util.createSmartPointer
import com.intellij.psi.util.parentOfType
import com.intellij.refactoring.util.RefactoringUtil
abstract internal class CreateExecutableFromJavaUsageRequest<T : PsiCall>(call: T) : CreateExecutableRequest {
internal abstract class CreateExecutableFromJavaUsageRequest<out T : PsiCall>(
call: T,
private val modifiers: Collection<JvmModifier>
) : CreateExecutableRequest {
private val psiManager = call.manager
protected val project = psiManager.project
protected val callPointer: SmartPsiElementPointer<T> = call.createSmartPointer(project)
private val project = psiManager.project
private val callPointer: SmartPsiElementPointer<T> = call.createSmartPointer(project)
protected val call: T get() = callPointer.element ?: error("dead pointer")
override val isValid: Boolean get() = callPointer.element != null
override fun isValid() = callPointer.element != null
override val annotations: Collection<AnnotationRequest> get() = emptyList()
override fun getAnnotations() = emptyList<AnnotationRequest>()
override val targetSubstitutor: JvmSubstitutor get() = PsiJvmSubstitutor(project, getTargetSubstitutor(call))
override fun getModifiers() = modifiers
override val parameters: List<ExpectedParameter>
get() {
val argumentList = call.argumentList ?: return emptyList()
val scope = call.resolveScope
val codeStyleManager: JavaCodeStyleManager = project.service()
return argumentList.expressions.map { expression ->
var argType: PsiType? = RefactoringUtil.getTypeByExpression(expression)
val names = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, null, expression, argType)
if (argType == null || PsiType.NULL == argType || LambdaUtil.notInferredType(argType)) {
argType = PsiType.getJavaLangObject(psiManager, scope)
}
else if (argType is PsiDisjunctionType) {
argType = argType.leastUpperBound
}
else if (argType is PsiWildcardType) {
argType = if (argType.isBounded) argType.bound else PsiType.getJavaLangObject(psiManager, scope)
}
val expectedTypeInfo = argType?.let { expectedType(it, ExpectedType.Kind.SUPERTYPE) }
val expectedTypes = expectedTypeInfo?.let { listOf(it) } ?: emptyList()
ExpectedParameter(names, expectedTypes)
override fun getTargetSubstitutor() = PsiJvmSubstitutor(project, getTargetSubstitutor(call))
override fun getParameters(): List<ExpectedParameter> {
val argumentList = call.argumentList ?: return emptyList()
val scope = call.resolveScope
val codeStyleManager: JavaCodeStyleManager = project.service()
return argumentList.expressions.map { expression ->
var argType: PsiType? = RefactoringUtil.getTypeByExpression(expression)
val names = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, null, expression, argType)
if (argType == null || PsiType.NULL == argType || LambdaUtil.notInferredType(argType)) {
argType = PsiType.getJavaLangObject(psiManager, scope)
}
else if (argType is PsiDisjunctionType) {
argType = argType.leastUpperBound
}
else if (argType is PsiWildcardType) {
argType = if (argType.isBounded) argType.bound else PsiType.getJavaLangObject(psiManager, scope)
}
val expectedTypeInfo = argType?.let { expectedType(it, ExpectedType.Kind.SUPERTYPE) }
val expectedTypes = expectedTypeInfo?.let { listOf(it) } ?: emptyList()
ExpectedParameter(names, expectedTypes)
}
}
val context get() = call.parentOfType(PsiMethod::class, PsiClass::class)
}
@@ -1,26 +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.lang.java.request
import com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageBaseFix.getTargetSubstitutor
import com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageUtils.guessExpectedTypes
import com.intellij.lang.jvm.JvmModifier
import com.intellij.lang.jvm.actions.CreateFieldRequest
import com.intellij.lang.jvm.actions.ExpectedTypes
import com.intellij.lang.jvm.types.JvmSubstitutor
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiJvmSubstitutor
import com.intellij.psi.PsiReferenceExpression
@@ -28,22 +12,26 @@ import com.intellij.psi.util.createSmartPointer
internal class CreateFieldFromJavaUsageRequest(
reference: PsiReferenceExpression,
override val modifiers: Collection<JvmModifier>,
override val constant: Boolean,
private val modifiers: Collection<JvmModifier>,
private val isConstant: Boolean,
private val useAnchor: Boolean
) : CreateFieldRequest {
private val myReference = reference.createSmartPointer()
override val isValid: Boolean get() = myReference.element?.referenceName != null
override fun isValid() = myReference.element?.referenceName != null
val reference: PsiReferenceExpression get() = myReference.element!!
val reference get() = myReference.element!!
val anchor: PsiElement? get() = if (useAnchor) reference else null
override val fieldName: String get() = reference.referenceName!!
override fun getModifiers() = modifiers
override val fieldType: ExpectedTypes get() = guessExpectedTypes(reference, false).map(::ExpectedJavaType)
override fun getFieldName() = reference.referenceName!!
override val targetSubstitutor: JvmSubstitutor get() = PsiJvmSubstitutor(reference.project, getTargetSubstitutor(reference))
override fun getFieldType() = guessExpectedTypes(reference, false).map(::ExpectedJavaType)
override fun getTargetSubstitutor() = PsiJvmSubstitutor(reference.project, getTargetSubstitutor(reference))
override fun isConstant(): Boolean = isConstant
}
@@ -1,11 +1,10 @@
// Copyright 2000-2017 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.
// 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.java.request
import com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageUtils.guessExpectedTypes
import com.intellij.codeInsight.daemon.impl.quickfix.CreateMethodFromUsageFix.hasErrorsInArgumentList
import com.intellij.lang.jvm.JvmModifier
import com.intellij.lang.jvm.actions.CreateMethodRequest
import com.intellij.lang.jvm.actions.ExpectedTypes
import com.intellij.psi.*
import com.intellij.psi.util.parentOfType
import com.intellij.psi.util.parents
@@ -13,19 +12,16 @@ import com.intellij.util.withPrevious
internal class CreateMethodFromJavaUsageRequest(
methodCall: PsiMethodCallExpression,
override val modifiers: Collection<JvmModifier>
) : CreateExecutableFromJavaUsageRequest<PsiMethodCallExpression>(methodCall), CreateMethodRequest {
modifiers: Collection<JvmModifier>
) : CreateExecutableFromJavaUsageRequest<PsiMethodCallExpression>(methodCall, modifiers), CreateMethodRequest {
override val isValid: Boolean
get() {
val call = callPointer.element ?: return false
call.methodExpression.referenceName ?: return false
return !hasErrorsInArgumentList(call)
}
override fun isValid() = super.isValid() && call.let {
it.methodExpression.referenceName != null && !hasErrorsInArgumentList(it)
}
override val methodName: String get() = call.methodExpression.referenceName!!
override fun getMethodName() = call.methodExpression.referenceName!!
override val returnType: ExpectedTypes get() = guessExpectedTypes(call, call.parent is PsiStatement).map(::ExpectedJavaType)
override fun getReturnType() = guessExpectedTypes(call, call.parent is PsiStatement).map(::ExpectedJavaType)
fun getAnchor(targetClass: PsiClass): PsiElement? {
val enclosingMember = call.parentOfType(PsiMethod::class, PsiField::class, PsiClassInitializer::class) ?: return null
@@ -1,18 +1,4 @@
/*
* 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.lang.java.request
import com.intellij.codeInsight.ExpectedTypeInfo
@@ -21,12 +7,11 @@ import com.intellij.lang.jvm.types.JvmType
internal class ExpectedJavaType(val info: ExpectedTypeInfo) : ExpectedType {
override val theType: JvmType get() = info.defaultType
override fun getTheType(): JvmType = info.defaultType
override val theKind: ExpectedType.Kind
get() = when (info.kind) {
ExpectedTypeInfo.TYPE_OR_SUBTYPE -> ExpectedType.Kind.SUBTYPE
ExpectedTypeInfo.TYPE_OR_SUPERTYPE -> ExpectedType.Kind.SUPERTYPE
else -> ExpectedType.Kind.EXACT
}
override fun getTheKind(): ExpectedType.Kind = when (info.kind) {
ExpectedTypeInfo.TYPE_OR_SUBTYPE -> ExpectedType.Kind.SUBTYPE
ExpectedTypeInfo.TYPE_OR_SUPERTYPE -> ExpectedType.Kind.SUPERTYPE
else -> ExpectedType.Kind.EXACT
}
}
@@ -112,7 +112,7 @@ private class CreateFieldRequests(val myRef: PsiReferenceExpression) {
modifiers = modifiers,
reference = myRef,
useAnchor = target.toJavaClassOrNull() == ownerClass,
constant = false
isConstant = false
)
requests[target] = request
}
@@ -5,7 +5,6 @@ import com.intellij.codeInsight.daemon.QuickFixActionRegistrar
import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider
import com.intellij.lang.jvm.JvmModifier
import com.intellij.lang.jvm.actions.*
import com.intellij.lang.jvm.types.JvmSubstitutor
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiJvmSubstitutor
import com.intellij.psi.PsiModifier
@@ -41,18 +40,17 @@ class CreateEventHandlerRequest(element: XmlAttributeValue) : CreateMethodReques
private val myVisibility = getVisibility(myProject)
private val myPointer = element.createSmartPointer(myProject)
override val isValid: Boolean get() {
val element = myPointer.element
return element != null && element.value != null
override fun isValid(): Boolean = myPointer.element.let {
it != null && it.value != null
}
private val myElement get() = myPointer.element!!
override val methodName: String get() = myElement.value!!.substring(1)
override fun getMethodName() = myElement.value!!.substring(1)
override val returnType: ExpectedTypes get() = listOf(expectedType(PsiType.VOID, ExpectedType.Kind.EXACT))
override fun getReturnType() = listOf(expectedType(PsiType.VOID, ExpectedType.Kind.EXACT))
override val parameters: List<ExpectedParameter> get() {
override fun getParameters(): List<ExpectedParameter> {
val eventType = getEventType(myElement)
val expectedType = expectedType(eventType, ExpectedType.Kind.EXACT)
val nameInfo = suggestParamName(myProject, eventType)
@@ -60,18 +58,16 @@ class CreateEventHandlerRequest(element: XmlAttributeValue) : CreateMethodReques
return listOf(parameter)
}
override val modifiers: Collection<JvmModifier> get() = setOf(myVisibility)
override fun getModifiers() = setOf(myVisibility)
override val annotations: Collection<AnnotationRequest> get() {
return if (myVisibility != JvmModifier.PUBLIC) {
listOf(annotationRequest(JavaFxCommonNames.JAVAFX_FXML_ANNOTATION))
}
else {
emptyList()
}
override fun getAnnotations() = if (myVisibility != JvmModifier.PUBLIC) {
listOf(annotationRequest(JavaFxCommonNames.JAVAFX_FXML_ANNOTATION))
}
else {
emptyList()
}
override val targetSubstitutor: JvmSubstitutor get() = PsiJvmSubstitutor(myProject, PsiSubstitutor.EMPTY)
override fun getTargetSubstitutor() = PsiJvmSubstitutor(myProject, PsiSubstitutor.EMPTY)
}
private fun getVisibility(project: Project): JvmModifier {