Documentation
¶
Index ¶
- Constants
- Variables
- func MemberIsDeprecated(docString string) bool
- func RegisterAnalyzer(name string, analyzer *analysis.Analyzer)
- func ReplacementHint(expr ast.Expression, location common.Location, r ast.Range) *analysis.Diagnostic
- type CheckCastVisitor
- func (d *CheckCastVisitor) IsRedundantCast(expr ast.Expression, exprInferredType, targetType sema.Type) bool
- func (d *CheckCastVisitor) VisitArrayExpression(expr *ast.ArrayExpression) bool
- func (d *CheckCastVisitor) VisitAttachExpression(_ *ast.AttachExpression) bool
- func (d *CheckCastVisitor) VisitBinaryExpression(_ *ast.BinaryExpression) bool
- func (d *CheckCastVisitor) VisitBoolExpression(_ *ast.BoolExpression) bool
- func (d *CheckCastVisitor) VisitCastingExpression(_ *ast.CastingExpression) bool
- func (d *CheckCastVisitor) VisitConditionalExpression(conditionalExpr *ast.ConditionalExpression) bool
- func (d *CheckCastVisitor) VisitCreateExpression(_ *ast.CreateExpression) bool
- func (d *CheckCastVisitor) VisitDestroyExpression(_ *ast.DestroyExpression) bool
- func (d *CheckCastVisitor) VisitDictionaryExpression(expr *ast.DictionaryExpression) bool
- func (d *CheckCastVisitor) VisitFixedPointExpression(expr *ast.FixedPointExpression) bool
- func (d *CheckCastVisitor) VisitForceExpression(_ *ast.ForceExpression) bool
- func (d *CheckCastVisitor) VisitFunctionExpression(_ *ast.FunctionExpression) bool
- func (d *CheckCastVisitor) VisitIdentifierExpression(_ *ast.IdentifierExpression) bool
- func (d *CheckCastVisitor) VisitIndexExpression(_ *ast.IndexExpression) bool
- func (d *CheckCastVisitor) VisitIntegerExpression(_ *ast.IntegerExpression) bool
- func (d *CheckCastVisitor) VisitInvocationExpression(_ *ast.InvocationExpression) bool
- func (d *CheckCastVisitor) VisitMemberExpression(_ *ast.MemberExpression) bool
- func (d *CheckCastVisitor) VisitNilExpression(_ *ast.NilExpression) bool
- func (d *CheckCastVisitor) VisitPathExpression(_ *ast.PathExpression) bool
- func (d *CheckCastVisitor) VisitReferenceExpression(_ *ast.ReferenceExpression) bool
- func (d *CheckCastVisitor) VisitStringExpression(_ *ast.StringExpression) bool
- func (d *CheckCastVisitor) VisitStringTemplateExpression(_ *ast.StringTemplateExpression) bool
- func (d *CheckCastVisitor) VisitUnaryExpression(_ *ast.UnaryExpression) bool
- func (d *CheckCastVisitor) VisitVoidExpression(_ *ast.VoidExpression) bool
- type Config
- type Linter
- func (l *Linter) AnalyzeAccount(address string, networkName string)
- func (l *Linter) AnalyzeCSV(path string)
- func (l *Linter) AnalyzeDirectory(directory string)
- func (l *Linter) AnalyzeTransaction(transactionID flow.Identifier, networkName string)
- func (l *Linter) PrettyPrintError(err error, location common.Location)
Constants ¶
View Source
const ( ReplacementCategory = "replacement-hint" RemovalCategory = "removal-hint" UnnecessaryCastCategory = "unnecessary-cast-hint" UnusedResultCategory = "unused-result-hint" DeprecatedCategory = "deprecated" CadenceV1Category = "cadence-v1" )
View Source
const LoadMode = analysis.NeedTypes | analysis.NeedExtendedElaboration
Variables ¶
View Source
var Analyzers = map[string]*analysis.Analyzer{}
View Source
var CadenceV1Analyzer = (func() *analysis.Analyzer { return &analysis.Analyzer{ Description: "Detects uses of removed features in Cadence 1.0", Requires: []*analysis.Analyzer{ analysis.InspectorAnalyzer, }, Run: func(pass *analysis.Pass) interface{} { analyzer := newCadenceV1Analyzer(pass) analyzer.AnalyzeAll() return nil }, } })()
View Source
var DeprecatedMemberAnalyzer = (func() *analysis.Analyzer { elementFilter := []ast.Element{ (*ast.MemberExpression)(nil), } return &analysis.Analyzer{ Description: "Detects uses of deprecated members", Requires: []*analysis.Analyzer{ analysis.InspectorAnalyzer, }, Run: func(pass *analysis.Pass) interface{} { inspector := pass.ResultOf[analysis.InspectorAnalyzer].(*ast.Inspector) program := pass.Program location := program.Location elaboration := program.Checker.Elaboration report := pass.Report inspector.Preorder( elementFilter, func(element ast.Element) { memberExpression, ok := element.(*ast.MemberExpression) if !ok { return } memberInfo, _ := elaboration.MemberExpressionMemberAccessInfo(memberExpression) member := memberInfo.Member if member == nil { return } docStringMatch := docStringDeprecationWarningPattern.FindStringSubmatch(member.DocString) if docStringMatch == nil { return } memberName := memberInfo.Member.Identifier.Identifier identifierRange := ast.NewRangeFromPositioned(nil, memberExpression.Identifier) report( analysis.Diagnostic{ Location: location, Range: identifierRange, Category: DeprecatedCategory, Message: fmt.Sprintf( "%s '%s' is deprecated", member.DeclarationKind.Name(), memberName, ), SecondaryMessage: docStringMatch[1], }, ) }, ) return nil }, } })()
View Source
var NumberFunctionArgumentAnalyzer = (func() *analysis.Analyzer { elementFilter := []ast.Element{ (*ast.IntegerExpression)(nil), (*ast.FixedPointExpression)(nil), } return &analysis.Analyzer{ Description: "Detects redundant uses of number conversion functions.", Requires: []*analysis.Analyzer{ analysis.InspectorAnalyzer, }, Run: func(pass *analysis.Pass) interface{} { inspector := pass.ResultOf[analysis.InspectorAnalyzer].(*ast.Inspector) program := pass.Program location := program.Location elaboration := program.Checker.Elaboration report := pass.Report inspector.Preorder( elementFilter, func(element ast.Element) { var diagnostic *analysis.Diagnostic switch expr := element.(type) { case *ast.IntegerExpression: argumentData := elaboration.NumberConversionArgumentTypes(expr) if argumentData.Type == nil { return } diagnostic = suggestIntegerLiteralConversionReplacement( expr, location, argumentData.Type, argumentData.Range, ) case *ast.FixedPointExpression: argumentData := elaboration.NumberConversionArgumentTypes(expr) if argumentData.Type == nil { return } diagnostic = suggestFixedPointLiteralConversionReplacement( expr, location, argumentData.Type, argumentData.Range, ) default: return } if diagnostic != nil { report(*diagnostic) } }, ) return nil }, } })()
View Source
var RedundantCastAnalyzer = (func() *analysis.Analyzer { elementFilter := []ast.Element{ (*ast.CastingExpression)(nil), } return &analysis.Analyzer{ Description: "Detects unnecessary cast expressions", Requires: []*analysis.Analyzer{ analysis.InspectorAnalyzer, }, Run: func(pass *analysis.Pass) interface{} { inspector := pass.ResultOf[analysis.InspectorAnalyzer].(*ast.Inspector) program := pass.Program location := program.Location elaboration := program.Checker.Elaboration report := pass.Report inspector.Preorder( elementFilter, func(element ast.Element) { castingExpression, ok := element.(*ast.CastingExpression) if !ok { return } redundantType := elaboration.StaticCastTypes(castingExpression) if redundantType.ExprActualType != nil && isRedundantCast( castingExpression.Expression, redundantType.ExprActualType, redundantType.TargetType, redundantType.ExpectedType, ) { report( analysis.Diagnostic{ Location: location, Range: ast.NewRangeFromPositioned(nil, castingExpression.TypeAnnotation), Category: UnnecessaryCastCategory, Message: fmt.Sprintf("cast to `%s` is redundant", redundantType.TargetType), }, ) return } alwaysSucceedingTypes := elaboration.RuntimeCastTypes(castingExpression) if alwaysSucceedingTypes.Left != nil && sema.IsSubType(alwaysSucceedingTypes.Left, alwaysSucceedingTypes.Right) { switch castingExpression.Operation { case ast.OperationFailableCast: report( analysis.Diagnostic{ Location: location, Range: ast.NewRangeFromPositioned(nil, castingExpression), Category: UnnecessaryCastCategory, Message: fmt.Sprintf("failable cast ('%s') from `%s` to `%s` always succeeds", ast.OperationFailableCast.Symbol(), alwaysSucceedingTypes.Left, alwaysSucceedingTypes.Right), }, ) case ast.OperationForceCast: report( analysis.Diagnostic{ Location: location, Range: ast.NewRangeFromPositioned(nil, castingExpression), Category: UnnecessaryCastCategory, Message: fmt.Sprintf("force cast ('%s') from `%s` to `%s` always succeeds", ast.OperationForceCast.Symbol(), alwaysSucceedingTypes.Left, alwaysSucceedingTypes.Right), }, ) default: panic(errors.NewUnreachableError()) } } }, ) return nil }, } })()
View Source
var UnnecessaryForceAnalyzer = (func() *analysis.Analyzer { elementFilter := []ast.Element{ (*ast.ForceExpression)(nil), } return &analysis.Analyzer{ Description: "Detects unnecessary uses of the force operator", Requires: []*analysis.Analyzer{ analysis.InspectorAnalyzer, }, Run: func(pass *analysis.Pass) interface{} { inspector := pass.ResultOf[analysis.InspectorAnalyzer].(*ast.Inspector) program := pass.Program location := program.Location elaboration := program.Checker.Elaboration report := pass.Report inspector.Preorder( elementFilter, func(element ast.Element) { forceExpression, ok := element.(*ast.ForceExpression) if !ok { return } valueType := elaboration.ForceExpressionType(forceExpression) if valueType == nil { return } _, ok = valueType.(*sema.OptionalType) if !ok { report( analysis.Diagnostic{ Location: location, Range: ast.NewRangeFromPositioned(nil, element), Category: RemovalCategory, Message: "unnecessary force operator", }, ) } }, ) return nil }, } })()
View Source
var UnusedResultAnalyzer = (func() *analysis.Analyzer { elementFilter := []ast.Element{ (*ast.ExpressionStatement)(nil), } return &analysis.Analyzer{ Description: "Detects unused results of expressions", Requires: []*analysis.Analyzer{ analysis.InspectorAnalyzer, }, Run: func(pass *analysis.Pass) interface{} { inspector := pass.ResultOf[analysis.InspectorAnalyzer].(*ast.Inspector) program := pass.Program location := program.Location elaboration := program.Checker.Elaboration report := pass.Report inspector.Preorder( elementFilter, func(element ast.Element) { expressionStatement, ok := element.(*ast.ExpressionStatement) if !ok { return } ty := elaboration.ExpressionTypes(expressionStatement.Expression).ActualType switch ty { case nil, sema.VoidType, sema.NeverType: default: report( analysis.Diagnostic{ Location: location, Range: ast.NewRangeFromPositioned(nil, element), Category: UnusedResultCategory, Message: "unused result", }, ) } }, ) return nil }, } })()
Functions ¶
func MemberIsDeprecated ¶ added in v0.9.0
func RegisterAnalyzer ¶ added in v0.5.0
func ReplacementHint ¶
func ReplacementHint( expr ast.Expression, location common.Location, r ast.Range, ) *analysis.Diagnostic
Types ¶
type CheckCastVisitor ¶
type CheckCastVisitor struct {
// contains filtered or unexported fields
}
func (*CheckCastVisitor) IsRedundantCast ¶
func (d *CheckCastVisitor) IsRedundantCast(expr ast.Expression, exprInferredType, targetType sema.Type) bool
func (*CheckCastVisitor) VisitArrayExpression ¶
func (d *CheckCastVisitor) VisitArrayExpression(expr *ast.ArrayExpression) bool
func (*CheckCastVisitor) VisitAttachExpression ¶ added in v0.5.0
func (d *CheckCastVisitor) VisitAttachExpression(_ *ast.AttachExpression) bool
func (*CheckCastVisitor) VisitBinaryExpression ¶
func (d *CheckCastVisitor) VisitBinaryExpression(_ *ast.BinaryExpression) bool
func (*CheckCastVisitor) VisitBoolExpression ¶
func (d *CheckCastVisitor) VisitBoolExpression(_ *ast.BoolExpression) bool
func (*CheckCastVisitor) VisitCastingExpression ¶
func (d *CheckCastVisitor) VisitCastingExpression(_ *ast.CastingExpression) bool
func (*CheckCastVisitor) VisitConditionalExpression ¶
func (d *CheckCastVisitor) VisitConditionalExpression(conditionalExpr *ast.ConditionalExpression) bool
func (*CheckCastVisitor) VisitCreateExpression ¶
func (d *CheckCastVisitor) VisitCreateExpression(_ *ast.CreateExpression) bool
func (*CheckCastVisitor) VisitDestroyExpression ¶
func (d *CheckCastVisitor) VisitDestroyExpression(_ *ast.DestroyExpression) bool
func (*CheckCastVisitor) VisitDictionaryExpression ¶
func (d *CheckCastVisitor) VisitDictionaryExpression(expr *ast.DictionaryExpression) bool
func (*CheckCastVisitor) VisitFixedPointExpression ¶
func (d *CheckCastVisitor) VisitFixedPointExpression(expr *ast.FixedPointExpression) bool
func (*CheckCastVisitor) VisitForceExpression ¶
func (d *CheckCastVisitor) VisitForceExpression(_ *ast.ForceExpression) bool
func (*CheckCastVisitor) VisitFunctionExpression ¶
func (d *CheckCastVisitor) VisitFunctionExpression(_ *ast.FunctionExpression) bool
func (*CheckCastVisitor) VisitIdentifierExpression ¶
func (d *CheckCastVisitor) VisitIdentifierExpression(_ *ast.IdentifierExpression) bool
func (*CheckCastVisitor) VisitIndexExpression ¶
func (d *CheckCastVisitor) VisitIndexExpression(_ *ast.IndexExpression) bool
func (*CheckCastVisitor) VisitIntegerExpression ¶
func (d *CheckCastVisitor) VisitIntegerExpression(_ *ast.IntegerExpression) bool
func (*CheckCastVisitor) VisitInvocationExpression ¶
func (d *CheckCastVisitor) VisitInvocationExpression(_ *ast.InvocationExpression) bool
func (*CheckCastVisitor) VisitMemberExpression ¶
func (d *CheckCastVisitor) VisitMemberExpression(_ *ast.MemberExpression) bool
func (*CheckCastVisitor) VisitNilExpression ¶
func (d *CheckCastVisitor) VisitNilExpression(_ *ast.NilExpression) bool
func (*CheckCastVisitor) VisitPathExpression ¶
func (d *CheckCastVisitor) VisitPathExpression(_ *ast.PathExpression) bool
func (*CheckCastVisitor) VisitReferenceExpression ¶
func (d *CheckCastVisitor) VisitReferenceExpression(_ *ast.ReferenceExpression) bool
func (*CheckCastVisitor) VisitStringExpression ¶
func (d *CheckCastVisitor) VisitStringExpression(_ *ast.StringExpression) bool
func (*CheckCastVisitor) VisitStringTemplateExpression ¶ added in v1.2.0
func (d *CheckCastVisitor) VisitStringTemplateExpression(_ *ast.StringTemplateExpression) bool
func (*CheckCastVisitor) VisitUnaryExpression ¶
func (d *CheckCastVisitor) VisitUnaryExpression(_ *ast.UnaryExpression) bool
func (*CheckCastVisitor) VisitVoidExpression ¶
func (d *CheckCastVisitor) VisitVoidExpression(_ *ast.VoidExpression) bool
type Linter ¶
type Linter struct { Config Config Codes map[common.Location][]byte // contains filtered or unexported fields }
func (*Linter) AnalyzeAccount ¶
func (*Linter) AnalyzeCSV ¶
func (*Linter) AnalyzeDirectory ¶
func (*Linter) AnalyzeTransaction ¶
Source Files
¶
Click to show internal directories.
Click to hide internal directories.