Skip to content

Ability to check if a match is within a method implementing interface (or method name matches)  #409

@jippi

Description

@jippi

Hey!

First off, thanks for a fantastic tool! :) Been spending a day or two at work to implement it in a large'ish codebase, and it has already proven immensely valuable in finding bad patterns that had slipped through the cracks in review.

I'm trying to write a rule guard that will satisfy the following but can't quite figure out if it is possible or not:

  1. I want to flag any call to check.OK() anywhere within a method named Fix(context.Context)
  2. Calls to check.OK() in other places is fine
  3. Calls to other methods than OK() is fine
type Fixer interface {
	Fix(context.Context) *Entry
}

type CheckLoggedInImpl struct {
	checks.Entry
}

func (check *CheckLoggedInImpl) Fix(ctx context.Context) *checks.Entry {
        // .... lots of code here

	if true {
		return check.OK() // not working
	}   

	return check.OK() // working
}

I've tried a bunch of rules, like the one below, but I can't figure out how to traverse the stack and see what the method name is for the Match(), so I know whether it's a problem or not it's being called.

I got the last return of the Fix() method matching, but I can't figure out how to get any call to check.OK() as reporting - regardless of indentation and what code formatting

// Don't use 'path' package as it doesn't support Windows path separator,
// which often leads to bugs and other trouble
//
// https://stackoverflow.com/a/48050736/1081818
func fixMustCallCheck(m dsl.Matcher) {
	m.Import("$INTERNAL_URL/internal/system/checks")

	m.
		Match(
			`func ($_ $implType) Fix($_ context.Context) $_ { $*_ ; return $check.OK() }`,
			`func ($_ $implType) Fix($_ context.Context) $_ { $*_ ; { $*_ ; return $check.OK() } ; $*_ }`,
		).
		Where(m["implType"].Filter(ensureFixer)).
		At(m["check"]).
		Report(`You should not call check.OK() within a Fix() method - please call check.Check(ctx) instead`)
}

func ensureFixer(ctx *dsl.VarFilterContext) bool {
	fixer := ctx.GetInterface(`$INTERNAL_URL/internal/system/checks.Fixer`)
	return types.Implements(ctx.Type, fixer)
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions