Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var NoMisusedSpreadRule = rule.CreateRule(rule.Rule{ Name: "no-misused-spread", Run: func(ctx rule.RuleContext, options any) rule.RuleListeners { opts, ok := options.(NoMisusedSpreadOptions) if !ok { opts = NoMisusedSpreadOptions{} } if opts.Allow == nil { opts.Allow = []utils.TypeOrValueSpecifier{} } if opts.AllowInline == nil { opts.AllowInline = []string{} } checkArrayOrCallSpread := func(node *ast.Node) { t := utils.GetConstrainedTypeAtLocation(ctx.TypeChecker, node.AsSpreadElement().Expression) if !utils.TypeMatchesSomeSpecifier(t, opts.Allow, opts.AllowInline, ctx.Program) && isString(t) { ctx.ReportNode(node, buildNoStringSpreadMessage()) } } insertAwaitFix := func(node *ast.Node) []rule.RuleFix { if utils.IsHigherPrecedenceThanAwait(node) { return []rule.RuleFix{ rule.RuleFixInsertBefore(ctx.SourceFile, node, "await "), } } return []rule.RuleFix{ rule.RuleFixInsertBefore(ctx.SourceFile, node, "await ("), rule.RuleFixInsertAfter(node, ")"), } } getMapSpreadSuggestions := func(node *ast.Node, argument *ast.Node, t *checker.Type) []rule.RuleSuggestion { for _, t := range utils.UnionTypeParts(t) { if !isMap(ctx.Program, ctx.TypeChecker, t) { return []rule.RuleSuggestion{} } } if ast.IsObjectLiteralExpression(node.Parent) { properties := node.Parent.AsObjectLiteralExpression().Properties if len(properties.Nodes) == 1 { return []rule.RuleSuggestion{ { Message: buildReplaceMapSpreadInObjectMessage(), FixesArr: []rule.RuleFix{ rule.RuleFixRemoveRange(scanner.GetRangeOfTokenAtPosition(ctx.SourceFile, node.Parent.Pos())), rule.RuleFixReplaceRange(scanner.GetRangeOfTokenAtPosition(ctx.SourceFile, node.Pos()), "Object.fromEntries("), rule.RuleFixReplaceRange(properties.Loc.WithPos(argument.End()), ")"), rule.RuleFixRemoveRange(node.Parent.Loc.WithPos(node.Parent.End() - 1)), }, }, } } } return []rule.RuleSuggestion{ { Message: buildReplaceMapSpreadInObjectMessage(), FixesArr: []rule.RuleFix{ rule.RuleFixInsertBefore(ctx.SourceFile, argument, "Object.fromEntries("), rule.RuleFixInsertAfter(argument, ")"), }, }, } } checkObjectSpread := func(node *ast.Node, argument *ast.Node) { t := utils.GetConstrainedTypeAtLocation(ctx.TypeChecker, argument) if utils.TypeMatchesSomeSpecifier(t, opts.Allow, opts.AllowInline, ctx.Program) { return } if isPromise(ctx.Program, ctx.TypeChecker, t) { ctx.ReportNodeWithSuggestions(node, buildNoPromiseSpreadInObjectMessage(), rule.RuleSuggestion{ Message: buildAddAwaitMessage(), FixesArr: insertAwaitFix(ast.SkipParentheses(argument)), }) return } if isFunctionWithoutProps(ctx.TypeChecker, t) { ctx.ReportNode(node, buildNoFunctionSpreadInObjectMessage()) return } if isMap(ctx.Program, ctx.TypeChecker, t) { ctx.ReportNodeWithSuggestions(node, buildNoMapSpreadInObjectMessage(), getMapSpreadSuggestions(node, argument, t)...) return } if isArray(ctx.TypeChecker, t) { ctx.ReportNode(node, buildNoArraySpreadInObjectMessage()) return } if isIterable(ctx.TypeChecker, t) && !isString(t) { ctx.ReportNode(node, buildNoIterableSpreadInObjectMessage()) return } if isClassInstance(ctx.TypeChecker, t) { ctx.ReportNode(node, buildNoClassInstanceSpreadInObjectMessage()) return } if isClassDeclaration(t) { ctx.ReportNode(node, buildNoClassDeclarationSpreadInObjectMessage()) return } } return rule.RuleListeners{ rule.ListenerOnNotAllowPattern(ast.KindArrayLiteralExpression): func(node *ast.Node) { for _, element := range node.AsArrayLiteralExpression().Elements.Nodes { if ast.IsSpreadElement(element) { checkArrayOrCallSpread(element) } } }, ast.KindCallExpression: func(node *ast.Node) { for _, element := range node.AsCallExpression().Arguments.Nodes { if ast.IsSpreadElement(element) { checkArrayOrCallSpread(element) } } }, ast.KindJsxSpreadAttribute: func(node *ast.Node) { checkObjectSpread(node, node.AsJsxSpreadAttribute().Expression) }, rule.ListenerOnNotAllowPattern(ast.KindObjectLiteralExpression): func(node *ast.Node) { for _, element := range node.AsObjectLiteralExpression().Properties.Nodes { if ast.IsSpreadAssignment(element) { checkObjectSpread(element, element.AsSpreadAssignment().Expression) } } }, } }, })
Functions ¶
This section is empty.
Types ¶
type NoMisusedSpreadOptions ¶
type NoMisusedSpreadOptions struct {
Allow []utils.TypeOrValueSpecifier
AllowInline []string
}
Click to show internal directories.
Click to hide internal directories.