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

Commit 8db3e74

Browse files
author
Juanjo Alvarez
committed
Checkpoint with the C# like transform
Signed-off-by: Juanjo Alvarez <[email protected]>
1 parent a92fe3f commit 8db3e74

File tree

3 files changed

+195
-14
lines changed

3 files changed

+195
-14
lines changed

Gopkg.lock

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

Gopkg.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
[[constraint]]
55
name = "gopkg.in/bblfsh/sdk.v2"
6-
version = "2.13.4"
6+
version = "2.14.x"
77

88
[prune]
99
go-tests = true

driver/normalizer/normalizer.go

Lines changed: 191 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
11
package normalizer
22

33
import (
4+
"errors"
5+
46
"gopkg.in/bblfsh/sdk.v2/uast"
7+
"gopkg.in/bblfsh/sdk.v2/uast/nodes"
58
"gopkg.in/bblfsh/sdk.v2/uast/role"
69
. "gopkg.in/bblfsh/sdk.v2/uast/transformer"
710
)
811

912
var Preprocess = Transformers([][]Transformer{
13+
{Mappings(
14+
// Move the Leading/TrailingTrivia outside of nodes.
15+
//
16+
// This cannot be inside Normalizers because it should precede any
17+
// other transformation.
18+
Map(
19+
opMoveCommentsAnns{Var("group")},
20+
Check(Has{uast.KeyType: String(typeGroup)}, Var("group")),
21+
),
22+
)},
1023
{Mappings(Preprocessors...)},
1124
}...)
1225

