mirror of
https://github.com/fork-maintainers/iceraven-browser
synced 2024-11-09 19:10:42 +00:00
This commit is contained in:
parent
d208ffe002
commit
6d699105ad
@ -12,6 +12,9 @@ dependencies {
|
||||
compileOnly "org.jetbrains.kotlin:kotlin-stdlib:${Versions.kotlin}"
|
||||
compileOnly "com.android.tools.lint:lint-api:${Versions.android_lint_api}"
|
||||
compileOnly "com.android.tools.lint:lint-checks:${Versions.android_lint_api}"
|
||||
|
||||
testImplementation "com.android.tools.lint:lint:${Versions.android_lint_api}"
|
||||
testImplementation "com.android.tools.lint:lint-tests:${Versions.android_lint_api}"
|
||||
}
|
||||
|
||||
jar {
|
||||
|
@ -0,0 +1,84 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.lintrules
|
||||
|
||||
import com.android.tools.lint.client.api.UElementHandler
|
||||
import com.android.tools.lint.detector.api.JavaContext
|
||||
import com.android.tools.lint.detector.api.LintFix
|
||||
import org.jetbrains.kotlin.psi.psiUtil.siblings
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startsWithComment
|
||||
import org.jetbrains.uast.UComment
|
||||
import org.jetbrains.uast.UFile
|
||||
|
||||
class LicenseCommentChecker(private val context: JavaContext) : UElementHandler() {
|
||||
|
||||
companion object {
|
||||
val ValidLicenseForKotlinFiles = """
|
||||
|/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
| * License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */""".trimMargin()
|
||||
}
|
||||
|
||||
override fun visitFile(node: UFile) {
|
||||
if (!node.sourcePsi.startsWithComment()) {
|
||||
reportMissingLicense(node)
|
||||
} else {
|
||||
val firstComment = node.allCommentsInFile.first()
|
||||
if (firstComment.text != ValidLicenseForKotlinFiles) {
|
||||
reportInvalidLicenseFormat(firstComment)
|
||||
} else {
|
||||
val nextSibling =
|
||||
firstComment.sourcePsi.siblings(withItself = false).firstOrNull()
|
||||
if (nextSibling?.text != "\n\n") {
|
||||
reportMissingLeadingNewLineCharacter(firstComment)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun reportMissingLicense(node: UFile) = context.report(
|
||||
LicenseDetector.ISSUE_MISSING_LICENSE,
|
||||
context.getLocation(node.sourcePsi.firstChild),
|
||||
"The file must start with a comment containing the license",
|
||||
addLicenseQuickFix()
|
||||
)
|
||||
|
||||
private fun reportInvalidLicenseFormat(comment: UComment) = context.report(
|
||||
LicenseDetector.ISSUE_INVALID_LICENSE_FORMAT,
|
||||
context.getLocation(comment),
|
||||
"The license comment doesn't have the appropriate format",
|
||||
replaceCommentWithValidLicenseFix(comment)
|
||||
)
|
||||
|
||||
private fun reportMissingLeadingNewLineCharacter(licenseComment: UComment) = context.report(
|
||||
LicenseDetector.ISSUE_INVALID_LICENSE_FORMAT,
|
||||
context.getRangeLocation(licenseComment, licenseComment.text.lastIndex, 1),
|
||||
"The license comment must be followed by a newline character",
|
||||
addLeadingNewLineQuickFix(licenseComment)
|
||||
)
|
||||
|
||||
private fun addLicenseQuickFix() = LintFix.create()
|
||||
.name("Insert license at the top of the file")
|
||||
.replace()
|
||||
.beginning()
|
||||
.with(ValidLicenseForKotlinFiles + "\n\n")
|
||||
.autoFix()
|
||||
.build()
|
||||
|
||||
private fun replaceCommentWithValidLicenseFix(comment: UComment) = LintFix.create()
|
||||
.name("Replace with correctly formatted license")
|
||||
.replace()
|
||||
.range(context.getLocation(comment))
|
||||
.with(ValidLicenseForKotlinFiles)
|
||||
.build()
|
||||
|
||||
private fun addLeadingNewLineQuickFix(licenseComment: UComment) = LintFix.create()
|
||||
.name("Insert newline character after the license")
|
||||
.replace()
|
||||
.range(context.getLocation(licenseComment))
|
||||
.with(ValidLicenseForKotlinFiles + "\n")
|
||||
.autoFix()
|
||||
.build()
|
||||
}
|
@ -0,0 +1,46 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.lintrules
|
||||
|
||||
import com.android.tools.lint.client.api.UElementHandler
|
||||
import com.android.tools.lint.detector.api.*
|
||||
import org.jetbrains.uast.UElement
|
||||
import org.jetbrains.uast.UFile
|
||||
|
||||
class LicenseDetector : Detector(), SourceCodeScanner {
|
||||
|
||||
companion object {
|
||||
|
||||
private val Implementation = Implementation(
|
||||
LicenseDetector::class.java,
|
||||
Scope.JAVA_FILE_SCOPE
|
||||
)
|
||||
|
||||
val ISSUE_MISSING_LICENSE = Issue.create(
|
||||
id = "MissingLicense",
|
||||
briefDescription = "File doesn't start with the license comment",
|
||||
explanation = "Every file must start with the license comment:\n" +
|
||||
LicenseCommentChecker.ValidLicenseForKotlinFiles,
|
||||
category = Category.CORRECTNESS,
|
||||
severity = Severity.WARNING,
|
||||
implementation = Implementation
|
||||
)
|
||||
|
||||
val ISSUE_INVALID_LICENSE_FORMAT = Issue.create(
|
||||
id = "InvalidLicenseFormat",
|
||||
briefDescription = "License isn't formatted correctly",
|
||||
explanation = "The license must be:\n${LicenseCommentChecker.ValidLicenseForKotlinFiles}",
|
||||
category = Category.CORRECTNESS,
|
||||
severity = Severity.WARNING,
|
||||
implementation = Implementation
|
||||
)
|
||||
}
|
||||
|
||||
override fun getApplicableUastTypes(): List<Class<out UElement>>? = listOf(UFile::class.java)
|
||||
|
||||
override fun createUastHandler(context: JavaContext): UElementHandler? =
|
||||
LicenseCommentChecker(context)
|
||||
|
||||
}
|
@ -17,6 +17,8 @@ class LintIssueRegistry : IssueRegistry() {
|
||||
ButtonStyleXmlDetector.ISSUE_XML_STYLE,
|
||||
AndroidSrcXmlDetector.ISSUE_XML_SRC_USAGE,
|
||||
TextViewAndroidSrcXmlDetector.ISSUE_XML_SRC_USAGE,
|
||||
ImageViewAndroidTintXmlDetector.ISSUE_XML_SRC_USAGE
|
||||
ImageViewAndroidTintXmlDetector.ISSUE_XML_SRC_USAGE,
|
||||
LicenseDetector.ISSUE_MISSING_LICENSE,
|
||||
LicenseDetector.ISSUE_INVALID_LICENSE_FORMAT
|
||||
) + ConstraintLayoutPerfDetector.ISSUES
|
||||
}
|
||||
|
@ -0,0 +1,140 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
package org.mozilla.fenix.lintrules
|
||||
|
||||
import com.android.tools.lint.checks.infrastructure.TestFiles
|
||||
import com.android.tools.lint.checks.infrastructure.TestLintTask.lint
|
||||
import org.junit.Test
|
||||
import org.mozilla.fenix.lintrules.LicenseCommentChecker.Companion.ValidLicenseForKotlinFiles
|
||||
import org.mozilla.fenix.lintrules.LicenseDetector.Companion.ISSUE_INVALID_LICENSE_FORMAT
|
||||
import org.mozilla.fenix.lintrules.LicenseDetector.Companion.ISSUE_MISSING_LICENSE
|
||||
|
||||
class LicenseDetectorTest {
|
||||
|
||||
@Test
|
||||
fun `report missing license if it isn't at the top of the file`() {
|
||||
val code = """
|
||||
|package example
|
||||
|
|
||||
|class SomeExample {
|
||||
| fun test() {
|
||||
| val x = 10
|
||||
| println("Hello")
|
||||
| }
|
||||
|}""".trimMargin()
|
||||
|
||||
val expectedReport = """
|
||||
|src/example/SomeExample.kt:1: Warning: The file must start with a comment containing the license [MissingLicense]
|
||||
|package example
|
||||
|~~~~~~~~~~~~~~~
|
||||
|0 errors, 1 warnings""".trimMargin()
|
||||
|
||||
val expectedFixOutput = """
|
||||
|Fix for src/example/SomeExample.kt line 1: Insert license at the top of the file:
|
||||
|@@ -1 +1
|
||||
|+ /* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
|+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
|+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|+""".trimMargin()
|
||||
|
||||
lint()
|
||||
.files(TestFiles.kt(code))
|
||||
.issues(ISSUE_MISSING_LICENSE, ISSUE_INVALID_LICENSE_FORMAT)
|
||||
.run()
|
||||
.expect(expectedReport)
|
||||
.expectFixDiffs(expectedFixOutput)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `report invalid license format if it doesn't have a leading newline character`() {
|
||||
val code = """
|
||||
|$ValidLicenseForKotlinFiles
|
||||
|package example
|
||||
|
|
||||
|class SomeExample {
|
||||
| fun test() {
|
||||
| val x = 10
|
||||
| println("Hello")
|
||||
| }
|
||||
|}""".trimMargin()
|
||||
|
||||
val expectedReport = """
|
||||
|src/example/SomeExample.kt:3: Warning: The license comment must be followed by a newline character [InvalidLicenseFormat]
|
||||
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
| ~
|
||||
|0 errors, 1 warnings""".trimMargin()
|
||||
|
||||
val expectedFixOutput = """
|
||||
|Fix for src/example/SomeExample.kt line 3: Insert newline character after the license:
|
||||
|@@ -4 +4
|
||||
|+""".trimMargin()
|
||||
|
||||
lint()
|
||||
.files(TestFiles.kt(code))
|
||||
.issues(ISSUE_MISSING_LICENSE, ISSUE_INVALID_LICENSE_FORMAT)
|
||||
.run()
|
||||
.expect(expectedReport)
|
||||
.expectFixDiffs(expectedFixOutput)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `valid license does not generate a warning`() {
|
||||
val code = """
|
||||
|$ValidLicenseForKotlinFiles
|
||||
|
|
||||
|package example
|
||||
|
|
||||
|class SomeExample {
|
||||
| fun test() {
|
||||
| val x = 10
|
||||
| println("Hello")
|
||||
| }
|
||||
|}""".trimMargin()
|
||||
|
||||
lint()
|
||||
.files(TestFiles.kt(code))
|
||||
.issues(ISSUE_MISSING_LICENSE, ISSUE_INVALID_LICENSE_FORMAT)
|
||||
.run()
|
||||
.expectClean()
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `report incorrectly formatted license`() {
|
||||
val code = """
|
||||
|/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
| License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
| file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
|
||||
|package example
|
||||
|
|
||||
|class SomeExample {
|
||||
| fun test() {
|
||||
| val x = 10
|
||||
| println("Hello")
|
||||
| }
|
||||
|}""".trimMargin()
|
||||
|
||||
val expectedReport = """
|
||||
|src/example/SomeExample.kt:1: Warning: The license comment doesn't have the appropriate format [InvalidLicenseFormat]
|
||||
|/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
|^
|
||||
|0 errors, 1 warnings""".trimMargin()
|
||||
|
||||
val expectedFixOutput = """
|
||||
|Fix for src/example/SomeExample.kt line 1: Replace with correctly formatted license:
|
||||
|@@ -2 +2
|
||||
|- License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
|- file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|+ * License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
|+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */""".trimMargin()
|
||||
|
||||
lint()
|
||||
.files(TestFiles.kt(code))
|
||||
.issues(ISSUE_MISSING_LICENSE, ISSUE_INVALID_LICENSE_FORMAT)
|
||||
.run()
|
||||
.expect(expectedReport)
|
||||
.expectFixDiffs(expectedFixOutput)
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user