Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var NoUnsafeRule = rule.Rule{ Name: "react/no-unsafe", Run: func(ctx rule.RuleContext, options any) rule.RuleListeners { if reactutil.ReactVersionLessThan(ctx.Settings, 16, 3, 0) { return rule.RuleListeners{} } checkAliases := parseOptions(options) unsafeMap := buildUnsafeMap(checkAliases) pragma := reactutil.GetReactPragma(ctx.Settings) createClass := reactutil.GetReactCreateClass(ctx.Settings) checkLifeCycleMethods := func(members []*ast.Node) { counts := map[string]int{} firstNode := map[string]*ast.Node{} // First pass: count occurrences and remember first node per name. // Order of first appearance is recorded by the slice below so // our output order is deterministic and matches a source-order // (== ESLint reporter (line,column)) walk. var orderedNames []string for _, m := range members { if m == nil { continue } name := memberKeyName(m) if name == "" { continue } if _, ok := unsafeMap[name]; !ok { continue } if _, seen := firstNode[name]; !seen { firstNode[name] = m orderedNames = append(orderedNames, name) } counts[name]++ } for _, name := range orderedNames { meta := unsafeMap[name] node := firstNode[name] for range counts[name] { ctx.ReportNode(node, rule.RuleMessage{ Id: "unsafeMethod", Description: formatMessage(name, meta), }) } } } isES5Component := func(obj *ast.Node) bool { if obj == nil || obj.Kind != ast.KindObjectLiteralExpression { return false } cur := obj for cur.Parent != nil && cur.Parent.Kind == ast.KindParenthesizedExpression { cur = cur.Parent } parent := cur.Parent if parent == nil { return false } var calleeExpr *ast.Node var args *ast.NodeList switch parent.Kind { case ast.KindCallExpression: ce := parent.AsCallExpression() calleeExpr = ce.Expression args = ce.Arguments case ast.KindNewExpression: ne := parent.AsNewExpression() calleeExpr = ne.Expression args = ne.Arguments default: return false } if args == nil { return false } inArgs := false for _, arg := range args.Nodes { if arg == cur { inArgs = true break } } if !inArgs { return false } callee := ast.SkipParentheses(calleeExpr) switch callee.Kind { case ast.KindIdentifier: return callee.AsIdentifier().Text == createClass case ast.KindPropertyAccessExpression: pa := callee.AsPropertyAccessExpression() obj := ast.SkipParentheses(pa.Expression) if obj.Kind != ast.KindIdentifier || obj.AsIdentifier().Text != pragma { return false } name := pa.Name() if name == nil || name.Kind != ast.KindIdentifier { return false } return name.AsIdentifier().Text == createClass } return false } return rule.RuleListeners{ ast.KindClassDeclaration: func(node *ast.Node) { if !reactutil.ExtendsReactComponent(node, pragma) { return } checkLifeCycleMethods(node.Members()) }, ast.KindClassExpression: func(node *ast.Node) { if !reactutil.ExtendsReactComponent(node, pragma) { return } checkLifeCycleMethods(node.Members()) }, ast.KindObjectLiteralExpression: func(node *ast.Node) { if !isES5Component(node) { return } ol := node.AsObjectLiteralExpression() if ol == nil || ol.Properties == nil { return } checkLifeCycleMethods(ol.Properties.Nodes) }, } }, }
Functions ¶
This section is empty.
Types ¶
This section is empty.
Click to show internal directories.
Click to hide internal directories.