diff options
| -rw-r--r-- | defererr.go | 146 | 
1 files changed, 78 insertions, 68 deletions
| diff --git a/defererr.go b/defererr.go index 12ecd2f..dfaffc4 100644 --- a/defererr.go +++ b/defererr.go @@ -147,90 +147,100 @@ func checkFunctions(pass *analysis.Pass, node ast.Node) {  				return true  			} -			ast.Inspect( -				funcDecl.Body, -				func(node ast.Node) bool { -					returnStmt, ok := node.(*ast.ReturnStmt) -					if !ok { -						return true -					} +			checkFunctionReturns(pass, funcDecl.Body, errorReturnIndex, fState) -					if returnStmt.Pos() <= fState.firstErrorDeferEndPos { -						return true -					} +			fmt.Println() -					// TODO: Check whether returnStmt uses error variable. -					fmt.Printf("returnStmt: %#v\n", returnStmt) +			return true +		}, +	) +} -					if returnStmt.Results == nil { -						return true -					} +// TODO: doc +func checkFunctionReturns( +	pass *analysis.Pass, +	funcBody *ast.BlockStmt, +	errorReturnIndex int, +	fState *functionState, +) { +	ast.Inspect( +		funcBody, +		func(node ast.Node) bool { +			returnStmt, ok := node.(*ast.ReturnStmt) +			if !ok { +				return true +			} -					fmt.Printf("returnStmt.Results: %#v\n", returnStmt.Results) +			if returnStmt.Pos() <= fState.firstErrorDeferEndPos { +				return true +			} -					for _, expr := range returnStmt.Results { -						fmt.Printf("returnStmt expr: %#v\n", expr) +			// TODO: Check whether returnStmt uses error variable. +			fmt.Printf("returnStmt: %#v\n", returnStmt) -						t := pass.TypesInfo.Types[expr] -						fmt.Printf("returnStmt expr type: %#v\n", t) -					} +			if returnStmt.Results == nil { +				return true +			} -					// TODO: Get returnStmt.Results[error index from function result signature] -					// If not variable and name not [error variable name from defer], report diagnostic -					returnErrorExpr := returnStmt.Results[errorReturnIndex] -					t := pass.TypesInfo.Types[returnErrorExpr] -					fmt.Printf("returnStmt value type: %#v\n", t) -					fmt.Printf("returnStmt type type: %#v\n", t.Type) +			fmt.Printf("returnStmt.Results: %#v\n", returnStmt.Results) -					returnErrorIdent, ok := returnErrorExpr.(*ast.Ident) -					if !ok { -						return true -					} +			for _, expr := range returnStmt.Results { +				fmt.Printf("returnStmt expr: %#v\n", expr) -					// TODO: Require t.Type to be *types.Named -					_, ok = t.Type.(*types.Named) -					if !ok { -						// TODO: report +				t := pass.TypesInfo.Types[expr] +				fmt.Printf("returnStmt expr type: %#v\n", t) +			} -						pass.Reportf( -							returnErrorIdent.Pos(), -							"does not return '%s'", -							fState.deferErrorVar, -						) +			// TODO: Get returnStmt.Results[error index from function result signature] +			// If not variable and name not [error variable name from defer], report diagnostic +			returnErrorExpr := returnStmt.Results[errorReturnIndex] +			t := pass.TypesInfo.Types[returnErrorExpr] +			fmt.Printf("returnStmt value type: %#v\n", t) +			fmt.Printf("returnStmt type type: %#v\n", t.Type) -						return true -					} +			returnErrorIdent, ok := returnErrorExpr.(*ast.Ident) +			if !ok { +				return true +			} -					// Or, we want to compare with the error declared in the function signature. -					fmt.Printf("returnError: %#v\n", returnErrorExpr) +			// TODO: Require t.Type to be *types.Named +			_, ok = t.Type.(*types.Named) +			if !ok { +				// TODO: report -					if returnErrorIdent.Name == fState.deferErrorVar.Name { -						fmt.Printf( -							"names: return:%#v : defer:%#v\n", -							returnErrorIdent.Name, -							fState.deferErrorVar.Name, -						) -					} +				pass.Reportf( +					returnErrorIdent.Pos(), +					"does not return '%s'", +					fState.deferErrorVar, +				) -					if returnErrorIdent.Name != fState.deferErrorVar.Name { -						fmt.Printf( -							"names: return:%#v : defer:%#v\n", -							returnErrorIdent.Name, -							fState.deferErrorVar.Name, -						) - -						pass.Reportf( -							returnErrorIdent.Pos(), -							"does not return '%s'", -							fState.deferErrorVar, -						) -					} +				return true +			} -					return true -				}, -			) +			// Or, we want to compare with the error declared in the function signature. +			fmt.Printf("returnError: %#v\n", returnErrorExpr) -			fmt.Println() +			if returnErrorIdent.Name == fState.deferErrorVar.Name { +				fmt.Printf( +					"names: return:%#v : defer:%#v\n", +					returnErrorIdent.Name, +					fState.deferErrorVar.Name, +				) +			} + +			if returnErrorIdent.Name != fState.deferErrorVar.Name { +				fmt.Printf( +					"names: return:%#v : defer:%#v\n", +					returnErrorIdent.Name, +					fState.deferErrorVar.Name, +				) + +				pass.Reportf( +					returnErrorIdent.Pos(), +					"does not return '%s'", +					fState.deferErrorVar, +				) +			}  			return true  		}, | 
