feat: null safety
This commit is contained in:
68
common/nullSafetyCheck.go
Normal file
68
common/nullSafetyCheck.go
Normal file
@@ -0,0 +1,68 @@
|
||||
package common
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/fatih/structtag"
|
||||
"go/ast"
|
||||
"golang.org/x/tools/go/analysis"
|
||||
)
|
||||
|
||||
func isPointerType(typeExpr ast.Expr) bool {
|
||||
isPointer := false
|
||||
if _, ok := typeExpr.(*ast.StarExpr); ok {
|
||||
isPointer = true
|
||||
}
|
||||
return isPointer
|
||||
}
|
||||
|
||||
func isGormValueNullable(tags *structtag.Tags) (*bool, error) {
|
||||
gormTag, err := tags.Get("gorm")
|
||||
if gormTag == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
gormTag.Options = append([]string{gormTag.Name}, gormTag.Options...)
|
||||
|
||||
if err != nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
nullTagExist := gormTag.HasOption("null")
|
||||
notNullTagExist := gormTag.HasOption("not null")
|
||||
|
||||
if nullTagExist == notNullTagExist && nullTagExist == true {
|
||||
return nil, errors.New(`tags "null" and "not null" are specified at one field`)
|
||||
}
|
||||
|
||||
if nullTagExist {
|
||||
return PointerOf(true), nil
|
||||
} else if notNullTagExist {
|
||||
return PointerOf(false), nil
|
||||
} else {
|
||||
return PointerOf(false), nil
|
||||
}
|
||||
}
|
||||
|
||||
func CheckFieldNullConsistency(pass analysis.Pass, field ast.Field, structName string, structTags string) {
|
||||
tags, err := structtag.Parse(structTags)
|
||||
if err != nil {
|
||||
pass.Reportf(field.Pos(), "Invalid structure tag: %s", err)
|
||||
}
|
||||
if tags == nil {
|
||||
return
|
||||
}
|
||||
|
||||
isFieldNullable := isPointerType(field.Type)
|
||||
isColumnNullable, err := isGormValueNullable(tags)
|
||||
|
||||
if err != nil {
|
||||
pass.Reportf(field.Pos(), "Null safety error: %s", err)
|
||||
}
|
||||
if isColumnNullable == nil {
|
||||
return
|
||||
}
|
||||
|
||||
if isFieldNullable != *isColumnNullable {
|
||||
pass.Reportf(field.Pos(), "Null safety error in \"%s\" model, field \"%s\": column nullable policy doesn't match to tag nullable policy", structName, field.Names[0].Name)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user