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

Commit e032655

Browse files
authored
Merge pull request #44 from bblfsh/feature/node.filter
Make Node.filter() work.
2 parents eb1fafe + bf948ad commit e032655

3 files changed

Lines changed: 55 additions & 29 deletions

File tree

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

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,9 @@ class BblfshClient(host: String, port: Int, maxMsgSize: Int) {
1616
.maxInboundMessageSize(maxMsgSize)
1717
.build()
1818
private val stub = ProtocolServiceGrpc.blockingStub(channel)
19-
private val libuast = new Libuast
2019

2120
def parse(name: String, content: String, lang: String = "",
22-
encoding: Encoding = Encoding.UTF8) = {
21+
encoding: Encoding = Encoding.UTF8): ParseResponse = {
2322
// assume content is already encoded in one of:
2423
// https://github.com/bblfsh/sdk/blob/master/protocol/protocol.go#L68
2524
val req = ParseRequest(filename = name,
@@ -30,13 +29,17 @@ class BblfshClient(host: String, port: Int, maxMsgSize: Int) {
3029
parsed
3130
}
3231

33-
def filter(node: Node, query: String): List[Node] = Libuast.synchronized {
34-
libuast.filter(node, query)
32+
/**
33+
* Proxy for Bblfsh.filter / Node.filter, provided for backward compatibility.
34+
*/
35+
def filter(node: Node, query: String): List[Node] = {
36+
BblfshClient.filter(node, query)
3537
}
3638
}
3739

3840
object BblfshClient {
3941
val DEFAULT_MAX_MSG_SIZE = 100 * 1024 * 1024
42+
private val libuast = new Libuast
4043

4144
def apply(host: String, port: Int,
4245
maxMsgSize: Int = DEFAULT_MAX_MSG_SIZE): BblfshClient =
@@ -53,5 +56,15 @@ object BblfshClient {
5356
.replace("+", "p")
5457
.replace("#", "sharp")
5558
}
59+
60+
def filter(node: Node, query: String): List[Node] = Libuast.synchronized {
61+
libuast.filter(node, query)
62+
}
63+
64+
implicit class NodeMethods(val node: Node) {
65+
def filter(query: String): List[Node] = {
66+
BblfshClient.filter(node, query)
67+
}
68+
}
5669
}
5770

src/main/scala/org/bblfsh/client/cli/ScalaClientCLI.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ object ScalaClientCLI extends App {
2222

2323
if (resp.errors.isEmpty) {
2424
if (query != null && query != "") {
25-
println(client.filter(resp.uast.get, query))
25+
println(BblfshClient.filter(resp.uast.get, query))
2626
} else {
2727
println(resp.uast.get)
2828
}

src/test/scala/org/bblf/client/BblfshClientTest.scala

Lines changed: 37 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package org.bblfsh.client
22

3-
import gopkg.in.bblfsh.sdk.v1.protocol.generated.ParseResponse
3+
import org.bblfsh.client.BblfshClient._
44

5+
import gopkg.in.bblfsh.sdk.v1.protocol.generated.ParseResponse
6+
import gopkg.in.bblfsh.sdk.v1.uast.generated.Node
57
import org.scalatest.FunSuite
68
import org.scalatest.BeforeAndAfter
79

@@ -14,9 +16,14 @@ class BblfshClientTest extends FunSuite with BeforeAndAfter {
1416
val fileName = "src/test/resources/SampleJavaFile.java"
1517
val fileContent = Source.fromFile(fileName) .getLines.mkString
1618
var resp: ParseResponse = _
19+
var rootNode: Node = _
1720

1821
before {
1922
resp = client.parse(fileName, fileContent)
23+
24+
if (resp.uast.isDefined) {
25+
rootNode = resp.uast.get
26+
}
2027
}
2128

2229
test("Parse UAST for existing .java file") {
@@ -25,33 +32,39 @@ class BblfshClientTest extends FunSuite with BeforeAndAfter {
2532
}
2633

2734
test("Get the internalType") {
28-
assert(resp.uast.get.internalType == "CompilationUnit")
35+
assert(rootNode.internalType == "CompilationUnit")
2936
}
3037

3138
test("Get the children") {
32-
val children = resp.uast.get.children
39+
val children = rootNode.children
3340
assert(children.length == 2)
3441
}
3542

3643
test("Get the token") {
37-
assert(resp.uast.get.children.head.token == "package")
44+
assert(rootNode.children.head.token == "package")
3845
}
3946

4047
test("Get the properties") {
41-
val properties = resp.uast.get.children.head.properties
48+
val properties = rootNode.children.head.properties
4249
assert(properties.size == 1)
4350
assert(properties("internalRole") == "package")
4451
}
4552

46-
test("Simple XPath query") {
47-
var filtered = client.filter(resp.uast.get, "//QualifiedName[@roleExpression]")
53+
test("Simple XPath query called on client object andinstance") {
54+
var filtered = client.filter(rootNode, "//QualifiedName[@roleExpression]")
55+
var filtered2 = BblfshClient.filter(rootNode, "//QualifiedName[@roleExpression]")
4856
assert(filtered.length == 3)
57+
assert(filtered == filtered2)
58+
}
59+
60+
test("Simple XPath query calling filter on the Node") {
61+
rootNode.filter("//QualifiedName[@roleExpression]")
4962
}
5063

5164
test("XPath query with threads") {
5265
val th = new Thread(new Runnable {
5366
def run() {
54-
var filtered = client.filter(resp.uast.get, "//QualifiedName[@roleExpression]")
67+
var filtered = rootNode.filter("//QualifiedName[@roleExpression]")
5568
assert(filtered.length == 3)
5669
}
5770
})
@@ -63,56 +76,56 @@ class BblfshClientTest extends FunSuite with BeforeAndAfter {
6376
}
6477

6578
test("XPath filter properties") {
66-
val filtered = client.filter(resp.uast.get, "//*[@internalRole='types']");
79+
val filtered = rootNode.filter("//*[@internalRole='types']");
6780
assert(filtered.length == 1)
68-
val filteredNeg = client.filter(resp.uast.get, "//*[@internalRole='foo']");
81+
val filteredNeg = rootNode.filter("//*[@internalRole='foo']");
6982
assert(filteredNeg.length == 0)
7083
}
7184

7285
test("Xpath filter StartOffset") {
73-
val filtered = client.filter(resp.uast.get, "//*[@startOffset='24']");
86+
val filtered = rootNode.filter("//*[@startOffset='24']");
7487
assert(filtered.length == 1)
75-
val filteredNeg = client.filter(resp.uast.get, "//*[@startOffset='44']");
88+
val filteredNeg = rootNode.filter("//*[@startOffset='44']");
7689
assert(filteredNeg.length == 0)
7790
}
7891

7992
test("Xpath filter StartLine") {
80-
val filtered = client.filter(resp.uast.get, "//*[@startLine='1']");
93+
val filtered = rootNode.filter("//*[@startLine='1']");
8194
assert(filtered.length == 17)
82-
val filteredNeg = client.filter(resp.uast.get, "//*[@startLine='100']");
95+
val filteredNeg = rootNode.filter("//*[@startLine='100']");
8396
assert(filteredNeg.length == 0)
8497
}
8598

8699
test("Xpath filter StartCol") {
87-
val filtered = client.filter(resp.uast.get, "//*[@startCol='25']");
100+
val filtered = rootNode.filter("//*[@startCol='25']");
88101
assert(filtered.length == 1)
89-
val filteredNeg = client.filter(resp.uast.get, "//*[@startCol='999']");
102+
val filteredNeg = rootNode.filter("//*[@startCol='999']");
90103
assert(filteredNeg.length == 0)
91104
}
92105

93106
test("Xpath filter EndOffset") {
94-
val filtered = client.filter(resp.uast.get, "//*[@endOffset='44']");
107+
val filtered = rootNode.filter("//*[@endOffset='44']");
95108
assert(filtered.length == 1)
96-
val filteredNeg = client.filter(resp.uast.get, "//*[@endOffset='999']");
109+
val filteredNeg = rootNode.filter("//*[@endOffset='999']");
97110
assert(filteredNeg.length == 0)
98111
}
99112

100113
test("Xpath filter EndLine") {
101-
val filtered = client.filter(resp.uast.get, "//*[@endLine='1']");
114+
val filtered = rootNode.filter("//*[@endLine='1']");
102115
assert(filtered.length == 16)
103-
val filteredNeg = client.filter(resp.uast.get, "//*[@endLine='100']");
116+
val filteredNeg = rootNode.filter("//*[@endLine='100']");
104117
assert(filteredNeg.length == 0)
105118
}
106119

107120
test("Xpath filter EndCol") {
108-
val filtered = client.filter(resp.uast.get, "//*[@endCol='45']");
121+
val filtered = rootNode.filter("//*[@endCol='45']");
109122
assert(filtered.length == 1)
110-
val filteredNeg = client.filter(resp.uast.get, "//*[@endCol='999']");
123+
val filteredNeg = rootNode.filter("//*[@endCol='999']");
111124
assert(filteredNeg.length == 0)
112125
}
113126

114127
test("Get the start position") {
115-
val childWithPos = resp.uast.get.children(1)
128+
val childWithPos = rootNode.children(1)
116129
val startPos = childWithPos.startPosition
117130
assert(!startPos.isEmpty)
118131
assert(startPos.get.offset == 24)
@@ -121,7 +134,7 @@ class BblfshClientTest extends FunSuite with BeforeAndAfter {
121134
}
122135

123136
test("Get the end position") {
124-
val childWithPos = resp.uast.get.children(1).children.head
137+
val childWithPos = rootNode.children(1).children.head
125138
val endPos = childWithPos.endPosition
126139
assert(!endPos.isEmpty)
127140
assert(endPos.get.offset == 44)

0 commit comments

Comments
 (0)