Skip to content
This repository was archived by the owner on Mar 8, 2020. It is now read-only.

Commit d5b20f0

Browse files
authored
Merge pull request #97 from bzz/nodext
Node documentation and convenience
2 parents 25fcda2 + 55abd1f commit d5b20f0

13 files changed

+102
-66
lines changed

src/main/native/jni_utils.cc

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,18 @@ JNIEnv *getJNIEnv() {
1414

1515
case JNI_EDETACHED: // Thread is detached, need to attach
1616
jvm->AttachCurrentThread((void **)&pEnv, NULL);
17+
// FIXME(bzz): this is a memory leak (at least)
18+
// - jvm->DetachCurrentThread() is never called
19+
// - local references are _never_ deleted :scream:
20+
// https://developer.android.com/training/articles/perf-jni#local-and-global-references
1721
break;
1822
}
1923

2024
return pEnv;
2125
}
2226

2327
// Class fully qualified names
24-
const char CLS_NODE[] = "org/bblfsh/client/v2/Node";
28+
const char CLS_NODE[] = "org/bblfsh/client/v2/NodeExt";
2529
const char CLS_CTX[] = "org/bblfsh/client/v2/ContextExt";
2630
const char CLS_OBJ[] = "java/lang/Object";
2731
const char CLS_RE[] = "java/lang/RuntimeException";

src/main/native/org_bblfsh_client_v2_ContextExt.h

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main/native/org_bblfsh_client_v2_Node.h

Lines changed: 0 additions & 21 deletions
This file was deleted.

src/main/native/org_bblfsh_client_v2_NodeExt.h

Lines changed: 21 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main/native/org_bblfsh_client_v2_libuast_Libuast.cc

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
#include "org_bblfsh_client_v2_Context.h"
55
#include "org_bblfsh_client_v2_ContextExt.h"
66
#include "org_bblfsh_client_v2_Context__.h"
7-
#include "org_bblfsh_client_v2_Node.h"
7+
#include "org_bblfsh_client_v2_NodeExt.h"
88
#include "org_bblfsh_client_v2_libuast_Libuast.h"
99

1010
#include "libuast.h"
@@ -560,6 +560,15 @@ Java_org_bblfsh_client_v2_Context_00024_create(JNIEnv *env, jobject self) {
560560
return (long)c;
561561
}
562562

563+
JNIEXPORT void JNICALL
564+
Java_org_bblfsh_client_v2_Context_dispose(JNIEnv *env, jobject self){
565+
Context *p = getHandle<Context>(env, self, nativeContext);
566+
setHandle<Context>(env, self, 0, nativeContext);
567+
delete p;
568+
};
569+
570+
571+
563572
// ==========================================
564573
// v2.ContextExt()
565574
// ==========================================
@@ -589,8 +598,8 @@ Java_org_bblfsh_client_v2_ContextExt_dispose(JNIEnv *env, jobject self) {
589598
// v2.Node()
590599
// ==========================================
591600

592-
JNIEXPORT jobject JNICALL Java_org_bblfsh_client_v2_Node_load(JNIEnv *env,
593-
jobject self) {
601+
JNIEXPORT jobject JNICALL Java_org_bblfsh_client_v2_NodeExt_load(JNIEnv *env,
602+
jobject self) {
594603
auto ctx = new Context();
595604
jobject node = ctx->LoadFrom(self);
596605
delete (ctx);

src/main/native/org_bblfsh_client_v2_libuast_Libuast.h

Lines changed: 15 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/main/scala/org/bblfsh/client/v2/BblfshClient.scala

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ class BblfshClient(host: String, port: Int, maxMsgSize: Int) {
100100
object BblfshClient {
101101
val DEFAULT_MAX_MSG_SIZE = 100 * 1024 * 1024 // bytes
102102

103-
// TODO(bzz): expose new 'children' order and use enum/case class
103+
// TODO(bzz): expose new 'children' order, use enum/case class
104104
val PreOrder = 0
105105
val PostOrder = 1
106106
val LevelOrder = 2
@@ -113,7 +113,7 @@ object BblfshClient {
113113
maxMsgSize: Int = DEFAULT_MAX_MSG_SIZE
114114
): BblfshClient = new BblfshClient(host, port, maxMsgSize)
115115

116-
def filter(node: Node, query: String): List[Node] = Libuast.synchronized {
116+
def filter(node: NodeExt, query: String): List[NodeExt] = Libuast.synchronized {
117117
libuast.filter(node, query)
118118
}
119119

@@ -142,14 +142,19 @@ object BblfshClient {
142142
BblfshClient.decode(bufDirectCopy)
143143
}
144144
}
145-
146-
// TODO(bzz): implement
147-
// def iterator(node: Node, treeOrder: Int): Libuast.UastIterator = {
148-
// libuast.iterator(node, treeOrder)
145+
146+
// TODO(bzz): implement iterator
147+
// def iterator(node: NodeExt, treeOrder: Int): Libuast.NodeIterator = {
148+
// new Libuast.NodeIterator(node, treeOrder)
149+
// }
150+
// def iterator(node: JNode, treeOrder: Int): Libuast.NodeIterator = {
151+
// new Libuast.NodeIterator(node, treeOrder)
149152
// }
150153

151-
// implicit class NodeMethods(val node: Node) {
152-
// def filter(query: String): List[Node] = {
154+
// Enables API: resp.uast.decode().load().filter("//query")
155+
// TODO(bzz): implement XPath query
156+
// implicit class NodeExtMethods(val node: NodeExt) {
157+
// def filter(query: String): List[NodeExt] = {
153158
// BblfshClient.filter(node, query)
154159
// }
155160
// }

src/main/scala/org/bblfsh/client/v2/ContextExt.scala

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,15 @@ package org.bblfsh.client.v2
33
import java.nio.ByteBuffer
44

55
/**
6-
* Represents Go-side results of Libuast.decode()
6+
* Represents Go-side constructed tree, result of Libuast.decode()
77
*
88
* This is equivalent of pyuast.ContextExt API
99
*/
1010
case class ContextExt(nativeContext: Long) {
11-
@native def root(): Node
12-
// @native def load() // TODO(bzz): implement after clarifying when it's needed
11+
@native def root(): NodeExt
12+
// @native def load(): JNode // TODO(bzz): clarify when it's needed VS just .root().load()
1313
@native def filter()
14-
@native def encode(n: Node): ByteBuffer
14+
@native def encode(n: NodeExt): ByteBuffer
1515

1616
@native def dispose()
1717
override def finalize(): Unit = {

src/main/scala/org/bblfsh/client/v2/Node.scala

Lines changed: 0 additions & 5 deletions
This file was deleted.

src/main/scala/org/bblfsh/client/v2/JNode.scala renamed to src/main/scala/org/bblfsh/client/v2/NodeExt.scala

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,23 @@ import java.io.Serializable
44

55
import scala.collection.mutable
66

7-
/** UAST nodes representation on the JVM side.
7+
/**
8+
* UAST representation for the nodes originated from the Go side.
9+
* This is equivalent of pyuast.NodeExt API.
810
*
9-
* Mirrors https://godoc.org/github.com/bblfsh/sdk/uast/nodes
11+
* @param ctx pointer to the native ContextExt
12+
* @param handle pointer to the native Node
13+
*/
14+
case class NodeExt(ctx: Long, handle: Long) {
15+
@native def load(): JNode
16+
}
17+
18+
19+
/**
20+
* UAST representation for the nodes originated from or loaded to the JVM side.
21+
* Mirrors https://godoc.org/github.com/bblfsh/sdk/uast/nodes
22+
*
23+
* This is equivalent of pyuast.Node API.
1024
*/
1125
sealed abstract class JNode {
1226
/* Dynamic dispatch is a convenience to be called from JNI */
@@ -53,6 +67,7 @@ case class JBool(value: Boolean) extends JNode
5367

5468
case class JObject(obj: mutable.Buffer[JField]) extends JNode {
5569
def this() = this(mutable.Buffer[JField]())
70+
def filter(p: ((String, JNode)) => Boolean) = this.obj.filter(p)
5671
def add(k: String, v: JNode) = {
5772
obj += ((k, v))
5873
}
@@ -67,11 +82,13 @@ case object JObject {
6782

6883
case class JArray(arr: mutable.Buffer[JNode]) extends JNode {
6984
def this(size: Int) = this(new mutable.ArrayBuffer[JNode](size))
85+
def filter(p: JNode => Boolean) = this.arr.filter(p)
7086
def add(n: JNode) = {
7187
arr += n
7288
}
7389
}
7490
case object JArray {
91+
/** Helper to construct literals in map-like notation */
7592
def apply[T <: (Product with Serializable with JNode)](ns: T *) = {
7693
val ja = new JArray(ns.length)
7794
ja.arr ++= ns

src/main/scala/org/bblfsh/client/v2/libuast/Libuast.scala

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package org.bblfsh.client.v2.libuast
22

3-
import org.bblfsh.client.v2.{ContextExt, JNode, Node}
3+
import org.bblfsh.client.v2.{ContextExt, JNode, NodeExt}
44

55
import scala.collection.Iterator
66
import java.io.File
@@ -80,11 +80,11 @@ class Libuast {
8080
}
8181
}
8282

83-
// TODO(bzz): implement iterators
84-
// def iterator(node: Node, treeOrder: Int) = {
85-
// new Libuast.UastIterator(node, treeOrder)
86-
// }
83+
@native def filter(node: NodeExt, query: String): List[NodeExt]
84+
85+
// def iterator(node: Node, treeOrder: Int) =
86+
// new Libuast.NodeIterator(node, treeOrder)
8787

8888
@native def decode(buf: ByteBuffer): ContextExt
89-
@native def filter(node: Node, query: String): List[Node]
89+
9090
}

src/test/scala/org/bblfsh/client/v2/BblfshClientLoadTest.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ class BblfshClientLoadTest extends BblfshClientBaseTest {
1111

1212
"Loading Go -> JVM of a real tree" should "bring JNode tree to memory" in {
1313
val uast = resp.uast.decode()
14-
val rootNode: Node = uast.root()
14+
val rootNode: NodeExt = uast.root()
1515

1616
println(s"Loading $rootNode")
1717
val root = rootNode.load()
@@ -55,7 +55,7 @@ class BblfshClientLoadTest extends BblfshClientBaseTest {
5555
"Decoding, loading & encoding to different context" should "produce the same results" in {
5656
// decode -> load -> encode, and compare bytes
5757
val uast = resp.uast.decode()
58-
val rootNode: Node = uast.root()
58+
val rootNode: NodeExt = uast.root()
5959

6060
println(s"Loading $rootNode")
6161
val root = rootNode.load()
@@ -66,7 +66,7 @@ class BblfshClientLoadTest extends BblfshClientBaseTest {
6666

6767
// decode -> load -> encoded -> decode -> load, and compare trees
6868
val uast2 = BblfshClient.decode(data)
69-
val rootNode2: Node = uast2.root()
69+
val rootNode2: NodeExt = uast2.root()
7070
println(s"Loading $rootNode2")
7171
val root2 = rootNode2.load()
7272

src/test/scala/org/bblfsh/client/v2/BblfshClientParseTest.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ class BblfshClientParseTest extends BblfshClientBaseTest {
2424

2525
"Decoded UAST RootNode" should "not be NULL" in {
2626
val uast = resp.uast.decode()
27-
val rootNode: Node = uast.root()
27+
val rootNode: NodeExt = uast.root()
2828
println(rootNode.getClass)
2929

3030
rootNode should not be null
@@ -36,7 +36,7 @@ class BblfshClientParseTest extends BblfshClientBaseTest {
3636

3737
"Encoding back the RootNode of decoded UAST" should "produce same bytes" in {
3838
val uastCtx: ContextExt = resp.uast.decode()
39-
val rootNode: Node = uastCtx.root()
39+
val rootNode: NodeExt = uastCtx.root()
4040
println(s"Root node: $rootNode")
4141

4242
val encodedBytes: ByteBuffer = uastCtx.encode(rootNode)

0 commit comments

Comments
 (0)