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

Conflict of argument name and imported package name results in compilation error #177

Open
TomerSalton opened this issue May 20, 2024 · 0 comments

Comments

@TomerSalton
Copy link

TomerSalton commented May 20, 2024

Actual behavior
Given a method of an interface,
if one of the return values is of a type that comes from different package,
and if the name of one of the arguments conflicts with this package name,
then a compilation error happens.

Expected behavior
Such arg names should be sanitized - not only if they're empty ( or _), but also if they conflicts with such package name.

To Reproduce

Define interface

type Client interface {
        // `file` is our package, that is defined outside of the interface's package
	Upload(ctx context.Context, file *file.Handle) (*file.Header, error)
}

Then, when generating, this is what happens:

// Upload mocks base method.
func (m *MockClient) Upload(ctx context.Context, file *file.Handle) (*file.Header, error) {
	m.ctrl.T.Helper()
	ret := m.ctrl.Call(m, "Upload", ctx, file)
        // compilation error: go treats `Header` as a property of the argument named file,
        // instead of a struct defined in the `file` package
	ret0, _ := ret[0].(*file.Header)
	ret1, _ := ret[1].(error)
	return ret0, ret1
}

Additional Information

I have already crafted a small PR with the following fix.
I will be happy to contribute if you guys find it useful.

fix getArgNames

reference to the current function

func (g *generator) getArgNames(m *model.Method, in bool) []string {
	var params []*model.Parameter

	forbidden := map[string]bool{}
	for _, v := range g.packageMap {
		forbidden[v] = true
	}

	if in {
		params = m.In
	} else {
		params = m.Out
	}
	argNames := make([]string, len(params))
	for i, p := range params {
		argNames[i] = sanitizeName(p.Name, forbidden, i)
	}
	if m.Variadic != nil && in {
		name := sanitizeName(m.Variadic.Name, forbidden, len(params))
		argNames = append(argNames, name)
	}
	return argNames
}

...

func sanitizeName(name string, forbidden map[string]bool, i int) string {
	if name == "" || name == "_" || forbidden[name] {
		return fmt.Sprintf("arg%d", i)
	}
	return name
}
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

1 participant