no_mutable_exports

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

Documentation

Index

Constants

This section is empty.

Variables

View Source
var NoMutableExportsRule = rule.Rule{
	Name: "import/no-mutable-exports",
	Run: func(ctx rule.RuleContext, options any) rule.RuleListeners {

		checkDeclarationList := func(declList *ast.Node) {
			if declList == nil || !ast.IsVariableDeclarationList(declList) {
				return
			}
			if ast.IsVarConstLike(declList) {
				return
			}
			kind := "var"
			if ast.IsVarLet(declList) {
				kind = "let"
			}
			ctx.ReportNode(declList, rule.RuleMessage{
				Id:          "noMutableExports",
				Description: fmt.Sprintf("Exporting mutable '%s' binding, use 'const' instead.", kind),
			})
		}

		resolveVarDeclListBySymbol := func(identNode *ast.Node) *ast.Node {
			if ctx.TypeChecker == nil {
				return nil
			}
			sym := ctx.TypeChecker.GetSymbolAtLocation(identNode)
			if sym == nil {
				return nil
			}
			resolved := ctx.TypeChecker.SkipAlias(sym)
			if resolved == nil || len(resolved.Declarations) == 0 {
				return nil
			}

			for _, decl := range resolved.Declarations {
				if ast.IsVariableDeclaration(decl) {
					declList := decl.Parent
					if declList != nil && ast.IsVariableDeclarationList(declList) {
						return declList
					}
				}
			}
			return nil
		}

		findVarDeclListByWalk := func(name string) *ast.Node {
			if ctx.SourceFile == nil || ctx.SourceFile.Statements == nil {
				return nil
			}
			for _, stmt := range ctx.SourceFile.Statements.Nodes {
				if !ast.IsVariableStatement(stmt) {
					continue
				}
				declList := stmt.AsVariableStatement().DeclarationList
				if declList == nil || !ast.IsVariableDeclarationList(declList) {
					continue
				}
				vdl := declList.AsVariableDeclarationList()
				if vdl.Declarations == nil {
					continue
				}
				for _, decl := range vdl.Declarations.Nodes {
					if !ast.IsVariableDeclaration(decl) {
						continue
					}
					declName := decl.AsVariableDeclaration().Name()
					if declName == nil {
						continue
					}
					if utils.HasNameInBindingPattern(declName, name) {
						return declList
					}
				}
			}
			return nil
		}

		findVarDeclarationList := func(identNode *ast.Node) *ast.Node {
			if declList := resolveVarDeclListBySymbol(identNode); declList != nil {
				return declList
			}
			if identNode.Kind == ast.KindIdentifier {
				return findVarDeclListByWalk(identNode.AsIdentifier().Text)
			}
			return nil
		}

		isModuleLevelNode := func(node *ast.Node) bool {
			return node.Parent != nil && node.Parent.Kind == ast.KindSourceFile
		}

		return rule.RuleListeners{

			ast.KindVariableStatement: func(node *ast.Node) {
				if !isModuleLevelNode(node) {
					return
				}
				if !ast.HasSyntacticModifier(node, ast.ModifierFlagsExport) {
					return
				}
				checkDeclarationList(node.AsVariableStatement().DeclarationList)
			},

			ast.KindExportDeclaration: func(node *ast.Node) {
				if !isModuleLevelNode(node) {
					return
				}
				exportDecl := node.AsExportDeclaration()

				if exportDecl.ModuleSpecifier != nil {
					return
				}
				if exportDecl.IsTypeOnly {
					return
				}
				if exportDecl.ExportClause == nil || exportDecl.ExportClause.Kind != ast.KindNamedExports {
					return
				}
				namedExports := exportDecl.ExportClause.AsNamedExports()
				if namedExports.Elements == nil {
					return
				}
				for _, spec := range namedExports.Elements.Nodes {
					if spec.Kind != ast.KindExportSpecifier {
						continue
					}
					exportSpec := spec.AsExportSpecifier()
					if exportSpec.IsTypeOnly {
						continue
					}

					localNode := exportSpec.PropertyName
					if localNode == nil {
						localNode = exportSpec.Name()
					}
					if localNode == nil {
						continue
					}
					if declList := findVarDeclarationList(localNode); declList != nil {
						checkDeclarationList(declList)
					}
				}
			},

			ast.KindExportAssignment: func(node *ast.Node) {
				if !isModuleLevelNode(node) {
					return
				}
				exportAssign := node.AsExportAssignment()
				if exportAssign.IsExportEquals {
					return
				}
				expr := ast.SkipParentheses(exportAssign.Expression)
				if expr == nil || expr.Kind != ast.KindIdentifier {
					return
				}
				if declList := findVarDeclarationList(expr); declList != nil {
					checkDeclarationList(declList)
				}
			},
		}
	},
}

See: https://github.com/import-js/eslint-plugin-import/blob/main/src/rules/no-mutable-exports.js

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