diff options
| -rw-r--r-- | gocapturedrefrace.go | 89 | 
1 files changed, 52 insertions, 37 deletions
| diff --git a/gocapturedrefrace.go b/gocapturedrefrace.go index cdc6486..3f776e0 100644 --- a/gocapturedrefrace.go +++ b/gocapturedrefrace.go @@ -85,13 +85,12 @@ func checkClosure(pass *analysis.Pass, funcLit *ast.FuncLit) {  	// Get the closure's scope.  	funcScope := pass.TypesInfo.Scopes[funcLit.Type] +	localAssignments := checkShadowing(pass, funcLit) +	fmt.Printf("localAssignments: %#v\n", localAssignments) +  	ast.Inspect(  		funcLit,  		func(node ast.Node) bool { -			if isShadowingDeclaration(pass, node, funcScope) { -				return true -			} -  			ident, ok := node.(*ast.Ident)  			if !ok {  				return true @@ -101,6 +100,13 @@ func checkClosure(pass *analysis.Pass, funcLit *ast.FuncLit) {  				return true  			} +			// Ignore shadowed variables. +			for _, localAssignmentIdent := range localAssignments { +				if ident == localAssignmentIdent { +					return true +				} +			} +  			// Find out whether `ident` was defined in an outer scope.  			scope, scopeObj := funcScope.LookupParent(ident.Name, ident.NamePos) @@ -140,43 +146,52 @@ func checkClosure(pass *analysis.Pass, funcLit *ast.FuncLit) {  }  // TODO: doc -func isShadowingDeclaration( +func checkShadowing(  	pass *analysis.Pass, -	node ast.Node, -	funcScope *types.Scope, -) bool { +	funcLit *ast.FuncLit, +	// funcScope *types.Scope, +) (localAssignments []*ast.Ident) {  	// TODO: Plan: Change this function to checkShadowing. Call ast.Inspect and build a list of local assignments in the closure. Then in checkClosure, ignore objects in the local assignments list. -	assignStmt, ok := node.(*ast.AssignStmt) -	if !ok { -		return false -	} +	localAssignments = []*ast.Ident{} -	if assignStmt.Tok != token.DEFINE { -		return false -	} +	ast.Inspect( +		funcLit, +		func(node ast.Node) bool { +			assignStmt, ok := node.(*ast.AssignStmt) +			if !ok { +				return true +			} -	for _, lhs := range assignStmt.Lhs { -		ident, ok := lhs.(*ast.Ident) -		if !ok { -			return false -		} -		fmt.Printf("assignStmt: %#v\n", ident) - -		if ident == nil { -			return false -		} - -		return true - -		// TODO: If ident is in parent, ignore it an move on. -		// scope, scopeObj := funcScope.LookupParent(ident.Name, ident.NamePos) -		// -		// // Identifier is local to the closure. -		// if scope == nil && scopeObj == nil { -		// 	return -		// } -	} +			if assignStmt.Tok != token.DEFINE { +				return true +			} + +			for _, lhs := range assignStmt.Lhs { +				ident, ok := lhs.(*ast.Ident) +				if !ok { +					return true +				} +				fmt.Printf("assignStmt: %#v\n", ident) + +				if ident == nil { +					return true +				} + +				localAssignments = append(localAssignments, ident) + +				// TODO: If ident is in parent, ignore it an move on. +				// scope, scopeObj := funcScope.LookupParent(ident.Name, ident.NamePos) +				// +				// // Identifier is local to the closure. +				// if scope == nil && scopeObj == nil { +				// 	return +				// } +			} + +			return true +		}, +	) -	return false +	return localAssignments  } | 
