mirror of
https://github.com/FabricMC/fabric
synced 2026-08-19 06:26:07 -04:00
Generate package-infos on IDE sync (#5510)
* allow @ApiStatus.Internal in impl package-infos * remove unnecessary perm api explicit impl package-info * run generate task on ideaSync and add check task for explicit package-infos * address reviews * allow explicit impl package-infos again * cache text * revert accidental indentation changes
This commit is contained in:
parent
11dbb7d77f
commit
536fad2f4d
3 changed files with 26 additions and 41 deletions
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* Copyright (c) 2016, 2017, 2018, 2019 FabricMC
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
@NullMarked
|
||||
package net.fabricmc.fabric.impl.permission;
|
||||
|
||||
import org.jspecify.annotations.NullMarked;
|
||||
|
|
@ -7,8 +7,7 @@ for (def sourceSet in [
|
|||
// We have to capture the source set name for the lazy string literals,
|
||||
// otherwise it'll just be whatever the last source set is in the list.
|
||||
def sourceSetName = sourceSet.name
|
||||
def taskName = sourceSet.getTaskName('generate', 'PackageInfos')
|
||||
def task = tasks.register(taskName, GeneratePackageInfos) {
|
||||
def generateTask = tasks.register(sourceSet.getTaskName('generate', 'PackageInfos'), GeneratePackageInfos) {
|
||||
group = 'fabric'
|
||||
description = "Generates package-info files for $sourceSetName packages."
|
||||
|
||||
|
|
@ -18,7 +17,8 @@ for (def sourceSet in [
|
|||
header = rootProject.file('HEADER')
|
||||
outputDir = file("src/generated/$sourceSetName")
|
||||
}
|
||||
sourceSet.java.srcDir task
|
||||
sourceSet.java.srcDir generateTask
|
||||
ideaSyncTask.dependsOn generateTask
|
||||
|
||||
def cleanTask = tasks.register(sourceSet.getTaskName('clean', 'PackageInfos'), Delete) {
|
||||
group = 'fabric'
|
||||
|
|
@ -53,38 +53,42 @@ abstract class GeneratePackageInfos extends DefaultTask {
|
|||
def root = sourceRoot.get().asFile.toPath()
|
||||
|
||||
root.eachDirRecurse {
|
||||
def containsJava = Files.list(it).any {
|
||||
Files.isRegularFile(it) && it.fileName.toString().endsWith('.java')
|
||||
def containsJava = Files.list(it).withCloseable { stream ->
|
||||
stream.any {
|
||||
Files.isRegularFile(it) && it.fileName.toString().endsWith('.java')
|
||||
}
|
||||
}
|
||||
|
||||
if (!containsJava) {
|
||||
return
|
||||
}
|
||||
|
||||
// Check existing package-info.java to ensure it has @NullMarked
|
||||
def existingPackageInfo = it.resolve('package-info.java')
|
||||
if (Files.exists(existingPackageInfo)) {
|
||||
if (!existingPackageInfo.text.contains("@NullMarked")) {
|
||||
throw new RuntimeException("package-info.java ${existingPackageInfo} is missing @NullMarked annotation.")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
def relativePath = root.relativize(it)
|
||||
def target = output.resolve(relativePath)
|
||||
Files.createDirectories(target)
|
||||
|
||||
def packageName = relativePath.toString().replace(File.separator, '.')
|
||||
def implPattern = /^(net[\/\\]fabricmc[\/\\]fabric[\/\\](impl|mixin))/
|
||||
def isImpl = relativePath.toString() =~ implPattern
|
||||
|
||||
if (packageName == "net.fabricmc.fabric.api.util" && projectName.get() == "fabric-content-registries-v0") {
|
||||
// Hack: This package clashes with api-base, don't generate any annotations for it.
|
||||
return
|
||||
}
|
||||
|
||||
def implPattern = /^(net[\/\\]fabricmc[\/\\]fabric[\/\\](impl|mixin))/
|
||||
def isImpl = relativePath.toString() =~ implPattern
|
||||
// Check existing explicit package-info.java to ensure it has @NullMarked / @ApiStatus.Internal
|
||||
def existingPackageInfo = it.resolve('package-info.java')
|
||||
if (Files.exists(existingPackageInfo)) {
|
||||
def text = existingPackageInfo.text
|
||||
|
||||
if (!text.contains("@NullMarked")) {
|
||||
throw new RuntimeException("package-info.java ${existingPackageInfo} is missing @NullMarked annotation.")
|
||||
} else if (isImpl && !text.contains("@ApiStatus.Internal")) {
|
||||
throw new RuntimeException("Impl package-info.java ${existingPackageInfo} is missing @ApiStatus.Internal annotation.")
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
Files.createDirectories(target)
|
||||
target.resolve('package-info.java').withWriter {
|
||||
if (isImpl) {
|
||||
it.write("""$headerText
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ abstract class ValidateAnnotations extends SourceTask {
|
|||
}
|
||||
|
||||
def contents = it.text
|
||||
def name = it.name
|
||||
|
||||
// @Environment is never allowed
|
||||
if (ENVIRONMENT.matcher(contents).find()) {
|
||||
|
|
@ -38,9 +39,9 @@ abstract class ValidateAnnotations extends SourceTask {
|
|||
}
|
||||
|
||||
// @ApiStatus.Internal is only allowed in api packages (it's auto-generated for impl and mixin packages)
|
||||
if (dir != "api") {
|
||||
if (dir != "api" && name != "package-info.java") {
|
||||
if (API_STATUS_INTERNAL.matcher(contents).find()) {
|
||||
throw new RuntimeException("Found @ApiStatus.Internal in implementation file: " + it)
|
||||
throw new RuntimeException("Found @ApiStatus.Internal in non-package-info implementation file: " + it)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue