-
Notifications
You must be signed in to change notification settings - Fork 7
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
refactor: move common classes into
common
package + add: module dep…
…endency checker + fix: the `production work` in `works module` can't work if `resource world module` is disabled.
- Loading branch information
1 parent
0054a33
commit 684710f
Showing
19 changed files
with
236 additions
and
20 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Submodule fuji-fabric.wiki
updated
from c2becb to f63cdf
31 changes: 31 additions & 0 deletions
31
src/main/java/io/github/sakurawald/generator/structure/Reference.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
package io.github.sakurawald.generator.structure; | ||
|
||
import lombok.AllArgsConstructor; | ||
import lombok.Data; | ||
|
||
import java.util.*; | ||
|
||
@Data | ||
@AllArgsConstructor | ||
public class Reference { | ||
String definition; | ||
List<String> reference; | ||
|
||
public static List<Reference> reduce(List<Reference> references) { | ||
// merge | ||
Map<String, Reference> map = new HashMap<>(); | ||
for (Reference reference : references) { | ||
map.putIfAbsent(reference.definition, reference); | ||
map.get(reference.definition).getReference().addAll(reference.reference); | ||
} | ||
|
||
//reduce | ||
for (Reference reference : map.values()) { | ||
Set<String> set = new HashSet<>(reference.reference); | ||
reference.reference.clear(); | ||
reference.reference.addAll(set); | ||
} | ||
|
||
return map.values().stream().toList(); | ||
} | ||
} |
2 changes: 1 addition & 1 deletion
2
...lizer/chat/mention/MentionPlayersJob.java → .../module/common/job/MentionPlayersJob.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...welcome/random_teleport/HeightFinder.java → .../common/random_teleport/HeightFinder.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...andom_teleport/HeightFindingStrategy.java → ...andom_teleport/HeightFindingStrategy.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...lcome/random_teleport/RandomTeleport.java → ...ommon/random_teleport/RandomTeleport.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...java/io/github/sakurawald/module/initializer/newbie_welcome/NewbieWelcomeInitializer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
2 changes: 1 addition & 1 deletion
2
...hunks/ThreadedAnvilChunkStorageMixin.java → ...level/ThreadedAnvilChunkStorageMixin.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
package io.github.sakurawald.util; | ||
|
||
import com.google.gson.JsonObject; | ||
import lombok.experimental.UtilityClass; | ||
|
||
@UtilityClass | ||
public class JsonUtil { | ||
|
||
public static boolean existsNode(JsonObject root, String path){ | ||
String[] nodes = path.split("\\."); | ||
for (int i = 0; i < nodes.length - 1; i++) { | ||
String node = nodes[i]; | ||
if (!root.has(node)) return false; | ||
if (!root.isJsonObject()) return false; | ||
|
||
root = root.getAsJsonObject(node); | ||
} | ||
|
||
return root.has(nodes[nodes.length - 1]); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,156 @@ | ||
package checker; | ||
|
||
import com.google.gson.Gson; | ||
import com.google.gson.GsonBuilder; | ||
import com.google.gson.JsonElement; | ||
import com.google.gson.JsonObject; | ||
import io.github.sakurawald.Fuji; | ||
import io.github.sakurawald.config.model.ConfigModel; | ||
import io.github.sakurawald.generator.structure.Reference; | ||
import io.github.sakurawald.util.JsonUtil; | ||
import lombok.SneakyThrows; | ||
import lombok.extern.slf4j.Slf4j; | ||
import org.apache.commons.io.FileUtils; | ||
import org.junit.jupiter.api.Test; | ||
|
||
import java.nio.charset.Charset; | ||
import java.nio.file.FileVisitResult; | ||
import java.nio.file.Files; | ||
import java.nio.file.Path; | ||
import java.nio.file.SimpleFileVisitor; | ||
import java.nio.file.attribute.BasicFileAttributes; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import java.util.regex.Matcher; | ||
import java.util.regex.Pattern; | ||
|
||
@Slf4j | ||
public class CheckModuleDependencyTest { | ||
|
||
public static final String COMMON = "common"; | ||
private static final Pattern importPattern = Pattern.compile("import\\s+(\\S+);"); | ||
private static final Pattern staticImportPattern = Pattern.compile("import\\s+static\\s+(\\S+)\\.\\S+;"); | ||
private static final Pattern moduleNamePattern = Pattern.compile("io\\.github\\.sakurawald\\.module\\.(?:initializer|mixin)\\.(\\S+)\\.\\S+;?"); | ||
private static final Gson gson = new GsonBuilder().setPrettyPrinting().create(); | ||
|
||
private List<String> extractMatches(Pattern pattern, String text, int group) { | ||
Matcher matcher = pattern.matcher(text); | ||
|
||
List<String> ret = new ArrayList<>(); | ||
while (matcher.find()) { | ||
ret.add(matcher.group(group)); | ||
} | ||
|
||
return ret; | ||
} | ||
|
||
@SneakyThrows | ||
private List<String> getRefClassNameList(String path) { | ||
String text = FileUtils.readFileToString(Path.of(path).toFile(), Charset.defaultCharset()); | ||
|
||
List<String> ret = new ArrayList<>(); | ||
ret.addAll(extractMatches(importPattern, text, 1)); | ||
ret.addAll(extractMatches(staticImportPattern, text, 1)); | ||
return ret; | ||
} | ||
|
||
private List<String> filterClassName(List<String> className, String prefix) { | ||
return className.stream().filter(s -> s.startsWith(prefix)).toList(); | ||
} | ||
|
||
private Path getCodebasePath() { | ||
return Path.of("src", "main", "java"); | ||
} | ||
|
||
private Reference makeClassRef(Path file) { | ||
String className = file.toString().replace("/", ".").replace("src.main.java.", "").replace(".java", ""); | ||
List<String> refClassNameList = getRefClassNameList(file.toString()); | ||
|
||
// filter only project class ref | ||
refClassNameList = filterClassName(refClassNameList, Fuji.class.getPackage().getName()); | ||
|
||
return new Reference(className, refClassNameList); | ||
} | ||
|
||
private String extractModuleName(String className) { | ||
List<String> moduleNameList = extractMatches(moduleNamePattern, className, 1); | ||
if (moduleNameList.isEmpty()) { | ||
return COMMON; | ||
} | ||
return moduleNameList.getFirst(); | ||
} | ||
|
||
private boolean isRealModulePath(String moduleName) { | ||
JsonElement root = gson.toJsonTree(new ConfigModel()); | ||
return JsonUtil.existsNode((JsonObject) root, "modules.%s.enable".formatted(moduleName)); | ||
} | ||
|
||
private boolean isSibling(String a, String b) { | ||
String[] A = a.split("\\."); | ||
String[] B = b.split("\\."); | ||
|
||
if (A.length != B.length) return false; | ||
for (int i = 0; i < A.length - 1; i++) { | ||
if (!A[i].equals(B[i])) return false; | ||
} | ||
return true; | ||
} | ||
|
||
private Reference makeModuleRef(Reference classRef) { | ||
String definition = extractModuleName(classRef.getDefinition()); | ||
List<String> reference = new ArrayList<>(); | ||
for (String ref : classRef.getReference()) { | ||
String str = extractModuleName(ref); | ||
// skip -> common reference | ||
if (str.equals(COMMON)) continue; | ||
// skip -> self reference | ||
if (definition.equals(str) || definition.startsWith(str)) continue; | ||
if (str.startsWith(definition) && !isRealModulePath(str)) continue; | ||
if (isSibling(definition, str) && !isRealModulePath(definition) && !isRealModulePath(str)) continue; | ||
// skip -> reference internal module | ||
if (str.startsWith("_")) continue; | ||
|
||
reference.add(str); | ||
} | ||
|
||
if (definition.equals(COMMON)) return null; | ||
if (reference.isEmpty()) return null; | ||
return new Reference(definition, reference); | ||
} | ||
|
||
|
||
@SneakyThrows | ||
private List<Reference> walk(Path path) { | ||
/* per class reference */ | ||
List<Reference> refs = new ArrayList<>(); | ||
Files.walkFileTree(path, new SimpleFileVisitor<>() { | ||
@Override | ||
public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) { | ||
Reference reference = makeModuleRef(makeClassRef(file)); | ||
if (reference != null) { | ||
refs.add(reference); | ||
} | ||
|
||
return FileVisitResult.CONTINUE; | ||
} | ||
}); | ||
|
||
/* reduce */ | ||
return Reference.reduce(refs); | ||
} | ||
|
||
@Test | ||
void test() { | ||
CheckModuleDependencyTest gen = new CheckModuleDependencyTest(); | ||
|
||
List<Reference> refs = gen.walk(gen.getCodebasePath()); | ||
|
||
System.out.println("\n=== module dependency analysis ==="); | ||
refs.forEach(System.out::println); | ||
System.out.println(); | ||
|
||
if (!refs.isEmpty()) { | ||
throw new RuntimeException("module dependency is not pure !"); | ||
} | ||
} | ||
} |