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

Commit 9ecf3b9

Browse files
author
Denys Smirnov
committed
diff: refactor
Signed-off-by: Denys Smirnov <[email protected]>
1 parent 1a3c2aa commit 9ecf3b9

File tree

4 files changed

+172
-130
lines changed

4 files changed

+172
-130
lines changed

uast/diff/apply.go

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,22 @@
11
package diff
22

33
import (
4+
"errors"
45
"fmt"
56

67
"gopkg.in/bblfsh/sdk.v2/uast/nodes"
78
)
89

9-
// Apply is a method that takes a tree (nodes.Node) and applies the current changelist to that
10-
// tree.
11-
func (changelist Changelist) Apply(root nodes.Node) nodes.Node {
10+
// Apply is a method that takes a tree (nodes.Node) and applies the current changelist to
11+
// that tree.
12+
func (cl Changelist) Apply(root nodes.Node) (nodes.Node, error) {
1213
nodeDict := make(map[ID]nodes.Node)
1314
nodes.WalkPreOrder(root, func(node nodes.Node) bool {
1415
nodeDict[nodes.UniqueKey(node)] = node
1516
return true
1617
})
1718

18-
for _, change := range changelist {
19+
for _, change := range cl {
1920
switch ch := change.(type) {
2021
case Create:
2122
// create a node and add to the dictionary
@@ -25,47 +26,45 @@ func (changelist Changelist) Apply(root nodes.Node) nodes.Node {
2526
// get src and chld from the dictionary, attach (modify src)
2627
parent, ok := nodeDict[ch.Parent]
2728
if !ok {
28-
panic("invalid attachment point")
29+
return nil, errors.New("diff: invalid attachment point")
2930
}
3031
child, ok := nodeDict[ch.Child]
3132
if !ok {
3233
child, ok = ch.Child.(nodes.Value)
3334
if !ok {
34-
panic(fmt.Errorf("unknown type of a child: %v (type %T)", ch.Child, ch.Child))
35+
return nil, fmt.Errorf("diff: unknown type of a child: %T", ch.Child)
3536
}
3637
}
3738

3839
switch key := ch.Key.(type) {
39-
4040
case String:
4141
parent := parent.(nodes.Object)
4242
parent[string(key)] = child
43-
4443
case Int:
4544
parent := parent.(nodes.Array)
4645
parent[int(key)] = child
46+
default:
47+
return nil, fmt.Errorf("diff: unknown type of a key: %T", ch.Key)
4748
}
48-
49-
case Deatach:
49+
case Detach:
5050
// get the src from the dictionary, deatach (modify src)
5151
parent := nodeDict[ch.Parent]
5252

5353
switch key := ch.Key.(type) {
54-
5554
case String:
5655
parent := parent.(nodes.Object)
5756
delete(parent, string(key))
58-
5957
case Int:
60-
panic(fmt.Errorf("cannot deatach from an Array"))
58+
return nil, errors.New("diff: cannot detach from an Array")
59+
default:
60+
return nil, fmt.Errorf("diff: unknown type of a key: %T", ch.Key)
6161
}
6262

6363
case Delete:
64-
panic(fmt.Errorf("delete is not supported in a Changelist"))
65-
64+
return nil, errors.New("diff: delete is not supported in a Changelist")
6665
default:
67-
panic(fmt.Sprintf("unknown change %v of type %T", change, change))
66+
return nil, fmt.Errorf("diff: unknown change of type %T", change)
6867
}
6968
}
70-
return root
69+
return root, nil
7170
}

uast/diff/changelist.go

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,10 @@ type Changelist []Change
1111
// Change is a single operation performed
1212
type Change interface {
1313
isChange()
14-
TransactionID() uint64
14+
// GroupID is the same for multiple changes that are a part of one high-level operation.
15+
GroupID() uint64
1516
}
1617

17-
type changeBase struct {
18-
txID uint64
19-
}
20-
21-
func (changeBase) isChange() {}
22-
func (ch changeBase) TransactionID() uint64 { return ch.txID }
23-
2418
// ID is a type representing node unique ID that can be compared in O(1)
2519
type ID nodes.Comparable
2620

@@ -40,28 +34,55 @@ func (String) isKey() {}
4034

4135
// Create a node. Each array and object is created separately.
4236
type Create struct {
43-
changeBase
37+
group uint64
38+
39+
// Node to create.
4440
Node nodes.Node
4541
}
4642

43+
func (Create) isChange() {}
44+
45+
func (ch Create) GroupID() uint64 { return ch.group }
46+
4747
// Delete a node by ID
4848
type Delete struct {
49-
changeBase
50-
NodeID ID
49+
group uint64
50+
51+
// Node to delete.
52+
Node ID
5153
}
5254

55+
func (Delete) isChange() {}
56+
57+
func (ch Delete) GroupID() uint64 { return ch.group }
58+
5359
// Attach a node as a child of another node with a given key
5460
type Attach struct {
55-
changeBase
61+
group uint64
62+
63+
// Parent node ID to attach the key to.
5664
Parent ID
57-
Key Key
58-
Child ID
65+
// Key to attach.
66+
Key Key
67+
// Child to attach on a given key.
68+
Child ID
5969
}
6070

61-
// Deatach a child from a node
62-
type Deatach struct {
63-
changeBase
71+
func (Attach) isChange() {}
72+
73+
func (ch Attach) GroupID() uint64 { return ch.group }
74+
75+
// Detach a child from a node
76+
type Detach struct {
77+
group uint64
78+
79+
// Parent node ID to detach the key from.
6480
Parent ID
65-
Key Key // Currently deatach semantics are only defined for nodes.Object so the Key is
66-
// practically always a string
81+
// Key to detach. Currently detach semantics are only defined for nodes.Object so the
82+
// Key is practically always a String.
83+
Key Key
6784
}
85+
86+
func (Detach) isChange() {}
87+
88+
func (ch Detach) GroupID() uint64 { return ch.group }

uast/diff/changelist_test.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,8 @@ func TestChangelist(t *testing.T) {
4040
dst := readUAST(t, dstName)
4141

4242
changes := Changes(src, dst)
43-
newsrc := changes.Apply(src)
43+
newsrc, err := changes.Apply(src)
44+
require.NoError(t, err)
4445
require.True(t, nodes.Equal(newsrc, dst))
4546
})
4647
}

0 commit comments

Comments
 (0)