Skip to content

v0.4.3 #689

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 44 commits into from
Mar 19, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
f38bc13
fix view history on watch log expression
BFergerson Mar 15, 2022
1646eb5
lower logging
BFergerson Mar 15, 2022
c0da0b3
rename
BFergerson Mar 15, 2022
04543b2
update
BFergerson Mar 15, 2022
5f84af3
link
BFergerson Mar 15, 2022
8158f9f
Update README.md
BFergerson Mar 15, 2022
23348e1
Update README.md
BFergerson Mar 15, 2022
6568d30
Update README.md
BFergerson Mar 15, 2022
5c37977
Update README.md
BFergerson Mar 15, 2022
c4a8f1b
Update README.md
BFergerson Mar 15, 2022
a97d924
Update README.md
BFergerson Mar 15, 2022
8c04cfc
Update README.md
BFergerson Mar 15, 2022
b44993a
Update README.md
BFergerson Mar 15, 2022
5e92668
Update README.md
BFergerson Mar 15, 2022
d9cab78
Update README.md
BFergerson Mar 15, 2022
458ed62
Update README.md
BFergerson Mar 15, 2022
4c0c1ad
Update README.md
BFergerson Mar 15, 2022
af6676d
Update README.md
BFergerson Mar 15, 2022
33235ae
Update README.md
BFergerson Mar 15, 2022
87e5f9a
Update README.md
BFergerson Mar 16, 2022
4838782
trigger event
BFergerson Mar 17, 2022
03c0e03
convenience method
BFergerson Mar 17, 2022
f133199
createMethodGutterMark
BFergerson Mar 17, 2022
dee50c0
default
BFergerson Mar 18, 2022
d05af32
lazy changelog
BFergerson Mar 18, 2022
1c7cf7f
move method
BFergerson Mar 18, 2022
318dfeb
impl SWLiveViewService
BFergerson Mar 18, 2022
1034189
allow live view commands
BFergerson Mar 18, 2022
681b11e
move code to processor
BFergerson Mar 18, 2022
925bfe3
impl show/hide quick stats
BFergerson Mar 19, 2022
2794e7c
todo
BFergerson Mar 19, 2022
5a34119
accept events to indiv subscriber
BFergerson Mar 19, 2022
8e6d282
Merge branch 'master' into dev
BFergerson Mar 19, 2022
72fc955
bump
BFergerson Mar 19, 2022
c19b07e
Merge remote-tracking branch 'origin/dev' into dev
BFergerson Mar 19, 2022
55d5f14
don't need
BFergerson Mar 19, 2022
5fd681f
Update JVMMarkerUtils.kt
BFergerson Mar 19, 2022
10d0cb5
auto-display endpoint quick stats setting
BFergerson Mar 19, 2022
0459a94
auto-display endpoint quick stats setting
BFergerson Mar 19, 2022
0b509f5
change default
BFergerson Mar 19, 2022
e2d72e2
impl auto-resolve for SWLiveService
BFergerson Mar 19, 2022
cdb202d
fix compatibility issues
BFergerson Mar 19, 2022
19277b8
fix compatibility issues
BFergerson Mar 19, 2022
4d38574
fix compatibility issues
BFergerson Mar 19, 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
71 changes: 57 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,85 @@
![GitHub release](https://img.shields.io/github/v/release/sourceplusplus/interface-jetbrains?include_prereleases)
[![Build](https://github.com/sourceplusplus/interface-jetbrains/actions/workflows/build.yml/badge.svg)](https://github.com/sourceplusplus/interface-jetbrains/actions/workflows/build.yml)

## What is this?
# What is this?

<!-- Plugin description -->

This project contains the JetBrains IDE plugin for [Source++](https://github.com/sourceplusplus/live-platform), the open-source live coding platform.
This project contains the JetBrains IDE plugin for [Source++](https://github.com/sourceplusplus/live-platform), the open-source live coding platform. This plugin also works with regular [SkyWalking](https://github.com/apache/skywalking) installations, but only [Live View](#live-view) commands will be available.

<!-- Plugin description end -->

## Features
# How to use?

### Live Views
Once installed, this plugin adds a command bar to the JetBrains IDE, which is accessible by pressing `Ctrl+Shift+S`.
The commands available are determined by the location the command bar is opened and the accessibility of either [SkyWalking](https://github.com/apache/skywalking) or the [Live Platform](https://github.com/sourceplusplus/live-platform).

> Contextual popups for displaying live operational data on the code currently in view.
# Available Commands

## Live Views

**Live View** commands utilize existing SkyWalking metrics to display live production data directly inside of your IDE.

<details>
<summary>Screencast</summary>
<summary><b>Show Commands</b> &nbsp; 👈 &nbsp; <i>(click to expand)</i></summary>

### Show/Hide Quick Stats

> Inlay hints which indicate an endpoint's current activity.

<details>
<summary>Screencast</summary>

![screencast](https://user-images.githubusercontent.com/3278877/158376181-7fe597f9-f3c2-4609-bd07-4ea55e10b579.gif)
</details>

### Watch Log

> Follow specific logging statements in real-time.

<details>
<summary>Screencast</summary>

![screencast](https://user-images.githubusercontent.com/3278877/158381411-214285ba-7291-4c70-8e1f-8489140fa239.gif)
</details>

### Display Portal

> Contextual popups for displaying live operational data on the code currently in view.

<details>
<summary>Screencast</summary>

![screencast](https://user-images.githubusercontent.com/3278877/149158868-135568d5-20cc-44d4-886a-2202195b594b.gif)
</details>

</details>

### Live Breakpoint
## Live Instruments

> Live Breakpoints (a.k.a non-breaking breakpoints) are useful debugging instruments for gaining insight into the live variables available in production at a given scope.
**Live Instrument** commands require a [Live Probe](https://github.com/sourceplusplus/probe-jvm) to inject additional metrics for live production debugging.

<details>
<summary>Screencast</summary>
<summary><b>Show Commands</b> &nbsp; 👈 &nbsp; <i>(click to expand)</i></summary>

### Add Breakpoint

> Live Breakpoints (a.k.a. non-breaking breakpoints) are useful debugging instruments for gaining insight into the live variables available in production at a given scope.

<details>
<summary>Screencast</summary>

![live-breakpoint](https://user-images.githubusercontent.com/3278877/136304451-2c98ad30-032b-4ce0-9f37-f98cd750adb3.gif)
</details>
</details>

### Live Log
### Add Log

> Live Logs (a.k.a just-in-time logging) are quick and easy debugging instruments for instantly outputting live data from production without redeploying or restarting your application.
> Live Logs (a.k.a. just-in-time logging) are quick and easy debugging instruments for instantly outputting live data from production without redeploying or restarting your application.

<details>
<summary>Screencast</summary>
<details>
<summary>Screencast</summary>

![live-log](https://user-images.githubusercontent.com/3278877/136304738-d46c2796-4dd3-45a3-81bb-5692547c1c71.gif)
</details>

</details>
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ kotlin.code.style=official

pluginGroup = spp.jetbrains
pluginName = Source++
projectVersion=0.4.2
projectVersion=0.4.3
pluginSinceBuild = 202.4357
# Plugin Verifier integration -> https://github.com/JetBrains/gradle-intellij-plugin#plugin-verifier-dsl
# See https://jb.gg/intellij-platform-builds-list for available build versions
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,14 @@ class JVMArtifactCreationService : ArtifactCreationService {
}
}

override fun createMethodGutterMark(
fileMarker: SourceFileMarker,
element: PsiElement,
autoApply: Boolean
): MethodGutterMark {
return JVMMarkerUtils.createMethodGutterMark(fileMarker, element, autoApply)
}

override fun createMethodInlayMark(
fileMarker: SourceFileMarker,
element: PsiElement,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,6 @@ class JVMVariableSimpleNode(val variable: LiveVariable) : SimpleNode() {
"java.lang.Float",
"java.lang.Double"
)
private val gsonPrimitives = setOf(
"java.math.BigInteger",
"java.lang.Date"
)
private val scheme = DebuggerUIUtil.getColorScheme(null)

override fun getChildren(): Array<SimpleNode> {
Expand Down Expand Up @@ -112,28 +108,15 @@ class JVMVariableSimpleNode(val variable: LiveVariable) : SimpleNode() {
}
presentation.setIcon(AllIcons.Debugger.Db_primitive)
} else if (variable.liveClazz != null) {
if (variable.liveClazz == "java.lang.Class") {
presentation.addText(
"{ " + variable.value.toString().substringAfterLast(".") + " }",
SimpleTextAttributes.GRAYED_ATTRIBUTES
)
presentation.setIcon(AllIcons.Debugger.Value)
} else if (gsonPrimitives.contains(variable.liveClazz)) {
val simpleClassName = variable.liveClazz!!.substringAfterLast(".")
val identity = variable.liveIdentity
presentation.addText("{ $simpleClassName@$identity }", SimpleTextAttributes.GRAYED_ATTRIBUTES)
presentation.addText(" \"" + variable.value + "\"", SimpleTextAttributes.REGULAR_ATTRIBUTES)
presentation.setIcon(AllIcons.Debugger.Db_primitive)
val simpleClassName = variable.liveClazz!!.substringAfterLast(".")
val identity = variable.liveIdentity
if (variable.presentation != null) {
presentation.addText("{ $simpleClassName@$identity } ", SimpleTextAttributes.GRAYED_ATTRIBUTES)
presentation.addText("\"${variable.presentation}\"", SimpleTextAttributes.REGULAR_ATTRIBUTES)
} else {
val simpleClassName = variable.liveClazz!!.substringAfterLast(".")
val identity = variable.liveIdentity
if (variable.presentation != null) {
presentation.addText("\"${variable.presentation}\"", SimpleTextAttributes.REGULAR_ATTRIBUTES)
} else {
presentation.addText("{ $simpleClassName@$identity }", SimpleTextAttributes.GRAYED_ATTRIBUTES)
}
presentation.setIcon(AllIcons.Debugger.Value)
presentation.addText("{ $simpleClassName@$identity }", SimpleTextAttributes.GRAYED_ATTRIBUTES)
}
presentation.setIcon(AllIcons.Debugger.Value)
} else {
if (variable.value is Number) {
presentation.addText(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ class EndpointDetector(val vertx: Vertx) {
log.trace("Determining endpoint name")
val detectedEndpoint = determineEndpointName(sourceMark).await().orElse(null)
if (detectedEndpoint != null) {
log.debug("Detected endpoint name: ${detectedEndpoint.name}")
log.trace("Detected endpoint name: ${detectedEndpoint.name}")
sourceMark.putUserData(ENDPOINT_NAME, detectedEndpoint.name)
sourceMark.putUserData(ENDPOINT_INTERNAL, detectedEndpoint.internal)

Expand All @@ -125,9 +125,9 @@ class EndpointDetector(val vertx: Vertx) {
val endpoint = EndpointBridge.searchExactEndpoint(endpointName, vertx)
if (endpoint != null) {
sourceMark.putUserData(ENDPOINT_ID, endpoint.id)
log.debug("Detected endpoint id: ${endpoint.id}")
log.trace("Detected endpoint id: ${endpoint.id}")
} else {
log.debug("Could not find endpoint id for: $endpointName")
log.trace("Could not find endpoint id for: $endpointName")
}
} catch (ex: ReplyException) {
if (ex.failureType() == ReplyFailure.TIMEOUT) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import org.jetbrains.uast.java.JavaUSimpleNameReferenceExpression
import org.jetbrains.uast.kotlin.KotlinStringULiteralExpression
import org.jetbrains.uast.kotlin.KotlinUQualifiedReferenceExpression
import org.jetbrains.uast.kotlin.KotlinUSimpleReferenceExpression
import org.jetbrains.uast.kotlin.expressions.KotlinUCollectionLiteralExpression
import org.jooq.tools.reflect.Reflect
import spp.jetbrains.marker.jvm.psi.EndpointDetector
import spp.jetbrains.marker.jvm.psi.EndpointDetector.DetectedEndpoint
import java.util.*
Expand Down Expand Up @@ -206,12 +206,12 @@ class SpringMVCEndpoint : EndpointDetector.EndpointNameDeterminer {
}

val methodExpr = annotation.attributeValues.find { it.name == "method" }!!.expression
var value = if (endpointNameExpr is KotlinUCollectionLiteralExpression) {
endpointNameExpr.valueArguments[0].evaluate()
var value = if (endpointNameExpr?.javaClass?.simpleName?.equals("KotlinUCollectionLiteralExpression") == true) {
getField<List<UExpression>>(endpointNameExpr, "valueArguments")[0].evaluate()
} else {
endpointNameExpr?.evaluate() ?: ""
}
val valueArg = (methodExpr as KotlinUCollectionLiteralExpression).valueArguments[0]
val valueArg = getField<List<Any>>(methodExpr, "valueArguments")[0]
val method = if (valueArg is KotlinUSimpleReferenceExpression) {
valueArg.resolvedName
} else if (valueArg is KotlinUQualifiedReferenceExpression) {
Expand All @@ -224,8 +224,8 @@ class SpringMVCEndpoint : EndpointDetector.EndpointNameDeterminer {
} else {
var valueExpr = annotation.findAttributeValue("value")
if (valueExpr == null) valueExpr = annotation.findAttributeValue("path")
var value = if (valueExpr is KotlinUCollectionLiteralExpression) {
valueExpr.valueArguments[0].evaluate()
var value = if (valueExpr?.javaClass?.simpleName?.equals("KotlinUCollectionLiteralExpression") == true) {
getField<List<UExpression>>(valueExpr, "valueArguments")[0].evaluate()
} else if (valueExpr != null) {
valueExpr.evaluate()
} else {
Expand Down Expand Up @@ -276,8 +276,8 @@ class SpringMVCEndpoint : EndpointDetector.EndpointNameDeterminer {
if (valueExpr is UastEmptyExpression) valueExpr =
annotation.findAttributeValue("path") //todo: have to call this twice???
if (valueExpr is UastEmptyExpression) valueExpr = null
var value = if (valueExpr is KotlinUCollectionLiteralExpression) {
valueExpr.valueArguments[0].evaluate()
var value = if (valueExpr?.javaClass?.simpleName?.equals("KotlinUCollectionLiteralExpression") == true) {
getField<List<UExpression>>(valueExpr, "valueArguments")[0].evaluate()
} else if (valueExpr != null) {
valueExpr.evaluate()
} else {
Expand All @@ -289,4 +289,20 @@ class SpringMVCEndpoint : EndpointDetector.EndpointNameDeterminer {
return Optional.of(DetectedEndpoint("$method:$value", false, value.toString(), method))
}
}

private fun <T> getField(value: Any, name: String): T {
val fields = Reflect.on(value).fields()
return if (fields.containsKey(name)) {
fields[name]!!.get()
} else if (fields.containsKey("$name\$delegate")) {
val value = fields["$name\$delegate"]!!.get<Any>()
return if (value is Lazy<*>) {
value.value as T
} else {
value as T
}
} else {
throw IllegalArgumentException("Field $name not found")
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import spp.jetbrains.marker.source.mark.api.SourceMark
import spp.jetbrains.marker.source.mark.api.key.SourceKey
import spp.jetbrains.marker.source.mark.gutter.ClassGutterMark
import spp.jetbrains.marker.source.mark.gutter.ExpressionGutterMark
import spp.jetbrains.marker.source.mark.gutter.MethodGutterMark
import spp.jetbrains.marker.source.mark.inlay.ExpressionInlayMark
import spp.jetbrains.marker.source.mark.inlay.MethodInlayMark
import spp.protocol.artifact.ArtifactQualifiedName
Expand Down Expand Up @@ -309,6 +310,37 @@ object JVMMarkerUtils {
return statementExpression
}

/**
* todo: description.
*
* @since 0.4.3
*/
@JvmStatic
@JvmOverloads
@Synchronized
fun createMethodGutterMark(
fileMarker: SourceFileMarker,
element: PsiElement,
autoApply: Boolean = false
): MethodGutterMark {
log.trace("createMethodGutterMark: $element")
val gutterMark = fileMarker.createMethodSourceMark(
element.parent as PsiNameIdentifierOwner,
getFullyQualifiedName(element.parent.toUElement() as UMethod),
SourceMark.Type.GUTTER
) as MethodGutterMark
return if (autoApply) {
if (gutterMark.canApply()) {
gutterMark.apply(true)
gutterMark
} else {
throw IllegalStateException("Could not apply gutter mark: $gutterMark")
}
} else {
gutterMark
}
}

/**
* todo: description.
*
Expand Down Expand Up @@ -340,7 +372,6 @@ object JVMMarkerUtils {
}
}


/**
* todo: description.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,14 @@ class PythonArtifactCreationService : ArtifactCreationService {
return Optional.empty()
}

override fun createMethodGutterMark(
fileMarker: SourceFileMarker,
element: PsiElement,
autoApply: Boolean
): MethodGutterMark {
TODO("Not yet implemented")
}

override fun createMethodInlayMark(
fileMarker: SourceFileMarker,
element: PsiElement,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ interface ArtifactCreationService {
autoApply: Boolean = false
): Optional<ExpressionInlayMark>

fun createMethodGutterMark(
fileMarker: SourceFileMarker,
element: PsiElement,
autoApply: Boolean = false
): MethodGutterMark

fun createMethodInlayMark(
fileMarker: SourceFileMarker,
element: PsiElement,
Expand Down
Loading