| // Licensed to Apache Software Foundation (ASF) under one or more contributor |
| // license agreements. See the NOTICE file distributed with |
| // this work for additional information regarding copyright |
| // ownership. Apache Software Foundation (ASF) licenses this file to you under |
| // the Apache License, Version 2.0 (the "License"); you may |
| // not use this file except in compliance with the License. |
| // You may obtain a copy of the License at |
| // |
| // http://www.apache.org/licenses/LICENSE-2.0 |
| // |
| // Unless required by applicable law or agreed to in writing, |
| // software distributed under the License is distributed on an |
| // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| // KIND, either express or implied. See the License for the |
| // specific language governing permissions and limitations |
| // under the License. |
| |
| package rewrite |
| |
| import ( |
| "fmt" |
| "go/token" |
| "path/filepath" |
| "strings" |
| |
| "github.com/apache/skywalking-go/tools/go-agent/instrument/agentcore" |
| |
| "github.com/dave/dst" |
| "github.com/dave/dst/dstutil" |
| ) |
| |
| func (c *Context) Import(imp *dst.ImportSpec, cursor *dstutil.Cursor) { |
| shouldRemove := false |
| operatorCode := false |
| // delete the original import("agent/core/xxx") |
| for _, subPackageName := range OperatorDirs { |
| path := strings.ReplaceAll(filepath.Join(agentcore.EnhanceFromBasePackage, subPackageName), `\`, `/`) |
| if imp.Path.Value == fmt.Sprintf("%q", path) { |
| shouldRemove = true |
| operatorCode = true |
| break |
| } |
| } |
| // delete the same framework package import, such as the interceptor of http package("github.com/gin-gonic/gin") |
| if imp.Path.Value == fmt.Sprintf("%q", c.pkgFullPath) { |
| shouldRemove = true |
| } |
| |
| if shouldRemove { |
| realPath := imp.Path.Value[1 : len(imp.Path.Value)-1] |
| subPath := filepath.Base(realPath) |
| info := &rewriteImportInfo{pkgName: subPath, isAgentCore: operatorCode, ctx: c} |
| if imp.Name == nil { |
| c.packageImport[subPath] = info |
| } else { |
| c.packageImport[imp.Name.Name] = info |
| } |
| cursor.Delete() |
| } |
| } |
| |
| func (c *Context) AddingImportToCurrentFile(name, path string) { |
| // if needs to been added package same with current package, then ignore |
| if c.pkgFullPath == path { |
| return |
| } |
| var latestImport *dst.GenDecl |
| var containsPath bool |
| dstutil.Apply(c.currentProcessingFile, func(cursor *dstutil.Cursor) bool { |
| if gen, ok := cursor.Node().(*dst.GenDecl); ok && gen.Tok == token.IMPORT { |
| latestImport = gen |
| for _, spec := range gen.Specs { |
| if imp, ok := spec.(*dst.ImportSpec); ok && imp.Path.Value == fmt.Sprintf("%q", path) { |
| containsPath = true |
| } |
| } |
| return false |
| } |
| // reduce the looping |
| if cursor.Node() == c.currentProcessingFile { |
| return true |
| } |
| return false |
| }, func(cursor *dstutil.Cursor) bool { |
| return true |
| }) |
| |
| // if already contains the path, then ignore |
| if containsPath { |
| return |
| } |
| |
| // if import not found, then create one and add to the file |
| if latestImport == nil { |
| latestImport = &dst.GenDecl{ |
| Tok: token.IMPORT, |
| Specs: []dst.Spec{}, |
| } |
| c.currentProcessingFile.Decls = append([]dst.Decl{latestImport}, c.currentProcessingFile.Decls...) |
| } |
| |
| // adding the import |
| imp := &dst.ImportSpec{ |
| Path: &dst.BasicLit{ |
| Kind: token.STRING, |
| Value: fmt.Sprintf("%q", path), |
| }, |
| Name: dst.NewIdent(name), |
| } |
| latestImport.Specs = append(latestImport.Specs, imp) |
| } |