no_unreachable

package
v0.5.2 Latest Latest
Warning

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

Go to latest
Published: May 7, 2026 License: MIT Imports: 4 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var NoUnreachableRule = rule.Rule{
	Name: "no-unreachable",
	Run: func(ctx rule.RuleContext, options any) rule.RuleListeners {
		msg := rule.RuleMessage{
			Id:          "unreachableCode",
			Description: "Unreachable code.",
		}

		checkStatements := func(statements []*ast.Node) {
			if len(statements) == 0 {
				return
			}

			if isUnreachable(statements[0]) {
				return
			}

			var rangeStart *ast.Node // first unreachable stmt in current consecutive group
			var rangeEnd *ast.Node   // last unreachable stmt in current consecutive group

			flush := func() {
				if rangeStart != nil {

					startRange := utils.TrimNodeTextRange(ctx.SourceFile, rangeStart)
					ctx.ReportRange(
						core.NewTextRange(startRange.Pos(), rangeEnd.End()),
						msg,
					)
					rangeStart = nil
					rangeEnd = nil
				}
			}

			for _, stmt := range statements {
				if stmt == nil {
					continue
				}
				if isUnreachable(stmt) {
					if isHoistedOrEmpty(stmt) {

						flush()
					} else {
						if rangeStart == nil {
							rangeStart = stmt
						}
						rangeEnd = stmt
					}
				} else {
					flush()
				}
			}
			flush()
		}

		if sf := ctx.SourceFile; sf != nil && sf.Statements != nil {
			checkStatements(sf.Statements.Nodes)
		}

		return rule.RuleListeners{
			ast.KindBlock: func(node *ast.Node) {
				block := node.AsBlock()
				if block == nil || block.Statements == nil {
					return
				}
				checkStatements(block.Statements.Nodes)
			},
			ast.KindCaseClause: func(node *ast.Node) {
				clause := node.AsCaseOrDefaultClause()
				if clause == nil || clause.Statements == nil {
					return
				}
				checkStatements(clause.Statements.Nodes)
			},
			ast.KindDefaultClause: func(node *ast.Node) {
				clause := node.AsCaseOrDefaultClause()
				if clause == nil || clause.Statements == nil {
					return
				}
				checkStatements(clause.Statements.Nodes)
			},
			ast.KindTryStatement: func(node *ast.Node) {
				ts := node.AsTryStatement()
				if ts == nil || ts.CatchClause == nil || ts.TryBlock == nil {
					return
				}

				if isUnreachable(node) {
					return
				}

				if !utils.CanBlockThrow(ts.TryBlock) {
					cc := ts.CatchClause.AsCatchClause()
					if cc != nil && cc.Block != nil {
						startRange := utils.TrimNodeTextRange(ctx.SourceFile, ts.CatchClause)
						ctx.ReportRange(
							core.NewTextRange(startRange.Pos(), ts.CatchClause.End()),
							msg,
						)
					}
				}
			},
			ast.KindModuleBlock: func(node *ast.Node) {
				mb := node.AsModuleBlock()
				if mb == nil || mb.Statements == nil {
					return
				}
				checkStatements(mb.Statements.Nodes)
			},
		}
	},
}

NoUnreachableRule disallows unreachable code after return, throw, break, and continue statements.

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