Skip to content

Commit e2ac5de

Browse files
authored
v0.4.3 (#689)
* fix view history on watch log expression * lower logging * rename * update * link * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * Update README.md * trigger event * convenience method * createMethodGutterMark * default * lazy changelog * move method * impl SWLiveViewService * allow live view commands * move code to processor * impl show/hide quick stats * todo * accept events to indiv subscriber * bump * don't need * Update JVMMarkerUtils.kt * auto-display endpoint quick stats setting * auto-display endpoint quick stats setting * change default * impl auto-resolve for SWLiveService
1 parent 5c5d68b commit e2ac5de

File tree

35 files changed

+916
-421
lines changed

35 files changed

+916
-421
lines changed

README.md

Lines changed: 57 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -4,42 +4,85 @@
44
![GitHub release](https://img.shields.io/github/v/release/sourceplusplus/interface-jetbrains?include_prereleases)
55
[![Build](https://github.com/sourceplusplus/interface-jetbrains/actions/workflows/build.yml/badge.svg)](https://github.com/sourceplusplus/interface-jetbrains/actions/workflows/build.yml)
66

7-
## What is this?
7+
# What is this?
88

99
<!-- Plugin description -->
1010

11-
This project contains the JetBrains IDE plugin for [Source++](https://github.com/sourceplusplus/live-platform), the open-source live coding platform.
11+
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.
1212

1313
<!-- Plugin description end -->
1414

15-
## Features
15+
# How to use?
1616

17-
### Live Views
17+
Once installed, this plugin adds a command bar to the JetBrains IDE, which is accessible by pressing `Ctrl+Shift+S`.
18+
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).
1819

19-
> Contextual popups for displaying live operational data on the code currently in view.
20+
# Available Commands
21+
22+
## Live Views
23+
24+
**Live View** commands utilize existing SkyWalking metrics to display live production data directly inside of your IDE.
2025

2126
<details>
22-
<summary>Screencast</summary>
27+
<summary><b>Show Commands</b> &nbsp; 👈 &nbsp; <i>(click to expand)</i></summary>
28+
29+
### Show/Hide Quick Stats
30+
31+
> Inlay hints which indicate an endpoint's current activity.
32+
33+
<details>
34+
<summary>Screencast</summary>
35+
36+
![screencast](https://user-images.githubusercontent.com/3278877/158376181-7fe597f9-f3c2-4609-bd07-4ea55e10b579.gif)
37+
</details>
38+
39+
### Watch Log
40+
41+
> Follow specific logging statements in real-time.
42+
43+
<details>
44+
<summary>Screencast</summary>
45+
46+
![screencast](https://user-images.githubusercontent.com/3278877/158381411-214285ba-7291-4c70-8e1f-8489140fa239.gif)
47+
</details>
48+
49+
### Display Portal
50+
51+
> Contextual popups for displaying live operational data on the code currently in view.
52+
53+
<details>
54+
<summary>Screencast</summary>
2355

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

27-
### Live Breakpoint
61+
## Live Instruments
2862

29-
> 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.
63+
**Live Instrument** commands require a [Live Probe](https://github.com/sourceplusplus/probe-jvm) to inject additional metrics for live production debugging.
3064

3165
<details>
32-
<summary>Screencast</summary>
66+
<summary><b>Show Commands</b> &nbsp; 👈 &nbsp; <i>(click to expand)</i></summary>
67+
68+
### Add Breakpoint
69+
70+
> 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.
71+
72+
<details>
73+
<summary>Screencast</summary>
3374

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

37-
### Live Log
78+
### Add Log
3879

39-
> 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.
80+
> 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.
4081
41-
<details>
42-
<summary>Screencast</summary>
82+
<details>
83+
<summary>Screencast</summary>
4384

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

gradle.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ kotlin.code.style=official
44

55
pluginGroup = spp.jetbrains
66
pluginName = Source++
7-
projectVersion=0.4.2
7+
projectVersion=0.4.3
88
pluginSinceBuild = 202.4357
99
# Plugin Verifier integration -> https://github.com/JetBrains/gradle-intellij-plugin#plugin-verifier-dsl
1010
# See https://jb.gg/intellij-platform-builds-list for available build versions

marker/jvm-marker/src/main/kotlin/spp/jetbrains/marker/jvm/JVMArtifactCreationService.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,14 @@ class JVMArtifactCreationService : ArtifactCreationService {
119119
}
120120
}
121121

122+
override fun createMethodGutterMark(
123+
fileMarker: SourceFileMarker,
124+
element: PsiElement,
125+
autoApply: Boolean
126+
): MethodGutterMark {
127+
return JVMMarkerUtils.createMethodGutterMark(fileMarker, element, autoApply)
128+
}
129+
122130
override fun createMethodInlayMark(
123131
fileMarker: SourceFileMarker,
124132
element: PsiElement,

marker/jvm-marker/src/main/kotlin/spp/jetbrains/marker/jvm/JVMVariableSimpleNode.kt

Lines changed: 7 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,6 @@ class JVMVariableSimpleNode(val variable: LiveVariable) : SimpleNode() {
5656
"java.lang.Float",
5757
"java.lang.Double"
5858
)
59-
private val gsonPrimitives = setOf(
60-
"java.math.BigInteger",
61-
"java.lang.Date"
62-
)
6359
private val scheme = DebuggerUIUtil.getColorScheme(null)
6460

6561
override fun getChildren(): Array<SimpleNode> {
@@ -112,28 +108,15 @@ class JVMVariableSimpleNode(val variable: LiveVariable) : SimpleNode() {
112108
}
113109
presentation.setIcon(AllIcons.Debugger.Db_primitive)
114110
} else if (variable.liveClazz != null) {
115-
if (variable.liveClazz == "java.lang.Class") {
116-
presentation.addText(
117-
"{ " + variable.value.toString().substringAfterLast(".") + " }",
118-
SimpleTextAttributes.GRAYED_ATTRIBUTES
119-
)
120-
presentation.setIcon(AllIcons.Debugger.Value)
121-
} else if (gsonPrimitives.contains(variable.liveClazz)) {
122-
val simpleClassName = variable.liveClazz!!.substringAfterLast(".")
123-
val identity = variable.liveIdentity
124-
presentation.addText("{ $simpleClassName@$identity }", SimpleTextAttributes.GRAYED_ATTRIBUTES)
125-
presentation.addText(" \"" + variable.value + "\"", SimpleTextAttributes.REGULAR_ATTRIBUTES)
126-
presentation.setIcon(AllIcons.Debugger.Db_primitive)
111+
val simpleClassName = variable.liveClazz!!.substringAfterLast(".")
112+
val identity = variable.liveIdentity
113+
if (variable.presentation != null) {
114+
presentation.addText("{ $simpleClassName@$identity } ", SimpleTextAttributes.GRAYED_ATTRIBUTES)
115+
presentation.addText("\"${variable.presentation}\"", SimpleTextAttributes.REGULAR_ATTRIBUTES)
127116
} else {
128-
val simpleClassName = variable.liveClazz!!.substringAfterLast(".")
129-
val identity = variable.liveIdentity
130-
if (variable.presentation != null) {
131-
presentation.addText("\"${variable.presentation}\"", SimpleTextAttributes.REGULAR_ATTRIBUTES)
132-
} else {
133-
presentation.addText("{ $simpleClassName@$identity }", SimpleTextAttributes.GRAYED_ATTRIBUTES)
134-
}
135-
presentation.setIcon(AllIcons.Debugger.Value)
117+
presentation.addText("{ $simpleClassName@$identity }", SimpleTextAttributes.GRAYED_ATTRIBUTES)
136118
}
119+
presentation.setIcon(AllIcons.Debugger.Value)
137120
} else {
138121
if (variable.value is Number) {
139122
presentation.addText(

marker/jvm-marker/src/main/kotlin/spp/jetbrains/marker/jvm/psi/EndpointDetector.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ class EndpointDetector(val vertx: Vertx) {
105105
log.trace("Determining endpoint name")
106106
val detectedEndpoint = determineEndpointName(sourceMark).await().orElse(null)
107107
if (detectedEndpoint != null) {
108-
log.debug("Detected endpoint name: ${detectedEndpoint.name}")
108+
log.trace("Detected endpoint name: ${detectedEndpoint.name}")
109109
sourceMark.putUserData(ENDPOINT_NAME, detectedEndpoint.name)
110110
sourceMark.putUserData(ENDPOINT_INTERNAL, detectedEndpoint.internal)
111111

@@ -125,9 +125,9 @@ class EndpointDetector(val vertx: Vertx) {
125125
val endpoint = EndpointBridge.searchExactEndpoint(endpointName, vertx)
126126
if (endpoint != null) {
127127
sourceMark.putUserData(ENDPOINT_ID, endpoint.id)
128-
log.debug("Detected endpoint id: ${endpoint.id}")
128+
log.trace("Detected endpoint id: ${endpoint.id}")
129129
} else {
130-
log.debug("Could not find endpoint id for: $endpointName")
130+
log.trace("Could not find endpoint id for: $endpointName")
131131
}
132132
} catch (ex: ReplyException) {
133133
if (ex.failureType() == ReplyFailure.TIMEOUT) {

marker/jvm-marker/src/main/kotlin/spp/jetbrains/marker/jvm/psi/endpoint/SpringMVCEndpoint.kt

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ import org.jetbrains.uast.java.JavaUSimpleNameReferenceExpression
2828
import org.jetbrains.uast.kotlin.KotlinStringULiteralExpression
2929
import org.jetbrains.uast.kotlin.KotlinUQualifiedReferenceExpression
3030
import org.jetbrains.uast.kotlin.KotlinUSimpleReferenceExpression
31-
import org.jetbrains.uast.kotlin.expressions.KotlinUCollectionLiteralExpression
31+
import org.jooq.tools.reflect.Reflect
3232
import spp.jetbrains.marker.jvm.psi.EndpointDetector
3333
import spp.jetbrains.marker.jvm.psi.EndpointDetector.DetectedEndpoint
3434
import java.util.*
@@ -206,12 +206,12 @@ class SpringMVCEndpoint : EndpointDetector.EndpointNameDeterminer {
206206
}
207207

208208
val methodExpr = annotation.attributeValues.find { it.name == "method" }!!.expression
209-
var value = if (endpointNameExpr is KotlinUCollectionLiteralExpression) {
210-
endpointNameExpr.valueArguments[0].evaluate()
209+
var value = if (endpointNameExpr?.javaClass?.simpleName?.equals("KotlinUCollectionLiteralExpression") == true) {
210+
getField<List<UExpression>>(endpointNameExpr, "valueArguments")[0].evaluate()
211211
} else {
212212
endpointNameExpr?.evaluate() ?: ""
213213
}
214-
val valueArg = (methodExpr as KotlinUCollectionLiteralExpression).valueArguments[0]
214+
val valueArg = getField<List<Any>>(methodExpr, "valueArguments")[0]
215215
val method = if (valueArg is KotlinUSimpleReferenceExpression) {
216216
valueArg.resolvedName
217217
} else if (valueArg is KotlinUQualifiedReferenceExpression) {
@@ -224,8 +224,8 @@ class SpringMVCEndpoint : EndpointDetector.EndpointNameDeterminer {
224224
} else {
225225
var valueExpr = annotation.findAttributeValue("value")
226226
if (valueExpr == null) valueExpr = annotation.findAttributeValue("path")
227-
var value = if (valueExpr is KotlinUCollectionLiteralExpression) {
228-
valueExpr.valueArguments[0].evaluate()
227+
var value = if (valueExpr?.javaClass?.simpleName?.equals("KotlinUCollectionLiteralExpression") == true) {
228+
getField<List<UExpression>>(valueExpr, "valueArguments")[0].evaluate()
229229
} else if (valueExpr != null) {
230230
valueExpr.evaluate()
231231
} else {
@@ -276,8 +276,8 @@ class SpringMVCEndpoint : EndpointDetector.EndpointNameDeterminer {
276276
if (valueExpr is UastEmptyExpression) valueExpr =
277277
annotation.findAttributeValue("path") //todo: have to call this twice???
278278
if (valueExpr is UastEmptyExpression) valueExpr = null
279-
var value = if (valueExpr is KotlinUCollectionLiteralExpression) {
280-
valueExpr.valueArguments[0].evaluate()
279+
var value = if (valueExpr?.javaClass?.simpleName?.equals("KotlinUCollectionLiteralExpression") == true) {
280+
getField<List<UExpression>>(valueExpr, "valueArguments")[0].evaluate()
281281
} else if (valueExpr != null) {
282282
valueExpr.evaluate()
283283
} else {
@@ -289,4 +289,20 @@ class SpringMVCEndpoint : EndpointDetector.EndpointNameDeterminer {
289289
return Optional.of(DetectedEndpoint("$method:$value", false, value.toString(), method))
290290
}
291291
}
292+
293+
private fun <T> getField(value: Any, name: String): T {
294+
val fields = Reflect.on(value).fields()
295+
return if (fields.containsKey(name)) {
296+
fields[name]!!.get()
297+
} else if (fields.containsKey("$name\$delegate")) {
298+
val value = fields["$name\$delegate"]!!.get<Any>()
299+
return if (value is Lazy<*>) {
300+
value.value as T
301+
} else {
302+
value as T
303+
}
304+
} else {
305+
throw IllegalArgumentException("Field $name not found")
306+
}
307+
}
292308
}

marker/jvm-marker/src/main/kotlin/spp/jetbrains/marker/source/JVMMarkerUtils.kt

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ import spp.jetbrains.marker.source.mark.api.SourceMark
2929
import spp.jetbrains.marker.source.mark.api.key.SourceKey
3030
import spp.jetbrains.marker.source.mark.gutter.ClassGutterMark
3131
import spp.jetbrains.marker.source.mark.gutter.ExpressionGutterMark
32+
import spp.jetbrains.marker.source.mark.gutter.MethodGutterMark
3233
import spp.jetbrains.marker.source.mark.inlay.ExpressionInlayMark
3334
import spp.jetbrains.marker.source.mark.inlay.MethodInlayMark
3435
import spp.protocol.artifact.ArtifactQualifiedName
@@ -309,6 +310,37 @@ object JVMMarkerUtils {
309310
return statementExpression
310311
}
311312

313+
/**
314+
* todo: description.
315+
*
316+
* @since 0.4.3
317+
*/
318+
@JvmStatic
319+
@JvmOverloads
320+
@Synchronized
321+
fun createMethodGutterMark(
322+
fileMarker: SourceFileMarker,
323+
element: PsiElement,
324+
autoApply: Boolean = false
325+
): MethodGutterMark {
326+
log.trace("createMethodGutterMark: $element")
327+
val gutterMark = fileMarker.createMethodSourceMark(
328+
element.parent as PsiNameIdentifierOwner,
329+
getFullyQualifiedName(element.parent.toUElement() as UMethod),
330+
SourceMark.Type.GUTTER
331+
) as MethodGutterMark
332+
return if (autoApply) {
333+
if (gutterMark.canApply()) {
334+
gutterMark.apply(true)
335+
gutterMark
336+
} else {
337+
throw IllegalStateException("Could not apply gutter mark: $gutterMark")
338+
}
339+
} else {
340+
gutterMark
341+
}
342+
}
343+
312344
/**
313345
* todo: description.
314346
*
@@ -340,7 +372,6 @@ object JVMMarkerUtils {
340372
}
341373
}
342374

343-
344375
/**
345376
* todo: description.
346377
*

marker/py-marker/src/main/kotlin/spp/jetbrains/marker/py/PythonArtifactCreationService.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,14 @@ class PythonArtifactCreationService : ArtifactCreationService {
115115
return Optional.empty()
116116
}
117117

118+
override fun createMethodGutterMark(
119+
fileMarker: SourceFileMarker,
120+
element: PsiElement,
121+
autoApply: Boolean
122+
): MethodGutterMark {
123+
TODO("Not yet implemented")
124+
}
125+
118126
override fun createMethodInlayMark(
119127
fileMarker: SourceFileMarker,
120128
element: PsiElement,

marker/src/main/kotlin/spp/jetbrains/marker/ArtifactCreationService.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ interface ArtifactCreationService {
5151
autoApply: Boolean = false
5252
): Optional<ExpressionInlayMark>
5353

54+
fun createMethodGutterMark(
55+
fileMarker: SourceFileMarker,
56+
element: PsiElement,
57+
autoApply: Boolean = false
58+
): MethodGutterMark
59+
5460
fun createMethodInlayMark(
5561
fileMarker: SourceFileMarker,
5662
element: PsiElement,

0 commit comments

Comments
 (0)