rulesdata

package
v0.2.3 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jan 29, 2023 License: MIT Imports: 1 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var PrecompiledRules = &ir.File{
	PkgPath:       "gorules",
	CustomDecls:   []string{},
	BundleImports: []ir.BundleImport{},
	RuleGroups: []ir.RuleGroup{
		{
			Line:        15,
			Name:        "unusedFormatting",
			MatcherName: "m",
			DocTags:     []string{"style"},
			DocSummary:  "Detects unused formatting functionality",
			DocBefore:   "fmt.Sprintf(\"42\")",
			DocAfter:    "fmt.Sprint(\"42\")",
			Rules: []ir.Rule{{
				Line: 16,
				SyntaxPatterns: []ir.PatternString{
					{Line: 16, Value: "fmt.Sprintf($_)"},
					{Line: 16, Value: "fmt.Errorf($_)"},
				},
				ReportTemplate: "use function alternative without formatting",
			}},
		},
		{
			Line:        35,
			Name:        "uncheckedTypeAssert",
			MatcherName: "m",
			DocTags:     []string{"diagnostic"},
			DocSummary:  "Detects unchecked type assertation",
			DocBefore:   "foo := bar.(string) // var bar interface{}",
			DocAfter:    "foo, ok := bar.(string)",
			Rules: []ir.Rule{{
				Line: 36,
				SyntaxPatterns: []ir.PatternString{
					{Line: 37, Value: "$_ := $_.($_)"},
					{Line: 38, Value: "$_ = $_.($_)"},
					{Line: 39, Value: "$_($*_, $_.($_), $*_)"},
					{Line: 40, Value: "$_{$*_, $_.($_), $*_}"},
					{Line: 41, Value: "$_{$*_, $_: $_.($_), $*_}"},
					{Line: 42, Value: "$_ <- $_.($_)"},
					{Line: 43, Value: "$_{$*_, $_.($_): $_, $*_}"},
				},
				ReportTemplate: "avoid unchecked type assertions as they can panic",
			}},
		},
		{
			Line:        51,
			Name:        "rangeCopyVal",
			MatcherName: "m",
			DocTags:     []string{"performance"},
			DocSummary:  "Detects copy big structs in loop body",
			DocBefore:   "for _, x := range xs { myfunc(x) } // for example var xs [][2048]string",
			DocAfter:    "for i := range xs { myfunc(xs[i]) }",
			Rules: []ir.Rule{{
				Line: 52,
				SyntaxPatterns: []ir.PatternString{
					{Line: 52, Value: "for $_, $x := range $xs { $*_ }"},
					{Line: 52, Value: "for $_, $x = range $xs { $*_ }"},
				},
				ReportTemplate: "each iteration copies more than 256 bytes (consider pointers or indexing)",
				WhereExpr: ir.FilterExpr{
					Line: 53,
					Op:   ir.FilterAndOp,
					Src:  "(m[\"xs\"].Type.Is(\"[]$_\") || m[\"xs\"].Type.Is(\"[$_]$_\")) && m[\"x\"].Type.Size >= 256",
					Args: []ir.FilterExpr{
						{
							Line: 53,
							Op:   ir.FilterOrOp,
							Src:  "(m[\"xs\"].Type.Is(\"[]$_\") || m[\"xs\"].Type.Is(\"[$_]$_\"))",
							Args: []ir.FilterExpr{
								{
									Line:  53,
									Op:    ir.FilterVarTypeIsOp,
									Src:   "m[\"xs\"].Type.Is(\"[]$_\")",
									Value: "xs",
									Args:  []ir.FilterExpr{{Line: 53, Op: ir.FilterStringOp, Src: "\"[]$_\"", Value: "[]$_"}},
								},
								{
									Line:  53,
									Op:    ir.FilterVarTypeIsOp,
									Src:   "m[\"xs\"].Type.Is(\"[$_]$_\")",
									Value: "xs",
									Args:  []ir.FilterExpr{{Line: 53, Op: ir.FilterStringOp, Src: "\"[$_]$_\"", Value: "[$_]$_"}},
								},
							},
						},
						{
							Line: 53,
							Op:   ir.FilterGtEqOp,
							Src:  "m[\"x\"].Type.Size >= 256",
							Args: []ir.FilterExpr{
								{
									Line:  53,
									Op:    ir.FilterVarTypeSizeOp,
									Src:   "m[\"x\"].Type.Size",
									Value: "x",
								},
								{
									Line:  53,
									Op:    ir.FilterIntOp,
									Src:   "256",
									Value: int64(256),
								},
							},
						},
					},
				},
				LocationVar: "x",
			}},
		},
		{
			Line:        62,
			Name:        "rangeExprCopy",
			MatcherName: "m",
			DocTags:     []string{"performance"},
			DocSummary:  "Detects big array copy in loop",
			DocBefore:   "for _, x := range xs { myfunc(x) } // var xs [2048]string",
			DocAfter:    "for _, x := range &xs { myfunc(x) }",
			Rules: []ir.Rule{{
				Line: 63,
				SyntaxPatterns: []ir.PatternString{
					{Line: 63, Value: "for $_, $_ := range $x { $*_ }"},
					{Line: 64, Value: "for $_, $_ = range $x { $*_ }"},
				},
				ReportTemplate:  "copy of $x can be avoided with &$x",
				SuggestTemplate: "&$x",
				WhereExpr: ir.FilterExpr{
					Line: 65,
					Op:   ir.FilterAndOp,
					Src:  "m[\"x\"].Type.Is(\"[$_]$_\") && m[\"x\"].Type.Size >= 256",
					Args: []ir.FilterExpr{
						{
							Line:  65,
							Op:    ir.FilterVarTypeIsOp,
							Src:   "m[\"x\"].Type.Is(\"[$_]$_\")",
							Value: "x",
							Args:  []ir.FilterExpr{{Line: 65, Op: ir.FilterStringOp, Src: "\"[$_]$_\"", Value: "[$_]$_"}},
						},
						{
							Line: 65,
							Op:   ir.FilterGtEqOp,
							Src:  "m[\"x\"].Type.Size >= 256",
							Args: []ir.FilterExpr{
								{
									Line:  65,
									Op:    ir.FilterVarTypeSizeOp,
									Src:   "m[\"x\"].Type.Size",
									Value: "x",
								},
								{
									Line:  65,
									Op:    ir.FilterIntOp,
									Src:   "256",
									Value: int64(256),
								},
							},
						},
					},
				},
				LocationVar: "x",
			}},
		},
		{
			Line:        73,
			Name:        "ifacePtr",
			MatcherName: "m",
			DocTags:     []string{"performance"},
			DocSummary:  "Detects pointer to interface{}",
			Rules: []ir.Rule{{
				Line:           74,
				SyntaxPatterns: []ir.PatternString{{Line: 74, Value: "*$x"}},
				ReportTemplate: "don't use pointers to an interface",
				WhereExpr: ir.FilterExpr{
					Line:  75,
					Op:    ir.FilterVarTypeUnderlyingIsOp,
					Src:   "m[\"x\"].Type.Underlying().Is(`interface{ $*_ }`)",
					Value: "x",
					Args:  []ir.FilterExpr{{Line: 75, Op: ir.FilterStringOp, Src: "`interface{ $*_ }`", Value: "interface{ $*_ }"}},
				},
			}},
		},
		{
			Line:        83,
			Name:        "camelCaseNaming",
			MatcherName: "m",
			DocTags:     []string{"style"},
			DocSummary:  "Detects non camel case naming strategy for functions, constants, types, variables",
			DocBefore:   "type my_type struct {}",
			DocAfter:    "type myType struct {}",
			Rules: []ir.Rule{{
				Line: 84,
				SyntaxPatterns: []ir.PatternString{
					{Line: 85, Value: "func $x($*_) $*_ { $*_ }"},
					{Line: 86, Value: "func ($_) $x($*_) $*_ { $*_ }"},
					{Line: 87, Value: "func ($_ $_) $x($*_) $*_ { $*_ }"},
					{Line: 88, Value: "const $x = $_"},
					{Line: 88, Value: "const $x $_ = $_"},
					{Line: 89, Value: "const ($x = $_; $*_)"},
					{Line: 90, Value: "const ($_ = $_; $x = $_; $*_)"},
					{Line: 91, Value: "const ($x $_= $_; $*_)"},
					{Line: 92, Value: "const ($_ $_ = $_; $x $_= $_; $*_)"},
					{Line: 93, Value: "type $x $_"},
					{Line: 94, Value: "$x := $_"},
					{Line: 95, Value: "var $x = $_"},
					{Line: 96, Value: "var $x $_ = $_"},
				},
				ReportTemplate: "use camelCase naming strategy",
				WhereExpr: ir.FilterExpr{
					Line: 98,
					Op:   ir.FilterAndOp,
					Src:  "!m[\"x\"].Text.Matches(`^_$`) && (m[\"x\"].Text.Matches(`-|_`))",
					Args: []ir.FilterExpr{
						{
							Line: 98,
							Op:   ir.FilterNotOp,
							Src:  "!m[\"x\"].Text.Matches(`^_$`)",
							Args: []ir.FilterExpr{{
								Line:  98,
								Op:    ir.FilterVarTextMatchesOp,
								Src:   "m[\"x\"].Text.Matches(`^_$`)",
								Value: "x",
								Args:  []ir.FilterExpr{{Line: 98, Op: ir.FilterStringOp, Src: "`^_$`", Value: "^_$"}},
							}},
						},
						{
							Line:  98,
							Op:    ir.FilterVarTextMatchesOp,
							Src:   "(m[\"x\"].Text.Matches(`-|_`))",
							Value: "x",
							Args:  []ir.FilterExpr{{Line: 98, Op: ir.FilterStringOp, Src: "`-|_`", Value: "-|_"}},
						},
					},
				},
				LocationVar: "x",
			}},
		},
		{
			Line:        107,
			Name:        "notInformativePackageNaming",
			MatcherName: "m",
			DocTags:     []string{"style"},
			DocSummary:  "Detects general names for package",
			DocBefore:   "package lib",
			DocAfter:    "package concreteLib",
			Rules: []ir.Rule{{
				Line:           108,
				SyntaxPatterns: []ir.PatternString{{Line: 108, Value: "package $x"}},
				ReportTemplate: "don't use general names to package naming",
				WhereExpr: ir.FilterExpr{
					Line: 109,
					Op:   ir.FilterOrOp,
					Src:  "m[\"x\"].Text.Matches(`(^c|C|_(c|C))ommon([A-Z]|_|$|\\d)`) ||\n\tm[\"x\"].Text.Matches(`(^l|L|_(l|L))ib([A-Z]|_|$|\\d)`) ||\n\tm[\"x\"].Text.Matches(`(^u|U|_(u|U))til([A-Z]|_|$|\\d)`) ||\n\tm[\"x\"].Text.Matches(`(^s|S|_(s|S))hared([A-Z]|_|$|\\d)`)",
					Args: []ir.FilterExpr{
						{
							Line: 109,
							Op:   ir.FilterOrOp,
							Src:  "m[\"x\"].Text.Matches(`(^c|C|_(c|C))ommon([A-Z]|_|$|\\d)`) ||\n\tm[\"x\"].Text.Matches(`(^l|L|_(l|L))ib([A-Z]|_|$|\\d)`) ||\n\tm[\"x\"].Text.Matches(`(^u|U|_(u|U))til([A-Z]|_|$|\\d)`)",
							Args: []ir.FilterExpr{
								{
									Line: 109,
									Op:   ir.FilterOrOp,
									Src:  "m[\"x\"].Text.Matches(`(^c|C|_(c|C))ommon([A-Z]|_|$|\\d)`) ||\n\tm[\"x\"].Text.Matches(`(^l|L|_(l|L))ib([A-Z]|_|$|\\d)`)",
									Args: []ir.FilterExpr{
										{
											Line:  109,
											Op:    ir.FilterVarTextMatchesOp,
											Src:   "m[\"x\"].Text.Matches(`(^c|C|_(c|C))ommon([A-Z]|_|$|\\d)`)",
											Value: "x",
											Args:  []ir.FilterExpr{{Line: 109, Op: ir.FilterStringOp, Src: "`(^c|C|_(c|C))ommon([A-Z]|_|$|\\d)`", Value: "(^c|C|_(c|C))ommon([A-Z]|_|$|\\d)"}},
										},
										{
											Line:  110,
											Op:    ir.FilterVarTextMatchesOp,
											Src:   "m[\"x\"].Text.Matches(`(^l|L|_(l|L))ib([A-Z]|_|$|\\d)`)",
											Value: "x",
											Args:  []ir.FilterExpr{{Line: 110, Op: ir.FilterStringOp, Src: "`(^l|L|_(l|L))ib([A-Z]|_|$|\\d)`", Value: "(^l|L|_(l|L))ib([A-Z]|_|$|\\d)"}},
										},
									},
								},
								{
									Line:  111,
									Op:    ir.FilterVarTextMatchesOp,
									Src:   "m[\"x\"].Text.Matches(`(^u|U|_(u|U))til([A-Z]|_|$|\\d)`)",
									Value: "x",
									Args:  []ir.FilterExpr{{Line: 111, Op: ir.FilterStringOp, Src: "`(^u|U|_(u|U))til([A-Z]|_|$|\\d)`", Value: "(^u|U|_(u|U))til([A-Z]|_|$|\\d)"}},
								},
							},
						},
						{
							Line:  112,
							Op:    ir.FilterVarTextMatchesOp,
							Src:   "m[\"x\"].Text.Matches(`(^s|S|_(s|S))hared([A-Z]|_|$|\\d)`)",
							Value: "x",
							Args:  []ir.FilterExpr{{Line: 112, Op: ir.FilterStringOp, Src: "`(^s|S|_(s|S))hared([A-Z]|_|$|\\d)`", Value: "(^s|S|_(s|S))hared([A-Z]|_|$|\\d)"}},
						},
					},
				},
				LocationVar: "x",
			}},
		},
		{
			Line:        121,
			Name:        "getterNaming",
			MatcherName: "m",
			DocTags:     []string{"style"},
			DocSummary:  "Detects 'get' word in getter functions",
			DocBefore:   "func (x myType) getValue() string { return x.v }",
			DocAfter:    "func (x myType) value() string { return x.v }",
			Rules: []ir.Rule{{
				Line: 122,
				SyntaxPatterns: []ir.PatternString{
					{Line: 123, Value: "func ($x $_) $name($*_) $*_ { return $x.$_ }"},
					{Line: 124, Value: "func ($x $_) $name($*_) $*_ { return $_($x.$_) }"},
					{Line: 125, Value: "func ($x $_) $name($*_) $*_ { return $_($x) }"},
					{Line: 126, Value: "func ($x $_) $name($*_) $*_ { return $_(*$x) }"},
				},
				ReportTemplate: "don't use 'get' in getter functions",
				WhereExpr: ir.FilterExpr{
					Line:  128,
					Op:    ir.FilterVarTextMatchesOp,
					Src:   "m[\"name\"].Text.Matches(`(^g|G|_(g|G))et([A-Z]|$|_|\\d)`)",
					Value: "name",
					Args:  []ir.FilterExpr{{Line: 128, Op: ir.FilterStringOp, Src: "`(^g|G|_(g|G))et([A-Z]|$|_|\\d)`", Value: "(^g|G|_(g|G))et([A-Z]|$|_|\\d)"}},
				},
				LocationVar: "name",
			}},
		},
		{
			Line:        145,
			Name:        "interfaceWordInInterfaceDeclaration",
			MatcherName: "m",
			DocTags:     []string{"style"},
			DocSummary:  "Detects 'interface' word in interface declarations",
			DocBefore:   "type interfaceDb interface { }",
			DocAfter:    "type db interface { }",
			Rules: []ir.Rule{{
				Line:           146,
				SyntaxPatterns: []ir.PatternString{{Line: 146, Value: "type $name interface{ $*_ }"}},
				ReportTemplate: "don't use 'interface' word' in interface declaration'",
				WhereExpr: ir.FilterExpr{
					Line:  147,
					Op:    ir.FilterVarTextMatchesOp,
					Src:   "m[\"name\"].Text.Matches(`(^i|I|_(i|I))nterface([A-Z]|_|$|\\d)`)",
					Value: "name",
					Args:  []ir.FilterExpr{{Line: 147, Op: ir.FilterStringOp, Src: "`(^i|I|_(i|I))nterface([A-Z]|_|$|\\d)`", Value: "(^i|I|_(i|I))nterface([A-Z]|_|$|\\d)"}},
				},
				LocationVar: "name",
			}},
		},
		{
			Line:        157,
			Name:        "simplifyErrorReturn",
			MatcherName: "m",
			DocTags:     []string{"style"},
			DocSummary:  "Detects expressions that can be rewritten in form without 'if' usage",
			DocBefore:   "err := myFunc(); if err != nil { return err }; return nil",
			DocAfter:    "return myFunc()",
			Rules: []ir.Rule{{
				Line: 158,
				SyntaxPatterns: []ir.PatternString{
					{Line: 158, Value: "if $*_, $err = $_; $err != nil { return $err }; return nil"},
					{Line: 159, Value: "if $*_, $err := $_; $err != nil { return $err }; return nil"},
					{Line: 160, Value: "$*_, $err = $_; if $err != nil { return $err }; return nil"},
					{Line: 161, Value: "var $*_, $err = $_; if $err != nil { return $err }; return nil"},
					{Line: 162, Value: "$*_, $err := $_; if $err != nil { return $err }; return nil"},
					{Line: 163, Value: "if $*_, $err = $_; $err != nil { return $err }; return $err"},
					{Line: 164, Value: "if $*_, $err := $_; $err != nil { return $err }; return $err"},
					{Line: 165, Value: "$*_, $err = $_; if $err != nil { return $err }; return $err"},
					{Line: 166, Value: "var $*_, $err = $_; if $err != nil { return $err }; return $err"},
					{Line: 167, Value: "$*_, $err := $_; if $err != nil { return $err }; return $err"},
				},
				ReportTemplate: "may be simplified to return error without if statement",
				WhereExpr: ir.FilterExpr{
					Line:  169,
					Op:    ir.FilterVarTypeImplementsOp,
					Src:   "m[\"err\"].Type.Implements(\"error\")",
					Value: "err",
					Args:  []ir.FilterExpr{{Line: 169, Op: ir.FilterStringOp, Src: "\"error\"", Value: "error"}},
				},
			}},
		},
		{
			Line:        226,
			Name:        "deferInLoop",
			MatcherName: "m",
			DocTags:     []string{"diagnostic"},
			DocSummary:  "Detects loops inside functions that use defer",
			DocBefore:   "for _, filename := range []string{\"foo\", \"bar\"} { f, err := os.Open(filename); defer f.Close() }",
			DocAfter:    "func process(filename string) {",
			Rules: []ir.Rule{{
				Line: 227,
				SyntaxPatterns: []ir.PatternString{
					{Line: 228, Value: "for $*_; $*_; $*_ { $*_; defer func($*args) $*_ { $*_ }($*_); $*_ }"},
					{Line: 229, Value: "for $*_; $*_; $*_ { $*_; defer $_($*args); $*_ }"},
					{Line: 231, Value: "for { $*_; defer func($*args) $*_ { $*_ }($*_); $*_ }"},
					{Line: 232, Value: "for { $*_; defer $_($*args); $*_ }"},
					{Line: 234, Value: "for $_, $_ := range $_ { $*_; defer func($*args) $*_ { $*_ }($*_); $*_ }"},
					{Line: 235, Value: "for $_, $_ := range $_ { $*_; defer $_($*args); $*_ }"},
					{Line: 237, Value: "for $_, $_ = range $_ { $*_; defer func($*args) $*_ { $*_ }($*_); $*_ }"},
					{Line: 238, Value: "for $_, $_ = range $_ { $*_; defer $_($*args); $*_ }"},
					{Line: 240, Value: "for $_ := range $_ { $*_; defer func($*args) $*_ { $*_ }($*_); $*_ }"},
					{Line: 241, Value: "for $_ := range $_ { $*_; defer $_($*args); $*_ }"},
					{Line: 243, Value: "for $_ = range $_ { $*_; defer func($*args) $*_ { $*_ }($*_); $*_ }"},
					{Line: 244, Value: "for $_ = range $_ { $*_; defer $_($*args); $*_ }"},
					{Line: 246, Value: "for range $_ { $*_; defer func($*args) $*_ { $*_ }($*_); $*_ }"},
					{Line: 247, Value: "for range $_ { $*_; defer $_($*args); $*_ }"},
				},
				ReportTemplate: "Possible resource leak, 'defer' is called in the 'for' loop",
				LocationVar:    "args",
			}},
		},
		{
			Line:        300,
			Name:        "regexpCompileInLoop",
			MatcherName: "m",
			DocTags:     []string{"performance"},
			DocSummary:  "Detects regular expression compilation in loop",
			DocBefore:   "for { if regexp.MatchString(\"\\d\", \"123\") { /*...*/ } }",
			DocAfter:    "dig := regexp.MustCompile(\"\\d\"); for { if dig.MatchString(\"123\") { /*...*/ } }",
			Rules: []ir.Rule{{
				Line: 301,
				SyntaxPatterns: []ir.PatternString{
					{Line: 302, Value: "for $*_; $*_; $*_ { $*_; $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 303, Value: "for { $*_; $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 304, Value: "for $_, $_ := range $_ { $*_; $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 305, Value: "for $_, $_ = range $_ { $*_; $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 306, Value: "for $_ := range $_ { $*_; $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 307, Value: "for $_ = range $_ { $*_; $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 308, Value: "for range $_ { $*_; $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 310, Value: "for $*_; $*_; $*_ { $*_; $*_ := regexp.$method($s, $*args); $*_ }"},
					{Line: 311, Value: "for { $*_; $*_ := regexp.$method($s, $*args); $*_ }"},
					{Line: 312, Value: "for $_, $_ := range $_ { $*_; $*_ := regexp.$method($s, $*args); $*_ }"},
					{Line: 313, Value: "for $_, $_ = range $_ { $*_; $*_ := regexp.$method($s, $*args); $*_ }"},
					{Line: 314, Value: "for $_ := range $_ { $*_; $*_ := regexp.$method($s, $*args); $*_ }"},
					{Line: 315, Value: "for $_ = range $_ { $*_; $*_ := regexp.$method($s, $*args); $*_ }"},
					{Line: 316, Value: "for range $_ { $*_; $*_ := regexp.$method($s, $*args); $*_ }"},
					{Line: 318, Value: "for $*_; $*_; $*_ { $*_; var $*_ $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 319, Value: "for { $*_; var $*_ $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 320, Value: "for $_, $_ := range $_ { $*_; var $*_ $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 321, Value: "for $_, $_ = range $_ { $*_; var $*_ $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 322, Value: "for $_ := range $_ { $*_; var $*_ $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 323, Value: "for $_ = range $_ { $*_; var $*_ $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 324, Value: "for range $_ { $*_; var $*_ $*_ = regexp.$method($s, $*args); $*_ }"},
				},
				ReportTemplate: "don't compile regex in the loop, move it outside of the loop",
				WhereExpr: ir.FilterExpr{
					Line: 327,
					Op:   ir.FilterAndOp,
					Src:  "m[\"s\"].Const && !m[\"method\"].Contains(`QuoteMeta`)",
					Args: []ir.FilterExpr{
						{
							Line:  327,
							Op:    ir.FilterVarConstOp,
							Src:   "m[\"s\"].Const",
							Value: "s",
						},
						{
							Line: 327,
							Op:   ir.FilterNotOp,
							Src:  "!m[\"method\"].Contains(`QuoteMeta`)",
							Args: []ir.FilterExpr{{
								Line:  327,
								Op:    ir.FilterVarContainsOp,
								Src:   "m[\"method\"].Contains(`QuoteMeta`)",
								Value: "method",
								Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "QuoteMeta"}},
							}},
						},
					},
				},
				LocationVar: "s",
			}},
		},
		{
			Line:        335,
			Name:        "unclosedResource",
			MatcherName: "m",
			DocTags:     []string{"experimental", "diagnostic"},
			DocSummary:  "Detects unreleased resources",
			DocBefore:   "s, _ := os.Open(\"foo.txt\"); s.Read(body); return body",
			DocAfter:    "s, _ := os.Open(\"foo.txt\"); defer s.Close(); s.Read(body); return body",
			Rules: []ir.Rule{{
				Line: 344,
				SyntaxPatterns: []ir.PatternString{
					{Line: 344, Value: "$res, $err := $_($*_); $*body"},
					{Line: 345, Value: "$res, $err = $_($*_); $*body"},
					{Line: 346, Value: "var $res, $err = $_($*_); $*body"},
				},
				ReportTemplate: "$res.Close() should be deferred right after the resource creation",
				WhereExpr: ir.FilterExpr{
					Line: 349,
					Op:   ir.FilterAndOp,
					Src:  "m[\"res\"].Type.Implements(`io.Closer`) &&\n\t!m[\"res\"].Object.IsGlobal() &&\n\tm[\"err\"].Type.Implements(`error`) &&\n\t!m[\"body\"].Contains(`$res.Close()`) &&\n\t!varEscapeFunction(m[\"body\"])",
					Args: []ir.FilterExpr{
						{
							Line: 349,
							Op:   ir.FilterAndOp,
							Src:  "m[\"res\"].Type.Implements(`io.Closer`) &&\n\t!m[\"res\"].Object.IsGlobal() &&\n\tm[\"err\"].Type.Implements(`error`) &&\n\t!m[\"body\"].Contains(`$res.Close()`)",
							Args: []ir.FilterExpr{
								{
									Line: 349,
									Op:   ir.FilterAndOp,
									Src:  "m[\"res\"].Type.Implements(`io.Closer`) &&\n\t!m[\"res\"].Object.IsGlobal() &&\n\tm[\"err\"].Type.Implements(`error`)",
									Args: []ir.FilterExpr{
										{
											Line: 349,
											Op:   ir.FilterAndOp,
											Src:  "m[\"res\"].Type.Implements(`io.Closer`) &&\n\t!m[\"res\"].Object.IsGlobal()",
											Args: []ir.FilterExpr{
												{
													Line:  349,
													Op:    ir.FilterVarTypeImplementsOp,
													Src:   "m[\"res\"].Type.Implements(`io.Closer`)",
													Value: "res",
													Args:  []ir.FilterExpr{{Line: 349, Op: ir.FilterStringOp, Src: "`io.Closer`", Value: "io.Closer"}},
												},
												{
													Line: 350,
													Op:   ir.FilterNotOp,
													Src:  "!m[\"res\"].Object.IsGlobal()",
													Args: []ir.FilterExpr{{
														Line:  350,
														Op:    ir.FilterVarObjectIsGlobalOp,
														Src:   "m[\"res\"].Object.IsGlobal()",
														Value: "res",
													}},
												},
											},
										},
										{
											Line:  351,
											Op:    ir.FilterVarTypeImplementsOp,
											Src:   "m[\"err\"].Type.Implements(`error`)",
											Value: "err",
											Args:  []ir.FilterExpr{{Line: 351, Op: ir.FilterStringOp, Src: "`error`", Value: "error"}},
										},
									},
								},
								{
									Line: 352,
									Op:   ir.FilterNotOp,
									Src:  "!m[\"body\"].Contains(`$res.Close()`)",
									Args: []ir.FilterExpr{{
										Line:  352,
										Op:    ir.FilterVarContainsOp,
										Src:   "m[\"body\"].Contains(`$res.Close()`)",
										Value: "body",
										Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$res.Close()"}},
									}},
								},
							},
						},
						{
							Line: 353,
							Op:   ir.FilterNotOp,
							Src:  "!varEscapeFunction(m[\"body\"])",
							Args: []ir.FilterExpr{{
								Line: 353,
								Op:   ir.FilterOrOp,
								Src:  "varEscapeFunction(m[\"body\"])",
								Args: []ir.FilterExpr{
									{
										Line: 353,
										Op:   ir.FilterOrOp,
										Src:  "m[\"body\"].Contains(`$_{$*_, $res, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $res, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_ <- $res`) ||\n\n\tm[\"body\"].Contains(`return $*_, $res, $*_`) ||\n\n\tm[\"body\"].Contains(`$_[$_] = $res`) ||\n\n\tm[\"body\"].Contains(`$_[$res] = $_`) ||\n\n\tm[\"body\"].Contains(`$_ = $res;`) ||\n\n\tm[\"body\"].Contains(`$_ := $res;`) ||\n\n\tm[\"body\"].Contains(`var $_ = $res;`)",
										Args: []ir.FilterExpr{
											{
												Line: 353,
												Op:   ir.FilterOrOp,
												Src:  "m[\"body\"].Contains(`$_{$*_, $res, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $res, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_ <- $res`) ||\n\n\tm[\"body\"].Contains(`return $*_, $res, $*_`) ||\n\n\tm[\"body\"].Contains(`$_[$_] = $res`) ||\n\n\tm[\"body\"].Contains(`$_[$res] = $_`) ||\n\n\tm[\"body\"].Contains(`$_ = $res;`) ||\n\n\tm[\"body\"].Contains(`$_ := $res;`)",
												Args: []ir.FilterExpr{
													{
														Line: 353,
														Op:   ir.FilterOrOp,
														Src:  "m[\"body\"].Contains(`$_{$*_, $res, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $res, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_ <- $res`) ||\n\n\tm[\"body\"].Contains(`return $*_, $res, $*_`) ||\n\n\tm[\"body\"].Contains(`$_[$_] = $res`) ||\n\n\tm[\"body\"].Contains(`$_[$res] = $_`) ||\n\n\tm[\"body\"].Contains(`$_ = $res;`)",
														Args: []ir.FilterExpr{
															{
																Line: 353,
																Op:   ir.FilterOrOp,
																Src:  "m[\"body\"].Contains(`$_{$*_, $res, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $res, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_ <- $res`) ||\n\n\tm[\"body\"].Contains(`return $*_, $res, $*_`) ||\n\n\tm[\"body\"].Contains(`$_[$_] = $res`) ||\n\n\tm[\"body\"].Contains(`$_[$res] = $_`)",
																Args: []ir.FilterExpr{
																	{
																		Line: 353,
																		Op:   ir.FilterOrOp,
																		Src:  "m[\"body\"].Contains(`$_{$*_, $res, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $res, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_ <- $res`) ||\n\n\tm[\"body\"].Contains(`return $*_, $res, $*_`) ||\n\n\tm[\"body\"].Contains(`$_[$_] = $res`)",
																		Args: []ir.FilterExpr{
																			{
																				Line: 353,
																				Op:   ir.FilterOrOp,
																				Src:  "m[\"body\"].Contains(`$_{$*_, $res, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $res, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_ <- $res`) ||\n\n\tm[\"body\"].Contains(`return $*_, $res, $*_`)",
																				Args: []ir.FilterExpr{
																					{
																						Line: 353,
																						Op:   ir.FilterOrOp,
																						Src:  "m[\"body\"].Contains(`$_{$*_, $res, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $res, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_ <- $res`)",
																						Args: []ir.FilterExpr{
																							{
																								Line: 353,
																								Op:   ir.FilterOrOp,
																								Src:  "m[\"body\"].Contains(`$_{$*_, $res, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $res, $*_}`)",
																								Args: []ir.FilterExpr{
																									{
																										Line:  353,
																										Op:    ir.FilterVarContainsOp,
																										Src:   "m[\"body\"].Contains(`$_{$*_, $res, $*_}`)",
																										Value: "body",
																										Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_{$*_, $res, $*_}"}},
																									},
																									{
																										Line:  353,
																										Op:    ir.FilterVarContainsOp,
																										Src:   "m[\"body\"].Contains(`$_{$*_, $_: $res, $*_}`)",
																										Value: "body",
																										Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_{$*_, $_: $res, $*_}"}},
																									},
																								},
																							},
																							{
																								Line:  353,
																								Op:    ir.FilterVarContainsOp,
																								Src:   "m[\"body\"].Contains(`$_ <- $res`)",
																								Value: "body",
																								Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_ <- $res"}},
																							},
																						},
																					},
																					{
																						Line:  353,
																						Op:    ir.FilterVarContainsOp,
																						Src:   "m[\"body\"].Contains(`return $*_, $res, $*_`)",
																						Value: "body",
																						Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "return $*_, $res, $*_"}},
																					},
																				},
																			},
																			{
																				Line:  353,
																				Op:    ir.FilterVarContainsOp,
																				Src:   "m[\"body\"].Contains(`$_[$_] = $res`)",
																				Value: "body",
																				Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_[$_] = $res"}},
																			},
																		},
																	},
																	{
																		Line:  353,
																		Op:    ir.FilterVarContainsOp,
																		Src:   "m[\"body\"].Contains(`$_[$res] = $_`)",
																		Value: "body",
																		Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_[$res] = $_"}},
																	},
																},
															},
															{
																Line:  353,
																Op:    ir.FilterVarContainsOp,
																Src:   "m[\"body\"].Contains(`$_ = $res;`)",
																Value: "body",
																Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_ = $res;"}},
															},
														},
													},
													{
														Line:  353,
														Op:    ir.FilterVarContainsOp,
														Src:   "m[\"body\"].Contains(`$_ := $res;`)",
														Value: "body",
														Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_ := $res;"}},
													},
												},
											},
											{
												Line:  353,
												Op:    ir.FilterVarContainsOp,
												Src:   "m[\"body\"].Contains(`var $_ = $res;`)",
												Value: "body",
												Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "var $_ = $res;"}},
											},
										},
									},
									{
										Line:  353,
										Op:    ir.FilterVarContainsOp,
										Src:   "m[\"body\"].Contains(`var $_ $_ = $res;`)",
										Value: "body",
										Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "var $_ $_ = $res;"}},
									},
								},
							}},
						},
					},
				},
				LocationVar: "res",
			}},
		},
		{
			Line:        363,
			Name:        "unstoppedTimer",
			MatcherName: "m",
			DocTags:     []string{"performance"},
			DocSummary:  "Detects unreleased timer",
			DocBefore:   "timer := time.NewTimer(time.Second); select { case <-timer.C: return nil; default: return nil }",
			DocAfter:    "timer := time.NewTimer(time.Second); defer timer.Stop(); select { case <-timer.C: return nil; default: return nil }",
			Rules: []ir.Rule{{
				Line: 372,
				SyntaxPatterns: []ir.PatternString{
					{Line: 372, Value: "$x := time.NewTimer($_); $*body"},
					{Line: 373, Value: "$x = time.NewTimer($_); $*body"},
					{Line: 374, Value: "var $x = time.NewTimer($_); $*body"},
					{Line: 375, Value: "var $x $_ = time.NewTimer($_); $*body"},
				},
				ReportTemplate: "unstopped timer",
				WhereExpr: ir.FilterExpr{
					Line: 376,
					Op:   ir.FilterAndOp,
					Src:  "!m[\"x\"].Object.IsGlobal() && !m[\"body\"].Contains(`$x.Stop()`) && !varEscapeFunction(m[\"body\"])",
					Args: []ir.FilterExpr{
						{
							Line: 376,
							Op:   ir.FilterAndOp,
							Src:  "!m[\"x\"].Object.IsGlobal() && !m[\"body\"].Contains(`$x.Stop()`)",
							Args: []ir.FilterExpr{
								{
									Line: 376,
									Op:   ir.FilterNotOp,
									Src:  "!m[\"x\"].Object.IsGlobal()",
									Args: []ir.FilterExpr{{
										Line:  376,
										Op:    ir.FilterVarObjectIsGlobalOp,
										Src:   "m[\"x\"].Object.IsGlobal()",
										Value: "x",
									}},
								},
								{
									Line: 376,
									Op:   ir.FilterNotOp,
									Src:  "!m[\"body\"].Contains(`$x.Stop()`)",
									Args: []ir.FilterExpr{{
										Line:  376,
										Op:    ir.FilterVarContainsOp,
										Src:   "m[\"body\"].Contains(`$x.Stop()`)",
										Value: "body",
										Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$x.Stop()"}},
									}},
								},
							},
						},
						{
							Line: 376,
							Op:   ir.FilterNotOp,
							Src:  "!varEscapeFunction(m[\"body\"])",
							Args: []ir.FilterExpr{{
								Line: 376,
								Op:   ir.FilterOrOp,
								Src:  "varEscapeFunction(m[\"body\"])",
								Args: []ir.FilterExpr{
									{
										Line: 376,
										Op:   ir.FilterOrOp,
										Src:  "m[\"body\"].Contains(`$_($*_, $x, $*_)`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_ <- $x`) ||\n\n\tm[\"body\"].Contains(`return $*_, $x, $*_`) ||\n\n\tm[\"body\"].Contains(`$_[$_] = $x`) ||\n\n\tm[\"body\"].Contains(`$_[$x] = $_`) ||\n\n\tm[\"body\"].Contains(`$_ = $x;`) ||\n\n\tm[\"body\"].Contains(`$_ := $x;`) ||\n\n\tm[\"body\"].Contains(`var $_ = $x;`)",
										Args: []ir.FilterExpr{
											{
												Line: 376,
												Op:   ir.FilterOrOp,
												Src:  "m[\"body\"].Contains(`$_($*_, $x, $*_)`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_ <- $x`) ||\n\n\tm[\"body\"].Contains(`return $*_, $x, $*_`) ||\n\n\tm[\"body\"].Contains(`$_[$_] = $x`) ||\n\n\tm[\"body\"].Contains(`$_[$x] = $_`) ||\n\n\tm[\"body\"].Contains(`$_ = $x;`) ||\n\n\tm[\"body\"].Contains(`$_ := $x;`)",
												Args: []ir.FilterExpr{
													{
														Line: 376,
														Op:   ir.FilterOrOp,
														Src:  "m[\"body\"].Contains(`$_($*_, $x, $*_)`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_ <- $x`) ||\n\n\tm[\"body\"].Contains(`return $*_, $x, $*_`) ||\n\n\tm[\"body\"].Contains(`$_[$_] = $x`) ||\n\n\tm[\"body\"].Contains(`$_[$x] = $_`) ||\n\n\tm[\"body\"].Contains(`$_ = $x;`)",
														Args: []ir.FilterExpr{
															{
																Line: 376,
																Op:   ir.FilterOrOp,
																Src:  "m[\"body\"].Contains(`$_($*_, $x, $*_)`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_ <- $x`) ||\n\n\tm[\"body\"].Contains(`return $*_, $x, $*_`) ||\n\n\tm[\"body\"].Contains(`$_[$_] = $x`) ||\n\n\tm[\"body\"].Contains(`$_[$x] = $_`)",
																Args: []ir.FilterExpr{
																	{
																		Line: 376,
																		Op:   ir.FilterOrOp,
																		Src:  "m[\"body\"].Contains(`$_($*_, $x, $*_)`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_ <- $x`) ||\n\n\tm[\"body\"].Contains(`return $*_, $x, $*_`) ||\n\n\tm[\"body\"].Contains(`$_[$_] = $x`)",
																		Args: []ir.FilterExpr{
																			{
																				Line: 376,
																				Op:   ir.FilterOrOp,
																				Src:  "m[\"body\"].Contains(`$_($*_, $x, $*_)`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_ <- $x`) ||\n\n\tm[\"body\"].Contains(`return $*_, $x, $*_`)",
																				Args: []ir.FilterExpr{
																					{
																						Line: 376,
																						Op:   ir.FilterOrOp,
																						Src:  "m[\"body\"].Contains(`$_($*_, $x, $*_)`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_ <- $x`)",
																						Args: []ir.FilterExpr{
																							{
																								Line: 376,
																								Op:   ir.FilterOrOp,
																								Src:  "m[\"body\"].Contains(`$_($*_, $x, $*_)`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $x, $*_}`)",
																								Args: []ir.FilterExpr{
																									{
																										Line: 376,
																										Op:   ir.FilterOrOp,
																										Src:  "m[\"body\"].Contains(`$_($*_, $x, $*_)`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $x, $*_}`)",
																										Args: []ir.FilterExpr{
																											{
																												Line:  376,
																												Op:    ir.FilterVarContainsOp,
																												Src:   "m[\"body\"].Contains(`$_($*_, $x, $*_)`)",
																												Value: "body",
																												Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_($*_, $x, $*_)"}},
																											},
																											{
																												Line:  376,
																												Op:    ir.FilterVarContainsOp,
																												Src:   "m[\"body\"].Contains(`$_{$*_, $x, $*_}`)",
																												Value: "body",
																												Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_{$*_, $x, $*_}"}},
																											},
																										},
																									},
																									{
																										Line:  376,
																										Op:    ir.FilterVarContainsOp,
																										Src:   "m[\"body\"].Contains(`$_{$*_, $_: $x, $*_}`)",
																										Value: "body",
																										Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_{$*_, $_: $x, $*_}"}},
																									},
																								},
																							},
																							{
																								Line:  376,
																								Op:    ir.FilterVarContainsOp,
																								Src:   "m[\"body\"].Contains(`$_ <- $x`)",
																								Value: "body",
																								Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_ <- $x"}},
																							},
																						},
																					},
																					{
																						Line:  376,
																						Op:    ir.FilterVarContainsOp,
																						Src:   "m[\"body\"].Contains(`return $*_, $x, $*_`)",
																						Value: "body",
																						Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "return $*_, $x, $*_"}},
																					},
																				},
																			},
																			{
																				Line:  376,
																				Op:    ir.FilterVarContainsOp,
																				Src:   "m[\"body\"].Contains(`$_[$_] = $x`)",
																				Value: "body",
																				Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_[$_] = $x"}},
																			},
																		},
																	},
																	{
																		Line:  376,
																		Op:    ir.FilterVarContainsOp,
																		Src:   "m[\"body\"].Contains(`$_[$x] = $_`)",
																		Value: "body",
																		Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_[$x] = $_"}},
																	},
																},
															},
															{
																Line:  376,
																Op:    ir.FilterVarContainsOp,
																Src:   "m[\"body\"].Contains(`$_ = $x;`)",
																Value: "body",
																Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_ = $x;"}},
															},
														},
													},
													{
														Line:  376,
														Op:    ir.FilterVarContainsOp,
														Src:   "m[\"body\"].Contains(`$_ := $x;`)",
														Value: "body",
														Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_ := $x;"}},
													},
												},
											},
											{
												Line:  376,
												Op:    ir.FilterVarContainsOp,
												Src:   "m[\"body\"].Contains(`var $_ = $x;`)",
												Value: "body",
												Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "var $_ = $x;"}},
											},
										},
									},
									{
										Line:  376,
										Op:    ir.FilterVarContainsOp,
										Src:   "m[\"body\"].Contains(`var $_ $_ = $x;`)",
										Value: "body",
										Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "var $_ $_ = $x;"}},
									},
								},
							}},
						},
					},
				},
				LocationVar: "x",
			}},
		},
		{
			Line:        385,
			Name:        "unstoppedTicker",
			MatcherName: "m",
			DocTags:     []string{"diagnostic"},
			DocSummary:  "Detects unreleased ticker",
			DocBefore:   "ticker := time.NewTicker(time.Second); select { case <-ticker.C: return nil; default: return nil }",
			DocAfter:    "ticker := time.NewTicker(time.Second); defer ticker.Stop(); select { case <-ticker.C: return nil; default: return nil }",
			Rules: []ir.Rule{{
				Line: 394,
				SyntaxPatterns: []ir.PatternString{
					{Line: 394, Value: "$x := time.NewTicker($_); $*body"},
					{Line: 395, Value: "$x = time.NewTicker($_); $*body"},
					{Line: 396, Value: "var $x = time.NewTicker($_); $*body"},
					{Line: 397, Value: "var $x $_ = time.NewTicker($_); $*body"},
				},
				ReportTemplate: "unstopped ticker",
				WhereExpr: ir.FilterExpr{
					Line: 398,
					Op:   ir.FilterAndOp,
					Src:  "!m[\"x\"].Object.IsGlobal() && !m[\"body\"].Contains(`$x.Stop()`) && !varEscapeFunction(m[\"body\"])",
					Args: []ir.FilterExpr{
						{
							Line: 398,
							Op:   ir.FilterAndOp,
							Src:  "!m[\"x\"].Object.IsGlobal() && !m[\"body\"].Contains(`$x.Stop()`)",
							Args: []ir.FilterExpr{
								{
									Line: 398,
									Op:   ir.FilterNotOp,
									Src:  "!m[\"x\"].Object.IsGlobal()",
									Args: []ir.FilterExpr{{
										Line:  398,
										Op:    ir.FilterVarObjectIsGlobalOp,
										Src:   "m[\"x\"].Object.IsGlobal()",
										Value: "x",
									}},
								},
								{
									Line: 398,
									Op:   ir.FilterNotOp,
									Src:  "!m[\"body\"].Contains(`$x.Stop()`)",
									Args: []ir.FilterExpr{{
										Line:  398,
										Op:    ir.FilterVarContainsOp,
										Src:   "m[\"body\"].Contains(`$x.Stop()`)",
										Value: "body",
										Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$x.Stop()"}},
									}},
								},
							},
						},
						{
							Line: 398,
							Op:   ir.FilterNotOp,
							Src:  "!varEscapeFunction(m[\"body\"])",
							Args: []ir.FilterExpr{{
								Line: 398,
								Op:   ir.FilterOrOp,
								Src:  "varEscapeFunction(m[\"body\"])",
								Args: []ir.FilterExpr{
									{
										Line: 398,
										Op:   ir.FilterOrOp,
										Src:  "m[\"body\"].Contains(`$_($*_, $x, $*_)`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_ <- $x`) ||\n\n\tm[\"body\"].Contains(`return $*_, $x, $*_`) ||\n\n\tm[\"body\"].Contains(`$_[$_] = $x`) ||\n\n\tm[\"body\"].Contains(`$_[$x] = $_`) ||\n\n\tm[\"body\"].Contains(`$_ = $x;`) ||\n\n\tm[\"body\"].Contains(`$_ := $x;`) ||\n\n\tm[\"body\"].Contains(`var $_ = $x;`)",
										Args: []ir.FilterExpr{
											{
												Line: 398,
												Op:   ir.FilterOrOp,
												Src:  "m[\"body\"].Contains(`$_($*_, $x, $*_)`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_ <- $x`) ||\n\n\tm[\"body\"].Contains(`return $*_, $x, $*_`) ||\n\n\tm[\"body\"].Contains(`$_[$_] = $x`) ||\n\n\tm[\"body\"].Contains(`$_[$x] = $_`) ||\n\n\tm[\"body\"].Contains(`$_ = $x;`) ||\n\n\tm[\"body\"].Contains(`$_ := $x;`)",
												Args: []ir.FilterExpr{
													{
														Line: 398,
														Op:   ir.FilterOrOp,
														Src:  "m[\"body\"].Contains(`$_($*_, $x, $*_)`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_ <- $x`) ||\n\n\tm[\"body\"].Contains(`return $*_, $x, $*_`) ||\n\n\tm[\"body\"].Contains(`$_[$_] = $x`) ||\n\n\tm[\"body\"].Contains(`$_[$x] = $_`) ||\n\n\tm[\"body\"].Contains(`$_ = $x;`)",
														Args: []ir.FilterExpr{
															{
																Line: 398,
																Op:   ir.FilterOrOp,
																Src:  "m[\"body\"].Contains(`$_($*_, $x, $*_)`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_ <- $x`) ||\n\n\tm[\"body\"].Contains(`return $*_, $x, $*_`) ||\n\n\tm[\"body\"].Contains(`$_[$_] = $x`) ||\n\n\tm[\"body\"].Contains(`$_[$x] = $_`)",
																Args: []ir.FilterExpr{
																	{
																		Line: 398,
																		Op:   ir.FilterOrOp,
																		Src:  "m[\"body\"].Contains(`$_($*_, $x, $*_)`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_ <- $x`) ||\n\n\tm[\"body\"].Contains(`return $*_, $x, $*_`) ||\n\n\tm[\"body\"].Contains(`$_[$_] = $x`)",
																		Args: []ir.FilterExpr{
																			{
																				Line: 398,
																				Op:   ir.FilterOrOp,
																				Src:  "m[\"body\"].Contains(`$_($*_, $x, $*_)`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_ <- $x`) ||\n\n\tm[\"body\"].Contains(`return $*_, $x, $*_`)",
																				Args: []ir.FilterExpr{
																					{
																						Line: 398,
																						Op:   ir.FilterOrOp,
																						Src:  "m[\"body\"].Contains(`$_($*_, $x, $*_)`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_ <- $x`)",
																						Args: []ir.FilterExpr{
																							{
																								Line: 398,
																								Op:   ir.FilterOrOp,
																								Src:  "m[\"body\"].Contains(`$_($*_, $x, $*_)`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $x, $*_}`)",
																								Args: []ir.FilterExpr{
																									{
																										Line: 398,
																										Op:   ir.FilterOrOp,
																										Src:  "m[\"body\"].Contains(`$_($*_, $x, $*_)`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $x, $*_}`)",
																										Args: []ir.FilterExpr{
																											{
																												Line:  398,
																												Op:    ir.FilterVarContainsOp,
																												Src:   "m[\"body\"].Contains(`$_($*_, $x, $*_)`)",
																												Value: "body",
																												Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_($*_, $x, $*_)"}},
																											},
																											{
																												Line:  398,
																												Op:    ir.FilterVarContainsOp,
																												Src:   "m[\"body\"].Contains(`$_{$*_, $x, $*_}`)",
																												Value: "body",
																												Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_{$*_, $x, $*_}"}},
																											},
																										},
																									},
																									{
																										Line:  398,
																										Op:    ir.FilterVarContainsOp,
																										Src:   "m[\"body\"].Contains(`$_{$*_, $_: $x, $*_}`)",
																										Value: "body",
																										Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_{$*_, $_: $x, $*_}"}},
																									},
																								},
																							},
																							{
																								Line:  398,
																								Op:    ir.FilterVarContainsOp,
																								Src:   "m[\"body\"].Contains(`$_ <- $x`)",
																								Value: "body",
																								Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_ <- $x"}},
																							},
																						},
																					},
																					{
																						Line:  398,
																						Op:    ir.FilterVarContainsOp,
																						Src:   "m[\"body\"].Contains(`return $*_, $x, $*_`)",
																						Value: "body",
																						Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "return $*_, $x, $*_"}},
																					},
																				},
																			},
																			{
																				Line:  398,
																				Op:    ir.FilterVarContainsOp,
																				Src:   "m[\"body\"].Contains(`$_[$_] = $x`)",
																				Value: "body",
																				Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_[$_] = $x"}},
																			},
																		},
																	},
																	{
																		Line:  398,
																		Op:    ir.FilterVarContainsOp,
																		Src:   "m[\"body\"].Contains(`$_[$x] = $_`)",
																		Value: "body",
																		Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_[$x] = $_"}},
																	},
																},
															},
															{
																Line:  398,
																Op:    ir.FilterVarContainsOp,
																Src:   "m[\"body\"].Contains(`$_ = $x;`)",
																Value: "body",
																Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_ = $x;"}},
															},
														},
													},
													{
														Line:  398,
														Op:    ir.FilterVarContainsOp,
														Src:   "m[\"body\"].Contains(`$_ := $x;`)",
														Value: "body",
														Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_ := $x;"}},
													},
												},
											},
											{
												Line:  398,
												Op:    ir.FilterVarContainsOp,
												Src:   "m[\"body\"].Contains(`var $_ = $x;`)",
												Value: "body",
												Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "var $_ = $x;"}},
											},
										},
									},
									{
										Line:  398,
										Op:    ir.FilterVarContainsOp,
										Src:   "m[\"body\"].Contains(`var $_ $_ = $x;`)",
										Value: "body",
										Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "var $_ $_ = $x;"}},
									},
								},
							}},
						},
					},
				},
				LocationVar: "x",
			}},
		},
		{
			Line:        407,
			Name:        "simplifyErrorCheck",
			MatcherName: "m",
			DocTags:     []string{"style"},
			DocSummary:  "Detects expressions that can be rewritten in one 'if' form",
			DocBefore:   "err := myFunc(); if err != nil { println(err) }",
			DocAfter:    "if err := myFunc(); err != nil { println(err) }",
			Rules: []ir.Rule{
				{
					Line:            408,
					SyntaxPatterns:  []ir.PatternString{{Line: 408, Value: "$err := $f($*args); if $err != nil { $*body }"}},
					ReportTemplate:  "error check can be simplified in one line",
					SuggestTemplate: "if $err := $f($args); $err != nil { $body }",
					WhereExpr: ir.FilterExpr{
						Line: 409,
						Op:   ir.FilterAndOp,
						Src:  "m[\"err\"].Type.Implements(\"error\") &&\n\tm[\"f\"].Text.Matches(\"(?s)^.{0,40}$\") && m[\"args\"].Text.Matches(\"(?s)^.{0,40}$\")",
						Args: []ir.FilterExpr{
							{
								Line: 409,
								Op:   ir.FilterAndOp,
								Src:  "m[\"err\"].Type.Implements(\"error\") &&\n\tm[\"f\"].Text.Matches(\"(?s)^.{0,40}$\")",
								Args: []ir.FilterExpr{
									{
										Line:  409,
										Op:    ir.FilterVarTypeImplementsOp,
										Src:   "m[\"err\"].Type.Implements(\"error\")",
										Value: "err",
										Args:  []ir.FilterExpr{{Line: 409, Op: ir.FilterStringOp, Src: "\"error\"", Value: "error"}},
									},
									{
										Line:  410,
										Op:    ir.FilterVarTextMatchesOp,
										Src:   "m[\"f\"].Text.Matches(\"(?s)^.{0,40}$\")",
										Value: "f",
										Args:  []ir.FilterExpr{{Line: 410, Op: ir.FilterStringOp, Src: "\"(?s)^.{0,40}$\"", Value: "(?s)^.{0,40}$"}},
									},
								},
							},
							{
								Line:  410,
								Op:    ir.FilterVarTextMatchesOp,
								Src:   "m[\"args\"].Text.Matches(\"(?s)^.{0,40}$\")",
								Value: "args",
								Args:  []ir.FilterExpr{{Line: 410, Op: ir.FilterStringOp, Src: "\"(?s)^.{0,40}$\"", Value: "(?s)^.{0,40}$"}},
							},
						},
					},
				},
				{
					Line:            414,
					SyntaxPatterns:  []ir.PatternString{{Line: 414, Value: "$err = $f($*args); if $err != nil { $*body }"}},
					ReportTemplate:  "error check can be simplified in one line",
					SuggestTemplate: "if $err = $f($args); $err != nil { $body }",
					WhereExpr: ir.FilterExpr{
						Line: 415,
						Op:   ir.FilterAndOp,
						Src:  "m[\"err\"].Type.Implements(\"error\") &&\n\tm[\"f\"].Text.Matches(\"(?s)^.{0,40}$\") && m[\"args\"].Text.Matches(\"(?s)^.{0,40}$\")",
						Args: []ir.FilterExpr{
							{
								Line: 415,
								Op:   ir.FilterAndOp,
								Src:  "m[\"err\"].Type.Implements(\"error\") &&\n\tm[\"f\"].Text.Matches(\"(?s)^.{0,40}$\")",
								Args: []ir.FilterExpr{
									{
										Line:  415,
										Op:    ir.FilterVarTypeImplementsOp,
										Src:   "m[\"err\"].Type.Implements(\"error\")",
										Value: "err",
										Args:  []ir.FilterExpr{{Line: 415, Op: ir.FilterStringOp, Src: "\"error\"", Value: "error"}},
									},
									{
										Line:  416,
										Op:    ir.FilterVarTextMatchesOp,
										Src:   "m[\"f\"].Text.Matches(\"(?s)^.{0,40}$\")",
										Value: "f",
										Args:  []ir.FilterExpr{{Line: 416, Op: ir.FilterStringOp, Src: "\"(?s)^.{0,40}$\"", Value: "(?s)^.{0,40}$"}},
									},
								},
							},
							{
								Line:  416,
								Op:    ir.FilterVarTextMatchesOp,
								Src:   "m[\"args\"].Text.Matches(\"(?s)^.{0,40}$\")",
								Value: "args",
								Args:  []ir.FilterExpr{{Line: 416, Op: ir.FilterStringOp, Src: "\"(?s)^.{0,40}$\"", Value: "(?s)^.{0,40}$"}},
							},
						},
					},
				},
				{
					Line:            420,
					SyntaxPatterns:  []ir.PatternString{{Line: 420, Value: "var $err = $f($*args); if $err != nil { $*body }"}},
					ReportTemplate:  "error check can be simplified in one line",
					SuggestTemplate: "if $err := $f($args); $err != nil { $body }",
					WhereExpr: ir.FilterExpr{
						Line: 421,
						Op:   ir.FilterAndOp,
						Src:  "m[\"err\"].Type.Implements(\"error\") &&\n\tm[\"f\"].Text.Matches(\"(?s)^.{0,40}$\") && m[\"args\"].Text.Matches(\"(?s)^.{0,40}$\")",
						Args: []ir.FilterExpr{
							{
								Line: 421,
								Op:   ir.FilterAndOp,
								Src:  "m[\"err\"].Type.Implements(\"error\") &&\n\tm[\"f\"].Text.Matches(\"(?s)^.{0,40}$\")",
								Args: []ir.FilterExpr{
									{
										Line:  421,
										Op:    ir.FilterVarTypeImplementsOp,
										Src:   "m[\"err\"].Type.Implements(\"error\")",
										Value: "err",
										Args:  []ir.FilterExpr{{Line: 421, Op: ir.FilterStringOp, Src: "\"error\"", Value: "error"}},
									},
									{
										Line:  422,
										Op:    ir.FilterVarTextMatchesOp,
										Src:   "m[\"f\"].Text.Matches(\"(?s)^.{0,40}$\")",
										Value: "f",
										Args:  []ir.FilterExpr{{Line: 422, Op: ir.FilterStringOp, Src: "\"(?s)^.{0,40}$\"", Value: "(?s)^.{0,40}$"}},
									},
								},
							},
							{
								Line:  422,
								Op:    ir.FilterVarTextMatchesOp,
								Src:   "m[\"args\"].Text.Matches(\"(?s)^.{0,40}$\")",
								Value: "args",
								Args:  []ir.FilterExpr{{Line: 422, Op: ir.FilterStringOp, Src: "\"(?s)^.{0,40}$\"", Value: "(?s)^.{0,40}$"}},
							},
						},
					},
				},
			},
		},
		{
			Line:        429,
			Name:        "syncPoolNonPtr",
			MatcherName: "m",
			DocTags:     []string{"performance"},
			DocSummary:  "Non-pointer values in sync.Pool involve extra allocation",
			Rules: []ir.Rule{{
				Line:           436,
				SyntaxPatterns: []ir.PatternString{{Line: 436, Value: "$x.Put($y)"}},
				ReportTemplate: "non-pointer values in sync.Pool involve extra allocation",
				WhereExpr: ir.FilterExpr{
					Line: 437,
					Op:   ir.FilterAndOp,
					Src:  "m[\"x\"].Type.Is(\"sync.Pool\") && !isPointer(m[\"y\"])",
					Args: []ir.FilterExpr{
						{
							Line:  437,
							Op:    ir.FilterVarTypeIsOp,
							Src:   "m[\"x\"].Type.Is(\"sync.Pool\")",
							Value: "x",
							Args:  []ir.FilterExpr{{Line: 437, Op: ir.FilterStringOp, Src: "\"sync.Pool\"", Value: "sync.Pool"}},
						},
						{
							Line: 437,
							Op:   ir.FilterNotOp,
							Src:  "!isPointer(m[\"y\"])",
							Args: []ir.FilterExpr{{
								Line: 437,
								Op:   ir.FilterOrOp,
								Src:  "isPointer(m[\"y\"])",
								Args: []ir.FilterExpr{
									{
										Line: 437,
										Op:   ir.FilterOrOp,
										Src:  "m[\"y\"].Type.Underlying().Is(\"*$_\") ||\n\n\tm[\"y\"].Type.Underlying().Is(\"chan $_\") ||\n\n\tm[\"y\"].Type.Underlying().Is(\"map[$_]$_\") ||\n\n\tm[\"y\"].Type.Underlying().Is(\"interface{$*_}\") ||\n\n\tm[\"y\"].Type.Underlying().Is(`func($*_) $*_`)",
										Args: []ir.FilterExpr{
											{
												Line: 437,
												Op:   ir.FilterOrOp,
												Src:  "m[\"y\"].Type.Underlying().Is(\"*$_\") ||\n\n\tm[\"y\"].Type.Underlying().Is(\"chan $_\") ||\n\n\tm[\"y\"].Type.Underlying().Is(\"map[$_]$_\") ||\n\n\tm[\"y\"].Type.Underlying().Is(\"interface{$*_}\")",
												Args: []ir.FilterExpr{
													{
														Line: 437,
														Op:   ir.FilterOrOp,
														Src:  "m[\"y\"].Type.Underlying().Is(\"*$_\") ||\n\n\tm[\"y\"].Type.Underlying().Is(\"chan $_\") ||\n\n\tm[\"y\"].Type.Underlying().Is(\"map[$_]$_\")",
														Args: []ir.FilterExpr{
															{
																Line: 437,
																Op:   ir.FilterOrOp,
																Src:  "m[\"y\"].Type.Underlying().Is(\"*$_\") ||\n\n\tm[\"y\"].Type.Underlying().Is(\"chan $_\")",
																Args: []ir.FilterExpr{
																	{
																		Line:  437,
																		Op:    ir.FilterVarTypeUnderlyingIsOp,
																		Src:   "m[\"y\"].Type.Underlying().Is(\"*$_\")",
																		Value: "y",
																		Args:  []ir.FilterExpr{{Line: 431, Op: ir.FilterStringOp, Src: "\"*$_\"", Value: "*$_"}},
																	},
																	{
																		Line:  437,
																		Op:    ir.FilterVarTypeUnderlyingIsOp,
																		Src:   "m[\"y\"].Type.Underlying().Is(\"chan $_\")",
																		Value: "y",
																		Args:  []ir.FilterExpr{{Line: 431, Op: ir.FilterStringOp, Src: "\"chan $_\"", Value: "chan $_"}},
																	},
																},
															},
															{
																Line:  437,
																Op:    ir.FilterVarTypeUnderlyingIsOp,
																Src:   "m[\"y\"].Type.Underlying().Is(\"map[$_]$_\")",
																Value: "y",
																Args:  []ir.FilterExpr{{Line: 432, Op: ir.FilterStringOp, Src: "\"map[$_]$_\"", Value: "map[$_]$_"}},
															},
														},
													},
													{
														Line:  437,
														Op:    ir.FilterVarTypeUnderlyingIsOp,
														Src:   "m[\"y\"].Type.Underlying().Is(\"interface{$*_}\")",
														Value: "y",
														Args:  []ir.FilterExpr{{Line: 432, Op: ir.FilterStringOp, Src: "\"interface{$*_}\"", Value: "interface{$*_}"}},
													},
												},
											},
											{
												Line:  437,
												Op:    ir.FilterVarTypeUnderlyingIsOp,
												Src:   "m[\"y\"].Type.Underlying().Is(`func($*_) $*_`)",
												Value: "y",
												Args:  []ir.FilterExpr{{Line: 433, Op: ir.FilterStringOp, Src: "`func($*_) $*_`", Value: "func($*_) $*_"}},
											},
										},
									},
									{
										Line:  437,
										Op:    ir.FilterVarTypeUnderlyingIsOp,
										Src:   "m[\"y\"].Type.Underlying().Is(`unsafe.Pointer`)",
										Value: "y",
										Args:  []ir.FilterExpr{{Line: 433, Op: ir.FilterStringOp, Src: "`unsafe.Pointer`", Value: "unsafe.Pointer"}},
									},
								},
							}},
						},
					},
				},
				LocationVar: "y",
			}},
		},
		{
			Line:        444,
			Name:        "uselessLocalConst",
			MatcherName: "m",
			DocTags:     []string{"diagnostic"},
			DocSummary:  "Detects useless local constants",
			Rules: []ir.Rule{{
				Line: 445,
				SyntaxPatterns: []ir.PatternString{
					{Line: 445, Value: "const $x = $_; $*body"},
					{Line: 445, Value: "const $x $_ = $_; $*body"},
				},
				ReportTemplate: "useless local constant",
				WhereExpr: ir.FilterExpr{
					Line: 446,
					Op:   ir.FilterAndOp,
					Src:  "!m[\"x\"].Object.IsGlobal() && !m[\"body\"].Contains(`$x`)",
					Args: []ir.FilterExpr{
						{
							Line: 446,
							Op:   ir.FilterNotOp,
							Src:  "!m[\"x\"].Object.IsGlobal()",
							Args: []ir.FilterExpr{{
								Line:  446,
								Op:    ir.FilterVarObjectIsGlobalOp,
								Src:   "m[\"x\"].Object.IsGlobal()",
								Value: "x",
							}},
						},
						{
							Line: 446,
							Op:   ir.FilterNotOp,
							Src:  "!m[\"body\"].Contains(`$x`)",
							Args: []ir.FilterExpr{{
								Line:  446,
								Op:    ir.FilterVarContainsOp,
								Src:   "m[\"body\"].Contains(`$x`)",
								Value: "body",
								Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$x"}},
							}},
						},
					},
				},
			}},
		},
		{
			Line:        452,
			Name:        "oneLineReturn",
			MatcherName: "m",
			DocTags:     []string{"style", "experimental"},
			DocSummary:  "Detects variables assigment before return that can be simplified",
			Rules: []ir.Rule{{
				Line: 459,
				SyntaxPatterns: []ir.PatternString{
					{Line: 460, Value: "var $x = $v; return $x"},
					{Line: 461, Value: "$x := $v; return $x"},
				},
				ReportTemplate:  "suggestion: return $v",
				SuggestTemplate: "return $v",
				WhereExpr: ir.FilterExpr{
					Line: 463,
					Op:   ir.FilterNotOp,
					Src:  "!isPointer(m[\"x\"])",
					Args: []ir.FilterExpr{{
						Line: 463,
						Op:   ir.FilterOrOp,
						Src:  "isPointer(m[\"x\"])",
						Args: []ir.FilterExpr{
							{
								Line: 463,
								Op:   ir.FilterOrOp,
								Src:  "m[\"x\"].Type.Underlying().Is(\"*$_\") ||\n\n\tm[\"x\"].Type.Underlying().Is(\"chan $_\") ||\n\n\tm[\"x\"].Type.Underlying().Is(\"map[$_]$_\") ||\n\n\tm[\"x\"].Type.Underlying().Is(\"interface{$*_}\") ||\n\n\tm[\"x\"].Type.Underlying().Is(`func($*_) $*_`)",
								Args: []ir.FilterExpr{
									{
										Line: 463,
										Op:   ir.FilterOrOp,
										Src:  "m[\"x\"].Type.Underlying().Is(\"*$_\") ||\n\n\tm[\"x\"].Type.Underlying().Is(\"chan $_\") ||\n\n\tm[\"x\"].Type.Underlying().Is(\"map[$_]$_\") ||\n\n\tm[\"x\"].Type.Underlying().Is(\"interface{$*_}\")",
										Args: []ir.FilterExpr{
											{
												Line: 463,
												Op:   ir.FilterOrOp,
												Src:  "m[\"x\"].Type.Underlying().Is(\"*$_\") ||\n\n\tm[\"x\"].Type.Underlying().Is(\"chan $_\") ||\n\n\tm[\"x\"].Type.Underlying().Is(\"map[$_]$_\")",
												Args: []ir.FilterExpr{
													{
														Line: 463,
														Op:   ir.FilterOrOp,
														Src:  "m[\"x\"].Type.Underlying().Is(\"*$_\") ||\n\n\tm[\"x\"].Type.Underlying().Is(\"chan $_\")",
														Args: []ir.FilterExpr{
															{
																Line:  463,
																Op:    ir.FilterVarTypeUnderlyingIsOp,
																Src:   "m[\"x\"].Type.Underlying().Is(\"*$_\")",
																Value: "x",
																Args:  []ir.FilterExpr{{Line: 454, Op: ir.FilterStringOp, Src: "\"*$_\"", Value: "*$_"}},
															},
															{
																Line:  463,
																Op:    ir.FilterVarTypeUnderlyingIsOp,
																Src:   "m[\"x\"].Type.Underlying().Is(\"chan $_\")",
																Value: "x",
																Args:  []ir.FilterExpr{{Line: 454, Op: ir.FilterStringOp, Src: "\"chan $_\"", Value: "chan $_"}},
															},
														},
													},
													{
														Line:  463,
														Op:    ir.FilterVarTypeUnderlyingIsOp,
														Src:   "m[\"x\"].Type.Underlying().Is(\"map[$_]$_\")",
														Value: "x",
														Args:  []ir.FilterExpr{{Line: 455, Op: ir.FilterStringOp, Src: "\"map[$_]$_\"", Value: "map[$_]$_"}},
													},
												},
											},
											{
												Line:  463,
												Op:    ir.FilterVarTypeUnderlyingIsOp,
												Src:   "m[\"x\"].Type.Underlying().Is(\"interface{$*_}\")",
												Value: "x",
												Args:  []ir.FilterExpr{{Line: 455, Op: ir.FilterStringOp, Src: "\"interface{$*_}\"", Value: "interface{$*_}"}},
											},
										},
									},
									{
										Line:  463,
										Op:    ir.FilterVarTypeUnderlyingIsOp,
										Src:   "m[\"x\"].Type.Underlying().Is(`func($*_) $*_`)",
										Value: "x",
										Args:  []ir.FilterExpr{{Line: 456, Op: ir.FilterStringOp, Src: "`func($*_) $*_`", Value: "func($*_) $*_"}},
									},
								},
							},
							{
								Line:  463,
								Op:    ir.FilterVarTypeUnderlyingIsOp,
								Src:   "m[\"x\"].Type.Underlying().Is(`unsafe.Pointer`)",
								Value: "x",
								Args:  []ir.FilterExpr{{Line: 456, Op: ir.FilterStringOp, Src: "`unsafe.Pointer`", Value: "unsafe.Pointer"}},
							},
						},
					}},
				},
			}},
		},
		{
			Line:        480,
			Name:        "errCheckInIf",
			MatcherName: "m",
			DocTags:     []string{"diagnostic"},
			DocSummary:  "Finds unchecked errors in if statements",
			DocBefore:   "if err := expr(); err2 != nil { /*...*/ }",
			DocAfter:    "if err := expr(); err != nil { /*...*/ }",
			Rules: []ir.Rule{{
				Line: 481,
				SyntaxPatterns: []ir.PatternString{
					{Line: 482, Value: "if $err := $_($*_); $err2 != nil { $*_ }"},
					{Line: 483, Value: "if $err = $_($*_); $err2 != nil { $*_ }"},
					{Line: 484, Value: "if $*_, $err := $_($*_); $err2 != nil { $*_ }"},
					{Line: 485, Value: "if $*_, $err = $_($*_); $err2 != nil { $*_ }"},
				},
				ReportTemplate: "returned error '$err' must be checked",
				WhereExpr: ir.FilterExpr{
					Line: 486,
					Op:   ir.FilterAndOp,
					Src:  "m[\"err\"].Type.Implements(\"error\") && m[\"err2\"].Type.Implements(\"error\") &&\n\tm[\"err\"].Text != m[\"err2\"].Text",
					Args: []ir.FilterExpr{
						{
							Line: 486,
							Op:   ir.FilterAndOp,
							Src:  "m[\"err\"].Type.Implements(\"error\") && m[\"err2\"].Type.Implements(\"error\")",
							Args: []ir.FilterExpr{
								{
									Line:  486,
									Op:    ir.FilterVarTypeImplementsOp,
									Src:   "m[\"err\"].Type.Implements(\"error\")",
									Value: "err",
									Args:  []ir.FilterExpr{{Line: 486, Op: ir.FilterStringOp, Src: "\"error\"", Value: "error"}},
								},
								{
									Line:  486,
									Op:    ir.FilterVarTypeImplementsOp,
									Src:   "m[\"err2\"].Type.Implements(\"error\")",
									Value: "err2",
									Args:  []ir.FilterExpr{{Line: 486, Op: ir.FilterStringOp, Src: "\"error\"", Value: "error"}},
								},
							},
						},
						{
							Line: 487,
							Op:   ir.FilterNeqOp,
							Src:  "m[\"err\"].Text != m[\"err2\"].Text",
							Args: []ir.FilterExpr{
								{Line: 487, Op: ir.FilterVarTextOp, Src: "m[\"err\"].Text", Value: "err"},
								{Line: 487, Op: ir.FilterVarTextOp, Src: "m[\"err2\"].Text", Value: "err2"},
							},
						},
					},
				},
			}},
		},
	},
}

Functions

This section is empty.

Types

This section is empty.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL