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