-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconverter.go
More file actions
110 lines (101 loc) · 2.89 KB
/
converter.go
File metadata and controls
110 lines (101 loc) · 2.89 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
package gflowparser
import (
"github.com/flowdev/gflowparser/data"
"github.com/flowdev/gflowparser/data2svg"
"github.com/flowdev/gflowparser/parser"
"github.com/flowdev/gflowparser/svg"
"github.com/flowdev/gparselib"
)
// ConvertFlowDSLToSVG transforms a flow given as DSL string into a SVG image
// plus component (subflow) types, data types, (currently empty) feedback
// string and potential error(s).
func ConvertFlowDSLToSVG(flowContent, flowName string,
) (
svgData []byte,
compTypes []data.Type,
dataTypes []data.Type,
feedback string,
err error,
) {
pd := gparselib.NewParseData(flowName, flowContent)
pFlow, err := parser.NewFlowParser()
if err != nil {
return nil, nil, nil, "", err
}
pd, _ = pFlow.ParseFlow(pd, nil)
fb, err := parser.CheckFeedback(pd.Result)
if err != nil {
return nil, nil, nil, "", err
}
flow := pd.Result.Value.(data.Flow)
sf, err := data2svg.Convert(flow, pd.Source)
if err != nil {
return nil, nil, nil, "", err
}
compTypes, dataTypes = extractTypes(flow)
//fmt.Fprintf(os.Stderr, "DEBUG: svgFlow=`%s`\n", spew.Sdump(sf))
buf, err := svg.FromFlowData(sf)
if err != nil {
return nil, nil, nil, "", err
}
return buf, compTypes, dataTypes, fb, nil
}
func extractTypes(flow data.Flow) (compTypes []data.Type, dataTypes []data.Type) {
dataMap := make(map[string]data.Type)
compMap := make(map[string]data.Type)
compNames := make(map[string]bool)
for _, partLine := range flow.Parts {
for _, part := range partLine {
switch p := part.(type) {
case data.Arrow:
dataMap = addTypes(dataMap, p.Data)
case data.Component:
// check component, plugins, ...
if !p.Decl.VagueType || !compNames[p.Decl.Name] {
compMap = addType(compMap, p.Decl.Type)
compNames[p.Decl.Name] = true
}
for _, plugin := range p.Plugins {
compMap = addPluginTypes(compMap, compNames, plugin.Types)
}
}
}
}
return valuesOf(compMap), valuesOf(dataMap)
}
func valuesOf(typeMap map[string]data.Type) []data.Type {
types := make([]data.Type, 0, len(typeMap))
for _, t := range typeMap {
types = append(types, t)
}
return types
}
func addPluginTypes(compMap map[string]data.Type, compNames map[string]bool, types []data.Type,
) map[string]data.Type {
for _, t := range types {
if t.Package != "" || !compNames[t.LocalType] {
compMap = addType(compMap, t)
}
}
return compMap
}
func addTypes(typeMap map[string]data.Type, types []data.Type) map[string]data.Type {
for _, t := range types {
typeMap = addType(typeMap, t)
}
return typeMap
}
func addType(typeMap map[string]data.Type, typ data.Type) map[string]data.Type {
if typ.ListType != nil {
return addType(typeMap, *typ.ListType)
}
if typ.MapKeyType != nil {
typeMap = addType(typeMap, *typ.MapKeyType)
return addType(typeMap, *typ.MapValueType)
}
typeMap[typToString(typ)] = typ
return typeMap
}
func typToString(t data.Type) string {
return t.Package + "." + t.LocalType
}