no_unsafe_argument

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 NoUnsafeArgumentRule = rule.CreateRule(rule.Rule{
	Name: "no-unsafe-argument",
	Run: func(ctx rule.RuleContext, options any) rule.RuleListeners {
		describeType := func(t *checker.Type) string {
			if utils.IsIntrinsicErrorType(t) {
				return "error typed"
			}

			return ctx.TypeChecker.TypeToString(t)
		}

		describeTypeForSpread := func(t *checker.Type) string {
			if checker.Checker_isArrayType(ctx.TypeChecker, t) && utils.IsIntrinsicErrorType(checker.Checker_getTypeArguments(ctx.TypeChecker, t)[0]) {
				return "error"
			}

			return describeType(t)
		}

		describeTypeForTuple := func(t *checker.Type) string {
			if utils.IsIntrinsicErrorType(t) {
				return "error typed"
			}

			return "of type " + ctx.TypeChecker.TypeToString(t)
		}

		checkUnsafeArguments := func(
			args []*ast.Node,
			callee *ast.Expression,
			node *ast.Node,
		) {
			if len(args) == 0 {
				return
			}

			if utils.IsTypeAnyType(ctx.TypeChecker.GetTypeAtLocation(callee)) {
				return
			}

			signature := newFunctionSignature(ctx.TypeChecker, node)
			if signature == nil {
				panic("Expected to a signature resolved")
			}

			if ast.IsTaggedTemplateExpression(node) {

				signature.getNextParameterType()
			}

			for _, argument := range args {
				switch argument.Kind {

				case ast.KindSpreadElement:
					spreadArgType := ctx.TypeChecker.GetTypeAtLocation(argument.Expression())

					if utils.IsTypeAnyType(spreadArgType) {

						ctx.ReportNode(argument, buildUnsafeSpreadMessage(describeType(spreadArgType)))
					} else if utils.IsTypeAnyArrayType(spreadArgType, ctx.TypeChecker) {

						ctx.ReportNode(argument, buildUnsafeArraySpreadMessage(describeTypeForSpread(spreadArgType)))
					} else if checker.IsTupleType(spreadArgType) {

						spreadTypeArguments := checker.Checker_getTypeArguments(ctx.TypeChecker, spreadArgType)
						for _, tupleType := range spreadTypeArguments {
							parameterType := signature.getNextParameterType()
							if parameterType == nil {
								continue
							}
							_, _, unsafe := utils.IsUnsafeAssignment(
								tupleType,
								parameterType,
								ctx.TypeChecker,

								nil,
							)
							if unsafe {
								ctx.ReportNode(argument, buildUnsafeTupleSpreadMessage(describeTypeForTuple(tupleType), describeType(parameterType)))
							}
						}
						if checker.TupleType_combinedFlags(spreadArgType.Target().AsTupleType())&checker.ElementFlagsVariable != 0 {

							signature.consumeRemainingArguments()
						}

					} else {

					}

				default:
					parameterType := signature.getNextParameterType()
					if parameterType == nil {
						continue
					}

					argumentType := ctx.TypeChecker.GetTypeAtLocation(argument)
					_, _, unsafe := utils.IsUnsafeAssignment(
						argumentType,
						parameterType,
						ctx.TypeChecker,
						argument,
					)
					if unsafe {
						ctx.ReportNode(argument, buildUnsafeArgumentMessage(describeType(argumentType), describeType(parameterType)))
					}
				}
			}
		}

		return rule.RuleListeners{
			ast.KindCallExpression: func(node *ast.Node) {
				checkUnsafeArguments(node.Arguments(), node.Expression(), node)
			},
			ast.KindNewExpression: func(node *ast.Node) {
				checkUnsafeArguments(node.Arguments(), node.Expression(), node)
			},
			ast.KindTaggedTemplateExpression: func(node *ast.Node) {
				expr := node.AsTaggedTemplateExpression()
				template := expr.Template
				if ast.IsTemplateExpression(template) {
					checkUnsafeArguments(utils.Map(template.AsTemplateExpression().TemplateSpans.Nodes, func(span *ast.Node) *ast.Node {
						return span.Expression()
					}), expr.Tag, node)
				}
			},
		}
	},
})

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