Skip to content

[BUG] Symbol name conflict when applying certain aspects #674

Description

@rarguelloF

Version of orchestrion

v1.5.0

Describe what happened:
When applying an aspect like the one we are using in dd-trace-go for net/http:

aspects:
  - join-point:
      all-of:
        - not:
            # We don't want to instrument in net/http, it'd create a circular dependency!
            import-path: net/http
        - one-of:
            - function-call: net/http.Get
            - function-call: net/http.Head
            - function-call: net/http.Post
            - function-call: net/http.PostForm
    advice:
      - wrap-expression:
          imports:
            client: github.com/DataDog/dd-trace-go/contrib/net/http/v2/client
          template: |-
            {{- $ctx := .Function.ArgumentOfType "context.Context" -}}
            {{- $req := .Function.ArgumentOfType "*net/http.Request" }}
            {{- if $ctx -}}
              client.{{ .AST.Fun.Name }}(
                {{ $ctx }},
                {{ range .AST.Args }}{{ . }},
                {{ end }}
              )
            {{- else if $req -}}
              client.{{ .AST.Fun.Name }}(
                {{ $req }}.Context(),
                {{ range .AST.Args }}{{ . }},
                {{ end }}
              )
            {{- else -}}
              {{ . }}
            {{- end -}}

And having code like this that ends up going through the else branch (and just rendering the original AST node with {{ . }}):

package example

import (
    "net/http"
)

type httpClient struct {
    serverHost string
}

func (client *httpClient) Get(path string) (*http.Response, error) {
    return http.Get("http://" + client.serverHost + path)
}

Orchestrion ends up renaming the client symbol that is inside the matched node to __orchestrion_client, producing the following code and causing the build to fail:

//line input.go:1:1
package example

import (
  "net/http"
//line <generated>:1
  __orchestrion_client "github.com/DataDog/dd-trace-go/contrib/net/http/v2/client"
)

//line input.go:7
type httpClient struct {
  serverHost string
}

func (client *httpClient) Get(path string) (*http.Response, error) {
  return http.Get("http://" + __orchestrion_client.serverHost + path)
}

Note that if the original code was like this, everything works just fine:

package example

import (
    "net/http"
)

type httpClient struct {
    serverHost string
}

func (client *httpClient) Get(path string) (*http.Response, error) {
    serverHost := client.serverHost

    return http.Get("http://" + serverHost + path)
}

Other situations where the error would not be reproduced are:

  • if the receiver was called something different than client
  • if the key in the aspects import config did not conflict with a symbol inside the rendered AST node.

Describe what you expected:

I would expect Orchestrion to not cause the build to fail.

Steps to reproduce the issue:

The first code snippet provided above should be enough to reproduce the issue.

Additional environment details (Version of Go, Operating System, etc.):

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions