bykof/go-plantuml

Support top-level functions

Closed this issue · 4 comments

It would be nice if go-plantuml would support top-level functions (instead of only methods).

The main problem will be the decision on how to represent these, as UML ususally doesn't provide a notion of top-level functions.

One possibility would be to misuse a class for that purpose. See this discussion about such a topic.

I have prepared a rough idea how that could be achieved.

For the following classes:

// mypackage/functions.go
package mypackage

func Function1() []string {
  return []string{}
}

func Function2(param1, param2 string) {
}
// otherpackage.functions.go
package otherpackage

func New() MyStruct {
  return MyStruct{}
}

func Frobnicate(subject []string) {
}
// otherpackage/mystruct.go
package otherpackage

import (
  "fmt"

  "my.domain/rough/mypackage"
)

type MyStruct struct {
  Name string
}

func (s *MyStruct) DoSomething() {
  v := mypackage.Function1()
  fmt.Println(v)
}

func (s *MyStruct) GetSomething() string {
  return s.Name
}

the following puml file could be generated:

@startuml
title Rough idea
namespace mypackage {
  class mypackage.functions << (F, blanchedalmond) >> {
    + Function1() []string
    + Function2(string, string)
  }
}
namespace otherpackage {
  class otherpackage.MyStruct << (S, aquamarine) >> {
    + Name string
    + DoSomething()
    + GetSomething() string
  }

  class otherpackage.functions << (F, blanchedalmond) >> {
    + New() MyStruct
    + Frobnicate([]string)
  }
}

otherpackage.MyStruct uses --> mypackage.functions
@enduml

which would be rendered as:

dummy

Here a class with the dummy name "functions" is generated inside each package to hold all global functions of that package. To differentiate between this function "holder" and real structs I added the "F" and "S" symbol to them (an idea I have taken from https://github.com/jfeliu007/goplantuml). Maybe the functions "holder" could also be specified as "abstract".

As MyStruct calls mypackage.Function1 in its DoSomething() method I added a "usage"-association between them.

bykof commented

Here the implementation for packages should be implemented first.
Then the implementation for package functions can be added (which can be easily implemented and currently the parsing is skipped)

bykof commented

The "usage" statement is another layer and in my opinion not very useful. Because the diagram would only show, that the MyStruct calls any function of mypackage... it would be better to actually display which function it calls, otherwise this feature would not bring any value IMHO.

Yes, that sounds very well.

bykof commented

Top-level functions are now supported by go-plantuml.
Also there are package names, package constants, package variables, interfaces and implementations and many more.
Have fun and sorry that it took so long :)