Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var NoUnsafeMemberAccessRule = rule.CreateRule(rule.Rule{ Name: "no-unsafe-member-access", Run: func(ctx rule.RuleContext, options any) rule.RuleListeners { compilerOptions := ctx.Program.Options() isNoImplicitThis := utils.IsStrictCompilerOptionEnabled( compilerOptions, compilerOptions.NoImplicitThis, ) stateCache := map[*ast.Node]state{} var checkMemberExpression func(node *ast.Node) state checkMemberExpression = func(node *ast.Node) state { cachedState, ok := stateCache[node] if ok { return cachedState } parent := node.Parent for !ast.IsSourceFile(parent) { if ast.IsHeritageClause(parent) { return stateSafe } parent = parent.Parent } expression := node.Expression() if ast.IsAccessExpression(expression) { objectState := checkMemberExpression(expression) if objectState == stateUnsafe { stateCache[node] = objectState return objectState } } t := ctx.TypeChecker.GetTypeAtLocation(expression) state := stateSafe if utils.IsTypeAnyType(t) { state = stateUnsafe } stateCache[node] = state if state == stateUnsafe { var property *ast.Node var propertyName string if ast.IsPropertyAccessExpression(node) { property = node.Name() loc := utils.TrimNodeTextRange(ctx.SourceFile, property) propertyName = "." + ctx.SourceFile.Text()[loc.Pos():loc.End()] } else if ast.IsElementAccessExpression(node) { property = node.AsElementAccessExpression().ArgumentExpression loc := utils.TrimNodeTextRange(ctx.SourceFile, property) propertyName = "[" + ctx.SourceFile.Text()[loc.Pos():loc.End()] + "]" } if !isNoImplicitThis { thisExpression := utils.GetThisExpression(node) if thisExpression != nil && utils.IsTypeAnyType( utils.GetConstrainedTypeAtLocation(ctx.TypeChecker, thisExpression)) { ctx.ReportNode(property, buildUnsafeThisMemberExpressionMessage(propertyName)) return state } } ctx.ReportNode(property, buildUnsafeMemberExpressionMessage(propertyName, createDataType(t))) } return state } return rule.RuleListeners{ ast.KindPropertyAccessExpression: func(node *ast.Node) { checkMemberExpression(node) }, ast.KindElementAccessExpression: func(node *ast.Node) { checkMemberExpression(node) arg := node.AsElementAccessExpression().ArgumentExpression if ast.IsLiteralExpression(arg) { return } unaryOperatorKind := ast.KindUnknown if ast.IsPrefixUnaryExpression(arg) { unaryOperatorKind = arg.AsPrefixUnaryExpression().Operator } else if arg.Kind == ast.KindPostfixUnaryExpression { unaryOperatorKind = arg.AsPostfixUnaryExpression().Operator } if unaryOperatorKind == ast.KindPlusPlusToken || unaryOperatorKind == ast.KindMinusMinusToken { return } t := ctx.TypeChecker.GetTypeAtLocation(arg) if utils.IsTypeAnyType(t) { loc := utils.TrimNodeTextRange(ctx.SourceFile, arg) propertyName := "[" + ctx.SourceFile.Text()[loc.Pos():loc.End()] + "]" ctx.ReportNode(arg, buildUnsafeComputedMemberAccessMessage(propertyName, createDataType(t))) } }, } }, })
Functions ¶
This section is empty.
Types ¶
This section is empty.
Click to show internal directories.
Click to hide internal directories.