rulesdata

package
v0.0.2 Latest Latest
Warning

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

Go to latest
Published: Feb 9, 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:        24,
			Name:        "nestedErrorCall",
			MatcherName: "m",
			DocTags:     []string{"style"},
			DocSummary:  "Detects unnecessary nested calls for errors.New",
			DocBefore:   "errors.New(fmt.Sprintf(\"foo: %s\", \"bar\"))",
			DocAfter:    "fmt.Errorf(\"foo: %s\", \"bar\")",
			Rules: []ir.Rule{{
				Line:            25,
				SyntaxPatterns:  []ir.PatternString{{Line: 25, Value: "errors.New(fmt.Sprintf($*args))"}},
				ReportTemplate:  "use fmt.Errorf instead of nested calls",
				SuggestTemplate: "fmt.Errorf($args)",
			}},
		},
		{
			Line:        45,
			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: 46,
				SyntaxPatterns: []ir.PatternString{
					{Line: 47, Value: "$_ := $_.($_)"},
					{Line: 48, Value: "$_ = $_.($_)"},
					{Line: 49, Value: "$_($*_, $_.($_), $*_)"},
					{Line: 50, Value: "$_{$*_, $_.($_), $*_}"},
					{Line: 51, Value: "$_{$*_, $_: $_.($_), $*_}"},
					{Line: 52, Value: "$_ <- $_.($_)"},
					{Line: 53, Value: "$_{$*_, $_.($_): $_, $*_}"},
				},
				ReportTemplate: "avoid unchecked type assertions as they can panic",
			}},
		},
		{
			Line:        61,
			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: 62,
				SyntaxPatterns: []ir.PatternString{
					{Line: 62, Value: "for $_, $x := range $xs { $*_ }"},
					{Line: 62, Value: "for $_, $x = range $xs { $*_ }"},
				},
				ReportTemplate: "each iteration copies more than 256 bytes (consider pointers or indexing)",
				WhereExpr: ir.FilterExpr{
					Line: 63,
					Op:   ir.FilterAndOp,
					Src:  "(m[\"xs\"].Type.Is(\"[]$_\") || m[\"xs\"].Type.Is(\"[$_]$_\")) && m[\"x\"].Type.Size >= 256",
					Args: []ir.FilterExpr{
						{
							Line: 63,
							Op:   ir.FilterOrOp,
							Src:  "(m[\"xs\"].Type.Is(\"[]$_\") || m[\"xs\"].Type.Is(\"[$_]$_\"))",
							Args: []ir.FilterExpr{
								{
									Line:  63,
									Op:    ir.FilterVarTypeIsOp,
									Src:   "m[\"xs\"].Type.Is(\"[]$_\")",
									Value: "xs",
									Args:  []ir.FilterExpr{{Line: 63, Op: ir.FilterStringOp, Src: "\"[]$_\"", Value: "[]$_"}},
								},
								{
									Line:  63,
									Op:    ir.FilterVarTypeIsOp,
									Src:   "m[\"xs\"].Type.Is(\"[$_]$_\")",
									Value: "xs",
									Args:  []ir.FilterExpr{{Line: 63, Op: ir.FilterStringOp, Src: "\"[$_]$_\"", Value: "[$_]$_"}},
								},
							},
						},
						{
							Line: 63,
							Op:   ir.FilterGtEqOp,
							Src:  "m[\"x\"].Type.Size >= 256",
							Args: []ir.FilterExpr{
								{
									Line:  63,
									Op:    ir.FilterVarTypeSizeOp,
									Src:   "m[\"x\"].Type.Size",
									Value: "x",
								},
								{
									Line:  63,
									Op:    ir.FilterIntOp,
									Src:   "256",
									Value: int64(256),
								},
							},
						},
					},
				},
				LocationVar: "x",
			}},
		},
		{
			Line:        72,
			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: 73,
				SyntaxPatterns: []ir.PatternString{
					{Line: 73, Value: "for $_, $_ := range $x { $*_ }"},
					{Line: 74, Value: "for $_, $_ = range $x { $*_ }"},
				},
				ReportTemplate:  "copy of $x can be avoided with &$x",
				SuggestTemplate: "&$x",
				WhereExpr: ir.FilterExpr{
					Line: 75,
					Op:   ir.FilterAndOp,
					Src:  "m[\"x\"].Type.Is(\"[$_]$_\") && m[\"x\"].Type.Size >= 256",
					Args: []ir.FilterExpr{
						{
							Line:  75,
							Op:    ir.FilterVarTypeIsOp,
							Src:   "m[\"x\"].Type.Is(\"[$_]$_\")",
							Value: "x",
							Args:  []ir.FilterExpr{{Line: 75, Op: ir.FilterStringOp, Src: "\"[$_]$_\"", Value: "[$_]$_"}},
						},
						{
							Line: 75,
							Op:   ir.FilterGtEqOp,
							Src:  "m[\"x\"].Type.Size >= 256",
							Args: []ir.FilterExpr{
								{
									Line:  75,
									Op:    ir.FilterVarTypeSizeOp,
									Src:   "m[\"x\"].Type.Size",
									Value: "x",
								},
								{
									Line:  75,
									Op:    ir.FilterIntOp,
									Src:   "256",
									Value: int64(256),
								},
							},
						},
					},
				},
				LocationVar: "x",
			}},
		},
		{
			Line:        83,
			Name:        "ifacePtr",
			MatcherName: "m",
			DocTags:     []string{"performance"},
			DocSummary:  "Detects pointer to interface{}",
			Rules: []ir.Rule{{
				Line:           84,
				SyntaxPatterns: []ir.PatternString{{Line: 84, Value: "*$x"}},
				ReportTemplate: "don't use pointers to an interface",
				WhereExpr: ir.FilterExpr{
					Line:  85,
					Op:    ir.FilterVarTypeUnderlyingIsOp,
					Src:   "m[\"x\"].Type.Underlying().Is(`interface{ $*_ }`)",
					Value: "x",
					Args:  []ir.FilterExpr{{Line: 85, Op: ir.FilterStringOp, Src: "`interface{ $*_ }`", Value: "interface{ $*_ }"}},
				},
			}},
		},
		{
			Line:        93,
			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: 94,
				SyntaxPatterns: []ir.PatternString{
					{Line: 95, Value: "func $x($*_) $*_ { $*_ }"},
					{Line: 96, Value: "func ($_) $x($*_) $*_ { $*_ }"},
					{Line: 97, Value: "func ($_ $_) $x($*_) $*_ { $*_ }"},
					{Line: 98, Value: "const $x = $_"},
					{Line: 98, Value: "const $x $_ = $_"},
					{Line: 99, Value: "const ($x = $_; $*_)"},
					{Line: 100, Value: "const ($_ = $_; $x = $_; $*_)"},
					{Line: 101, Value: "const ($x $_= $_; $*_)"},
					{Line: 102, Value: "const ($_ $_ = $_; $x $_= $_; $*_)"},
					{Line: 103, Value: "type $x $_"},
					{Line: 104, Value: "$x := $_"},
					{Line: 105, Value: "var $x = $_"},
					{Line: 106, Value: "var $x $_ = $_"},
				},
				ReportTemplate: "use camelCase naming strategy",
				WhereExpr: ir.FilterExpr{
					Line: 108,
					Op:   ir.FilterAndOp,
					Src:  "!m[\"x\"].Text.Matches(`^_$`) && (m[\"x\"].Text.Matches(`-|_`))",
					Args: []ir.FilterExpr{
						{
							Line: 108,
							Op:   ir.FilterNotOp,
							Src:  "!m[\"x\"].Text.Matches(`^_$`)",
							Args: []ir.FilterExpr{{
								Line:  108,
								Op:    ir.FilterVarTextMatchesOp,
								Src:   "m[\"x\"].Text.Matches(`^_$`)",
								Value: "x",
								Args:  []ir.FilterExpr{{Line: 108, Op: ir.FilterStringOp, Src: "`^_$`", Value: "^_$"}},
							}},
						},
						{
							Line:  108,
							Op:    ir.FilterVarTextMatchesOp,
							Src:   "(m[\"x\"].Text.Matches(`-|_`))",
							Value: "x",
							Args:  []ir.FilterExpr{{Line: 108, Op: ir.FilterStringOp, Src: "`-|_`", Value: "-|_"}},
						},
					},
				},
				LocationVar: "x",
			}},
		},
		{
			Line:        117,
			Name:        "notInformativePackageNaming",
			MatcherName: "m",
			DocTags:     []string{"style"},
			DocSummary:  "Detects general names for package",
			DocBefore:   "package lib",
			DocAfter:    "package concreteLib",
			Rules: []ir.Rule{{
				Line:           118,
				SyntaxPatterns: []ir.PatternString{{Line: 118, Value: "package $x"}},
				ReportTemplate: "don't use general names to package naming",
				WhereExpr: ir.FilterExpr{
					Line: 119,
					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: 119,
							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: 119,
									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:  119,
											Op:    ir.FilterVarTextMatchesOp,
											Src:   "m[\"x\"].Text.Matches(`(^c|C|_(c|C))ommon([A-Z]|_|$|\\d)`)",
											Value: "x",
											Args:  []ir.FilterExpr{{Line: 119, Op: ir.FilterStringOp, Src: "`(^c|C|_(c|C))ommon([A-Z]|_|$|\\d)`", Value: "(^c|C|_(c|C))ommon([A-Z]|_|$|\\d)"}},
										},
										{
											Line:  120,
											Op:    ir.FilterVarTextMatchesOp,
											Src:   "m[\"x\"].Text.Matches(`(^l|L|_(l|L))ib([A-Z]|_|$|\\d)`)",
											Value: "x",
											Args:  []ir.FilterExpr{{Line: 120, Op: ir.FilterStringOp, Src: "`(^l|L|_(l|L))ib([A-Z]|_|$|\\d)`", Value: "(^l|L|_(l|L))ib([A-Z]|_|$|\\d)"}},
										},
									},
								},
								{
									Line:  121,
									Op:    ir.FilterVarTextMatchesOp,
									Src:   "m[\"x\"].Text.Matches(`(^u|U|_(u|U))til([A-Z]|_|$|\\d)`)",
									Value: "x",
									Args:  []ir.FilterExpr{{Line: 121, Op: ir.FilterStringOp, Src: "`(^u|U|_(u|U))til([A-Z]|_|$|\\d)`", Value: "(^u|U|_(u|U))til([A-Z]|_|$|\\d)"}},
								},
							},
						},
						{
							Line:  122,
							Op:    ir.FilterVarTextMatchesOp,
							Src:   "m[\"x\"].Text.Matches(`(^s|S|_(s|S))hared([A-Z]|_|$|\\d)`)",
							Value: "x",
							Args:  []ir.FilterExpr{{Line: 122, Op: ir.FilterStringOp, Src: "`(^s|S|_(s|S))hared([A-Z]|_|$|\\d)`", Value: "(^s|S|_(s|S))hared([A-Z]|_|$|\\d)"}},
						},
					},
				},
				LocationVar: "x",
			}},
		},
		{
			Line:        131,
			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: 132,
				SyntaxPatterns: []ir.PatternString{
					{Line: 133, Value: "func ($x $_) $name($*_) $*_ { return $x.$_ }"},
					{Line: 134, Value: "func ($x $_) $name($*_) $*_ { return $_($x.$_) }"},
					{Line: 135, Value: "func ($x $_) $name($*_) $*_ { return $_($x) }"},
					{Line: 136, Value: "func ($x $_) $name($*_) $*_ { return $_(*$x) }"},
				},
				ReportTemplate: "don't use 'get' in getter functions",
				WhereExpr: ir.FilterExpr{
					Line:  138,
					Op:    ir.FilterVarTextMatchesOp,
					Src:   "m[\"name\"].Text.Matches(`(^g|G|_(g|G))et([A-Z]|$|_|\\d)`)",
					Value: "name",
					Args:  []ir.FilterExpr{{Line: 138, Op: ir.FilterStringOp, Src: "`(^g|G|_(g|G))et([A-Z]|$|_|\\d)`", Value: "(^g|G|_(g|G))et([A-Z]|$|_|\\d)"}},
				},
				LocationVar: "name",
			}},
		},
		{
			Line:        155,
			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:           156,
				SyntaxPatterns: []ir.PatternString{{Line: 156, Value: "type $name interface{ $*_ }"}},
				ReportTemplate: "don't use 'interface' word' in interface declaration'",
				WhereExpr: ir.FilterExpr{
					Line:  157,
					Op:    ir.FilterVarTextMatchesOp,
					Src:   "m[\"name\"].Text.Matches(`(^i|I|_(i|I))nterface([A-Z]|_|$|\\d)`)",
					Value: "name",
					Args:  []ir.FilterExpr{{Line: 157, Op: ir.FilterStringOp, Src: "`(^i|I|_(i|I))nterface([A-Z]|_|$|\\d)`", Value: "(^i|I|_(i|I))nterface([A-Z]|_|$|\\d)"}},
				},
				LocationVar: "name",
			}},
		},
		{
			Line:        168,
			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: 169,
				SyntaxPatterns: []ir.PatternString{
					{Line: 169, Value: "if $*_, $err = $_; $err != nil { return $err }; return nil"},
					{Line: 170, Value: "if $*_, $err := $_; $err != nil { return $err }; return nil"},
					{Line: 171, Value: "$*_, $err = $_; if $err != nil { return $err }; return nil"},
					{Line: 172, Value: "var $*_, $err = $_; if $err != nil { return $err }; return nil"},
					{Line: 173, Value: "$*_, $err := $_; if $err != nil { return $err }; return nil"},
					{Line: 174, Value: "if $*_, $err = $_; $err != nil { return $err }; return $err"},
					{Line: 175, Value: "if $*_, $err := $_; $err != nil { return $err }; return $err"},
					{Line: 176, Value: "$*_, $err = $_; if $err != nil { return $err }; return $err"},
					{Line: 177, Value: "var $*_, $err = $_; if $err != nil { return $err }; return $err"},
					{Line: 178, Value: "$*_, $err := $_; if $err != nil { return $err }; return $err"},
				},
				ReportTemplate: "may be simplified to return error without if statement",
				WhereExpr: ir.FilterExpr{
					Line:  180,
					Op:    ir.FilterVarTypeImplementsOp,
					Src:   "m[\"err\"].Type.Implements(\"error\")",
					Value: "err",
					Args:  []ir.FilterExpr{{Line: 180, Op: ir.FilterStringOp, Src: "\"error\"", Value: "error"}},
				},
			}},
		},
		{
			Line:        238,
			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: 239,
				SyntaxPatterns: []ir.PatternString{
					{Line: 240, Value: "for $*_; $*_; $*_ { $*_; defer func($*args) $*_ { $*_ }($*_); $*_ }"},
					{Line: 241, Value: "for $*_; $*_; $*_ { $*_; defer $_($*args); $*_ }"},
					{Line: 243, Value: "for { $*_; defer func($*args) $*_ { $*_ }($*_); $*_ }"},
					{Line: 244, Value: "for { $*_; defer $_($*args); $*_ }"},
					{Line: 246, Value: "for $_, $_ := range $_ { $*_; defer func($*args) $*_ { $*_ }($*_); $*_ }"},
					{Line: 247, Value: "for $_, $_ := range $_ { $*_; defer $_($*args); $*_ }"},
					{Line: 249, Value: "for $_, $_ = range $_ { $*_; defer func($*args) $*_ { $*_ }($*_); $*_ }"},
					{Line: 250, Value: "for $_, $_ = range $_ { $*_; defer $_($*args); $*_ }"},
					{Line: 252, Value: "for $_ := range $_ { $*_; defer func($*args) $*_ { $*_ }($*_); $*_ }"},
					{Line: 253, Value: "for $_ := range $_ { $*_; defer $_($*args); $*_ }"},
					{Line: 255, Value: "for $_ = range $_ { $*_; defer func($*args) $*_ { $*_ }($*_); $*_ }"},
					{Line: 256, Value: "for $_ = range $_ { $*_; defer $_($*args); $*_ }"},
					{Line: 258, Value: "for range $_ { $*_; defer func($*args) $*_ { $*_ }($*_); $*_ }"},
					{Line: 259, Value: "for range $_ { $*_; defer $_($*args); $*_ }"},
				},
				ReportTemplate: "Possible resource leak, 'defer' is called in the 'for' loop",
				LocationVar:    "args",
			}},
		},
		{
			Line:        312,
			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: 313,
				SyntaxPatterns: []ir.PatternString{
					{Line: 314, Value: "for $*_; $*_; $*_ { $*_; $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 315, Value: "for { $*_; $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 316, Value: "for $_, $_ := range $_ { $*_; $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 317, Value: "for $_, $_ = range $_ { $*_; $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 318, Value: "for $_ := range $_ { $*_; $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 319, Value: "for $_ = range $_ { $*_; $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 320, Value: "for range $_ { $*_; $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 322, Value: "for $*_; $*_; $*_ { $*_; $*_ := regexp.$method($s, $*args); $*_ }"},
					{Line: 323, Value: "for { $*_; $*_ := regexp.$method($s, $*args); $*_ }"},
					{Line: 324, Value: "for $_, $_ := range $_ { $*_; $*_ := regexp.$method($s, $*args); $*_ }"},
					{Line: 325, Value: "for $_, $_ = range $_ { $*_; $*_ := regexp.$method($s, $*args); $*_ }"},
					{Line: 326, Value: "for $_ := range $_ { $*_; $*_ := regexp.$method($s, $*args); $*_ }"},
					{Line: 327, Value: "for $_ = range $_ { $*_; $*_ := regexp.$method($s, $*args); $*_ }"},
					{Line: 328, Value: "for range $_ { $*_; $*_ := regexp.$method($s, $*args); $*_ }"},
					{Line: 330, Value: "for $*_; $*_; $*_ { $*_; var $*_ $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 331, Value: "for { $*_; var $*_ $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 332, Value: "for $_, $_ := range $_ { $*_; var $*_ $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 333, Value: "for $_, $_ = range $_ { $*_; var $*_ $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 334, Value: "for $_ := range $_ { $*_; var $*_ $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 335, Value: "for $_ = range $_ { $*_; var $*_ $*_ = regexp.$method($s, $*args); $*_ }"},
					{Line: 336, 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: 339,
					Op:   ir.FilterAndOp,
					Src:  "m[\"s\"].Const && !m[\"method\"].Contains(`QuoteMeta`)",
					Args: []ir.FilterExpr{
						{
							Line:  339,
							Op:    ir.FilterVarConstOp,
							Src:   "m[\"s\"].Const",
							Value: "s",
						},
						{
							Line: 339,
							Op:   ir.FilterNotOp,
							Src:  "!m[\"method\"].Contains(`QuoteMeta`)",
							Args: []ir.FilterExpr{{
								Line:  339,
								Op:    ir.FilterVarContainsOp,
								Src:   "m[\"method\"].Contains(`QuoteMeta`)",
								Value: "method",
								Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "QuoteMeta"}},
							}},
						},
					},
				},
				LocationVar: "s",
			}},
		},
		{
			Line:        347,
			Name:        "unclosedResource",
			MatcherName: "m",
			DocTags:     []string{"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: 356,
				SyntaxPatterns: []ir.PatternString{
					{Line: 356, Value: "$res, $err := $_($*_); $*body"},
					{Line: 357, Value: "$res, $err = $_($*_); $*body"},
					{Line: 358, Value: "var $res, $err = $_($*_); $*body"},
				},
				ReportTemplate: "$res.Close() should be deferred right after the resource creation",
				WhereExpr: ir.FilterExpr{
					Line: 361,
					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: 361,
							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: 361,
									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: 361,
											Op:   ir.FilterAndOp,
											Src:  "m[\"res\"].Type.Implements(`io.Closer`) &&\n\t!m[\"res\"].Object.IsGlobal()",
											Args: []ir.FilterExpr{
												{
													Line:  361,
													Op:    ir.FilterVarTypeImplementsOp,
													Src:   "m[\"res\"].Type.Implements(`io.Closer`)",
													Value: "res",
													Args:  []ir.FilterExpr{{Line: 361, Op: ir.FilterStringOp, Src: "`io.Closer`", Value: "io.Closer"}},
												},
												{
													Line: 362,
													Op:   ir.FilterNotOp,
													Src:  "!m[\"res\"].Object.IsGlobal()",
													Args: []ir.FilterExpr{{
														Line:  362,
														Op:    ir.FilterVarObjectIsGlobalOp,
														Src:   "m[\"res\"].Object.IsGlobal()",
														Value: "res",
													}},
												},
											},
										},
										{
											Line:  363,
											Op:    ir.FilterVarTypeImplementsOp,
											Src:   "m[\"err\"].Type.Implements(`error`)",
											Value: "err",
											Args:  []ir.FilterExpr{{Line: 363, Op: ir.FilterStringOp, Src: "`error`", Value: "error"}},
										},
									},
								},
								{
									Line: 364,
									Op:   ir.FilterNotOp,
									Src:  "!m[\"body\"].Contains(`$res.Close()`)",
									Args: []ir.FilterExpr{{
										Line:  364,
										Op:    ir.FilterVarContainsOp,
										Src:   "m[\"body\"].Contains(`$res.Close()`)",
										Value: "body",
										Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$res.Close()"}},
									}},
								},
							},
						},
						{
							Line: 365,
							Op:   ir.FilterNotOp,
							Src:  "!varEscapeFunction(m[\"body\"])",
							Args: []ir.FilterExpr{{
								Line: 365,
								Op:   ir.FilterOrOp,
								Src:  "varEscapeFunction(m[\"body\"])",
								Args: []ir.FilterExpr{
									{
										Line: 365,
										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: 365,
												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: 365,
														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: 365,
																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: 365,
																		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: 365,
																				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: 365,
																						Op:   ir.FilterOrOp,
																						Src:  "m[\"body\"].Contains(`$_{$*_, $res, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $res, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_ <- $res`)",
																						Args: []ir.FilterExpr{
																							{
																								Line: 365,
																								Op:   ir.FilterOrOp,
																								Src:  "m[\"body\"].Contains(`$_{$*_, $res, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $res, $*_}`)",
																								Args: []ir.FilterExpr{
																									{
																										Line:  365,
																										Op:    ir.FilterVarContainsOp,
																										Src:   "m[\"body\"].Contains(`$_{$*_, $res, $*_}`)",
																										Value: "body",
																										Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_{$*_, $res, $*_}"}},
																									},
																									{
																										Line:  365,
																										Op:    ir.FilterVarContainsOp,
																										Src:   "m[\"body\"].Contains(`$_{$*_, $_: $res, $*_}`)",
																										Value: "body",
																										Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_{$*_, $_: $res, $*_}"}},
																									},
																								},
																							},
																							{
																								Line:  365,
																								Op:    ir.FilterVarContainsOp,
																								Src:   "m[\"body\"].Contains(`$_ <- $res`)",
																								Value: "body",
																								Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_ <- $res"}},
																							},
																						},
																					},
																					{
																						Line:  365,
																						Op:    ir.FilterVarContainsOp,
																						Src:   "m[\"body\"].Contains(`return $*_, $res, $*_`)",
																						Value: "body",
																						Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "return $*_, $res, $*_"}},
																					},
																				},
																			},
																			{
																				Line:  365,
																				Op:    ir.FilterVarContainsOp,
																				Src:   "m[\"body\"].Contains(`$_[$_] = $res`)",
																				Value: "body",
																				Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_[$_] = $res"}},
																			},
																		},
																	},
																	{
																		Line:  365,
																		Op:    ir.FilterVarContainsOp,
																		Src:   "m[\"body\"].Contains(`$_[$res] = $_`)",
																		Value: "body",
																		Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_[$res] = $_"}},
																	},
																},
															},
															{
																Line:  365,
																Op:    ir.FilterVarContainsOp,
																Src:   "m[\"body\"].Contains(`$_ = $res;`)",
																Value: "body",
																Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_ = $res;"}},
															},
														},
													},
													{
														Line:  365,
														Op:    ir.FilterVarContainsOp,
														Src:   "m[\"body\"].Contains(`$_ := $res;`)",
														Value: "body",
														Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_ := $res;"}},
													},
												},
											},
											{
												Line:  365,
												Op:    ir.FilterVarContainsOp,
												Src:   "m[\"body\"].Contains(`var $_ = $res;`)",
												Value: "body",
												Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "var $_ = $res;"}},
											},
										},
									},
									{
										Line:  365,
										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:        375,
			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: 384,
				SyntaxPatterns: []ir.PatternString{
					{Line: 384, Value: "$x := time.NewTimer($_); $*body"},
					{Line: 385, Value: "$x = time.NewTimer($_); $*body"},
					{Line: 386, Value: "var $x = time.NewTimer($_); $*body"},
					{Line: 387, Value: "var $x $_ = time.NewTimer($_); $*body"},
				},
				ReportTemplate: "unstopped timer",
				WhereExpr: ir.FilterExpr{
					Line: 388,
					Op:   ir.FilterAndOp,
					Src:  "!m[\"x\"].Object.IsGlobal() && !m[\"body\"].Contains(`$x.Stop()`) && !varEscapeFunction(m[\"body\"])",
					Args: []ir.FilterExpr{
						{
							Line: 388,
							Op:   ir.FilterAndOp,
							Src:  "!m[\"x\"].Object.IsGlobal() && !m[\"body\"].Contains(`$x.Stop()`)",
							Args: []ir.FilterExpr{
								{
									Line: 388,
									Op:   ir.FilterNotOp,
									Src:  "!m[\"x\"].Object.IsGlobal()",
									Args: []ir.FilterExpr{{
										Line:  388,
										Op:    ir.FilterVarObjectIsGlobalOp,
										Src:   "m[\"x\"].Object.IsGlobal()",
										Value: "x",
									}},
								},
								{
									Line: 388,
									Op:   ir.FilterNotOp,
									Src:  "!m[\"body\"].Contains(`$x.Stop()`)",
									Args: []ir.FilterExpr{{
										Line:  388,
										Op:    ir.FilterVarContainsOp,
										Src:   "m[\"body\"].Contains(`$x.Stop()`)",
										Value: "body",
										Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$x.Stop()"}},
									}},
								},
							},
						},
						{
							Line: 388,
							Op:   ir.FilterNotOp,
							Src:  "!varEscapeFunction(m[\"body\"])",
							Args: []ir.FilterExpr{{
								Line: 388,
								Op:   ir.FilterOrOp,
								Src:  "varEscapeFunction(m[\"body\"])",
								Args: []ir.FilterExpr{
									{
										Line: 388,
										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: 388,
												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: 388,
														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: 388,
																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: 388,
																		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: 388,
																				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: 388,
																						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: 388,
																								Op:   ir.FilterOrOp,
																								Src:  "m[\"body\"].Contains(`$_($*_, $x, $*_)`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $x, $*_}`)",
																								Args: []ir.FilterExpr{
																									{
																										Line: 388,
																										Op:   ir.FilterOrOp,
																										Src:  "m[\"body\"].Contains(`$_($*_, $x, $*_)`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $x, $*_}`)",
																										Args: []ir.FilterExpr{
																											{
																												Line:  388,
																												Op:    ir.FilterVarContainsOp,
																												Src:   "m[\"body\"].Contains(`$_($*_, $x, $*_)`)",
																												Value: "body",
																												Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_($*_, $x, $*_)"}},
																											},
																											{
																												Line:  388,
																												Op:    ir.FilterVarContainsOp,
																												Src:   "m[\"body\"].Contains(`$_{$*_, $x, $*_}`)",
																												Value: "body",
																												Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_{$*_, $x, $*_}"}},
																											},
																										},
																									},
																									{
																										Line:  388,
																										Op:    ir.FilterVarContainsOp,
																										Src:   "m[\"body\"].Contains(`$_{$*_, $_: $x, $*_}`)",
																										Value: "body",
																										Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_{$*_, $_: $x, $*_}"}},
																									},
																								},
																							},
																							{
																								Line:  388,
																								Op:    ir.FilterVarContainsOp,
																								Src:   "m[\"body\"].Contains(`$_ <- $x`)",
																								Value: "body",
																								Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_ <- $x"}},
																							},
																						},
																					},
																					{
																						Line:  388,
																						Op:    ir.FilterVarContainsOp,
																						Src:   "m[\"body\"].Contains(`return $*_, $x, $*_`)",
																						Value: "body",
																						Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "return $*_, $x, $*_"}},
																					},
																				},
																			},
																			{
																				Line:  388,
																				Op:    ir.FilterVarContainsOp,
																				Src:   "m[\"body\"].Contains(`$_[$_] = $x`)",
																				Value: "body",
																				Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_[$_] = $x"}},
																			},
																		},
																	},
																	{
																		Line:  388,
																		Op:    ir.FilterVarContainsOp,
																		Src:   "m[\"body\"].Contains(`$_[$x] = $_`)",
																		Value: "body",
																		Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_[$x] = $_"}},
																	},
																},
															},
															{
																Line:  388,
																Op:    ir.FilterVarContainsOp,
																Src:   "m[\"body\"].Contains(`$_ = $x;`)",
																Value: "body",
																Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_ = $x;"}},
															},
														},
													},
													{
														Line:  388,
														Op:    ir.FilterVarContainsOp,
														Src:   "m[\"body\"].Contains(`$_ := $x;`)",
														Value: "body",
														Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_ := $x;"}},
													},
												},
											},
											{
												Line:  388,
												Op:    ir.FilterVarContainsOp,
												Src:   "m[\"body\"].Contains(`var $_ = $x;`)",
												Value: "body",
												Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "var $_ = $x;"}},
											},
										},
									},
									{
										Line:  388,
										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:        397,
			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: 406,
				SyntaxPatterns: []ir.PatternString{
					{Line: 406, Value: "$x := time.NewTicker($_); $*body"},
					{Line: 407, Value: "$x = time.NewTicker($_); $*body"},
					{Line: 408, Value: "var $x = time.NewTicker($_); $*body"},
					{Line: 409, Value: "var $x $_ = time.NewTicker($_); $*body"},
				},
				ReportTemplate: "unstopped ticker",
				WhereExpr: ir.FilterExpr{
					Line: 410,
					Op:   ir.FilterAndOp,
					Src:  "!m[\"x\"].Object.IsGlobal() && !m[\"body\"].Contains(`$x.Stop()`) && !varEscapeFunction(m[\"body\"])",
					Args: []ir.FilterExpr{
						{
							Line: 410,
							Op:   ir.FilterAndOp,
							Src:  "!m[\"x\"].Object.IsGlobal() && !m[\"body\"].Contains(`$x.Stop()`)",
							Args: []ir.FilterExpr{
								{
									Line: 410,
									Op:   ir.FilterNotOp,
									Src:  "!m[\"x\"].Object.IsGlobal()",
									Args: []ir.FilterExpr{{
										Line:  410,
										Op:    ir.FilterVarObjectIsGlobalOp,
										Src:   "m[\"x\"].Object.IsGlobal()",
										Value: "x",
									}},
								},
								{
									Line: 410,
									Op:   ir.FilterNotOp,
									Src:  "!m[\"body\"].Contains(`$x.Stop()`)",
									Args: []ir.FilterExpr{{
										Line:  410,
										Op:    ir.FilterVarContainsOp,
										Src:   "m[\"body\"].Contains(`$x.Stop()`)",
										Value: "body",
										Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$x.Stop()"}},
									}},
								},
							},
						},
						{
							Line: 410,
							Op:   ir.FilterNotOp,
							Src:  "!varEscapeFunction(m[\"body\"])",
							Args: []ir.FilterExpr{{
								Line: 410,
								Op:   ir.FilterOrOp,
								Src:  "varEscapeFunction(m[\"body\"])",
								Args: []ir.FilterExpr{
									{
										Line: 410,
										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: 410,
												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: 410,
														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: 410,
																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: 410,
																		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: 410,
																				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: 410,
																						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: 410,
																								Op:   ir.FilterOrOp,
																								Src:  "m[\"body\"].Contains(`$_($*_, $x, $*_)`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $x, $*_}`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $_: $x, $*_}`)",
																								Args: []ir.FilterExpr{
																									{
																										Line: 410,
																										Op:   ir.FilterOrOp,
																										Src:  "m[\"body\"].Contains(`$_($*_, $x, $*_)`) ||\n\n\tm[\"body\"].Contains(`$_{$*_, $x, $*_}`)",
																										Args: []ir.FilterExpr{
																											{
																												Line:  410,
																												Op:    ir.FilterVarContainsOp,
																												Src:   "m[\"body\"].Contains(`$_($*_, $x, $*_)`)",
																												Value: "body",
																												Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_($*_, $x, $*_)"}},
																											},
																											{
																												Line:  410,
																												Op:    ir.FilterVarContainsOp,
																												Src:   "m[\"body\"].Contains(`$_{$*_, $x, $*_}`)",
																												Value: "body",
																												Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_{$*_, $x, $*_}"}},
																											},
																										},
																									},
																									{
																										Line:  410,
																										Op:    ir.FilterVarContainsOp,
																										Src:   "m[\"body\"].Contains(`$_{$*_, $_: $x, $*_}`)",
																										Value: "body",
																										Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_{$*_, $_: $x, $*_}"}},
																									},
																								},
																							},
																							{
																								Line:  410,
																								Op:    ir.FilterVarContainsOp,
																								Src:   "m[\"body\"].Contains(`$_ <- $x`)",
																								Value: "body",
																								Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_ <- $x"}},
																							},
																						},
																					},
																					{
																						Line:  410,
																						Op:    ir.FilterVarContainsOp,
																						Src:   "m[\"body\"].Contains(`return $*_, $x, $*_`)",
																						Value: "body",
																						Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "return $*_, $x, $*_"}},
																					},
																				},
																			},
																			{
																				Line:  410,
																				Op:    ir.FilterVarContainsOp,
																				Src:   "m[\"body\"].Contains(`$_[$_] = $x`)",
																				Value: "body",
																				Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_[$_] = $x"}},
																			},
																		},
																	},
																	{
																		Line:  410,
																		Op:    ir.FilterVarContainsOp,
																		Src:   "m[\"body\"].Contains(`$_[$x] = $_`)",
																		Value: "body",
																		Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_[$x] = $_"}},
																	},
																},
															},
															{
																Line:  410,
																Op:    ir.FilterVarContainsOp,
																Src:   "m[\"body\"].Contains(`$_ = $x;`)",
																Value: "body",
																Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_ = $x;"}},
															},
														},
													},
													{
														Line:  410,
														Op:    ir.FilterVarContainsOp,
														Src:   "m[\"body\"].Contains(`$_ := $x;`)",
														Value: "body",
														Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$_ := $x;"}},
													},
												},
											},
											{
												Line:  410,
												Op:    ir.FilterVarContainsOp,
												Src:   "m[\"body\"].Contains(`var $_ = $x;`)",
												Value: "body",
												Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "var $_ = $x;"}},
											},
										},
									},
									{
										Line:  410,
										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:        419,
			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:            420,
					SyntaxPatterns:  []ir.PatternString{{Line: 420, 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: 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:            426,
					SyntaxPatterns:  []ir.PatternString{{Line: 426, 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: 427,
						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: 427,
								Op:   ir.FilterAndOp,
								Src:  "m[\"err\"].Type.Implements(\"error\") &&\n\tm[\"f\"].Text.Matches(\"(?s)^.{0,40}$\")",
								Args: []ir.FilterExpr{
									{
										Line:  427,
										Op:    ir.FilterVarTypeImplementsOp,
										Src:   "m[\"err\"].Type.Implements(\"error\")",
										Value: "err",
										Args:  []ir.FilterExpr{{Line: 427, Op: ir.FilterStringOp, Src: "\"error\"", Value: "error"}},
									},
									{
										Line:  428,
										Op:    ir.FilterVarTextMatchesOp,
										Src:   "m[\"f\"].Text.Matches(\"(?s)^.{0,40}$\")",
										Value: "f",
										Args:  []ir.FilterExpr{{Line: 428, Op: ir.FilterStringOp, Src: "\"(?s)^.{0,40}$\"", Value: "(?s)^.{0,40}$"}},
									},
								},
							},
							{
								Line:  428,
								Op:    ir.FilterVarTextMatchesOp,
								Src:   "m[\"args\"].Text.Matches(\"(?s)^.{0,40}$\")",
								Value: "args",
								Args:  []ir.FilterExpr{{Line: 428, Op: ir.FilterStringOp, Src: "\"(?s)^.{0,40}$\"", Value: "(?s)^.{0,40}$"}},
							},
						},
					},
				},
				{
					Line:            432,
					SyntaxPatterns:  []ir.PatternString{{Line: 432, 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: 433,
						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: 433,
								Op:   ir.FilterAndOp,
								Src:  "m[\"err\"].Type.Implements(\"error\") &&\n\tm[\"f\"].Text.Matches(\"(?s)^.{0,40}$\")",
								Args: []ir.FilterExpr{
									{
										Line:  433,
										Op:    ir.FilterVarTypeImplementsOp,
										Src:   "m[\"err\"].Type.Implements(\"error\")",
										Value: "err",
										Args:  []ir.FilterExpr{{Line: 433, Op: ir.FilterStringOp, Src: "\"error\"", Value: "error"}},
									},
									{
										Line:  434,
										Op:    ir.FilterVarTextMatchesOp,
										Src:   "m[\"f\"].Text.Matches(\"(?s)^.{0,40}$\")",
										Value: "f",
										Args:  []ir.FilterExpr{{Line: 434, Op: ir.FilterStringOp, Src: "\"(?s)^.{0,40}$\"", Value: "(?s)^.{0,40}$"}},
									},
								},
							},
							{
								Line:  434,
								Op:    ir.FilterVarTextMatchesOp,
								Src:   "m[\"args\"].Text.Matches(\"(?s)^.{0,40}$\")",
								Value: "args",
								Args:  []ir.FilterExpr{{Line: 434, Op: ir.FilterStringOp, Src: "\"(?s)^.{0,40}$\"", Value: "(?s)^.{0,40}$"}},
							},
						},
					},
				},
			},
		},
		{
			Line:        441,
			Name:        "syncPoolNonPtr",
			MatcherName: "m",
			DocTags:     []string{"performance"},
			DocSummary:  "Non-pointer values in sync.Pool involve extra allocation",
			Rules: []ir.Rule{{
				Line:           448,
				SyntaxPatterns: []ir.PatternString{{Line: 448, Value: "$x.Put($y)"}},
				ReportTemplate: "non-pointer values in sync.Pool involve extra allocation",
				WhereExpr: ir.FilterExpr{
					Line: 449,
					Op:   ir.FilterAndOp,
					Src:  "m[\"x\"].Type.Is(\"sync.Pool\") && !isPointer(m[\"y\"])",
					Args: []ir.FilterExpr{
						{
							Line:  449,
							Op:    ir.FilterVarTypeIsOp,
							Src:   "m[\"x\"].Type.Is(\"sync.Pool\")",
							Value: "x",
							Args:  []ir.FilterExpr{{Line: 449, Op: ir.FilterStringOp, Src: "\"sync.Pool\"", Value: "sync.Pool"}},
						},
						{
							Line: 449,
							Op:   ir.FilterNotOp,
							Src:  "!isPointer(m[\"y\"])",
							Args: []ir.FilterExpr{{
								Line: 449,
								Op:   ir.FilterOrOp,
								Src:  "isPointer(m[\"y\"])",
								Args: []ir.FilterExpr{
									{
										Line: 449,
										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: 449,
												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: 449,
														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: 449,
																Op:   ir.FilterOrOp,
																Src:  "m[\"y\"].Type.Underlying().Is(\"*$_\") ||\n\n\tm[\"y\"].Type.Underlying().Is(\"chan $_\")",
																Args: []ir.FilterExpr{
																	{
																		Line:  449,
																		Op:    ir.FilterVarTypeUnderlyingIsOp,
																		Src:   "m[\"y\"].Type.Underlying().Is(\"*$_\")",
																		Value: "y",
																		Args:  []ir.FilterExpr{{Line: 443, Op: ir.FilterStringOp, Src: "\"*$_\"", Value: "*$_"}},
																	},
																	{
																		Line:  449,
																		Op:    ir.FilterVarTypeUnderlyingIsOp,
																		Src:   "m[\"y\"].Type.Underlying().Is(\"chan $_\")",
																		Value: "y",
																		Args:  []ir.FilterExpr{{Line: 443, Op: ir.FilterStringOp, Src: "\"chan $_\"", Value: "chan $_"}},
																	},
																},
															},
															{
																Line:  449,
																Op:    ir.FilterVarTypeUnderlyingIsOp,
																Src:   "m[\"y\"].Type.Underlying().Is(\"map[$_]$_\")",
																Value: "y",
																Args:  []ir.FilterExpr{{Line: 444, Op: ir.FilterStringOp, Src: "\"map[$_]$_\"", Value: "map[$_]$_"}},
															},
														},
													},
													{
														Line:  449,
														Op:    ir.FilterVarTypeUnderlyingIsOp,
														Src:   "m[\"y\"].Type.Underlying().Is(\"interface{$*_}\")",
														Value: "y",
														Args:  []ir.FilterExpr{{Line: 444, Op: ir.FilterStringOp, Src: "\"interface{$*_}\"", Value: "interface{$*_}"}},
													},
												},
											},
											{
												Line:  449,
												Op:    ir.FilterVarTypeUnderlyingIsOp,
												Src:   "m[\"y\"].Type.Underlying().Is(`func($*_) $*_`)",
												Value: "y",
												Args:  []ir.FilterExpr{{Line: 445, Op: ir.FilterStringOp, Src: "`func($*_) $*_`", Value: "func($*_) $*_"}},
											},
										},
									},
									{
										Line:  449,
										Op:    ir.FilterVarTypeUnderlyingIsOp,
										Src:   "m[\"y\"].Type.Underlying().Is(`unsafe.Pointer`)",
										Value: "y",
										Args:  []ir.FilterExpr{{Line: 445, Op: ir.FilterStringOp, Src: "`unsafe.Pointer`", Value: "unsafe.Pointer"}},
									},
								},
							}},
						},
					},
				},
				LocationVar: "y",
			}},
		},
		{
			Line:        456,
			Name:        "uselessLocalConst",
			MatcherName: "m",
			DocTags:     []string{"diagnostic"},
			DocSummary:  "Detects useless local constants",
			Rules: []ir.Rule{{
				Line: 457,
				SyntaxPatterns: []ir.PatternString{
					{Line: 457, Value: "const $x = $_; $*body"},
					{Line: 457, Value: "const $x $_ = $_; $*body"},
				},
				ReportTemplate: "useless local constant",
				WhereExpr: ir.FilterExpr{
					Line: 458,
					Op:   ir.FilterAndOp,
					Src:  "!m[\"x\"].Object.IsGlobal() && !m[\"body\"].Contains(`$x`)",
					Args: []ir.FilterExpr{
						{
							Line: 458,
							Op:   ir.FilterNotOp,
							Src:  "!m[\"x\"].Object.IsGlobal()",
							Args: []ir.FilterExpr{{
								Line:  458,
								Op:    ir.FilterVarObjectIsGlobalOp,
								Src:   "m[\"x\"].Object.IsGlobal()",
								Value: "x",
							}},
						},
						{
							Line: 458,
							Op:   ir.FilterNotOp,
							Src:  "!m[\"body\"].Contains(`$x`)",
							Args: []ir.FilterExpr{{
								Line:  458,
								Op:    ir.FilterVarContainsOp,
								Src:   "m[\"body\"].Contains(`$x`)",
								Value: "body",
								Args:  []ir.FilterExpr{{Line: 0, Op: ir.FilterStringOp, Src: "", Value: "$x"}},
							}},
						},
					},
				},
			}},
		},
		{
			Line:        464,
			Name:        "oneLineReturn",
			MatcherName: "m",
			DocTags:     []string{"style", "experimental"},
			DocSummary:  "Detects variables assigment before return that can be simplified",
			Rules: []ir.Rule{{
				Line: 471,
				SyntaxPatterns: []ir.PatternString{
					{Line: 472, Value: "var $x = $v; return $x"},
					{Line: 473, Value: "$x := $v; return $x"},
				},
				ReportTemplate:  "suggestion: return $v",
				SuggestTemplate: "return $v",
				WhereExpr: ir.FilterExpr{
					Line: 475,
					Op:   ir.FilterNotOp,
					Src:  "!isPointer(m[\"x\"])",
					Args: []ir.FilterExpr{{
						Line: 475,
						Op:   ir.FilterOrOp,
						Src:  "isPointer(m[\"x\"])",
						Args: []ir.FilterExpr{
							{
								Line: 475,
								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: 475,
										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: 475,
												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: 475,
														Op:   ir.FilterOrOp,
														Src:  "m[\"x\"].Type.Underlying().Is(\"*$_\") ||\n\n\tm[\"x\"].Type.Underlying().Is(\"chan $_\")",
														Args: []ir.FilterExpr{
															{
																Line:  475,
																Op:    ir.FilterVarTypeUnderlyingIsOp,
																Src:   "m[\"x\"].Type.Underlying().Is(\"*$_\")",
																Value: "x",
																Args:  []ir.FilterExpr{{Line: 466, Op: ir.FilterStringOp, Src: "\"*$_\"", Value: "*$_"}},
															},
															{
																Line:  475,
																Op:    ir.FilterVarTypeUnderlyingIsOp,
																Src:   "m[\"x\"].Type.Underlying().Is(\"chan $_\")",
																Value: "x",
																Args:  []ir.FilterExpr{{Line: 466, Op: ir.FilterStringOp, Src: "\"chan $_\"", Value: "chan $_"}},
															},
														},
													},
													{
														Line:  475,
														Op:    ir.FilterVarTypeUnderlyingIsOp,
														Src:   "m[\"x\"].Type.Underlying().Is(\"map[$_]$_\")",
														Value: "x",
														Args:  []ir.FilterExpr{{Line: 467, Op: ir.FilterStringOp, Src: "\"map[$_]$_\"", Value: "map[$_]$_"}},
													},
												},
											},
											{
												Line:  475,
												Op:    ir.FilterVarTypeUnderlyingIsOp,
												Src:   "m[\"x\"].Type.Underlying().Is(\"interface{$*_}\")",
												Value: "x",
												Args:  []ir.FilterExpr{{Line: 467, Op: ir.FilterStringOp, Src: "\"interface{$*_}\"", Value: "interface{$*_}"}},
											},
										},
									},
									{
										Line:  475,
										Op:    ir.FilterVarTypeUnderlyingIsOp,
										Src:   "m[\"x\"].Type.Underlying().Is(`func($*_) $*_`)",
										Value: "x",
										Args:  []ir.FilterExpr{{Line: 468, Op: ir.FilterStringOp, Src: "`func($*_) $*_`", Value: "func($*_) $*_"}},
									},
								},
							},
							{
								Line:  475,
								Op:    ir.FilterVarTypeUnderlyingIsOp,
								Src:   "m[\"x\"].Type.Underlying().Is(`unsafe.Pointer`)",
								Value: "x",
								Args:  []ir.FilterExpr{{Line: 468, Op: ir.FilterStringOp, Src: "`unsafe.Pointer`", Value: "unsafe.Pointer"}},
							},
						},
					}},
				},
			}},
		},
		{
			Line:        492,
			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: 493,
				SyntaxPatterns: []ir.PatternString{
					{Line: 494, Value: "if $err := $_($*_); $err2 != nil { $*_ }"},
					{Line: 495, Value: "if $err = $_($*_); $err2 != nil { $*_ }"},
					{Line: 496, Value: "if $*_, $err := $_($*_); $err2 != nil { $*_ }"},
					{Line: 497, Value: "if $*_, $err = $_($*_); $err2 != nil { $*_ }"},
				},
				ReportTemplate: "returned error '$err' must be checked",
				WhereExpr: ir.FilterExpr{
					Line: 498,
					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: 498,
							Op:   ir.FilterAndOp,
							Src:  "m[\"err\"].Type.Implements(\"error\") && m[\"err2\"].Type.Implements(\"error\")",
							Args: []ir.FilterExpr{
								{
									Line:  498,
									Op:    ir.FilterVarTypeImplementsOp,
									Src:   "m[\"err\"].Type.Implements(\"error\")",
									Value: "err",
									Args:  []ir.FilterExpr{{Line: 498, Op: ir.FilterStringOp, Src: "\"error\"", Value: "error"}},
								},
								{
									Line:  498,
									Op:    ir.FilterVarTypeImplementsOp,
									Src:   "m[\"err2\"].Type.Implements(\"error\")",
									Value: "err2",
									Args:  []ir.FilterExpr{{Line: 498, Op: ir.FilterStringOp, Src: "\"error\"", Value: "error"}},
								},
							},
						},
						{
							Line: 499,
							Op:   ir.FilterNeqOp,
							Src:  "m[\"err\"].Text != m[\"err2\"].Text",
							Args: []ir.FilterExpr{
								{Line: 499, Op: ir.FilterVarTextOp, Src: "m[\"err\"].Text", Value: "err"},
								{Line: 499, 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