Skip to content

Commit

Permalink
Merge pull request #119 from viartemev/add-polyadicexpressions-handling
Browse files Browse the repository at this point in the history
Impl of a feature 121
  • Loading branch information
viartemev committed Apr 27, 2018
2 parents b5f896c + 609e9ac commit 4a08237
Show file tree
Hide file tree
Showing 10 changed files with 96 additions and 21 deletions.
3 changes: 1 addition & 2 deletions .gitignore
Expand Up @@ -11,6 +11,5 @@ build/
node_modules/
yarn-error.log


### Others ###
### Custom ###
samples/
Expand Up @@ -4,11 +4,13 @@ import com.intellij.psi.PsiAnnotation
import com.intellij.psi.PsiAnnotationMemberValue
import com.intellij.psi.PsiArrayInitializerMemberValue
import com.intellij.psi.PsiBinaryExpression
import com.intellij.psi.PsiPolyadicExpression
import com.intellij.psi.PsiReferenceExpression
import com.viartemev.requestmapper.annotations.extraction.BasePsiAnnotationValueVisitor
import com.viartemev.requestmapper.annotations.extraction.PsiAnnotationMemberValueExtractor
import com.viartemev.requestmapper.annotations.extraction.PsiArrayInitializerMemberValueExtractor
import com.viartemev.requestmapper.annotations.extraction.PsiBinaryExpressionExtractor
import com.viartemev.requestmapper.annotations.extraction.PsiPolyadicExpressionExtractor
import com.viartemev.requestmapper.annotations.extraction.PsiReferenceExpressionExtractor

class PathAnnotation(private val annotation: PsiAnnotation) {
Expand All @@ -26,6 +28,9 @@ class PathAnnotation(private val annotation: PsiAnnotation) {

override fun visitPsiBinaryExpression(expression: PsiBinaryExpression) =
PsiBinaryExpressionExtractor().extract(expression)

override fun visitPsiPolyadicExpression(expression: PsiPolyadicExpression) =
PsiPolyadicExpressionExtractor().extract(expression)
}.visit(annotation, parameter)
}
}
Expand Up @@ -3,6 +3,7 @@ package com.viartemev.requestmapper.annotations.extraction
import com.intellij.psi.PsiAnnotation
import com.intellij.psi.PsiArrayInitializerMemberValue
import com.intellij.psi.PsiBinaryExpression
import com.intellij.psi.PsiPolyadicExpression
import com.intellij.psi.PsiReferenceExpression

abstract class BasePsiAnnotationValueVisitor : PsiAnnotationValueVisitor {
Expand All @@ -13,6 +14,7 @@ abstract class BasePsiAnnotationValueVisitor : PsiAnnotationValueVisitor {
is PsiArrayInitializerMemberValue -> visitPsiArrayInitializerMemberValue(attributeValue)
is PsiReferenceExpression -> visitPsiReferenceExpression(attributeValue)
is PsiBinaryExpression -> visitPsiBinaryExpression(attributeValue)
is PsiPolyadicExpression -> visitPsiPolyadicExpression(attributeValue)
else -> if (attributeValue != null && attributeValue.text.isNotBlank()) visitPsiAnnotationMemberValue(attributeValue) else emptyList()
}
}
Expand Down
Expand Up @@ -4,6 +4,7 @@ import com.intellij.psi.PsiAnnotationMemberValue
import com.intellij.psi.PsiArrayInitializerMemberValue
import com.intellij.psi.PsiBinaryExpression
import com.intellij.psi.PsiReferenceExpression
import com.intellij.psi.PsiPolyadicExpression

