Skip to content

Commit fb481ea

Browse files
committed
Add UAST mode to parse requests
Signed-off-by: Carlos Martín <[email protected]>
1 parent bca82c0 commit fb481ea

File tree

3 files changed

+89
-8
lines changed

3 files changed

+89
-8
lines changed

docs/rest-api.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ curl -X POST \
212212

213213
## POST /parse
214214

215-
Receives a file content and returns UAST.
215+
Receives a file content and returns UAST parsed by the bblfsh server.
216216

217217
```bash
218218
curl -X POST \
@@ -221,6 +221,7 @@ curl -X POST \
221221
-d '{
222222
"language": "javascript",
223223
"content": "console.log(test)"
224+
"mode": "annotated"
224225
}'
225226
```
226227

@@ -243,8 +244,11 @@ curl -X POST \
243244
}
244245
```
245246

246-
The endpoint also receives additional parameters:
247+
The endpoint accepts these parameters:
247248

249+
- `language`: Language name.
250+
- `content`: The file contents to parse.
251+
- `mode`: Transformation mode. Can be one of `native`, `annotated`, `semantic`. The default is `semantic`.
248252
- `serverUrl` - allows to override bblfsh server URL.
249253
- `filename` - can be used instead of language. Then the bblfsh server would try to guess the language.
250254
- `filter` - [xpath query](https://doc.bblf.sh/user/uast-querying.html) to filter the results.

server/handler/uast.go

+30-6
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,21 @@ import (
1616
"gopkg.in/bblfsh/sdk.v2/uast/nodes"
1717
)
1818

19+
type uastMode = string
20+
21+
const (
22+
native uastMode = "native"
23+
annotated uastMode = "annotated"
24+
semantic uastMode = "semantic"
25+
)
26+
1927
type parseRequest struct {
20-
ServerURL string `json:"serverUrl"`
21-
Language string `json:"language"`
22-
Filename string `json:"filename"`
23-
Content string `json:"content"`
24-
Filter string `json:"filter"`
28+
ServerURL string `json:"serverUrl"`
29+
Language string `json:"language"`
30+
Filename string `json:"filename"`
31+
Content string `json:"content"`
32+
Filter string `json:"filter"`
33+
Mode uastMode `json:"mode"`
2534
}
2635

2736
// Parse returns a function that parses text contents using bblfsh and
@@ -48,11 +57,26 @@ func Parse(bbblfshServerURL string) RequestProcessFunc {
4857
return nil, err
4958
}
5059

60+
var mode bblfsh.Mode
61+
switch req.Mode {
62+
case native:
63+
mode = bblfsh.Native
64+
case annotated:
65+
mode = bblfsh.Annotated
66+
case semantic:
67+
mode = bblfsh.Semantic
68+
case "":
69+
mode = bblfsh.Semantic
70+
default:
71+
return nil, serializer.NewHTTPError(http.StatusBadRequest,
72+
fmt.Sprintf(`invalid "mode" %q; it must be one of "native", "annotated", "semantic"`, req.Mode))
73+
}
74+
5175
resp, lang, err := cli.NewParseRequest().
5276
Language(req.Language).
5377
Filename(req.Filename).
5478
Content(req.Content).
55-
Mode(bblfsh.Semantic).
79+
Mode(mode).
5680
UAST()
5781

5882
if bblfsh.ErrSyntax.Is(err) {

server/handler/uast_integration_test.go

+53
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,59 @@ func (suite *UASTFilterSuite) TestFilterError() {
107107
suite.Equal(http.StatusBadRequest, res.Code)
108108
}
109109

110+
type UASTModeSuite struct {
111+
suite.Suite
112+
handler http.Handler
113+
}
114+
115+
func TestUASTModeSuite(t *testing.T) {
116+
q := new(UASTModeSuite)
117+
q.handler = lg.RequestLogger(logrus.New())(handler.APIHandlerFunc(handler.Parse(bblfshServerURL())))
118+
119+
if !isIntegration() {
120+
t.Skip("use the env var GITBASEPG_INTEGRATION_TESTS=true to run this test")
121+
}
122+
123+
suite.Run(t, q)
124+
}
125+
126+
func (suite *UASTModeSuite) TestSuccess() {
127+
testCases := []string{
128+
`{ "content": "console.log('test')", "language": "javascript", "mode": "" }`,
129+
`{ "content": "console.log('test')", "language": "javascript", "mode": "native" }`,
130+
`{ "content": "console.log('test')", "language": "javascript", "mode": "annotated" }`,
131+
`{ "content": "console.log('test')", "language": "javascript", "mode": "semantic" }`,
132+
}
133+
134+
for _, tc := range testCases {
135+
suite.T().Run(tc, func(t *testing.T) {
136+
req, _ := http.NewRequest("POST", "/parse", strings.NewReader(tc))
137+
138+
res := httptest.NewRecorder()
139+
suite.handler.ServeHTTP(res, req)
140+
141+
suite.Require().Equal(http.StatusOK, res.Code, res.Body.String())
142+
143+
var resBody serializer.Response
144+
err := json.Unmarshal(res.Body.Bytes(), &resBody)
145+
suite.Nil(err)
146+
147+
suite.Equal(res.Code, resBody.Status)
148+
suite.NotEmpty(resBody.Data)
149+
})
150+
}
151+
}
152+
153+
func (suite *UASTModeSuite) TestWrongMode() {
154+
jsonRequest := `{ "content": "console.log('test')", "language": "javascript", "mode": "foo" }`
155+
req, _ := http.NewRequest("POST", "/parse", strings.NewReader(jsonRequest))
156+
157+
res := httptest.NewRecorder()
158+
suite.handler.ServeHTTP(res, req)
159+
160+
suite.Equal(http.StatusBadRequest, res.Code)
161+
}
162+
110163
// JSON: [<UAST(console.log("test"))>]
111164
// Easy to obtain in the frontend with SELECT UAST('console.log("test")', 'JavaScript') AS uast
112165
// Gitbase v0.18.0-beta.1, Bblfsh v2.9.2-drivers

0 commit comments

Comments
 (0)