return bootstrapFixImports(srcFile)
}
+var (
+ importRE = regexp.MustCompile(`\Aimport\s+(\.|[A-Za-z0-9_]+)?\s*"([^"]+)"\s*(//.*)?\n\z`)
+ importBlockRE = regexp.MustCompile(`\A\s*(?:(\.|[A-Za-z0-9_]+)?\s*"([^"]+)")?\s*(//.*)?\n\z`)
+)
+
func bootstrapFixImports(srcFile string) string {
text := readfile(srcFile)
if !strings.Contains(srcFile, "/cmd/") && !strings.Contains(srcFile, `\cmd\`) {
}
lines := strings.SplitAfter(text, "\n")
inBlock := false
+ inComment := false
for i, line := range lines {
+ if strings.HasSuffix(line, "*/\n") {
+ inComment = false
+ }
+ if strings.HasSuffix(line, "/*\n") {
+ inComment = true
+ }
+ if inComment {
+ continue
+ }
if strings.HasPrefix(line, "import (") {
inBlock = true
continue
inBlock = false
continue
}
- if strings.HasPrefix(line, `import `) || inBlock {
- line = strings.Replace(line, `"cmd/`, `"bootstrap/cmd/`, -1)
+
+ var m []string
+ if !inBlock {
+ if !strings.HasPrefix(line, "import ") {
+ continue
+ }
+ m = importRE.FindStringSubmatch(line)
+ if m == nil {
+ fatalf("%s:%d: invalid import declaration: %q", srcFile, i+1, line)
+ }
+ } else {
+ m = importBlockRE.FindStringSubmatch(line)
+ if m == nil {
+ fatalf("%s:%d: invalid import block line", srcFile, i+1)
+ }
+ if m[2] == "" {
+ continue
+ }
+ }
+
+ path := m[2]
+ if strings.HasPrefix(path, "cmd/") {
+ path = "bootstrap/" + path
+ } else {
for _, dir := range bootstrapDirs {
- if strings.HasPrefix(dir, "cmd/") {
- continue
+ if path == dir {
+ path = "bootstrap/" + dir
+ break
}
- line = strings.Replace(line, `"`+dir+`"`, `"bootstrap/`+dir+`"`, -1)
}
- lines[i] = line
+ }
+
+ // Rewrite use of internal/reflectlite to be plain reflect.
+ if path == "internal/reflectlite" {
+ lines[i] = strings.ReplaceAll(line, `"reflect"`, `reflectlite "reflect"`)
+ continue
+ }
+
+ // Otherwise, reject direct imports of internal packages,
+ // since that implies knowledge of internal details that might
+ // change from one bootstrap toolchain to the next.
+ // There are many internal packages that are listed in
+ // bootstrapDirs and made into bootstrap copies based on the
+ // current repo's source code. Those are fine; this is catching
+ // references to internal packages in the older bootstrap toolchain.
+ if strings.HasPrefix(path, "internal/") {
+ fatalf("%s:%d: bootstrap-copied source file cannot import %s", srcFile, i+1, path)
+ }
+ if path != m[2] {
+ lines[i] = strings.ReplaceAll(line, `"`+m[2]+`"`, `"`+path+`"`)
}
}