https://github.com/dennwc/uastgraph
Experiments with UAST graphs
https://github.com/dennwc/uastgraph
Last synced: 3 months ago
JSON representation
Experiments with UAST graphs
- Host: GitHub
- URL: https://github.com/dennwc/uastgraph
- Owner: dennwc
- Created: 2019-06-27T17:23:20.000Z (almost 6 years ago)
- Default Branch: master
- Last Pushed: 2019-06-27T17:23:49.000Z (almost 6 years ago)
- Last Synced: 2025-03-10T19:13:10.420Z (3 months ago)
- Language: Go
- Size: 8.79 KB
- Stars: 0
- Watchers: 0
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
Awesome Lists containing this project
README
# uastgraph
Experiments with UAST graph.
## Installation
Get the latest [release](https://github.com/cayleygraph/cayley/releases) of Cayley, to be able to query the results.
```bash
go install ./cmd/uastgraph
```## Running
You will need some UAST files in the YML format. You can get them from any of
[Babelfish drivers](https://github.com/search?utf8=%E2%9C%93&q=org%3Abblfsh+topic%3Ababelfish+topic%3Adriver&type=Repositories&ref=advsearch&l=&l=)
(see `./fixtures` folder).Generate the graph data from UAST:
```bash
uastgraph -o out.nq.gz ./fixtures/*.sem.uast
```Import and run Cayley instance with the data:
```bash
cayley http -i out.nq.gz
```Web interface should be available at http://127.0.0.1:64210.
## Queries
### All identifiers
**Gizmo** query language (Tinkerpop's Gremlin inspired):
```javascript
// Find an unknown node
g.V().
// That has a specific type
Has("", "").
// Save the name of a node (apart from ID)
Save("", "name").
// Limit and emit all the results
Limit(100).All()
```**GraphQL** inspired query language:
```graphql
{
nodes(: , first: 100){
id
name:
}
}
```### All imports
**Gizmo**:
```javascript
// Helpers to process different import path nodes.
// Can be embedded into the program later.
function toPath(m) {
switch (m.type) {
case "":
return {path: g.V(m.id).Out("").ToValue()}
case "":
return {path: g.V(m.id).Out("").ToValue()}
case "":
return toPath(g.V(m.id).Out("").Save("", "type").TagArray()[0]);
case "":
var path = g.V(m.id).Out("").Save("", "type").TagArray();
var s = ""
for (i in path) {
var n = toPath(path[i])
if (i == 0) s = n.path
else s += "/"+n.path
}
return {path: s}
default:
return m
}
}// Start from unknown node
g.V().
// The node should be either Import or InlineImport
Has("", "", "uast:InlineImport").
// Traverse the Path field of the Import
Out("").
// Save the type for the path node
Save("", "type").
// Do not emit nodes directly, let JS function alter the data.
// We will extract a single import path from any node type
// that can be there.
ForEach(function(m){
g.Emit(toPath(m))
})
```**GraphQL** doesn't have a direct equivalent, since it cannot switch on the node type.
Instead we extract the path node, and optionally load path-related fields from the child node.```graphql
{
nodes(: ["", ""], first: 100){
id
path: {
type:
name: @opt
path: @opt
names: @opt {
name:
}
}
}
}
```### All files that import "fmt"
**Gizmo**:
```javascript
var pkg = "fmt"g.V().
// Find the identifier that matches the package name
Has("", "").
Has("", pkg).
// Find node that points to this identifier with the Path predicate
In("").
// Follow any relation backward recursively...
FollowRecursive(g.V().In()).
// until we hit a node with outgoing Root relation
// (which goes from file to a UAST root).
In("").All()
```Again, **GraphQL** doesn't have an equivalent.
### Import stats
**Gizmo**, _requires_ a helper from above:
```javascript
var imports = {}g.V().
Has("", "", "").
Out("").
Save("", "type").
// Do not emit results, instead load the import path and collect counts.
ForEach(function(m){
var path = toPath(m).path;
if (!imports[path]) imports[path] = 1;
else imports[path]++;
})g.Emit(imports)
```