interface PsiAnnotationValueVisitor {

Expand All @@ -14,4 +15,6 @@ interface PsiAnnotationValueVisitor {
fun visitPsiAnnotationMemberValue(value: PsiAnnotationMemberValue): List<String>

fun visitPsiBinaryExpression(expression: PsiBinaryExpression): List<String>

fun visitPsiPolyadicExpression(expression: PsiPolyadicExpression): List<String>
}
@@ -0,0 +1,9 @@
package com.viartemev.requestmapper.annotations.extraction

import com.intellij.psi.PsiPolyadicExpression
import com.viartemev.requestmapper.annotations.extraction.PsiExpressionExtractor.extractExpression

class PsiPolyadicExpressionExtractor : PsiAnnotationValueExtractor<PsiPolyadicExpression> {

override fun extract(value: PsiPolyadicExpression) = listOf(extractExpression(value))
}
@@ -1,15 +1,17 @@
package com.viartemev.requestmapper.annotations.jaxrs

import com.intellij.psi.PsiAnnotation
import com.intellij.psi.PsiLiteralExpression
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiReferenceExpression
import com.viartemev.requestmapper.RequestMappingItem
import com.viartemev.requestmapper.annotations.MappingAnnotation
import com.viartemev.requestmapper.annotations.PathAnnotation
import com.viartemev.requestmapper.annotations.extraction.PsiExpressionExtractor.extractExpression
import com.viartemev.requestmapper.model.Path
import com.viartemev.requestmapper.model.PathParameter
import com.viartemev.requestmapper.utils.dropFirstEmptyStringIfExists
import com.viartemev.requestmapper.utils.fetchAnnotatedMethod
import com.viartemev.requestmapper.utils.unquote

abstract class JaxRsMappingAnnotation(val psiAnnotation: PsiAnnotation) : MappingAnnotation {

Expand Down Expand Up @@ -59,8 +61,15 @@ abstract class JaxRsMappingAnnotation(val psiAnnotation: PsiAnnotation) : Mappin

private fun extractParameterNameFromAnnotation(annotation: PsiAnnotation, defaultValue: String): String {
val pathVariableValue = annotation.findAttributeValue(ATTRIBUTE_NAME)
return when {
pathVariableValue?.text?.unquote()?.isNotBlank() == true -> pathVariableValue.text.unquote()
return when (pathVariableValue) {
is PsiLiteralExpression -> {
val expression = extractExpression(pathVariableValue)
if (expression.isNotBlank()) expression else defaultValue
}
is PsiReferenceExpression -> {
val expression = extractExpression(pathVariableValue)
if (expression.isNotBlank()) expression else defaultValue
}
else -> defaultValue
}
}
Expand Down
@@ -1,15 +1,18 @@
package com.viartemev.requestmapper.annotations.spring

import com.intellij.psi.PsiAnnotation
import com.intellij.psi.PsiAnnotationMemberValue
import com.intellij.psi.PsiLiteralExpression
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiReferenceExpression
import com.viartemev.requestmapper.RequestMappingItem
import com.viartemev.requestmapper.annotations.MappingAnnotation
import com.viartemev.requestmapper.annotations.PathAnnotation
import com.viartemev.requestmapper.annotations.extraction.PsiExpressionExtractor
import com.viartemev.requestmapper.model.Path
import com.viartemev.requestmapper.model.PathParameter
import com.viartemev.requestmapper.utils.dropFirstEmptyStringIfExists
import com.viartemev.requestmapper.utils.fetchAnnotatedMethod
import com.viartemev.requestmapper.utils.unquote

abstract class SpringMappingAnnotation(val psiAnnotation: PsiAnnotation) : MappingAnnotation {

Expand Down Expand Up @@ -76,9 +79,21 @@ abstract class SpringMappingAnnotation(val psiAnnotation: PsiAnnotation) : Mappi
private fun extractParameterNameFromAnnotation(annotation: PsiAnnotation, defaultValue: String): String {
val pathVariableValue = annotation.findAttributeValue(VALUE)
val pathVariableName = annotation.findAttributeValue(NAME)
return when {
pathVariableValue?.text?.unquote()?.isNotBlank() == true -> pathVariableValue.text.unquote()
pathVariableName?.text?.unquote()?.isNotBlank() == true -> pathVariableName.text.unquote()

val valueAttribute = extractPsiAnnotation(pathVariableValue, defaultValue)
return if (valueAttribute != defaultValue) valueAttribute else extractPsiAnnotation(pathVariableName, defaultValue)
}

private fun extractPsiAnnotation(psiAnnotationMemberValue: PsiAnnotationMemberValue?, defaultValue: String): String {
return when (psiAnnotationMemberValue) {
is PsiLiteralExpression -> {
val expression = PsiExpressionExtractor.extractExpression(psiAnnotationMemberValue)
if (expression.isNotBlank()) expression else defaultValue
}
is PsiReferenceExpression -> {
val expression = PsiExpressionExtractor.extractExpression(psiAnnotationMemberValue)
if (expression.isNotBlank()) expression else defaultValue
}
else -> defaultValue
}
}
Expand Down
@@ -0,0 +1,33 @@
package com.viartemev.requestmapper.annotations.extraction

import com.intellij.psi.PsiLiteralExpression
import com.intellij.psi.PsiPolyadicExpression
import com.nhaarman.mockito_kotlin.doReturn
import com.nhaarman.mockito_kotlin.mock
import org.amshove.kluent.shouldContain
import org.amshove.kluent.shouldEqualTo
import org.jetbrains.spek.api.Spek
import org.jetbrains.spek.api.dsl.describe
import org.jetbrains.spek.api.dsl.it
import org.jetbrains.spek.api.dsl.on

object PsiPolyadicExpressionExtractorSpek : Spek({
describe("PsiPolyadicExpressionExtractor") {
on("extract with 2 PsiLiteralExpressions") {
it("should return list with sum of literal expressions texts") {
val apiElement = mock<PsiLiteralExpression> {
on { text } doReturn "\"/api\""
}
val versionElement = mock<PsiLiteralExpression> {
on { text } doReturn "\"/v1\""
}
val psiPolyadicExpression = mock<PsiPolyadicExpression> {
on { operands } doReturn arrayOf(apiElement, versionElement)
}
val extract = PsiPolyadicExpressionExtractor().extract(psiPolyadicExpression)
extract.size shouldEqualTo 1
extract shouldContain "/api/v1"
}
}
}
})
Expand Up @@ -13,7 +13,7 @@ import org.jetbrains.spek.api.dsl.on

object PsiReferenceExpressionExtractorSpek : Spek({
describe("PsiReferenceExpressionExtractor") {
on("extract with 2 PsiLiteralExpressions") {
on("extract with PsiLiteralExpression") {
it("should return list with sum of literal expressions texts") {
val psiElement = mock<PsiLiteralExpression> {
on { text } doReturn "\"api\""
Expand Down
@@ -1,9 +1,9 @@
package com.viartemev.requestmapper.annotations.spring

import com.intellij.psi.PsiAnnotation
import com.intellij.psi.PsiAnnotationMemberValue
import com.intellij.psi.PsiArrayInitializerMemberValue
import com.intellij.psi.PsiClass
import com.intellij.psi.PsiLiteralExpression
import com.intellij.psi.PsiMethod
import com.intellij.psi.PsiModifierList
import com.intellij.psi.PsiParameter
Expand Down Expand Up @@ -43,7 +43,7 @@ object RequestMappingSpek : Spek({
val psiParameterList = mock<PsiParameterList> {
on { parameters } doReturn emptyArray<PsiParameter>()
}
val memberValue = mock<PsiAnnotationMemberValue> {
val memberValue = mock<PsiLiteralExpression> {
on { text } doReturn "api"
}
val mappingAnnotation = mock<PsiAnnotation> {
Expand Down Expand Up @@ -75,7 +75,7 @@ object RequestMappingSpek : Spek({
val psiParameterList = mock<PsiParameterList> {
on { parameters } doReturn emptyArray<PsiParameter>()
}
val classMappingMemberValue = mock<PsiAnnotationMemberValue> {
val classMappingMemberValue = mock<PsiLiteralExpression> {
on { text } doReturn "api"
}
val classMappingAnnotation = mock<PsiAnnotation> {
Expand All @@ -92,7 +92,7 @@ object RequestMappingSpek : Spek({
on { parameterList } doReturn psiParameterList
on { containingClass } doReturn clazz
}
val methodMappingMemberValue = mock<PsiAnnotationMemberValue> {
val methodMappingMemberValue = mock<PsiLiteralExpression> {
on { text } doReturn "method"
}
val methodMappingAnnotation = mock<PsiAnnotation> {
Expand All @@ -111,7 +111,7 @@ object RequestMappingSpek : Spek({
val psiParameterList = mock<PsiParameterList> {
on { parameters } doReturn emptyArray<PsiParameter>()
}
val classMappingMemberValue = mock<PsiAnnotationMemberValue> {
val classMappingMemberValue = mock<PsiLiteralExpression> {
on { text } doReturn "api"
}
val classMappingAnnotation = mock<PsiAnnotation> {
Expand All @@ -128,7 +128,7 @@ object RequestMappingSpek : Spek({
on { parameterList } doReturn psiParameterList
on { containingClass } doReturn clazz
}
val methodMappingMemberValue = mock<PsiAnnotationMemberValue> {
val methodMappingMemberValue = mock<PsiLiteralExpression> {
on { text } doReturn "{id}"
}
val methodMappingAnnotation = mock<PsiAnnotation> {
Expand All @@ -143,7 +143,7 @@ object RequestMappingSpek : Spek({
}
}
on("values on annotation with annotated class and method with path variable with Long type") {
val methodModifierMappingMemberValue = mock<PsiAnnotationMemberValue> {
val methodModifierMappingMemberValue = mock<PsiLiteralExpression> {
on { text } doReturn "id"
}
val methodModifierAnnotation = mock<PsiAnnotation> {
Expand All @@ -164,7 +164,7 @@ object RequestMappingSpek : Spek({
val psiParameterList = mock<PsiParameterList> {
on { parameters } doReturn arrayOf(psiParameter)
}
val classMappingMemberValue = mock<PsiAnnotationMemberValue> {
val classMappingMemberValue = mock<PsiLiteralExpression> {
on { text } doReturn "api"
}
val classMappingAnnotation = mock<PsiAnnotation> {
Expand All @@ -181,7 +181,7 @@ object RequestMappingSpek : Spek({
on { parameterList } doReturn psiParameterList
on { containingClass } doReturn clazz
}
val methodMappingMemberValue = mock<PsiAnnotationMemberValue> {
val methodMappingMemberValue = mock<PsiLiteralExpression> {
on { text } doReturn "{id}"
}
val methodPsiAnnotation = mock<PsiAnnotation> {
Expand All @@ -200,10 +200,10 @@ object RequestMappingSpek : Spek({
val psiParameterList = mock<PsiParameterList> {
on { parameters } doReturn emptyArray<PsiParameter>()
}
val annotatedMemberValue1 = mock<PsiAnnotationMemberValue> {
val annotatedMemberValue1 = mock<PsiLiteralExpression> {
on { text } doReturn "api/v2"
}
val annotatedMemberValue2 = mock<PsiAnnotationMemberValue> {
val annotatedMemberValue2 = mock<PsiLiteralExpression> {
on { text } doReturn "api"
}
val memberValue = mock<PsiArrayInitializerMemberValue> {
Expand Down

0 comments on commit 4a08237

Please sign in to comment.