one_var

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: 7 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var OneVarRule = rule.Rule{
	Name: "one-var",
	Run: func(ctx rule.RuleContext, options any) rule.RuleListeners {
		opts := parseOptions(options)
		funcStack := []*funcScope{{}}
		blockStack := []*blockScope{{}}

		startBlock := func(*ast.Node) {
			blockStack = append(blockStack, &blockScope{})
		}
		endBlock := func(*ast.Node) {
			if len(blockStack) > 0 {
				blockStack = blockStack[:len(blockStack)-1]
			}
		}
		startFunction := func(node *ast.Node) {
			funcStack = append(funcStack, &funcScope{})
			startBlock(node)
		}
		endFunction := func(node *ast.Node) {
			if len(funcStack) > 0 {
				funcStack = funcStack[:len(funcStack)-1]
			}
			endBlock(node)
		}

		getCurrentScope := func(key string) *funcScope {
			if key == "var" {
				return funcStack[len(funcStack)-1]
			}
			return blockStack[len(blockStack)-1].get(key)
		}

		checkDeclList := func(node *ast.Node) {
			declList := node.AsVariableDeclarationList()
			if declList == nil || declList.Declarations == nil {
				return
			}
			parent := node.Parent
			if parent == nil {
				return
			}

			var stmtNode *ast.Node
			isForInit := false
			isForInOfInit := false
			switch parent.Kind {
			case ast.KindVariableStatement:
				stmtNode = parent
			case ast.KindForStatement:
				stmtNode = parent
				isForInit = true
			case ast.KindForInStatement, ast.KindForOfStatement:
				stmtNode = parent
				isForInOfInit = true
			default:
				return
			}

			view := makeView(node, ctx.SourceFile)
			reportRange := view.reportRange()

			kind := utils.GetVarDeclListKind(node)
			if kind == "" {
				return
			}
			key := optsKey(kind)
			typeOpts := opts.getType(key)
			if typeOpts.initialized == "" && typeOpts.uninitialized == "" {
				return
			}

			declarations := declList.Declarations.Nodes
			initCount, uninitCount := countDeclarations(declarations)

			if typeOpts.initialized == modeAlways && opts.separateRequires {
				if someRequire(declarations) && !everyRequire(declarations) {
					ctx.ReportRange(reportRange, msg("splitRequires", kind))
				}
			}

			if !isForInit && !isForInOfInit && stmtNode.Kind == ast.KindVariableStatement && !view.hasExportWrapper {
				if prev := findPreviousSibling(stmtNode); prev != nil && prev.Kind == ast.KindVariableStatement {
					prevDeclList := prev.AsVariableStatement().DeclarationList
					if prevDeclList != nil && utils.GetVarDeclListKind(prevDeclList) == kind {
						prevView := makeView(prevDeclList, ctx.SourceFile)
						if !prevView.hasExportWrapper {
							prevDecls := prevDeclList.AsVariableDeclarationList().Declarations.Nodes
							combinedAllRequire := everyRequire(declarations) && everyRequire(prevDecls)
							combinedAnyRequire := someRequire(declarations) || someRequire(prevDecls)
							mixedRequires := combinedAnyRequire && !combinedAllRequire

							if !mixedRequires {
								prevInitCount, prevUninitCount := countDeclarations(prevDecls)
								switch {
								case typeOpts.initialized == modeConsecutive && typeOpts.uninitialized == modeConsecutive:
									reportRangeWithFixes(ctx, reportRange, msg("combine", kind), fixCombine(view, node, kind, ctx.SourceFile))
								case typeOpts.initialized == modeConsecutive && initCount > 0 && prevInitCount > 0:
									reportRangeWithFixes(ctx, reportRange, msg("combineInitialized", kind), fixCombine(view, node, kind, ctx.SourceFile))
								case typeOpts.uninitialized == modeConsecutive && uninitCount > 0 && prevUninitCount > 0:
									reportRangeWithFixes(ctx, reportRange, msg("combineUninitialized", kind), fixCombine(view, node, kind, ctx.SourceFile))
								}
							}
						}
					}
				}
			}

			currentScope := getCurrentScope(key)
			if currentScope != nil && !hasOnlyOneStatement(currentScope, typeOpts, declarations, opts.separateRequires) {
				if typeOpts.initialized == modeAlways && typeOpts.uninitialized == modeAlways {
					reportRangeWithFixes(ctx, reportRange, msg("combine", kind), fixCombine(view, node, kind, ctx.SourceFile))
				} else {
					if typeOpts.initialized == modeAlways && initCount > 0 {
						reportRangeWithFixes(ctx, reportRange, msg("combineInitialized", kind), fixCombine(view, node, kind, ctx.SourceFile))
					}
					if typeOpts.uninitialized == modeAlways && uninitCount > 0 {

						if !isForInOfInit {
							reportRangeWithFixes(ctx, reportRange, msg("combineUninitialized", kind), fixCombine(view, node, kind, ctx.SourceFile))
						}
					}
				}
			}

			if !isForInit {
				totalDecls := initCount + uninitCount
				if totalDecls > 1 {
					if typeOpts.initialized == modeNever && typeOpts.uninitialized == modeNever {
						reportRangeWithFixes(ctx, reportRange, msg("split", kind), fixSplit(view, node, kind, ctx.SourceFile))
					} else if typeOpts.initialized == modeNever && initCount > 0 {
						reportRangeWithFixes(ctx, reportRange, msg("splitInitialized", kind), fixSplit(view, node, kind, ctx.SourceFile))
					} else if typeOpts.uninitialized == modeNever && uninitCount > 0 {
						reportRangeWithFixes(ctx, reportRange, msg("splitUninitialized", kind), fixSplit(view, node, kind, ctx.SourceFile))
					}
				}
			}
		}

		return rule.RuleListeners{
			ast.KindFunctionDeclaration:                              startFunction,
			rule.ListenerOnExit(ast.KindFunctionDeclaration):         endFunction,
			ast.KindFunctionExpression:                               startFunction,
			rule.ListenerOnExit(ast.KindFunctionExpression):          endFunction,
			ast.KindArrowFunction:                                    startFunction,
			rule.ListenerOnExit(ast.KindArrowFunction):               endFunction,
			ast.KindMethodDeclaration:                                startFunction,
			rule.ListenerOnExit(ast.KindMethodDeclaration):           endFunction,
			ast.KindGetAccessor:                                      startFunction,
			rule.ListenerOnExit(ast.KindGetAccessor):                 endFunction,
			ast.KindSetAccessor:                                      startFunction,
			rule.ListenerOnExit(ast.KindSetAccessor):                 endFunction,
			ast.KindConstructor:                                      startFunction,
			rule.ListenerOnExit(ast.KindConstructor):                 endFunction,
			ast.KindClassStaticBlockDeclaration:                      startFunction,
			rule.ListenerOnExit(ast.KindClassStaticBlockDeclaration): endFunction,

			ast.KindBlock:                                startBlock,
			rule.ListenerOnExit(ast.KindBlock):           endBlock,
			ast.KindForStatement:                         startBlock,
			rule.ListenerOnExit(ast.KindForStatement):    endBlock,
			ast.KindForInStatement:                       startBlock,
			rule.ListenerOnExit(ast.KindForInStatement):  endBlock,
			ast.KindForOfStatement:                       startBlock,
			rule.ListenerOnExit(ast.KindForOfStatement):  endBlock,
			ast.KindSwitchStatement:                      startBlock,
			rule.ListenerOnExit(ast.KindSwitchStatement): endBlock,

			ast.KindVariableDeclarationList: checkDeclList,
		}
	},
}

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