Merge "Collect deps from r8"
diff --git a/android/bazel.go b/android/bazel.go
index 0617367..7e2727c 100644
--- a/android/bazel.go
+++ b/android/bazel.go
@@ -393,7 +393,7 @@
 	// A module can either be in this list or its directory allowlisted entirely
 	// in bp2buildDefaultConfig, but not both at the same time.
 	bp2buildModuleAlwaysConvertList = []string{
-		"junit-params-assertj-core",
+		"prebuilt_junit-params-assertj-core",
 
 		//external/avb
 		"avbtool",
@@ -419,6 +419,10 @@
 		"fec",
 	}
 
+	// Per-module-type allowlist to always opt modules in of both bp2build and mixed builds
+	// when they have the same type as one listed.
+	bp2buildModuleTypeAlwaysConvertList = []string{}
+
 	// Per-module denylist to always opt modules out of both bp2build and mixed builds.
 	bp2buildModuleDoNotConvertList = []string{
 		"libnativehelper_compat_libc", // Broken compile: implicit declaration of function 'strerror_r' is invalid in C99
@@ -612,10 +616,11 @@
 	}
 
 	// Used for quicker lookups
-	bp2buildModuleDoNotConvert  = map[string]bool{}
-	bp2buildModuleAlwaysConvert = map[string]bool{}
-	bp2buildCcLibraryStaticOnly = map[string]bool{}
-	mixedBuildsDisabled         = map[string]bool{}
+	bp2buildModuleDoNotConvert      = map[string]bool{}
+	bp2buildModuleAlwaysConvert     = map[string]bool{}
+	bp2buildModuleTypeAlwaysConvert = map[string]bool{}
+	bp2buildCcLibraryStaticOnly     = map[string]bool{}
+	mixedBuildsDisabled             = map[string]bool{}
 )
 
 func init() {
@@ -623,6 +628,10 @@
 		bp2buildModuleAlwaysConvert[moduleName] = true
 	}
 
+	for _, moduleType := range bp2buildModuleTypeAlwaysConvertList {
+		bp2buildModuleTypeAlwaysConvert[moduleType] = true
+	}
+
 	for _, moduleName := range bp2buildModuleDoNotConvertList {
 		bp2buildModuleDoNotConvert[moduleName] = true
 	}
