cue/ast/astutil: use unlikely name for import

This is not principled at all, but better than nothing.

Change-Id: Ia92f0fe0b52a185d6b525ca865b77ab53244dfd8
Reviewed-on: https://cue-review.googlesource.com/c/cue/+/3241
Reviewed-by: Marcel van Lohuizen <mpvl@golang.org>
diff --git a/cue/ast/astutil/apply.go b/cue/ast/astutil/apply.go
index 42a70f4..d805c27 100644
--- a/cue/ast/astutil/apply.go
+++ b/cue/ast/astutil/apply.go
@@ -118,6 +118,16 @@
 		return nil
 	}
 
+	name := path.Base(importPath)
+	if p := strings.LastIndexByte(name, ':'); p > 0 {
+		name = name[p+1:]
+	}
+
+	// TODO: come up with something much better.
+	// For instance, hoist the uniquer form cue/export.go to
+	// here and make export.go use this.
+	name += "530467a1"
+
 	quoted := strconv.Quote(importPath)
 
 	var imports *ast.ImportDecl
@@ -136,10 +146,13 @@
 		case *ast.ImportDecl:
 			imports = t
 			for _, s := range t.Specs {
-				if s.Path.Value == quoted {
-					spec = s
-					break
+				if s.Path.Value != quoted ||
+					s.Name == nil ||
+					s.Name.Name != name {
+					continue
 				}
+				spec = s
+				break
 			}
 		}
 	}
@@ -153,7 +166,10 @@
 			info.current.decls = decls
 		}
 		path := &ast.BasicLit{Kind: token.STRING, Value: quoted}
-		spec = &ast.ImportSpec{Path: path}
+		spec = &ast.ImportSpec{
+			Name: ast.NewIdent(name),
+			Path: path,
+		}
 		imports.Specs = append(imports.Specs, spec)
 		ast.SetRelPos(imports.Specs[0], token.NoRelPos)
 	}
@@ -161,10 +177,6 @@
 	ident := &ast.Ident{Node: spec} // Name is set later.
 	info.importPatch = append(info.importPatch, ident)
 
-	name := path.Base(importPath)
-	if p := strings.LastIndexByte(name, ':'); p > 0 {
-		name = name[p+1:]
-	}
 	ident.Name = name
 
 	return ident
diff --git a/cue/ast/astutil/apply_test.go b/cue/ast/astutil/apply_test.go
index 899e225..4de20c1 100644
--- a/cue/ast/astutil/apply_test.go
+++ b/cue/ast/astutil/apply_test.go
@@ -205,14 +205,14 @@
 			return true
 		},
 	}, {
-		name: "imports",
+		name: "imports add",
 		in: `
 a: "string"
 			`,
 		out: `
-import "list"
+import list530467a1 "list"
 
-a: list
+a: list530467a1
 		`,
 		after: func(c astutil.Cursor) bool {
 			switch c.Node().(type) {
@@ -222,7 +222,7 @@
 			return true
 		},
 	}, {
-		name: "imports",
+		name: "imports add to",
 		in: `package foo
 
 import "math"
@@ -233,10 +233,10 @@
 
 import (
 	"math"
-	"list"
+	list530467a1 "list"
 )
 
-a: list
+a: list530467a1
 			`,
 		after: func(c astutil.Cursor) bool {
 			switch x := c.Node().(type) {
@@ -247,6 +247,32 @@
 			}
 			return true
 		},
+	}, {
+		name: "imports duplicate",
+		in: `package foo
+
+import "list"
+
+a: 3
+				`,
+		out: `package foo
+
+import (
+	"list"
+	list530467a1 "list"
+)
+
+a: list530467a1
+					`,
+		after: func(c astutil.Cursor) bool {
+			switch x := c.Node().(type) {
+			case *ast.BasicLit:
+				if x.Kind == token.INT {
+					c.Replace(c.Import("list"))
+				}
+			}
+			return true
+		},
 	}}
 	for _, tc := range testCases {
 		t.Run(tc.name, func(t *testing.T) {