Skip to content

Commit

Permalink
Add uast filter_func argument
Browse files Browse the repository at this point in the history
Signed-off-by: Carlos Martín <carlos.martin.sanchez@gmail.com>
  • Loading branch information
carlosms committed Jul 9, 2018
1 parent c120559 commit 9f6a686
Show file tree
Hide file tree
Showing 3 changed files with 76 additions and 2 deletions.
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,32 @@ Instead of setting a filter for each level of the query, you can use the `flat`
}
```

There is an **experimental** argument o pass a sort of UDF (User Defined Function) to filter the nodes with any arbitrary code. The JavaScript code must be set as a string for `filter_func`. `node` and `result` are accesible as global variables. For example,

- `filter_func: "result = node.token.length > 15;"`
- `filter_func: "result = node.internal_type !== 'Comment' && node.token.length > 0;"`

```graphql
{
allRepositories {
id
refs(name: "HEAD") {
commit {
files(language: "Go") {
path
size
uast(language: "Go", flat: true, filter_func:
"result = node.token.length > 15;") {
token
internal_type
}
}
}
}
}
}
```

## Advanced Usage

### Run from Sources
Expand Down
19 changes: 17 additions & 2 deletions data/resolvers.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import mysqlPool from './connectors';

const vm = require('vm');

const PROTO_PATH = `${__dirname}/../proto/generated.proto`;

const grpc = require('grpc');
Expand Down Expand Up @@ -165,8 +167,21 @@ function flattenUastArr(uast, args) {
}

function uastFilter(node, args) {
return (!args.token || node.token === args.token) &&
(!args.internal_type || node.internal_type === args.internal_type);
let good =
(!args.token || node.token === args.token) &&
(!args.internal_type || node.internal_type === args.internal_type);

if (good && args.filter_func !== undefined) {
// This is experimental, nodejs does not claim vm to be secure to execute
// untrusted code
const sandbox = { node, result: false };
vm.createContext(sandbox);
vm.runInContext(args.filter_func, sandbox);

good = sandbox.result;
}

return good;
}

function uastQuery(sql, args) {
Expand Down
33 changes: 33 additions & 0 deletions data/schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,17 @@ type Blob {
language: String!,
internal_type: String,
token: String,
"""
**EXPERIMENTAL**
A string with JS code. 'node' and 'result' are global variables.
e.g. "result = node.token.length > 15;"
"""
filter_func: String,
"""
Flatten the tree allowing you filter nodes ignoring the tree level they are at.
"""
flat: Boolean): [UASTNode]!
"""
Expand Down Expand Up @@ -104,6 +115,17 @@ type File {
language: String!,
internal_type: String,
token: String,
"""
**EXPERIMENTAL**
A string with JS code. 'node' and 'result' are global variables.
e.g. "result = node.token.length > 15;"
"""
filter_func: String,
"""
Flatten the tree allowing you filter nodes ignoring the tree level they are at.
"""
flat: Boolean): [UASTNode]!
"""
Expand All @@ -125,6 +147,17 @@ type UASTNode {
children(
internal_type: String,
token: String,
"""
**EXPERIMENTAL**
A string with JS code. 'node' and 'result' are global variables.
e.g. "result = node.token.length > 15;"
"""
filter_func: String,
"""
Flatten the tree allowing you filter nodes ignoring the tree level they are at.
"""
flat: Boolean): [UASTNode]!
"""
Expand Down

0 comments on commit 9f6a686

Please sign in to comment.