prefer_as_const

package
v0.1.9 Latest Latest
Warning

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

Go to latest
Published: Aug 13, 2025 License: MIT Imports: 5 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

View Source
var PreferAsConstRule = rule.CreateRule(rule.Rule{
	Name: "prefer-as-const",
	Run: func(ctx rule.RuleContext, options any) rule.RuleListeners {

		compareTypes := func(valueNode *ast.Node, typeNode *ast.Node, canFix bool) {
			if valueNode == nil || typeNode == nil {
				return
			}

			if !ast.IsLiteralExpression(valueNode) {
				return
			}

			var isLiteralType bool
			var literalNode *ast.Node

			if ast.IsLiteralTypeNode(typeNode) {
				literalTypeNode := typeNode.AsLiteralTypeNode()
				if literalTypeNode == nil {
					return
				}
				literalNode = literalTypeNode.Literal
				isLiteralType = true
			} else {
				return
			}

			if !isLiteralType || literalNode == nil {
				return
			}

			if !ast.IsLiteralExpression(literalNode) {
				return
			}

			if literalNode.Kind == ast.KindNoSubstitutionTemplateLiteral {
				return
			}

			valueRange := utils.TrimNodeTextRange(ctx.SourceFile, valueNode)
			valueText := ctx.SourceFile.Text()[valueRange.Pos():valueRange.End()]
			typeRange := utils.TrimNodeTextRange(ctx.SourceFile, literalNode)
			typeText := ctx.SourceFile.Text()[typeRange.Pos():typeRange.End()]

			if valueText == typeText {
				if canFix {

					ctx.ReportNodeWithFixes(literalNode, buildPreferConstAssertionMessage(),
						rule.RuleFixReplace(ctx.SourceFile, typeNode, "const"))
				} else {

					parent := typeNode.Parent
					if parent != nil {

						s := scanner.GetScannerForSourceFile(ctx.SourceFile, parent.Pos())
						colonStart := -1
						for s.TokenStart() < typeNode.Pos() {
							if s.Token() == ast.KindColonToken {
								colonStart = s.TokenStart()
							}
							s.Scan()
						}

						if colonStart != -1 {
							ctx.ReportNodeWithSuggestions(literalNode, buildVariableConstAssertionMessage(),
								rule.RuleSuggestion{
									Message: buildVariableSuggestMessage(),
									FixesArr: []rule.RuleFix{
										rule.RuleFixReplaceRange(
											core.NewTextRange(colonStart, typeNode.End()),
											"",
										),
										rule.RuleFixInsertAfter(valueNode, " as const"),
									},
								})
						}
					}
				}
			}
		}

		return rule.RuleListeners{

			ast.KindPropertyDeclaration: func(node *ast.Node) {
				if node.Kind != ast.KindPropertyDeclaration {
					return
				}
				propDecl := node.AsPropertyDeclaration()
				if propDecl == nil {
					return
				}
				if propDecl.Initializer != nil && propDecl.Type != nil {
					compareTypes(propDecl.Initializer, propDecl.Type, false)
				}
			},

			ast.KindAsExpression: func(node *ast.Node) {
				if node.Kind != ast.KindAsExpression {
					return
				}
				asExpr := node.AsAsExpression()
				if asExpr == nil {
					return
				}
				compareTypes(asExpr.Expression, asExpr.Type, true)
			},

			ast.KindTypeAssertionExpression: func(node *ast.Node) {
				if node.Kind != ast.KindTypeAssertionExpression {
					return
				}
				typeAssertion := node.AsTypeAssertion()
				if typeAssertion == nil {
					return
				}
				compareTypes(typeAssertion.Expression, typeAssertion.Type, true)
			},

			ast.KindVariableDeclaration: func(node *ast.Node) {
				if node.Kind != ast.KindVariableDeclaration {
					return
				}
				varDecl := node.AsVariableDeclaration()
				if varDecl == nil {
					return
				}
				if varDecl.Initializer != nil && varDecl.Type != nil {
					compareTypes(varDecl.Initializer, varDecl.Type, false)
				}
			},
		}
	},
})

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