Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8aa7beb5 authored by Anton Hansson's avatar Anton Hansson Committed by Gerrit Code Review
Browse files

Merge "Use trimmed lint database for mainline modules"

parents aed46487 18233a2b
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -1292,6 +1292,7 @@ func (j *Module) compile(ctx android.ModuleContext, aaptSrcJar android.Path) {
		j.linter.minSdkVersion = lintSDKVersionString(j.MinSdkVersion(ctx))
		j.linter.targetSdkVersion = lintSDKVersionString(j.TargetSdkVersion(ctx))
		j.linter.compileSdkVersion = lintSDKVersionString(j.SdkVersion(ctx))
		j.linter.compileSdkKind = j.SdkVersion(ctx).Kind
		j.linter.javaLanguageLevel = flags.javaVersion.String()
		j.linter.kotlinLanguageLevel = "1.3"
		if !apexInfo.IsForPlatform() && ctx.Config().UnbundledBuildApps() {
+47 −16
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@ type linter struct {
	minSdkVersion           string
	targetSdkVersion        string
	compileSdkVersion       string
	compileSdkKind          android.SdkKind
	javaLanguageLevel       string
	kotlinLanguageLevel     string
	outputs                 lintOutputs
@@ -389,13 +390,25 @@ func (l *linter) lint(ctx android.ModuleContext) {
	rule.Command().Text("mkdir -p").Flag(lintPaths.cacheDir.String()).Flag(lintPaths.homeDir.String())
	rule.Command().Text("rm -f").Output(html).Output(text).Output(xml)

	var apiVersionsName, apiVersionsPrebuilt string
	if l.compileSdkKind == android.SdkModule {
		// When compiling an SDK module we use the filtered database because otherwise lint's
		// NewApi check produces too many false positives; This database excludes information
		// about classes created in mainline modules hence removing those false positives.
		apiVersionsName = "api_versions_public_filtered.xml"
		apiVersionsPrebuilt = "prebuilts/sdk/current/public/data/api-versions-filtered.xml"
	} else {
		apiVersionsName = "api_versions.xml"
		apiVersionsPrebuilt = "prebuilts/sdk/current/public/data/api-versions.xml"
	}

	var annotationsZipPath, apiVersionsXMLPath android.Path
	if ctx.Config().AlwaysUsePrebuiltSdks() {
		annotationsZipPath = android.PathForSource(ctx, "prebuilts/sdk/current/public/data/annotations.zip")
		apiVersionsXMLPath = android.PathForSource(ctx, "prebuilts/sdk/current/public/data/api-versions.xml")
		apiVersionsXMLPath = android.PathForSource(ctx, apiVersionsPrebuilt)
	} else {
		annotationsZipPath = copiedAnnotationsZipPath(ctx)
		apiVersionsXMLPath = copiedAPIVersionsXmlPath(ctx)
		apiVersionsXMLPath = copiedAPIVersionsXmlPath(ctx, apiVersionsName)
	}

	cmd := rule.Command()
@@ -487,26 +500,38 @@ func (l *lintSingleton) GenerateBuildActions(ctx android.SingletonContext) {
	l.copyLintDependencies(ctx)
}

func findModuleOrErr(ctx android.SingletonContext, moduleName string) android.Module {
	var res android.Module
	ctx.VisitAllModules(func(m android.Module) {
		if ctx.ModuleName(m) == moduleName {
			if res == nil {
				res = m
			} else {
				ctx.Errorf("lint: multiple %s modules found: %s and %s", moduleName,
					ctx.ModuleSubDir(m), ctx.ModuleSubDir(res))
			}
		}
	})
	return res
}

func (l *lintSingleton) copyLintDependencies(ctx android.SingletonContext) {
	if ctx.Config().AlwaysUsePrebuiltSdks() {
		return
	}

	var frameworkDocStubs android.Module
	ctx.VisitAllModules(func(m android.Module) {
		if ctx.ModuleName(m) == "framework-doc-stubs" {
	frameworkDocStubs := findModuleOrErr(ctx, "framework-doc-stubs")
	if frameworkDocStubs == nil {
				frameworkDocStubs = m
			} else {
				ctx.Errorf("lint: multiple framework-doc-stubs modules found: %s and %s",
					ctx.ModuleSubDir(m), ctx.ModuleSubDir(frameworkDocStubs))
		if !ctx.Config().AllowMissingDependencies() {
			ctx.Errorf("lint: missing framework-doc-stubs")
		}
		return
	}
	})

	if frameworkDocStubs == nil {
	filteredDb := findModuleOrErr(ctx, "api-versions-xml-public-filtered")
	if filteredDb == nil {
		if !ctx.Config().AllowMissingDependencies() {
			ctx.Errorf("lint: missing framework-doc-stubs")
			ctx.Errorf("lint: missing api-versions-xml-public-filtered")
		}
		return
	}
@@ -520,7 +545,13 @@ func (l *lintSingleton) copyLintDependencies(ctx android.SingletonContext) {
	ctx.Build(pctx, android.BuildParams{
		Rule:   android.CpIfChanged,
		Input:  android.OutputFileForModule(ctx, frameworkDocStubs, ".api_versions.xml"),
		Output: copiedAPIVersionsXmlPath(ctx),
		Output: copiedAPIVersionsXmlPath(ctx, "api_versions.xml"),
	})

	ctx.Build(pctx, android.BuildParams{
		Rule:   android.CpIfChanged,
		Input:  android.OutputFileForModule(ctx, filteredDb, ""),
		Output: copiedAPIVersionsXmlPath(ctx, "api_versions_public_filtered.xml"),
	})
}

@@ -528,8 +559,8 @@ func copiedAnnotationsZipPath(ctx android.PathContext) android.WritablePath {
	return android.PathForOutput(ctx, "lint", "annotations.zip")
}

func copiedAPIVersionsXmlPath(ctx android.PathContext) android.WritablePath {
	return android.PathForOutput(ctx, "lint", "api_versions.xml")
func copiedAPIVersionsXmlPath(ctx android.PathContext, name string) android.WritablePath {
	return android.PathForOutput(ctx, "lint", name)
}

func (l *lintSingleton) generateLintReportZips(ctx android.SingletonContext) {
+69 −0
Original line number Diff line number Diff line
@@ -219,3 +219,72 @@ func TestJavaLintStrictUpdatabilityLinting(t *testing.T) {
		t.Error("did not restrict baselining NewApi")
	}
}

func TestJavaLintDatabaseSelectionFull(t *testing.T) {
	testCases := []string{
		"current", "core_platform", "system_current", "S", "30", "10000",
	}
	bp := `
		java_library {
			name: "foo",
			srcs: [
				"a.java",
			],
			min_sdk_version: "29",
			sdk_version: "XXX",
			lint: {
				strict_updatability_linting: true,
			},
		}
`
	for _, testCase := range testCases {
		thisBp := strings.Replace(bp, "XXX", testCase, 1)

		result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules, FixtureWithPrebuiltApis(map[string][]string{
			"30":    {"foo"},
			"10000": {"foo"},
		})).
			RunTestWithBp(t, thisBp)

		foo := result.ModuleForTests("foo", "android_common")
		sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
		if strings.Contains(*sboxProto.Commands[0].Command,
			"/api_versions_public_filtered.xml") {
			t.Error("used public-filtered lint api database for case", testCase)
		}
		if !strings.Contains(*sboxProto.Commands[0].Command,
			"/api_versions.xml") {
			t.Error("did not use full api database for case", testCase)
		}
	}

}

func TestJavaLintDatabaseSelectionPublicFiltered(t *testing.T) {
	bp := `
		java_library {
			name: "foo",
			srcs: [
				"a.java",
			],
			min_sdk_version: "29",
			sdk_version: "module_current",
			lint: {
				strict_updatability_linting: true,
			},
		}
`
	result := android.GroupFixturePreparers(PrepareForTestWithJavaDefaultModules).
		RunTestWithBp(t, bp)

	foo := result.ModuleForTests("foo", "android_common")
	sboxProto := android.RuleBuilderSboxProtoForTests(t, foo.Output("lint.sbox.textproto"))
	if !strings.Contains(*sboxProto.Commands[0].Command,
		"/api_versions_public_filtered.xml") {
		t.Error("did not use public-filtered lint api database", *sboxProto.Commands[0].Command)
	}
	if strings.Contains(*sboxProto.Commands[0].Command,
		"/api_versions.xml") {
		t.Error("used full api database")
	}
}