Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

doesn't draw the IS-A relation when type implements an interface in different packages #106

Open
hitzhangjie opened this issue Jan 6, 2021 · 6 comments

Comments

@hitzhangjie
Copy link

hitzhangjie commented Jan 6, 2021

image

Type helloworldServiceImpl implements the interface defined in package helloworld, the IS-A relation is not drawed.

the generated plantuml is :

@startuml

package "main" {
	class "helloworldServiceImpl" as main.helloworldServiceImpl <<E,#FFCC00>> {
		+Hello(ctx: context.Context, req: *helloworld.Request, rsp: *helloworld.Response): error
	}
}


	main.helloworldServiceImpl ..> helloworld.Request : <<use>> 
	main.helloworldServiceImpl ..> helloworld.Response : <<use>> 

package "helloworld" {
	interface "HelloworldClientProxy" as helloworld.HelloworldClientProxy {
		+Hello(ctx: context.Context, req: *helloworld.Request, opts: client.Option): (rsp: *helloworld.Response, err: error)
	}
}


	helloworld.HelloworldClientProxy ..> helloworld.Request : <<use>> 
	helloworld.HelloworldClientProxy ..> helloworld.Response : <<return>> 

package "helloworld" {
	class "HelloworldClientProxyImpl" as helloworld.HelloworldClientProxyImpl <<V,Orchid>> {
		-client: client.Client
		-opts: client.Option
		+Hello(ctx: context.Context, req: *helloworld.Request, opts: client.Option): (rsp: *helloworld.Response, err: error)
	}
}


	helloworld.HelloworldClientProxyImpl ..> helloworld.Request : <<use>> 
	helloworld.HelloworldClientProxyImpl ..> helloworld.Response : <<return>> 

package "helloworld" {
	interface "HelloworldService" as helloworld.HelloworldService {
		+Hello(ctx: context.Context, req: *helloworld.Request, rsp: *helloworld.Response): err: error
	}
}


	helloworld.HelloworldService ..> helloworld.Request : <<use>> 
	helloworld.HelloworldService ..> helloworld.Response : <<use>> 

package "helloworld" {
	class "Request" as helloworld.Request <<E,#FFCC00>> {
		-state: impl.MessageState
		-sizeCache: int32
		-unknownFields: []byte
		+Reset()
		+String(): string
		+ProtoMessage()
		+ProtoReflect(): protoreflect.Message
		+Descriptor(): ([]byte, []int)
	}
}



package "helloworld" {
	class "Response" as helloworld.Response <<E,#FFCC00>> {
		-state: impl.MessageState
		-sizeCache: int32
		-unknownFields: []byte
		+Reset()
		+String(): string
		+ProtoMessage()
		+ProtoReflect(): protoreflect.Message
		+Descriptor(): ([]byte, []int)
	}
}



	helloworld.HelloworldClientProxyImpl -up-|> helloworld.HelloworldClientProxy


@enduml
@jfeliu007
Copy link
Owner

jfeliu007 commented Jan 6, 2021

It would be interesting to see the code, since the example you posted has two different signatures in the Hello Method.

Hello(ctx: context.Context, req: *helloworld.Request, opts: client.Option): (rsp: *helloworld.Response, err: error)
Hello(ctx: context.Context, req: *helloworld.Request, rsp: *helloworld.Response): err: error

Notice the parameters and the returns are different. If the code is the same, then this means this tool just helped you see it :) . If not, then the tools is taking the information wrong :(. Is it possible for you to confirm this? Notice that the HelloworldClientProxyImpl does have the correct signature and it does indeed represents the correct relationship with the interface

@hitzhangjie
Copy link
Author

hitzhangjie commented Jan 6, 2021

  • interface type: HelloworldService, the right-most rectange in the picture
  • implemention type: helloworldServiceImpl, the left-most rectange in the picture

they have the same signature: Hello(ctx: context.Context, req: *helloworld.Request, rsp: *helloworld.Response): err: error

@jfeliu007
Copy link
Owner

jfeliu007 commented Jan 6, 2021

I see, my mistake. Usually in my code I don't reference the package within the same package. For example. Plantuml has the following structure

type Struct struct {
	PackageName         string
	Functions           []*Function
	Fields              []*Field
	Type                string
	Composition         map[string]struct{}
	Extends             map[string]struct{}
	Aggregations        map[string]struct{}
	PrivateAggregations map[string]struct{}
}

and the following function

func (st *Struct) ImplementsInterface(inter *Struct) bool {
...
}

notice I am not using (inter *parser.Struct) which is the case for you. I am not sure if that is the problem with the parsing of the relationship. Since the parser will assume the package and make the relationship with it. Maybe the interface needs to be defined as

Hello(ctx: context.Context, req: *Request, rsp: *Response): err: error

Instead, since Request and Response both belong to that package. I'd like to try what you are doing to see what the parser returns. If you could share the code it will help me see what is going on. I understand sometimes it is no possible, so something that compiles and produces a similar outcome will help me reproduce it.

@hitzhangjie
Copy link
Author

@jfeliu007 Thanks for your sharing, I'll check and test it later.

@jfeliu007
Copy link
Owner

Hi @hitzhangjie , is this still an issue?

@hitzhangjie
Copy link
Author

Yes, I think the problem still exists.

hello.zip

I uploaded an attachment. This contains a complete project based on some microservice framework, and a file.puml generated by the latest gouml.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants