Сценарий: Структура с методом
Этот коммит содержится в:
родитель
b6cb81fc11
коммит
5e7dec08df
6 изменённых файлов: 195 добавлений и 22 удалений
144
pkg/service/class.go
Обычный файл
144
pkg/service/class.go
Обычный файл
|
@ -0,0 +1,144 @@
|
|||
package service
|
||||
|
||||
import (
|
||||
"go/ast"
|
||||
)
|
||||
|
||||
var (
|
||||
classDeclarations []*Class
|
||||
)
|
||||
|
||||
type Class struct {
|
||||
Name string
|
||||
Struct *ast.StructType
|
||||
methods []*ast.FuncDecl
|
||||
}
|
||||
|
||||
func NewClass(className string) *Class {
|
||||
return &Class{Name: className}
|
||||
}
|
||||
|
||||
func (c *Class) String() (code string) {
|
||||
code += c.classDefinitionToString()
|
||||
code += c.methodImplementationsToString()
|
||||
return
|
||||
}
|
||||
func (c *Class) classDefinitionToString() (code string) {
|
||||
code = "class " + c.Name + " {"
|
||||
code += "public:\n"
|
||||
|
||||
code += c.structToString()
|
||||
code += "\n"
|
||||
|
||||
code += c.methodDeclarationsToString()
|
||||
code += "\n"
|
||||
|
||||
code += "};\n"
|
||||
return
|
||||
}
|
||||
func (c *Class) structToString() (code string) {
|
||||
code += handleExpr(c.Struct)
|
||||
code += "\n"
|
||||
return
|
||||
}
|
||||
func (c *Class) methodDeclarationsToString() (code string) {
|
||||
for _, m := range c.methods {
|
||||
code += c.methodDeclarationToString(m)
|
||||
}
|
||||
code += "\n"
|
||||
return
|
||||
}
|
||||
func (c *Class) methodDeclarationToString(m *ast.FuncDecl) (code string) {
|
||||
code += " "
|
||||
code += "void " + m.Name.String() + "();"
|
||||
code += "\n"
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Class) methodImplementationsToString() (code string) {
|
||||
for _, m := range c.methods {
|
||||
code += c.methodImplementationToString(m)
|
||||
}
|
||||
code += "\n"
|
||||
return
|
||||
}
|
||||
func (c *Class) methodImplementationToString(m *ast.FuncDecl) (code string) {
|
||||
code += "void "
|
||||
code += c.Name + "::"
|
||||
code += m.Name.String() + "("
|
||||
|
||||
code += ") {"
|
||||
code += handleBlockStmt(m.Body)
|
||||
code += "}"
|
||||
|
||||
code += "\n"
|
||||
return
|
||||
}
|
||||
|
||||
func (c *Class) AddMethod(m *ast.FuncDecl) {
|
||||
c.methods = append(c.methods, m)
|
||||
}
|
||||
|
||||
// Handlers
|
||||
func handleClass(t *ast.TypeSpec) string {
|
||||
st, ok := t.Type.(*ast.StructType)
|
||||
if !ok {
|
||||
return ""
|
||||
}
|
||||
|
||||
addClassFromStructType(t.Name.String(), st)
|
||||
|
||||
return ""
|
||||
}
|
||||
func addClassFromStructType(name string, s *ast.StructType) {
|
||||
c := createClass(name)
|
||||
c.Struct = s
|
||||
}
|
||||
|
||||
func handleMethodDeclaration(fd *ast.FuncDecl) string {
|
||||
class := getOrCreateClassFromFuncDecl(fd)
|
||||
class.AddMethod(fd)
|
||||
return ""
|
||||
}
|
||||
|
||||
func getOrCreateClassFromFuncDecl(fd *ast.FuncDecl) *Class {
|
||||
n := getClassNameFromReceiver(fd.Recv)
|
||||
return getOrCreateClass(n)
|
||||
}
|
||||
func getClassNameFromReceiver(recv *ast.FieldList) string {
|
||||
for _, f := range recv.List {
|
||||
return getClassNameFromStarReceiver(f.Type)
|
||||
}
|
||||
|
||||
return ""
|
||||
}
|
||||
func getClassNameFromStarReceiver(expr ast.Expr) string {
|
||||
switch e := expr.(type) {
|
||||
case *ast.StarExpr:
|
||||
return handleExpr(e.X)
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func getOrCreateClass(className string) *Class {
|
||||
for _, c := range classDeclarations {
|
||||
if c.Name == className {
|
||||
return c
|
||||
}
|
||||
}
|
||||
|
||||
return createClass(className)
|
||||
}
|
||||
|
||||
func createClass(className string) *Class {
|
||||
c := NewClass(className)
|
||||
addClassDeclaration(c)
|
||||
return c
|
||||
}
|
||||
|
||||
func addClassDeclaration(c *Class) {
|
||||
dlock.Lock()
|
||||
defer dlock.Unlock()
|
||||
|
||||
classDeclarations = append(classDeclarations, c)
|
||||
}
|
|
@ -79,3 +79,26 @@ public:
|
|||
std::string c,d,e;
|
||||
};
|
||||
```
|
||||
@f
|
||||
Сценарий: Структура с методом
|
||||
* Исходник:
|
||||
```
|
||||
package test
|
||||
|
||||
type device struct {
|
||||
a int
|
||||
}
|
||||
|
||||
func (d *device) doSomething() {
|
||||
}
|
||||
```
|
||||
* Результат:
|
||||
```
|
||||
class device {
|
||||
public:
|
||||
int a;
|
||||
void doSomething();
|
||||
};
|
||||
void device::doSomething() {
|
||||
}
|
||||
```
|
||||
|
|
|
@ -7,6 +7,12 @@ import (
|
|||
|
||||
func handleFuncDecl(decl ast.Decl) string {
|
||||
fd := decl.(*ast.FuncDecl)
|
||||
if fd.Recv != nil {
|
||||
return handleMethodDeclaration(fd)
|
||||
}
|
||||
return handleFunctionDeclaration(fd)
|
||||
}
|
||||
func handleFunctionDeclaration(fd *ast.FuncDecl) string {
|
||||
if shouldSkipFunction(fd.Type) {
|
||||
return ""
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"github.com/cucumber/godog/colors"
|
||||
|
||||
. "github.com/onsi/gomega"
|
||||
gomega_format "github.com/onsi/gomega/format"
|
||||
)
|
||||
|
||||
func InitializeScenario(ctx *godog.ScenarioContext) {
|
||||
|
@ -47,6 +48,7 @@ func TestMain(t *testing.T) {
|
|||
StopOnFailure: true,
|
||||
TestingT: t,
|
||||
}
|
||||
gomega_format.CharactersAroundMismatchToInclude = 100
|
||||
|
||||
godog.BindCommandLineFlags("godog.", &opts)
|
||||
godog.TestSuite{
|
||||
|
|
|
@ -86,6 +86,7 @@ func (s *defaultService) Start() error {
|
|||
dst[i] = make(chan string, 1)
|
||||
}
|
||||
|
||||
classDeclarations = nil
|
||||
funcDeclarations = nil
|
||||
helpersForDeclarations = nil
|
||||
|
||||
|
@ -103,6 +104,7 @@ func (s *defaultService) Start() error {
|
|||
}
|
||||
|
||||
s.printIncludeHeaders()
|
||||
s.printClassDeclarations()
|
||||
s.printFunctionDeclarations()
|
||||
s.printGoHelperDeclarations()
|
||||
|
||||
|
@ -128,6 +130,19 @@ func (s *defaultService) printIncludeHeaders() {
|
|||
h := "#include <Arduino.h>\n\n"
|
||||
s.out.Write([]byte(h))
|
||||
}
|
||||
func (s *defaultService) printClassDeclarations() {
|
||||
dlock.Lock()
|
||||
defer dlock.Unlock()
|
||||
|
||||
for _, c := range classDeclarations {
|
||||
d := c.String()
|
||||
s.out.Write([]byte(d + "\n"))
|
||||
if s.header != nil {
|
||||
s.header.Write([]byte(d + "\n"))
|
||||
}
|
||||
}
|
||||
s.out.Write([]byte("\n"))
|
||||
}
|
||||
func (s *defaultService) printFunctionDeclarations() {
|
||||
dlock.Lock()
|
||||
defer dlock.Unlock()
|
||||
|
|
|
@ -4,31 +4,14 @@ import (
|
|||
"go/ast"
|
||||
)
|
||||
|
||||
func handleTypeSpec(spec ast.Spec) string {
|
||||
func handleTypeSpec(spec ast.Spec) (code string) {
|
||||
s := spec.(*ast.TypeSpec)
|
||||
code := "class"
|
||||
code += " "
|
||||
code += s.Name.String()
|
||||
code += " "
|
||||
code += "{\n"
|
||||
code += handleClass(s.Type)
|
||||
// spew.Dump(s.TypeParams)
|
||||
code += "};\n"
|
||||
return code
|
||||
handleClass(s)
|
||||
return
|
||||
}
|
||||
|
||||
func handleClass(e ast.Expr) string {
|
||||
code := ""
|
||||
code += "public:\n"
|
||||
code += handleExpr(e)
|
||||
// spew.Dump(e)
|
||||
return code
|
||||
}
|
||||
|
||||
func handleStructType(s *ast.StructType) string {
|
||||
code := ""
|
||||
code += handleFieldList(s.Fields)
|
||||
return code
|
||||
func handleStructType(s *ast.StructType) (code string) {
|
||||
return handleFieldList(s.Fields)
|
||||
}
|
||||
|
||||
func handleFieldList(l *ast.FieldList) string {
|
||||
|
|
Загрузка…
Создание таблицы
Сослаться в новой задаче