Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var ArrayTypeRule = rule.CreateRule(rule.Rule{ Name: "array-type", Run: func(ctx rule.RuleContext, options any) rule.RuleListeners { opts := ArrayTypeOptions{ Default: "array", } if options != nil { var optsMap map[string]interface{} var ok bool if optArray, isArray := options.([]interface{}); isArray && len(optArray) > 0 { optsMap, ok = optArray[0].(map[string]interface{}) } else { optsMap, ok = options.(map[string]interface{}) } if ok { if defaultVal, ok := optsMap["default"].(string); ok { opts.Default = defaultVal } if readonlyVal, ok := optsMap["readonly"].(string); ok { opts.Readonly = readonlyVal } } } defaultOption := opts.Default readonlyOption := opts.Readonly if readonlyOption == "" { readonlyOption = defaultOption } getMessageType := func(node *ast.Node) string { if isSimpleType(node) { nodeRange := utils.TrimNodeTextRange(ctx.SourceFile, node) return ctx.SourceFile.Text()[nodeRange.Pos():nodeRange.End()] } return "T" } return rule.RuleListeners{ ast.KindArrayType: func(node *ast.Node) { arrayType := node.AsArrayTypeNode() if arrayType == nil { return } isReadonly := false if node.Parent != nil && node.Parent.Kind == ast.KindTypeOperator { typeOp := node.Parent.AsTypeOperatorNode() if typeOp != nil { isReadonly = typeOp.Operator == ast.KindReadonlyKeyword } } currentOption := defaultOption if isReadonly { currentOption = readonlyOption } if currentOption == "array" || (currentOption == "array-simple" && isSimpleType(arrayType.ElementType)) { return } var messageId string if currentOption == "generic" { messageId = "errorStringGeneric" } else { messageId = "errorStringGenericSimple" } errorNode := node if isReadonly { errorNode = node.Parent } typeStr := getMessageType(arrayType.ElementType) className := "Array" readonlyPrefix := "" if isReadonly { className = "ReadonlyArray" readonlyPrefix = "readonly " } var message rule.RuleMessage if messageId == "errorStringGeneric" { message = buildErrorStringGenericMessage(readonlyPrefix, typeStr, className) } else { message = buildErrorStringGenericSimpleMessage(readonlyPrefix, typeStr, className) } elementTypeRange := utils.TrimNodeTextRange(ctx.SourceFile, arrayType.ElementType) elementTypeText := ctx.SourceFile.Text()[elementTypeRange.Pos():elementTypeRange.End()] if ast.IsParenthesizedTypeNode(arrayType.ElementType) { parenType := arrayType.ElementType.AsParenthesizedTypeNode() if parenType != nil && parenType.Type != nil { innerTypeRange := utils.TrimNodeTextRange(ctx.SourceFile, parenType.Type) elementTypeText = ctx.SourceFile.Text()[innerTypeRange.Pos():innerTypeRange.End()] } } newText := fmt.Sprintf("%s<%s>", className, elementTypeText) ctx.ReportNodeWithFixes(errorNode, message, rule.RuleFixReplace(ctx.SourceFile, errorNode, newText)) }, ast.KindTypeReference: func(node *ast.Node) { typeRef := node.AsTypeReference() if typeRef == nil { return } if !ast.IsIdentifier(typeRef.TypeName) { return } identifier := typeRef.TypeName.AsIdentifier() if identifier == nil { return } typeName := identifier.Text if typeName != "Array" && typeName != "ReadonlyArray" && typeName != "Readonly" { return } if typeName == "Readonly" { if typeRef.TypeArguments == nil || len(typeRef.TypeArguments.Nodes) == 0 { return } if typeRef.TypeArguments.Nodes[0].Kind != ast.KindArrayType { return } } isReadonlyWithGenericArrayType := typeName == "Readonly" && typeRef.TypeArguments != nil && len(typeRef.TypeArguments.Nodes) > 0 && typeRef.TypeArguments.Nodes[0].Kind == ast.KindArrayType isReadonlyArrayType := typeName == "ReadonlyArray" || isReadonlyWithGenericArrayType currentOption := defaultOption if isReadonlyArrayType { currentOption = readonlyOption } if currentOption == "generic" { return } readonlyPrefix := "" if isReadonlyArrayType { readonlyPrefix = "readonly " } typeParams := typeRef.TypeArguments var messageId string switch currentOption { case "array": if isReadonlyWithGenericArrayType { messageId = "errorStringArrayReadonly" } else { messageId = "errorStringArray" } case "array-simple": isSimple := typeParams == nil || len(typeParams.Nodes) == 0 || (len(typeParams.Nodes) == 1 && isSimpleType(typeParams.Nodes[0])) if !isSimple { return } if isReadonlyArrayType && typeName != "ReadonlyArray" { messageId = "errorStringArraySimpleReadonly" } else { messageId = "errorStringArraySimple" } } if typeParams == nil || len(typeParams.Nodes) == 0 { className := "Array" if isReadonlyArrayType { className = "ReadonlyArray" } var message rule.RuleMessage switch messageId { case "errorStringArray": message = buildErrorStringArrayMessage(className, readonlyPrefix, "any") case "errorStringArrayReadonly": message = buildErrorStringArrayReadonlyMessage(className, readonlyPrefix, "any") case "errorStringArraySimple": message = buildErrorStringArraySimpleMessage(className, readonlyPrefix, "any") case "errorStringArraySimpleReadonly": message = buildErrorStringArraySimpleReadonlyMessage(className, readonlyPrefix, "any") } ctx.ReportNodeWithFixes(node, message, rule.RuleFixReplace(ctx.SourceFile, node, readonlyPrefix+"any[]")) return } if len(typeParams.Nodes) != 1 { return } typeParam := typeParams.Nodes[0] // Only add parentheses when converting Array<T> -> T[] if T needs them // Never add parentheses when converting T[] -> Array<T> var typeParens bool var parentParens bool if currentOption == "array" || currentOption == "array-simple" { typeParens = typeNeedsParentheses(typeParam) parentParens = readonlyPrefix != "" && node.Parent != nil && node.Parent.Kind == ast.KindArrayType && !isParenthesized(node.Parent.AsArrayTypeNode().ElementType) } start := "" if parentParens { start += "(" } start += readonlyPrefix if typeParens { start += "(" } end := "" if typeParens { end += ")" } if !isReadonlyWithGenericArrayType { end += "[]" } if parentParens { end += ")" } typeStr := getMessageType(typeParam) className := typeName if !isReadonlyArrayType { className = "Array" } var message rule.RuleMessage switch messageId { case "errorStringArray": message = buildErrorStringArrayMessage(className, readonlyPrefix, typeStr) case "errorStringArrayReadonly": message = buildErrorStringArrayReadonlyMessage(className, readonlyPrefix, typeStr) case "errorStringArraySimple": message = buildErrorStringArraySimpleMessage(className, readonlyPrefix, typeStr) case "errorStringArraySimpleReadonly": message = buildErrorStringArraySimpleReadonlyMessage(className, readonlyPrefix, typeStr) } typeParamRange := utils.TrimNodeTextRange(ctx.SourceFile, typeParam) typeParamText := ctx.SourceFile.Text()[typeParamRange.Pos():typeParamRange.End()] if (currentOption == "array-simple") && ast.IsParenthesizedTypeNode(typeParam) { parenType := typeParam.AsParenthesizedTypeNode() if parenType != nil && parenType.Type != nil { innerTypeRange := utils.TrimNodeTextRange(ctx.SourceFile, parenType.Type) typeParamText = ctx.SourceFile.Text()[innerTypeRange.Pos():innerTypeRange.End()] } } ctx.ReportNodeWithFixes(node, message, rule.RuleFixReplace(ctx.SourceFile, node, start+typeParamText+end)) }, } }, })
Functions ¶
This section is empty.
Types ¶
type ArrayTypeOptions ¶
Click to show internal directories.
Click to hide internal directories.