@@ -698,11 +707,17 @@
 }
 
 func (b *BazelModuleBase) shouldConvertWithBp2build(ctx BazelConversionContext, module blueprint.Module) bool {
-	moduleNameNoPrefix := RemoveOptionalPrebuiltPrefix(module.Name())
-	alwaysConvert := bp2buildModuleAlwaysConvert[moduleNameNoPrefix]
+	moduleName := module.Name()
+	moduleNameAllowed := bp2buildModuleAlwaysConvert[moduleName]
+	moduleTypeAllowed := bp2buildModuleTypeAlwaysConvert[ctx.OtherModuleType(module)]
+	allowlistConvert := moduleNameAllowed || moduleTypeAllowed
+	if moduleNameAllowed && moduleTypeAllowed {
+		ctx.(BaseModuleContext).ModuleErrorf("A module cannot be in bp2buildModuleAlwaysConvert and also be" +
+			" in bp2buildModuleTypeAlwaysConvert")
+	}
 
-	if bp2buildModuleDoNotConvert[moduleNameNoPrefix] {
-		if alwaysConvert {
+	if bp2buildModuleDoNotConvert[moduleName] {
+		if moduleNameAllowed {
 			ctx.(BaseModuleContext).ModuleErrorf("a module cannot be in bp2buildModuleDoNotConvert" +
 				" and also be in bp2buildModuleAlwaysConvert")
 		}
@@ -713,19 +728,23 @@
 		return false
 	}
 
+	propValue := b.bazelProperties.Bazel_module.Bp2build_available
 	packagePath := ctx.OtherModuleDir(module)
-	if alwaysConvert && ShouldKeepExistingBuildFileForDir(packagePath) {
-		ctx.(BaseModuleContext).ModuleErrorf("A module cannot be in a directory listed in bp2buildKeepExistingBuildFile"+
-			" and also be in bp2buildModuleAlwaysConvert. Directory: '%s'", packagePath)
-
+	// Modules in unit tests which are enabled in the allowlist by type or name
+	// trigger this conditional because unit tests run under the "." package path
+	isTestModule := packagePath == "." && proptools.BoolDefault(propValue, false)
+	if allowlistConvert && !isTestModule && ShouldKeepExistingBuildFileForDir(packagePath) {
+		if moduleNameAllowed {
+			ctx.(BaseModuleContext).ModuleErrorf("A module cannot be in a directory listed in bp2buildKeepExistingBuildFile"+
+				" and also be in bp2buildModuleAlwaysConvert. Directory: '%s'", packagePath)
+		}
 		return false
 	}
 
 	config := ctx.Config().bp2buildPackageConfig
 	// This is a tristate value: true, false, or unset.
-	propValue := b.bazelProperties.Bazel_module.Bp2build_available
 	if bp2buildDefaultTrueRecursively(packagePath, config) {
-		if alwaysConvert {
+		if moduleNameAllowed {
 			ctx.(BaseModuleContext).ModuleErrorf("A module cannot be in a directory marked Bp2BuildDefaultTrue"+
 				" or Bp2BuildDefaultTrueRecursively and also be in bp2buildModuleAlwaysConvert. Directory: '%s'",
 				packagePath)
@@ -736,7 +755,7 @@
 	}
 
 	// Allow modules to explicitly opt-in.
-	return proptools.BoolDefault(propValue, alwaysConvert)
+	return proptools.BoolDefault(propValue, allowlistConvert)
 }
 
 // bp2buildDefaultTrueRecursively checks that the package contains a prefix from the
diff --git a/android/bazel_handler.go b/android/bazel_handler.go
index 3d6babc..d851a98 100644
--- a/android/bazel_handler.go
+++ b/android/bazel_handler.go
@@ -50,8 +50,8 @@
 
 // Portion of cquery map key to describe target configuration.
 type configKey struct {
-	archType ArchType
-	osType   OsType
+	arch   string
+	osType OsType
 }
 
 // Map key to describe bazel cquery requests.
@@ -862,7 +862,7 @@
 }
 
 func getConfigString(key cqueryKey) string {
-	arch := key.configKey.archType.Name
+	arch := key.configKey.arch
 	if len(arch) == 0 || arch == "common" {
 		// Use host platform, which is currently hardcoded to be x86_64.
 		arch = "x86_64"
@@ -876,5 +876,9 @@
 }
 
 func GetConfigKey(ctx ModuleContext) configKey {
-	return configKey{archType: ctx.Arch().ArchType, osType: ctx.Os()}
+	return configKey{
+		// use string because Arch is not a valid key in go
+		arch:   ctx.Arch().String(),
+		osType: ctx.Os(),
+	}
 }
diff --git a/android/bazel_handler_test.go b/android/bazel_handler_test.go
index ad5b63b..e5cff90 100644
--- a/android/bazel_handler_test.go
+++ b/android/bazel_handler_test.go
@@ -9,9 +9,9 @@
 
 func TestRequestResultsAfterInvokeBazel(t *testing.T) {
 	label := "//foo:bar"
-	cfg := configKey{Arm64, Android}
+	cfg := configKey{"arm64_armv8-a", Android}
 	bazelContext, _ := testBazelContext(t, map[bazelCommand]string{
-		bazelCommand{command: "cquery", expression: "deps(@soong_injection//mixed_builds:buildroot, 2)"}: `//foo:bar|arm64|android>>out/foo/bar.txt`,
+		bazelCommand{command: "cquery", expression: "deps(@soong_injection//mixed_builds:buildroot, 2)"}: `//foo:bar|arm64_armv8-a|android>>out/foo/bar.txt`,
 	})
 	g, ok := bazelContext.GetOutputFiles(label, cfg)
 	if ok {
diff --git a/android/filegroup.go b/android/filegroup.go
index d2ff97d..50356d1 100644
--- a/android/filegroup.go
+++ b/android/filegroup.go
@@ -119,12 +119,12 @@
 		return
 	}
 
-	archVariant := ctx.Arch().ArchType
+	archVariant := ctx.Arch().String()
 	osVariant := ctx.Os()
 	if len(fg.Srcs()) == 1 && fg.Srcs()[0].Base() == fg.Name() {
 		// This will be a regular file target, not filegroup, in Bazel.
 		// See FilegroupBp2Build for more information.
-		archVariant = Common
+		archVariant = Common.String()
 		osVariant = CommonOS
 	}
 
diff --git a/androidmk/parser/parser.go b/androidmk/parser/parser.go
index d24efc1..fb6be38 100644
--- a/androidmk/parser/parser.go
+++ b/androidmk/parser/parser.go
@@ -222,7 +222,7 @@
 			if d == "ifdef" || d == "ifndef" || d == "ifeq" || d == "ifneq" {
 				d = "el" + d
 				p.ignoreSpaces()
-				expression = p.parseExpression()
+				expression = p.parseExpression('#')
 				expression.TrimRightSpaces()
 			} else {
 				p.errorf("expected ifdef/ifndef/ifeq/ifneq, found %s", d)
@@ -232,7 +232,7 @@
 		expression, endPos = p.parseDefine()
 	default:
 		p.ignoreSpaces()
-		expression = p.parseExpression()
+		expression = p.parseExpression('#')
 	}
 
 	p.nodes = append(p.nodes, &Directive{
@@ -338,9 +338,6 @@
 				value.appendString(`\` + string(p.tok))
 			}
 			p.accept(p.tok)
-		case '#':
-			p.parseComment()
-			break loop
 		case '$':
 			var variable Variable
 			variable = p.parseVariable()
@@ -522,7 +519,7 @@
 	// non-whitespace character after the = until the end of the logical line,
 	// which may included escaped newlines
 	p.accept('=')
-	value := p.parseExpression()
+	value := p.parseExpression('#')
 	value.TrimLeftSpaces()
 	if ident.EndsWith('+') && t == "=" {
 		ident.TrimRightOne()
diff --git a/androidmk/parser/parser_test.go b/androidmk/parser/parser_test.go
index f562c29..9efebf8 100644
--- a/androidmk/parser/parser_test.go
+++ b/androidmk/parser/parser_test.go
@@ -34,6 +34,56 @@
 			},
 		},
 	},
+	{
+		name: "Simple warning",
+		in:   `$(warning A warning)`,
+		out: []Node{
+			&Variable{
+				Name: SimpleMakeString("warning A warning", NoPos),
+			},
+		},
+	},
+	{
+		name: "Warning with #",
+		in:   `$(warning # A warning)`,
+		out: []Node{
+			&Variable{
+				Name: SimpleMakeString("warning # A warning", NoPos),
+			},
+		},
+	},
+	{
+		name: "Findstring with #",
+		in:   `$(findstring x,x a #)`,
+		out: []Node{
+			&Variable{
+				Name: SimpleMakeString("findstring x,x a #", NoPos),
+			},
+		},
+	},
+	{
+		name: "If statement",
+		in: `ifeq (a,b) # comment
+endif`,
+		out: []Node{
+			&Directive{
+				NamePos: NoPos,
+				Name:    "ifeq",
+				Args:    SimpleMakeString("(a,b) ", NoPos),
+				EndPos:  NoPos,
+			},
+			&Comment{
+				CommentPos: NoPos,
+				Comment:    " comment",
+			},
+			&Directive{
+				NamePos: NoPos,
+				Name:    "endif",
+				Args:    SimpleMakeString("", NoPos),
+				EndPos:  NoPos,
+			},
+		},
+	},
 }
 
 func TestParse(t *testing.T) {
diff --git a/java/config/kotlin.go b/java/config/kotlin.go
index 6cb61f3..a83f87f 100644
--- a/java/config/kotlin.go
+++ b/java/config/kotlin.go
@@ -47,4 +47,9 @@
 	pctx.StaticVariable("KotlincSuppressJDK9Warnings", strings.Join([]string{
 		"-J--add-opens=java.base/java.util=ALL-UNNAMED", // https://youtrack.jetbrains.com/issue/KT-43704
 	}, " "))
+
+	pctx.StaticVariable("KotlincGlobalFlags", strings.Join([]string{
+		// b/222162908: prevent kotlinc from reading /tmp/build.txt
+		"-Didea.plugins.compatible.build=999.SNAPSHOT",
+	}, " "))
 }
diff --git a/java/kotlin.go b/java/kotlin.go
index e4f1bc1..3e5cec0 100644
--- a/java/kotlin.go
+++ b/java/kotlin.go
@@ -34,7 +34,8 @@
 			`${config.GenKotlinBuildFileCmd} --classpath "$classpath" --name "$name"` +
 			` --out_dir "$classesDir" --srcs "$out.rsp" --srcs "$srcJarDir/list"` +
 			` $commonSrcFilesArg --out "$kotlinBuildFile" && ` +
-			`${config.KotlincCmd} ${config.KotlincSuppressJDK9Warnings} ${config.JavacHeapFlags} ` +
+			`${config.KotlincCmd} ${config.KotlincGlobalFlags} ` +
+			`${config.KotlincSuppressJDK9Warnings} ${config.JavacHeapFlags} ` +
 			`$kotlincFlags -jvm-target $kotlinJvmTarget -Xbuild-file=$kotlinBuildFile ` +
 			`-kotlin-home $emptyDir && ` +
 			`${config.SoongZipCmd} -jar -o $out -C $classesDir -D $classesDir && ` +
@@ -125,7 +126,8 @@
 			`${config.GenKotlinBuildFileCmd} --classpath "$classpath" --name "$name"` +
 			` --srcs "$out.rsp" --srcs "$srcJarDir/list"` +
 			` $commonSrcFilesArg --out "$kotlinBuildFile" && ` +
-			`${config.KotlincCmd} ${config.KaptSuppressJDK9Warnings} ${config.KotlincSuppressJDK9Warnings} ` +
+			`${config.KotlincCmd} ${config.KotlincGlobalFlags} ` +
+			`${config.KaptSuppressJDK9Warnings} ${config.KotlincSuppressJDK9Warnings} ` +
 			`${config.JavacHeapFlags} $kotlincFlags -Xplugin=${config.KotlinKaptJar} ` +
 			`-P plugin:org.jetbrains.kotlin.kapt3:sources=$kaptDir/sources ` +
 			`-P plugin:org.jetbrains.kotlin.kapt3:classes=$kaptDir/classes ` +
diff --git a/java/lint_defaults.txt b/java/lint_defaults.txt
index 3cc436c..4bc0c5f 100644
--- a/java/lint_defaults.txt
+++ b/java/lint_defaults.txt
@@ -1,8 +1,6 @@
 # Treat LintError as fatal to catch invocation errors
 --fatal_check LintError
 
---fatal_check ExtraText # 225341614
-
 # Checks which do not apply to the platform (implementation
 # in lint assumes that it's running on app code)
 
diff --git a/mk2rbc/mk2rbc.go b/mk2rbc/mk2rbc.go
index 212b7f6..c881751 100644
--- a/mk2rbc/mk2rbc.go
+++ b/mk2rbc/mk2rbc.go
@@ -1376,7 +1376,7 @@
 	if !args.Empty() {
 		return ctx.newBadExpr(node, "my-dir function cannot have any arguments passed to it.")
 	}
-	return &variableRefExpr{ctx.addVariable("LOCAL_PATH"), true}
+	return &stringLiteralExpr{literal: filepath.Dir(ctx.script.mkFile)}
 }
 
 type isProductInListCallParser struct{}
diff --git a/mk2rbc/mk2rbc_test.go b/mk2rbc/mk2rbc_test.go
index 08926e5..31739fa 100644
--- a/mk2rbc/mk2rbc_test.go
+++ b/mk2rbc/mk2rbc_test.go
@@ -254,6 +254,8 @@
 		in: `
 $(warning this is the warning)
 $(warning)
+$(warning # this warning starts with a pound)
+$(warning this warning has a # in the middle)
 $(info this is the info)
 $(error this is the error)
 PRODUCT_NAME:=$(shell echo *)
@@ -264,6 +266,8 @@
   cfg = rblf.cfg(handle)
   rblf.mkwarning("product.mk", "this is the warning")
   rblf.mkwarning("product.mk", "")
+  rblf.mkwarning("product.mk", "# this warning starts with a pound")
+  rblf.mkwarning("product.mk", "this warning has a # in the middle")
   rblf.mkinfo("product.mk", "this is the info")
   rblf.mkerror("product.mk", "this is the error")
   cfg["PRODUCT_NAME"] = rblf.shell("echo *")
@@ -1457,6 +1461,19 @@
   g["MY_STRING_VAR"] = " ".join(rblf.expand_wildcard("foo/bar.mk"))
 `,
 	},
+	{
+		desc:   "Set LOCAL_PATH to my-dir",
+		mkname: "product.mk",
+		in: `
+LOCAL_PATH := $(call my-dir)
+`,
+		expected: `load("//build/make/core:product_config.rbc", "rblf")
+
+def init(g, handle):
+  cfg = rblf.cfg(handle)
+  
+`,
+	},
 }
 
 var known_variables = []struct {
diff --git a/mk2rbc/variable.go b/mk2rbc/variable.go
index 506266a..be1b174 100644
--- a/mk2rbc/variable.go
+++ b/mk2rbc/variable.go
@@ -319,15 +319,13 @@
 			v = &localVariable{baseVariable{nam: name, typ: hintType}}
 		} else {
 			vt := hintType
-			if strings.HasPrefix(name, "LOCAL_") && vt == starlarkTypeUnknown {
-				// Heuristics: local variables that contribute to corresponding config variables
-				if cfgVarName, found := localProductConfigVariables[name]; found {
-					vi, found2 := KnownVariables[cfgVarName]
-					if !found2 {
-						panic(fmt.Errorf("unknown config variable %s for %s", cfgVarName, name))
-					}
-					vt = vi.valueType
+			// Heuristics: local variables that contribute to corresponding config variables
+			if cfgVarName, found := localProductConfigVariables[name]; found && vt == starlarkTypeUnknown {
+				vi, found2 := KnownVariables[cfgVarName]
+				if !found2 {
+					panic(fmt.Errorf("unknown config variable %s for %s", cfgVarName, name))
 				}
+				vt = vi.valueType
 			}
 			if strings.HasSuffix(name, "_LIST") && vt == starlarkTypeUnknown {
 				// Heuristics: Variables with "_LIST" suffix are lists
diff --git a/tests/lib.sh b/tests/lib.sh
index e6074f8..55f9ab4 100644
--- a/tests/lib.sh
+++ b/tests/lib.sh
@@ -86,6 +86,7 @@
 
   symlink_directory prebuilts/go
   symlink_directory prebuilts/build-tools
+  symlink_directory prebuilts/clang/host
   symlink_directory external/go-cmp
   symlink_directory external/golang-protobuf