addContext adds context to a node and its whole subtree. context is the surrounding context of a node (e.g. a function it's in) bind is a name that the node is bound to, i.e. if node is a local bind body then bind is its name. For nodes that are not bound to variables `anonymous` should be passed.
(node ast.Node, context *string, bind string)
| 376 | // In such case bind for binary node 2 + 2 is "x" and for every other node, |
| 377 | // including its children, its anonymous. |
| 378 | func addContext(node ast.Node, context *string, bind string) { |
| 379 | if node == nil { |
| 380 | return |
| 381 | } |
| 382 | |
| 383 | node.SetContext(context) |
| 384 | |
| 385 | switch node := node.(type) { |
| 386 | case *ast.Function: |
| 387 | funContext := functionContext(bind) |
| 388 | addContext(node.Body, funContext, anonymous) |
| 389 | for i := range node.Parameters { |
| 390 | if node.Parameters[i].DefaultArg != nil { |
| 391 | // Default arguments have the same context as the function body. |
| 392 | addContext(node.Parameters[i].DefaultArg, funContext, anonymous) |
| 393 | } |
| 394 | } |
| 395 | case *ast.Object: |
| 396 | // TODO(sbarzowski) include fieldname, maybe even chains |
| 397 | |
| 398 | outOfObject := DirectChildren(node) |
| 399 | for _, f := range outOfObject { |
| 400 | // This actually is evaluated outside of object |
| 401 | addContext(f, context, anonymous) |
| 402 | } |
| 403 | |
| 404 | objContext := objectContext(bind) |
| 405 | inObject := inObjectFieldsChildren(node.Fields) |
| 406 | for _, f := range inObject { |
| 407 | // This actually is evaluated outside of object |
| 408 | addContext(f, objContext, anonymous) |
| 409 | } |
| 410 | |
| 411 | case *ast.ObjectComp: |
| 412 | outOfObject := DirectChildren(node) |
| 413 | for _, f := range outOfObject { |
| 414 | // This actually is evaluated outside of object |
| 415 | addContext(f, context, anonymous) |
| 416 | } |
| 417 | |
| 418 | objContext := objectContext(bind) |
| 419 | inObject := inObjectFieldsChildren(node.Fields) |
| 420 | for _, f := range inObject { |
| 421 | // This actually is evaluated outside of object |
| 422 | addContext(f, objContext, anonymous) |
| 423 | } |
| 424 | |
| 425 | case *ast.Local: |
| 426 | for _, bind := range node.Binds { |
| 427 | namedThunkContext := "thunk <" + string(bind.Variable) + "> from <" + *context + ">" |
| 428 | if bind.Fun != nil { |
| 429 | addContext(bind.Fun, &namedThunkContext, string(bind.Variable)) |
| 430 | } else { |
| 431 | addContext(bind.Body, &namedThunkContext, string(bind.Variable)) |
| 432 | } |
| 433 | } |
| 434 | addContext(node.Body, context, bind) |
| 435 | default: |
no test coverage detected
searching dependent graphs…