Documentation
¶
Index ¶
Constants ¶
This section is empty.
Variables ¶
View Source
var NoEmptyFunctionRule = rule.CreateRule(rule.Rule{ Name: "no-empty-function", Run: func(ctx rule.RuleContext, options any) rule.RuleListeners { opts := NoEmptyFunctionOptions{ Allow: []string{}, } if options != nil { var optsMap map[string]interface{} if optsArray, ok := options.([]interface{}); ok && len(optsArray) > 0 { if opts, ok := optsArray[0].(map[string]interface{}); ok { optsMap = opts } } else if opts, ok := options.(map[string]interface{}); ok { optsMap = opts } if optsMap != nil { if allow, ok := optsMap["allow"].([]interface{}); ok { for _, a := range allow { if str, ok := a.(string); ok { opts.Allow = append(opts.Allow, str) } } } } } isAllowed := func(allowType string) bool { for _, a := range opts.Allow { if a == allowType { return true } } return false } isBodyEmpty := func(node *ast.Node) bool { switch node.Kind { case ast.KindFunctionDeclaration: fn := node.AsFunctionDeclaration() if fn == nil || fn.Body == nil { return false } return len(fn.Body.Statements()) == 0 case ast.KindFunctionExpression: fn := node.AsFunctionExpression() if fn == nil || fn.Body == nil { return false } return len(fn.Body.Statements()) == 0 case ast.KindArrowFunction: fn := node.AsArrowFunction() if fn == nil || fn.Body == nil { return false } if fn.Body.Kind != ast.KindBlock { return false } block := fn.Body.AsBlock() if block == nil || block.Statements == nil { return false } return len(block.Statements.Nodes) == 0 case ast.KindConstructor: constructor := node.AsConstructorDeclaration() if constructor == nil || constructor.Body == nil { return false } return len(constructor.Body.Statements()) == 0 case ast.KindMethodDeclaration: method := node.AsMethodDeclaration() if method == nil || method.Body == nil { return false } return len(method.Body.Statements()) == 0 case ast.KindGetAccessor: accessor := node.AsGetAccessorDeclaration() if accessor == nil || accessor.Body == nil { return false } return len(accessor.Body.Statements()) == 0 case ast.KindSetAccessor: accessor := node.AsSetAccessorDeclaration() if accessor == nil || accessor.Body == nil { return false } return len(accessor.Body.Statements()) == 0 default: return false } } hasParameterProperties := func(node *ast.Node) bool { var params []*ast.Node switch node.Kind { case ast.KindFunctionDeclaration: fn := node.AsFunctionDeclaration() if fn != nil && fn.Parameters != nil { params = fn.Parameters.Nodes } case ast.KindFunctionExpression: fn := node.AsFunctionExpression() if fn != nil && fn.Parameters != nil { params = fn.Parameters.Nodes } case ast.KindArrowFunction: fn := node.AsArrowFunction() if fn != nil && fn.Parameters != nil { params = fn.Parameters.Nodes } case ast.KindConstructor: constructor := node.AsConstructorDeclaration() if constructor != nil && constructor.Parameters != nil { params = constructor.Parameters.Nodes } } for _, param := range params { if param.Kind == ast.KindParameter { if ast.GetCombinedModifierFlags(param)&(ast.ModifierFlagsPublic|ast.ModifierFlagsPrivate|ast.ModifierFlagsProtected|ast.ModifierFlagsReadonly) != 0 { return true } } } return false } getBodyNode := func(node *ast.Node) *ast.Node { switch node.Kind { case ast.KindFunctionDeclaration: fn := node.AsFunctionDeclaration() if fn != nil { return fn.Body } case ast.KindFunctionExpression: fn := node.AsFunctionExpression() if fn != nil { return fn.Body } case ast.KindArrowFunction: fn := node.AsArrowFunction() if fn != nil && fn.Body != nil && fn.Body.Kind == ast.KindBlock { return fn.Body } case ast.KindConstructor: constructor := node.AsConstructorDeclaration() if constructor != nil { return constructor.Body } case ast.KindMethodDeclaration: method := node.AsMethodDeclaration() if method != nil { return method.Body } case ast.KindGetAccessor: accessor := node.AsGetAccessorDeclaration() if accessor != nil { return accessor.Body } case ast.KindSetAccessor: accessor := node.AsSetAccessorDeclaration() if accessor != nil { return accessor.Body } } return nil } getFunctionName := func(node *ast.Node) string { switch node.Kind { case ast.KindFunctionDeclaration: fn := node.AsFunctionDeclaration() if fn != nil && fn.Name() != nil && fn.Name().Kind == ast.KindIdentifier { ident := fn.Name().AsIdentifier() if ident != nil { return "function '" + ident.Text + "'" } } return "function" case ast.KindConstructor: return "constructor" case ast.KindMethodDeclaration: method := node.AsMethodDeclaration() if method != nil && method.Name() != nil { name, _ := utils.GetNameFromMember(ctx.SourceFile, method.Name()) return "method '" + name + "'" } return "method" case ast.KindGetAccessor: accessor := node.AsGetAccessorDeclaration() if accessor != nil && accessor.Name() != nil { name, _ := utils.GetNameFromMember(ctx.SourceFile, accessor.Name()) return "getter '" + name + "'" } return "getter" case ast.KindSetAccessor: accessor := node.AsSetAccessorDeclaration() if accessor != nil && accessor.Name() != nil { name, _ := utils.GetNameFromMember(ctx.SourceFile, accessor.Name()) return "setter '" + name + "'" } return "setter" case ast.KindFunctionExpression: parent := node.Parent if parent != nil { switch parent.Kind { case ast.KindMethodDeclaration: method := parent.AsMethodDeclaration() if method != nil && method.Name() != nil { name, _ := utils.GetNameFromMember(ctx.SourceFile, method.Name()) if method.Kind == ast.KindGetAccessor { return "getter '" + name + "'" } if method.Kind == ast.KindSetAccessor { return "setter '" + name + "'" } return "method '" + name + "'" } case ast.KindPropertyDeclaration: prop := parent.AsPropertyDeclaration() if prop != nil && prop.Name() != nil { name, _ := utils.GetNameFromMember(ctx.SourceFile, prop.Name()) if name != "" { return "function '" + name + "'" } } case ast.KindPropertyAssignment: prop := parent.AsPropertyAssignment() if prop != nil && prop.Name() != nil { name, _ := utils.GetNameFromMember(ctx.SourceFile, prop.Name()) if name != "" { return "function '" + name + "'" } } case ast.KindVariableDeclaration: decl := parent.AsVariableDeclaration() if decl != nil && decl.Name() != nil && decl.Name().Kind == ast.KindIdentifier { ident := decl.Name().AsIdentifier() if ident != nil { return "function '" + ident.Text + "'" } } } } return "function" case ast.KindArrowFunction: parent := node.Parent if parent != nil && parent.Kind == ast.KindVariableDeclaration { decl := parent.AsVariableDeclaration() if decl != nil && decl.Name() != nil && decl.Name().Kind == ast.KindIdentifier { ident := decl.Name().AsIdentifier() if ident != nil { return "arrow function '" + ident.Text + "'" } } } return "arrow function" default: return "function" } } checkFunction := func(node *ast.Node) { if !isBodyEmpty(node) { return } parent := node.Parent isAsync := false isGenerator := false switch node.Kind { case ast.KindFunctionDeclaration: fn := node.AsFunctionDeclaration() if fn != nil { isAsync = ast.HasSyntacticModifier(node, ast.ModifierFlagsAsync) isGenerator = fn.AsteriskToken != nil } case ast.KindFunctionExpression: fn := node.AsFunctionExpression() if fn != nil { isAsync = ast.HasSyntacticModifier(node, ast.ModifierFlagsAsync) isGenerator = fn.AsteriskToken != nil } case ast.KindArrowFunction: isAsync = ast.HasSyntacticModifier(node, ast.ModifierFlagsAsync) case ast.KindMethodDeclaration: method := node.AsMethodDeclaration() if method != nil { isAsync = ast.HasSyntacticModifier(node, ast.ModifierFlagsAsync) isGenerator = method.AsteriskToken != nil } case ast.KindGetAccessor: isAsync = ast.HasSyntacticModifier(node, ast.ModifierFlagsAsync) case ast.KindSetAccessor: isAsync = ast.HasSyntacticModifier(node, ast.ModifierFlagsAsync) case ast.KindConstructor: hasPrivate := ast.HasSyntacticModifier(node, ast.ModifierFlagsPrivate) hasProtected := ast.HasSyntacticModifier(node, ast.ModifierFlagsProtected) if isAllowed("constructors") { return } if hasPrivate && isAllowed("private-constructors") { return } if hasProtected && isAllowed("protected-constructors") { return } if hasParameterProperties(node) { return } } if node.Kind == ast.KindArrowFunction && isAllowed("arrowFunctions") { return } if isAsync && isAllowed("asyncFunctions") { return } if isGenerator && isAllowed("generatorFunctions") { return } if node.Kind == ast.KindFunctionDeclaration || node.Kind == ast.KindFunctionExpression { if isAllowed("functions") { return } } if node.Kind == ast.KindMethodDeclaration { if ast.GetCombinedModifierFlags(node)&ast.ModifierFlagsDecorator != 0 && isAllowed("decoratedFunctions") { return } if ast.HasSyntacticModifier(node, ast.ModifierFlagsOverride) && isAllowed("overrideMethods") { return } if isAsync && isAllowed("asyncMethods") { return } if isGenerator && isAllowed("generatorMethods") { return } if isAllowed("methods") { return } } if node.Kind == ast.KindGetAccessor && isAllowed("getters") { return } if node.Kind == ast.KindSetAccessor && isAllowed("setters") { return } if parent != nil && parent.Kind == ast.KindMethodDeclaration { method := parent.AsMethodDeclaration() if method != nil { if method.Kind == ast.KindGetAccessor && isAllowed("getters") { return } if method.Kind == ast.KindSetAccessor && isAllowed("setters") { return } if ast.GetCombinedModifierFlags(parent)&ast.ModifierFlagsDecorator != 0 && isAllowed("decoratedFunctions") { return } if ast.HasSyntacticModifier(parent, ast.ModifierFlagsOverride) && isAllowed("overrideMethods") { return } if method.Kind == ast.KindMethodSignature || method.Kind == ast.KindMethodDeclaration { if isAsync && isAllowed("asyncMethods") { return } if isGenerator && isAllowed("generatorMethods") { return } if isAllowed("methods") { return } } } } else { if node.Kind == ast.KindArrowFunction && isAllowed("arrowFunctions") { return } if isAsync && isAllowed("asyncFunctions") { return } if isGenerator && isAllowed("generatorFunctions") { return } if isAllowed("functions") { return } } funcName := getFunctionName(node) bodyNode := getBodyNode(node) if bodyNode != nil { ctx.ReportNode(bodyNode, rule.RuleMessage{ Id: "unexpected", Description: "Unexpected empty " + funcName + ".", }) } else { ctx.ReportNode(node, rule.RuleMessage{ Id: "unexpected", Description: "Unexpected empty " + funcName + ".", }) } } return rule.RuleListeners{ ast.KindFunctionDeclaration: checkFunction, ast.KindFunctionExpression: checkFunction, ast.KindArrowFunction: checkFunction, ast.KindConstructor: checkFunction, ast.KindMethodDeclaration: checkFunction, ast.KindGetAccessor: checkFunction, ast.KindSetAccessor: checkFunction, } }, })
Functions ¶
This section is empty.
Types ¶
type NoEmptyFunctionOptions ¶
type NoEmptyFunctionOptions struct {
Allow []string `json:"allow"`
}
Click to show internal directories.
Click to hide internal directories.