1
0
mirror of https://github.com/SquidDev-CC/CC-Tweaked synced 2025-11-03 23:22:59 +00:00

Merge branch 'mc-1.20.x' into mc-1.21.x

This commit is contained in:
Jonathan Coates
2025-02-16 21:04:28 +00:00
324 changed files with 1055 additions and 732 deletions

View File

@@ -0,0 +1,56 @@
// SPDX-FileCopyrightText: 2025 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
@file:Suppress("JAVA_MODULE_DOES_NOT_EXPORT_PACKAGE")
package cc.tweaked.linter
import com.google.errorprone.BugPattern
import com.google.errorprone.VisitorState
import com.google.errorprone.bugpatterns.BugChecker
import com.google.errorprone.fixes.SuggestedFix
import com.google.errorprone.matchers.Description
import com.google.errorprone.util.ASTHelpers
import com.sun.source.tree.ImportTree
import com.sun.source.tree.Tree
@BugPattern(
summary = "Checks for forbidden imports.",
severity = BugPattern.SeverityLevel.ERROR,
tags = [BugPattern.StandardTags.LIKELY_ERROR],
)
class ForbiddenImport : BugChecker(), BugChecker.ImportTreeMatcher {
override fun matchImport(tree: ImportTree, state: VisitorState): Description {
if (tree.isStatic || tree.qualifiedIdentifier.kind != Tree.Kind.MEMBER_SELECT) return Description.NO_MATCH
val sym = ASTHelpers.getSymbol(tree.qualifiedIdentifier) ?: return Description.NO_MATCH
val importedName = sym.qualifiedName.toString()
if (!IMPORTS.contains(importedName)) return Description.NO_MATCH
val message = buildDescription(tree.qualifiedIdentifier).setMessage("Cannot import this symbol")
val replacement = ALTERNATIVE_IMPORTS[importedName]
if (replacement != null) message.addFix(SuggestedFix.replace(tree.qualifiedIdentifier, replacement))
return message.build()
}
companion object {
private val ALTERNATIVE_IMPORTS = mapOf(
// Ban JSR 305 and JetBrains @Nullable, and prefer the JSpecify one.
"org.javax.annotation.Nullable" to "org.jspecify.annotations.Nullable",
"org.jetbrains.annotations.Nullable" to "org.jspecify.annotations.Nullable",
// Prefer ErrorProne annotations over JSR ones.
"javax.annotation.CheckReturnValue" to "com.google.errorprone.annotations.CheckReturnValue",
"javax.annotation.OverridingMethodsMustInvokeSuper" to "com.google.errorprone.annotations.OverridingMethodsMustInvokeSuper",
"javax.annotation.concurrent.GuardedBy" to "com.google.errorprone.annotations.concurrent.GuardedBy",
)
private val IMPORTS: Set<String> = setOf(
// We ban all @Nonnull annotations, because that should be default already.
"javax.annotation.Nonnull",
"org.jetbrains.annotations.NotNull",
"org.jspecify.annotations.NonNull",
) + ALTERNATIVE_IMPORTS.keys
}
}

View File

@@ -2,6 +2,7 @@
#
# SPDX-License-Identifier: MPL-2.0
cc.tweaked.linter.ExtraMustCallSuper
cc.tweaked.linter.ForbiddenImport
cc.tweaked.linter.LoaderOverride
cc.tweaked.linter.MissingLoaderOverride
cc.tweaked.linter.SideChecker

View File

@@ -0,0 +1,39 @@
// SPDX-FileCopyrightText: 2022 The CC: Tweaked Developers
//
// SPDX-License-Identifier: MPL-2.0
package cc.tweaked.linter;
import com.google.common.base.Predicates;
import com.google.errorprone.CompilationTestHelper;
import org.junit.jupiter.api.Test;
public class TestForbiddenImport {
private final CompilationTestHelper compilationHelper = CompilationTestHelper.newInstance(ForbiddenImport.class, getClass());
@Test
public void testForbiddenImport() {
compilationHelper
.addSourceLines("Import.java", """
// BUG: Diagnostic matches: X
import org.jspecify.annotations.NonNull;
class X {
}
""")
.expectErrorMessage("X", Predicates.containsPattern("Cannot import this symbol"))
.doTest();
}
@Test
public void testForbiddenImportSuggestion() {
compilationHelper
.addSourceLines("Import.java", """
// BUG: Diagnostic matches: X
import javax.annotation.concurrent.GuardedBy;
class X {
}
""")
.expectErrorMessage("X", Predicates.containsPattern("Did you mean 'import com.google.errorprone.annotations.concurrent.GuardedBy;'"))
.doTest();
}
}