no_extra_label

package
v0.5.3 Latest Latest
Warning

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

Go to latest
Published: May 14, 2026 License: MIT Imports: 5 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var NoExtraLabelRule = rule.Rule{
	Name: "no-extra-label",
	Run: func(ctx rule.RuleContext, options any) rule.RuleListeners {
		var scope *scopeInfo

		enterBreakable := func(node *ast.Node) {
			label := ""
			if parent := node.Parent; parent != nil && parent.Kind == ast.KindLabeledStatement {
				label = parent.AsLabeledStatement().Label.Text()
			}
			scope = &scopeInfo{
				label:     label,
				breakable: true,
				upper:     scope,
			}
		}

		exitBreakable := func(node *ast.Node) {
			if scope != nil {
				scope = scope.upper
			}
		}

		enterLabeled := func(node *ast.Node) {
			ls := node.AsLabeledStatement()
			if hasBreakableBody(ls.Statement) {
				return
			}
			scope = &scopeInfo{
				label:     ls.Label.Text(),
				breakable: false,
				upper:     scope,
			}
		}

		exitLabeled := func(node *ast.Node) {
			ls := node.AsLabeledStatement()
			if hasBreakableBody(ls.Statement) {
				return
			}
			if scope != nil {
				scope = scope.upper
			}
		}

		reportIfUnnecessary := func(node *ast.Node, labelNode *ast.Node) {
			if labelNode == nil {
				return
			}
			targetName := labelNode.Text()

			for info := scope; info != nil; info = info.upper {
				if info.breakable || info.label == targetName {
					if info.breakable && info.label == targetName {
						msg := rule.RuleMessage{
							Id:          "unexpected",
							Description: "This label '" + targetName + "' is unnecessary.",
						}

						firstTokenRange := scanner.GetRangeOfTokenAtPosition(ctx.SourceFile, node.Pos())
						keywordEnd := firstTokenRange.End()

						sourceText := ctx.SourceFile.Text()
						labelTrimmedStart := scanner.SkipTrivia(sourceText, labelNode.Pos())

						if utils.HasCommentsInRange(ctx.SourceFile, core.NewTextRange(keywordEnd, labelTrimmedStart)) {
							ctx.ReportNode(labelNode, msg)
						} else {
							fix := rule.RuleFixRemoveRange(core.NewTextRange(keywordEnd, labelNode.End()))
							ctx.ReportNodeWithFixes(labelNode, msg, fix)
						}
					}
					return
				}
			}
		}

		return rule.RuleListeners{
			ast.KindWhileStatement:                        enterBreakable,
			rule.ListenerOnExit(ast.KindWhileStatement):   exitBreakable,
			ast.KindDoStatement:                           enterBreakable,
			rule.ListenerOnExit(ast.KindDoStatement):      exitBreakable,
			ast.KindForStatement:                          enterBreakable,
			rule.ListenerOnExit(ast.KindForStatement):     exitBreakable,
			ast.KindForInStatement:                        enterBreakable,
			rule.ListenerOnExit(ast.KindForInStatement):   exitBreakable,
			ast.KindForOfStatement:                        enterBreakable,
			rule.ListenerOnExit(ast.KindForOfStatement):   exitBreakable,
			ast.KindSwitchStatement:                       enterBreakable,
			rule.ListenerOnExit(ast.KindSwitchStatement):  exitBreakable,
			ast.KindLabeledStatement:                      enterLabeled,
			rule.ListenerOnExit(ast.KindLabeledStatement): exitLabeled,
			ast.KindBreakStatement: func(node *ast.Node) {
				bs := node.AsBreakStatement()
				if bs.Label == nil {
					return
				}
				reportIfUnnecessary(node, bs.Label)
			},
			ast.KindContinueStatement: func(node *ast.Node) {
				cs := node.AsContinueStatement()
				if cs.Label == nil {
					return
				}
				reportIfUnnecessary(node, cs.Label)
			},
		}
	},
}

https://eslint.org/docs/latest/rules/no-extra-label

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