Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
37e5edc
fix: Kotlin logger detection
BFergerson Sep 30, 2022
0e0eeb1
Merge branch 'master' into issue-693
BFergerson Sep 30, 2022
39df293
wip: groovy logger detector
BFergerson Sep 30, 2022
78f05a5
Navigate to line on stack frame changes (#857)
MrMineO5 Sep 30, 2022
466f718
fix(deps): update vertxversion to v4.3.4 (#856)
renovate[bot] Sep 30, 2022
992e90c
refactor: remove unused
BFergerson Sep 30, 2022
e481b5b
refactor: improved packaging (#858)
BFergerson Sep 30, 2022
8ee9a01
fix: variable reference presentations differ from referenced variabl…
BFergerson Oct 1, 2022
846faf4
fix: fix relative path on windows
BFergerson Oct 1, 2022
387c800
Bump version to 0.7.2-SNAPSHOT
BFergerson Oct 1, 2022
406709f
fix: npe
BFergerson Oct 2, 2022
5a088dc
chore(deps): update actions/cache action to v3.0.10 (#860)
renovate[bot] Oct 3, 2022
c9e671f
fix: npe when control palette is on method line
BFergerson Oct 3, 2022
0d90f7e
fix(deps): update apollo graphql packages to v3.6.1 (#861)
renovate[bot] Oct 4, 2022
21d5a4e
refactor: remove deprecated
BFergerson Oct 4, 2022
58c4b8a
fix: npe when fetching line number for command autocompletion
BFergerson Oct 4, 2022
1536367
chore(deps): update actions/checkout action to v3.1.0 (#863)
renovate[bot] Oct 4, 2022
aa11896
fix: sourceplusplus/sourceplusplus#720 (#862)
MrMineO5 Oct 5, 2022
fbee2f1
refactor: support all languages with base lang javascript (#866)
BFergerson Oct 5, 2022
9a9d788
fix(deps): update apollo graphql packages to v3.6.2 (#865)
renovate[bot] Oct 5, 2022
53ad2e9
fix: live variable decoding error on Python dicts (#864)
BFergerson Oct 6, 2022
f05d493
refactor: remove duplicates
BFergerson Oct 6, 2022
6f6eafb
chore: improve startup performance (lazy load jbcef client)
BFergerson Oct 6, 2022
6c26039
feat: ability to set LCP on class/method and JVM end brackets (#867)
BFergerson Oct 8, 2022
9181f3c
refactor: shorten long locations
BFergerson Oct 9, 2022
67cdb45
refactor: suggestions
BFergerson Oct 9, 2022
cf37b61
chore: groovy LCP positioning improves
BFergerson Oct 9, 2022
4c9900f
Merge branch 'master' into issue-703
BFergerson Oct 9, 2022
7cea2e4
chore: fix merge
BFergerson Oct 9, 2022
f664db9
chore: fix merge
BFergerson Oct 9, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,12 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.util.Computable
import com.intellij.psi.PsiDocumentManager
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiRecursiveElementVisitor
import com.intellij.refactoring.suggested.endOffset
import com.intellij.refactoring.suggested.startOffset
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.literals.GrLiteral
import org.jetbrains.plugins.groovy.lang.psi.api.statements.expressions.path.GrMethodCallExpression
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod
import org.jetbrains.uast.UCallExpression
import org.jetbrains.uast.ULiteralExpression
import org.jetbrains.uast.UMethod
Expand Down Expand Up @@ -58,11 +62,15 @@ class JVMLoggerDetector(val project: Project) : LoggerDetector {
}

override fun determineLoggerStatements(guideMark: MethodGuideMark): List<DetectedLogger> {
val uMethod = ApplicationManager.getApplication().runReadAction(Computable {
guideMark.getPsiMethod().toUElementOfType<UMethod>()
})
if (uMethod != null) {
determineLoggerStatements(uMethod, guideMark.sourceFileMarker)
if (guideMark.language.id == "Groovy") {
determineLoggerStatements(guideMark.getPsiMethod() as GrMethod, guideMark.sourceFileMarker)
} else {
val uMethod = ApplicationManager.getApplication().runReadAction(Computable {
guideMark.getPsiMethod().toUElementOfType<UMethod>()
})
if (uMethod != null) {
determineLoggerStatements(uMethod, guideMark.sourceFileMarker)
}
}
return guideMark.getChildren().mapNotNull { it.getUserData(DETECTED_LOGGER) }
}
Expand Down Expand Up @@ -111,6 +119,54 @@ class JVMLoggerDetector(val project: Project) : LoggerDetector {
return loggerStatements
}

/**
* Unsure why, but Groovy UAST visitors don't work here. Have to use Groovy PSI.
*/
fun determineLoggerStatements(grMethod: GrMethod, fileMarker: SourceFileMarker): List<DetectedLogger> {
val loggerStatements = mutableListOf<DetectedLogger>()
ApplicationManager.getApplication().runReadAction {
grMethod.acceptChildren(object : PsiRecursiveElementVisitor() {
override fun visitElement(element: PsiElement) {
if (element is GrMethodCallExpression) {
val loggerClass = element.resolveMethod()?.containingClass?.qualifiedName
if (loggerClass != null && LOGGER_CLASSES.contains(loggerClass)) {
val methodName = element.resolveMethod()?.name
if (methodName != null && LOGGER_METHODS.contains(methodName)) {
val logTemplate = element.argumentList.expressionArguments.firstOrNull()?.run {
(this as? GrLiteral)?.value as? String
}

if (logTemplate != null) {
log.debug("Found log statement: $logTemplate")
val detectedLogger = DetectedLogger(
logTemplate, methodName, getLineNumber(element) + 1
)
loggerStatements.add(detectedLogger)

//create expression guide mark for the log statement
val guideMark = fileMarker.createExpressionSourceMark(
element, SourceMark.Type.GUIDE
)
if (!fileMarker.containsSourceMark(guideMark)) {
guideMark.putUserData(DETECTED_LOGGER, detectedLogger)
guideMark.apply(true)
} else {
fileMarker.getSourceMark(guideMark.artifactQualifiedName, SourceMark.Type.GUIDE)
?.putUserData(DETECTED_LOGGER, detectedLogger)
}
} else {
log.warn("No log template argument available for expression: $element")
}
}
}
}
super.visitElement(element)
}
})
}
return loggerStatements
}

private fun getLineNumber(element: PsiElement, start: Boolean = true): Int {
val document = element.containingFile.viewProvider.document
?: PsiDocumentManager.getInstance(element.project).getDocument(element.containingFile)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ package spp.jetbrains.marker.jvm.service
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiNameIdentifierOwner
import com.intellij.psi.PsiStatement
import com.intellij.psi.impl.source.tree.LeafPsiElement
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.imports.GrImportStatement
import org.jetbrains.plugins.groovy.lang.psi.api.toplevel.packaging.GrPackageDefinition
import spp.jetbrains.marker.IArtifactCreationService
import spp.jetbrains.marker.SourceMarkerUtils
import spp.jetbrains.marker.jvm.service.utils.JVMMarkerUtils
Expand Down Expand Up @@ -102,6 +105,12 @@ class JVMArtifactCreationService : IArtifactCreationService {
autoApply: Boolean
): Optional<ExpressionInlayMark> {
val element = SourceMarkerUtils.getElementAtLine(fileMarker.psiFile, lineNumber)
if (element is LeafPsiElement && element.parent is GrImportStatement) {
return Optional.empty()
} else if (element is LeafPsiElement && element.parent is GrPackageDefinition) {
return Optional.empty()
}

return if (element is PsiStatement) {
Optional.ofNullable(JVMMarkerUtils.getOrCreateExpressionInlayMark(fileMarker, element, autoApply))
} else if (element is PsiElement) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ object JVMMarkerUtils {
}

return if (inlayMark == null) {
if (element.text != "}") {
if (element.language.id != "Groovy" && element.text != "}") {
val uExpression = element.toUElement()
if (uExpression !is UExpression && uExpression !is UDeclaration) return null
}
Expand Down Expand Up @@ -404,7 +404,7 @@ object JVMMarkerUtils {
}
}
if (parentIdentifier == null) {
error("Could not determine parent of element: $element") //todo: extension function, see SourceMarkerConfig, make test
error("Could not determine parent of element: $element") //todo: extension function, see SourceMarkerConfig, make test, groovy import statements
}

element.textRange.startOffset.let {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ import io.vertx.core.Vertx
import org.intellij.lang.annotations.Language
import org.jetbrains.kotlin.idea.core.util.toPsiFile
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.plugins.groovy.lang.psi.GroovyFile
import org.jetbrains.plugins.groovy.lang.psi.api.statements.typedef.members.GrMethod
import org.jetbrains.uast.UFile
import org.jetbrains.uast.toUElement
import spp.jetbrains.UserData
Expand Down Expand Up @@ -192,4 +194,40 @@ class JVMLoggerDetectorTest : LightJavaCodeInsightFixtureTestCase() {
assertContainsOrdered(result, "trace {}", "debug {}", "info {}", "warn {}", "error {}")
}
}

fun testGroovyLogbackLogger() {
@Language("Groovy") val code = """
import ch.qos.logback.classic.Logger
class TestLogback {
var log = new Logger()
void loggers() {
log.trace("trace {}", "trace")
log.debug("debug {}", "debug")
log.info("info {}", "info")
log.warn("warn {}", "warn")
log.error("error {}", "error")
}
}
""".trimIndent()

ApplicationManager.getApplication().runReadAction {
val sourceFile = myFixture.createFile("TestLogback.groovy", code).toPsiFile(project)
assertNotNull(sourceFile)

val uFile = sourceFile.toUElement() as UFile
assertEquals(1, uFile.classes.size)
assertEquals(1, uFile.classes[0].methods.size)

JVMMarker.setup()
SourceFileMarker.SUPPORTED_FILE_TYPES.add(GroovyFile::class.java)
val fileMarker = SourceMarker.getSourceFileMarker(sourceFile!!)
assertNotNull(fileMarker)

val result = JVMLoggerDetector(project.apply { UserData.vertx(this, Vertx.vertx()) })
.determineLoggerStatements(uFile.classes[0].methods[0].sourcePsi as GrMethod, fileMarker!!)
.map { it.logPattern }
assertEquals(5, result.size)
assertContainsOrdered(result, "trace {}", "debug {}", "info {}", "warn {}", "error {}")
}
}
}
16 changes: 15 additions & 1 deletion marker/src/main/kotlin/spp/jetbrains/marker/SourceMarkerUtils.kt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ package spp.jetbrains.marker

import com.intellij.openapi.editor.Document
import com.intellij.psi.*
import com.intellij.psi.impl.source.tree.LeafPsiElement
import com.intellij.psi.javadoc.PsiDocComment
import com.intellij.psi.javadoc.PsiDocToken
import com.intellij.psi.util.parentOfType
import spp.jetbrains.marker.source.mark.api.SourceMark

Expand All @@ -35,7 +38,7 @@ object SourceMarkerUtils {
* @since 0.1.0
*/
@JvmStatic
fun getElementAtLine(file: PsiFile, line: Int): PsiElement? {
fun getElementAtLine(file: PsiFile, line: Int, ignoreComments: Boolean = true): PsiElement? {
val document: Document = PsiDocumentManager.getInstance(file.project).getDocument(file)!!
if (document.lineCount == line - 1) {
return null
Expand Down Expand Up @@ -67,11 +70,22 @@ object SourceMarkerUtils {

if (element != null && getLineNumber(element) != line) {
return null
} else if (element != null && ignoreComments && isComment(element)) {
return null
}

return element
}

private fun isComment(element: PsiElement): Boolean {
val comment = element is PsiDocToken || element is PsiComment || element is PsiDocComment
if (comment) return true

return if (element is LeafPsiElement) {
isComment(element.parent)
} else false
}

/**
* todo: description.
*
Expand Down