@@ -37,13 +50,19 @@ func funcDefMap(typ string, async bool) Mapping {
3750
uast.KeyPos: Var("_pos"),
3851
uast.KeyType: Var("_type"),
3952
},
53+
// Will be filled only if there is a Python3 type annotation
54+
"returns": Var("returns"),
55+
"decorator_list": Var("func_decorators"),
4056
},
4157
Obj{
4258
"Nodes": Arr(
4359
Obj{
4460
// FIXME: generator=true if it uses yield anywhere in the body
4561
"async": Bool(async),
4662
},
63+
Obj{
64+
"decorators": Var("func_decorators"),
65+
},
4766
UASTType(uast.Alias{}, Obj{
4867
// FIXME: can't call identifierWithPos because it would take the position of the
4968
// function node that is not exactly the same as the position of the function name
@@ -53,6 +72,7 @@ func funcDefMap(typ string, async bool) Mapping {
5372
"Node": UASTType(uast.Function{}, Obj{
5473
"Type": UASTType(uast.FunctionType{}, Obj{
5574
"Arguments": Var("arguments"),
75+
"Returns": Var("returns"),
5676
}),
5777
"Body": UASTType(uast.Block{}, Obj{
5878
"Statements": Var("body"),
@@ -89,17 +109,146 @@ func mapStr(nativeType string) Mapping {
89109
{Name: "boxed_value", Op: UASTType(uast.String{}, Obj{
90110
uast.KeyPos: Var("pos_"),
91111
"Value": Var("s"),
92-
//"Format": String(""),
93112
})},
94113
{Name: "noops_previous", Optional: "np_opt", Op: Var("noops_previous")},
95114
{Name: "noops_sameline", Optional: "ns_opt", Op: Var("noops_sameline")},
96115
}),
97116
)
98117
}
99118

119+
var (
120+
typeGroup = uast.TypeOf(uast.Group{})
121+
typeFuncGroup = uast.TypeOf(uast.FunctionGroup{})
122+
)
123+
124+
// Similar (but not equal) to:
125+
// https://github.com/bblfsh/csharp-driver/blob/master/driver/normalizer/normalizer.go#L827
126+
// Should be removed once we have some generic solution in the SDK
127+
type opMoveCommentsAnns struct {
128+
sub Op
129+
}
130+
131+
func (op opMoveCommentsAnns) Kinds() nodes.Kind {
132+
return nodes.KindObject
133+
}
134+
135+
func (op opMoveCommentsAnns) Check(st *State, n nodes.Node) (bool, error) {
136+
obj, ok := n.(nodes.Object)
137+
if !ok {
138+
return false, nil
139+
}
140+
modified := false
141+
noops_prevs, ok1 := obj["noops_previous"].(nodes.Array)
142+
noops_same, ok2 := obj["noops_sameline"].(nodes.Array)
143+
//decorators, ok3 := obj["decorator_list"].(nodes.Array)
144+
145+
if ok1 || ok2 {
146+
// we saved the comments and decorators, remove from them from this node
147+
obj = obj.CloneObject()
148+
modified = true
149+
delete(obj, "noops_previous")
150+
delete(obj, "noops_sameline")
151+
//delete(obj, "decorator_list")
152+
}
153+
154+
if len(noops_prevs) == 0 || len(noops_same) == 0 {
155+
if !modified {
156+
return false, nil
157+
}
158+
return op.sub.Check(st, obj)
159+
}
160+
161+
arr := make(nodes.Array, 0, len(noops_prevs) + 1 + len(noops_same))
162+
arr = append(arr, noops_prevs...)
163+
arr = append(arr, obj)
164+
arr = append(arr, noops_same)
165+
group, err := uast.ToNode(uast.Group{})
166+
if err != nil {
167+
return false, err
168+
}
169+
170+
obj = group.(nodes.Object)
171+
obj["Nodes"] = arr
172+
return op.sub.Check(st, obj)
173+
}
174+
175+
func (op opMoveCommentsAnns) Construct(st *State, n nodes.Node) (nodes.Node, error) {
176+
// TODO(dennwc): implement when we will need a reversal
177+
// see https://github.com/bblfsh/sdk/issues/355
178+
return op.sub.Construct(st, n)
179+
}
180+
181+
// opMergeGroups finds the uast:Group nodes and merges them into a child
182+
// uast:FunctionGroup, if it exists.
183+
//
184+
// This transform is necessary because opMoveTrivias will wrap all nodes that contain trivia
185+
// into a Group node, and the same will happen with MethodDeclaration nodes. But according
186+
// to a UAST schema defined in SDK, the comments (trivia) should be directly inside the
187+
// FunctionGroup node that wraps functions in Semantic mode.
188+
type opMergeGroups struct {
189+
sub Op
190+
}
191+
192+
func (op opMergeGroups) Kinds() nodes.Kind {
193+
return nodes.KindObject
194+
}
195+
196+
197+
// firstWithType returns an index of the first node type of which matches the filter function.
198+
func firstWithType(arr nodes.Array, fnc func(typ string) bool) int {
199+
for i, sub := range arr {
200+
if fnc(uast.TypeOf(sub)) {
201+
return i
202+
}
203+
}
204+
return -1
205+
}
206+
207+
// Check tests if the current node is uast:Group and if it contains a uast:FunctionGroup
208+
// node, it will remove the current node and merge other children into the FunctionGroup.
209+
func (op opMergeGroups) Check(st *State, n nodes.Node) (bool, error) {
210+
group, ok := n.(nodes.Object)
211+
if !ok || uast.TypeOf(group) != typeGroup {
212+
return false, nil
213+
}
214+
arr, ok := group["Nodes"].(nodes.Array)
215+
if !ok {
216+
return false, errors.New("expected an array in Group.Nodes")
217+
}
218+
ind := firstWithType(arr, func(typ string) bool {
219+
return typ == typeFuncGroup
220+
})
221+
if ind < 0 {
222+
return false, nil
223+
}
224+
leading := arr[:ind]
225+
fgroup := arr[ind].(nodes.Object)
226+
trailing := arr[ind+1:]
227+
228+
arr, ok = fgroup["Nodes"].(nodes.Array)
229+
if !ok {
230+
return false, errors.New("expected an array in Group.Nodes")
231+
}
232+
out := make(nodes.Array, 0, len(leading)+len(arr)+len(trailing))
233+
out = append(out, leading...)
234+
out = append(out, arr...)
235+
out = append(out, trailing...)
236+
237+
fgroup = fgroup.CloneObject()
238+
fgroup["Nodes"] = out
239+
240+
return op.sub.Check(st, fgroup)
241+
}
242+
243+
func (op opMergeGroups) Construct(st *State, n nodes.Node) (nodes.Node, error) {
244+
// TODO(dennwc): implement when we will need a reversal
245+
// see https://github.com/bblfsh/sdk/issues/355
246+
return op.sub.Construct(st, n)
247+
}
248+
100249
var Normalizers = []Mapping{
101250

102-
// Box Names, Strings, and Bools into a "BoxedFoo" moving the real node to the
251+
// Box Names, Strings, Attributes, ImportFroms and Bools into a "BoxedFoo" moving the real node to the
103252
// "value" property and keeping the comments in the parent (if not, comments would be lost
104253
// when promoting the objects)
105254
Map(
@@ -121,13 +270,10 @@ var Normalizers = []Mapping{
121270
}),
122271
),
123272

124-
// TODO: uncomment after SDK 2.13.x update
125-
// (upgrade currently blocked by: https://github.com/bblfsh/sdk/issues/353)
126273
Map(
127274
Part("_", Fields{
128275
{Name: uast.KeyType, Op: String("BoolLiteral")},
129276
{Name: uast.KeyPos, Op: Var("pos_")},
130-
//{Name: "LiteralValue", Op: Var("lv")},
131277
{Name: "value", Op: Var("lv")},
132278
{Name: "noops_previous", Optional: "np_opt", Op: Var("noops_previous")},
133279
{Name: "noops_sameline", Optional: "ns_opt", Op: Var("noops_sameline")},
@@ -136,13 +282,39 @@ var Normalizers = []Mapping{
136282
{Name: uast.KeyType, Op: String("BoxedBoolLiteral")},
137283
{Name: "boxed_value", Op: UASTType(uast.Bool{}, Obj{
138284
uast.KeyPos: Var("pos_"),
285+
<<<<<<< HEAD
286+
"Value": Var("lv"),
287+
||||||| merged common ancestors
288+
"Value": Var("lv"),
289+
=======
139290
"Value": Var("lv"),
140291
})},
141292
{Name: "noops_previous", Optional: "np_opt", Op: Var("noops_previous")},
142293
{Name: "noops_sameline", Optional: "ns_opt", Op: Var("noops_sameline")},
143294
}),
144295
),
145296

297+
Map(
298+
Part("_", Fields{
299+
{Name: uast.KeyType, Op: String("Attribute")},
300+
{Name: uast.KeyPos, Op: Var("pos_")},
301+
{Name: "attr", Op: Var("aname")},
302+
{Name: "ctx", Op: Any()},
303+
{Name: "noops_previous", Optional: "np_opt", Op: Var("noops_previous")},
304+
{Name: "noops_sameline", Optional: "ns_opt", Op: Var("noops_sameline")},
305+
}),
306+
Part("_", Fields{
307+
{Name: uast.KeyType, Op: String("BoxedAttribute")},
308+
{Name: "boxed_value", Op: UASTType(uast.Identifier{}, Obj{
309+
uast.KeyPos: Var("pos_"),
310+
"Name": Var("aname"),
311+
>>>>>>> Checkpoint with the C# like transform
312+
})},
313+
{Name: "noops_previous", Optional: "np_opt", Op: Var("noops_previous")},
314+
{Name: "noops_sameline", Optional: "ns_opt", Op: Var("noops_sameline")},
315+
}),
316+
),
317+
146318
mapStr("Bytes"),
147319
mapStr("Str"),
148320
mapStr("StringLiteral"),
@@ -174,15 +346,11 @@ var Normalizers = []Mapping{
174346
}),
175347
role.Name),
176348

177-
MapSemantic("Attribute", uast.Identifier{}, MapObj(
178-
Obj{"attr": Var("name")},
179-
Obj{"Name": Var("name")},
180-
)),
181-
182349
MapSemantic("arg", uast.Argument{}, MapObj(
183350
Obj{
184351
uast.KeyToken: Var("name"),
185352
"default": Var("init"),
353+
"ctx": Any(),
186354
},
187355
Obj{
188356
"Name": identifierWithPos("name"),
@@ -193,6 +361,7 @@ var Normalizers = []Mapping{
193361
MapSemantic("arg", uast.Argument{}, MapObj(
194362
Obj{
195363
uast.KeyToken: Var("name"),
364+
"ctx": Any(),
196365
},
197366
Obj{
198367
"Name": identifierWithPos("name"),
@@ -203,6 +372,8 @@ var Normalizers = []Mapping{
203372
Obj{
204373
uast.KeyToken: Var("name"),
205374
"default": Var("init"),
375+
// TODO: change this once we've a way to store other nodes on semantic objects
376+
"annotation": Any(),
206377
},
207378
Obj{
208379
"Init": Var("init"),
@@ -213,6 +384,8 @@ var Normalizers = []Mapping{
213384
MapSemantic("vararg", uast.Argument{}, MapObj(
214385
Obj{
215386
uast.KeyToken: Var("name"),
387+
// TODO: change this once we've a way to store other nodes on semantic objects
388+
"annotation": Any(),
216389
},
217390
Obj{
218391
"Name": identifierWithPos("name"),
@@ -223,6 +396,8 @@ var Normalizers = []Mapping{
223396
MapSemantic("kwarg", uast.Argument{}, MapObj(
224397
Obj{
225398
uast.KeyToken: Var("name"),
399+
// TODO: change this once we've a way to store other nodes on semantic objects
400+
"annotation": Any(),
226401
},
227402
Obj{
228403
"Name": identifierWithPos("name"),
@@ -317,4 +492,10 @@ var Normalizers = []Mapping{
317492
}),
318493
},
319494
)),
495+
496+
// Merge uast:Group with uast:FunctionGroup.
497+
Map(
498+
opMergeGroups{Var("group")},
499+
Check(Has{uast.KeyType: String(uast.TypeOf(uast.FunctionGroup{}))}, Var("group")),
500+
),
320501
}

0 commit comments

Comments
 (0)