Add contributing guide with Java style formatting rules
This commit is contained in:
parent
6b95a3891f
commit
72274c08f8
270
CONTRIBUTING.md
Normal file
270
CONTRIBUTING.md
Normal file
@ -0,0 +1,270 @@
|
|||||||
|
# Contributing Guide (Java Style)
|
||||||
|
|
||||||
|
This project follows a strict, C/C++-style Java formatting rule set. The goal is to preserve intent, control flow clarity, and fast mental parsing. Please follow these rules for any Java changes.
|
||||||
|
|
||||||
|
If a tool or formatter fights these rules, the tool is wrong.
|
||||||
|
|
||||||
|
## Core Philosophy
|
||||||
|
|
||||||
|
- Java is written as if it were C/C++.
|
||||||
|
- Formatting must never change perceived control flow.
|
||||||
|
- Readability means fast, correct parsing in your head.
|
||||||
|
- Tools adapt to the codebase, not the other way around.
|
||||||
|
|
||||||
|
## Indentation & Whitespace
|
||||||
|
|
||||||
|
- Indentation: 4 spaces.
|
||||||
|
- No tabs.
|
||||||
|
- Avoid excessive vertical whitespace.
|
||||||
|
- Blank lines only when they add logical separation.
|
||||||
|
|
||||||
|
✅ Good:
|
||||||
|
```java
|
||||||
|
int sum(int a, int b) {
|
||||||
|
int r = a + b;
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
❌ Bad:
|
||||||
|
```java
|
||||||
|
int sum(int a, int b)
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
int r = a + b;
|
||||||
|
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Braces
|
||||||
|
|
||||||
|
- Braces are always required.
|
||||||
|
- Opening brace stays on the same line.
|
||||||
|
- Never rely on implicit scopes.
|
||||||
|
|
||||||
|
✅ Good:
|
||||||
|
```java
|
||||||
|
if (value == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
❌ Bad:
|
||||||
|
```java
|
||||||
|
if (value == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Imports (Strict Rules)
|
||||||
|
|
||||||
|
### Never use fully-qualified class names inline
|
||||||
|
|
||||||
|
❌ Forbidden:
|
||||||
|
```java
|
||||||
|
net.minecraft.util.math.BlockPos pos = new net.minecraft.util.math.BlockPos(0, 0, 0);
|
||||||
|
```
|
||||||
|
|
||||||
|
✅ Required:
|
||||||
|
```java
|
||||||
|
import net.minecraft.util.math.BlockPos;
|
||||||
|
|
||||||
|
BlockPos pos = new BlockPos(0, 0, 0);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Import grouping and ordering
|
||||||
|
|
||||||
|
1) Imports from external/other packages first.
|
||||||
|
2) Blank line.
|
||||||
|
3) Imports from this project (net.Chipperfluff.*) next.
|
||||||
|
|
||||||
|
Inside each block, order by:
|
||||||
|
1) Classes
|
||||||
|
2) Functions (static method imports)
|
||||||
|
3) Variables/constants (static field imports)
|
||||||
|
4) Enums
|
||||||
|
|
||||||
|
If there are no project imports, do not add a blank line.
|
||||||
|
|
||||||
|
## Method Signatures
|
||||||
|
|
||||||
|
- Method signatures must stay on one line.
|
||||||
|
- Do not break parameters across multiple lines.
|
||||||
|
- Long lines are acceptable; ambiguity is not.
|
||||||
|
|
||||||
|
✅ Good:
|
||||||
|
```java
|
||||||
|
void processUser(User user, int flags, boolean force, long timeout) {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
❌ Bad:
|
||||||
|
```java
|
||||||
|
void processUser(
|
||||||
|
User user,
|
||||||
|
int flags,
|
||||||
|
boolean force,
|
||||||
|
long timeout
|
||||||
|
) {
|
||||||
|
...
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Function Calls & Argument Layout
|
||||||
|
|
||||||
|
### Default rule
|
||||||
|
- Single-line calls are preferred.
|
||||||
|
- Flat calls stay flat.
|
||||||
|
- Length alone is not a reason to wrap.
|
||||||
|
|
||||||
|
✅ Good:
|
||||||
|
```java
|
||||||
|
Color color = user.getProfile().getSettings().getTheme().getPrimaryColor();
|
||||||
|
```
|
||||||
|
|
||||||
|
### Multiline calls are allowed only when:
|
||||||
|
- The call is structural or declarative.
|
||||||
|
- Each argument is conceptually distinct.
|
||||||
|
- Nesting would otherwise hide meaning.
|
||||||
|
|
||||||
|
✅ Good (structural/declarative):
|
||||||
|
```java
|
||||||
|
BiomeModifications.addFeature(
|
||||||
|
BiomeSelectors.foundInOverworld(),
|
||||||
|
GenerationStep.Feature.UNDERGROUND_ORES,
|
||||||
|
RegistryKey.of(
|
||||||
|
RegistryKeys.PLACED_FEATURE,
|
||||||
|
new Identifier("chipi", "chipper_ore")
|
||||||
|
)
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
❌ Bad (no semantic gain):
|
||||||
|
```java
|
||||||
|
doThing(
|
||||||
|
a,
|
||||||
|
b,
|
||||||
|
c
|
||||||
|
);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Chained Calls
|
||||||
|
|
||||||
|
- Flat chains stay on one line.
|
||||||
|
- Long or builder-style chains may be split vertically.
|
||||||
|
- Each chained step gets its own line.
|
||||||
|
|
||||||
|
✅ Good:
|
||||||
|
```java
|
||||||
|
builder
|
||||||
|
.withColor(theme.getPrimaryColor())
|
||||||
|
.withSize(32)
|
||||||
|
.enableShadow()
|
||||||
|
.build();
|
||||||
|
```
|
||||||
|
|
||||||
|
❌ Bad:
|
||||||
|
```java
|
||||||
|
builder.withColor(
|
||||||
|
theme.getPrimaryColor()
|
||||||
|
).withSize(
|
||||||
|
32
|
||||||
|
).enableShadow().build();
|
||||||
|
```
|
||||||
|
|
||||||
|
## Control Flow & Returns
|
||||||
|
|
||||||
|
- Early returns are encouraged.
|
||||||
|
- Avoid artificial nesting.
|
||||||
|
- Single-exit functions are not required.
|
||||||
|
|
||||||
|
✅ Good:
|
||||||
|
```java
|
||||||
|
void handle(User user) {
|
||||||
|
if (user == null) return;
|
||||||
|
if (!user.isActive()) return;
|
||||||
|
|
||||||
|
process(user);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
❌ Bad:
|
||||||
|
```java
|
||||||
|
void handle(User user) {
|
||||||
|
if (user != null) {
|
||||||
|
if (user.isActive()) {
|
||||||
|
process(user);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## One-Liners
|
||||||
|
|
||||||
|
- One-liners allowed for simple guard clauses.
|
||||||
|
- No complex logic on one line.
|
||||||
|
|
||||||
|
✅ Allowed:
|
||||||
|
```java
|
||||||
|
if (value == null) return;
|
||||||
|
```
|
||||||
|
|
||||||
|
❌ Not allowed:
|
||||||
|
```java
|
||||||
|
if (a == b && c != d && flag && check()) doThing();
|
||||||
|
```
|
||||||
|
|
||||||
|
## Null Handling
|
||||||
|
|
||||||
|
- null is a valid, intentional state.
|
||||||
|
- Do not over-engineer around it.
|
||||||
|
- Prefer clarity over defensive clutter.
|
||||||
|
|
||||||
|
✅ Good:
|
||||||
|
```java
|
||||||
|
User user = findUser(id);
|
||||||
|
if (user == null) return;
|
||||||
|
```
|
||||||
|
|
||||||
|
## Logging & Debug Output
|
||||||
|
|
||||||
|
- Logging must be short and readable.
|
||||||
|
- Prefer System.out.println for quick diagnostics.
|
||||||
|
- Verbose logging only when justified.
|
||||||
|
|
||||||
|
✅ Good:
|
||||||
|
```java
|
||||||
|
System.out.println("Loaded structure: " + id);
|
||||||
|
```
|
||||||
|
|
||||||
|
## Autoformatters & Linters
|
||||||
|
|
||||||
|
Autoformatters must not:
|
||||||
|
|
||||||
|
- Break method signatures.
|
||||||
|
- Move braces to new lines.
|
||||||
|
- Introduce unwanted trailing newlines.
|
||||||
|
- Rewrap stable code repeatedly.
|
||||||
|
|
||||||
|
If a formatter fights these rules: disable or reconfigure it.
|
||||||
|
|
||||||
|
## Empty Methods
|
||||||
|
|
||||||
|
Empty methods or constructors must be written on one line:
|
||||||
|
|
||||||
|
```java
|
||||||
|
public static void register() {}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Summary (Non-Negotiable)
|
||||||
|
|
||||||
|
- Java written with C/C++ structure.
|
||||||
|
- Compact signatures, explicit layout.
|
||||||
|
- Imports always used (no fully-qualified inline types).
|
||||||
|
- Multiline formatting only when it adds meaning.
|
||||||
|
- Formatting reflects logic, not fashion.
|
||||||
|
|
||||||
Loading…
x
Reference in New Issue
Block a user