-
Notifications
You must be signed in to change notification settings - Fork 14
BTW Code Style Guide
This marks the code style for new contributions to BTW. It is recommended that addons for BTW also follow this code style.
A source file consists of, in order:
- License or copyright information, if present
- Package statement
- Import statements
- Exactly one top-level class
Exactly one blank line separates each section that is present.
Braces are used with if
, else
, for
, do
, and while
statements, even when the body is empty or contains only a single statement.
Brace placement around non-empty blocks should follow the Stroustrup Variation of Kernighan & Richie Style, which can be found here:
- No line break before the opening brace
- Exception: line-wrapped block openings should have a line break before the opening brace.
- Line break after the opening brace
- Line break before the closing brace
- Line break after the closing brace
- A single blank line after the closing brace, unless the closing brace is the middle of a compound block (e.g.
if/else
)
Example:
return () -> {
while (condition()) {
method();
}
};
return new MyClass() {
@Override public void method() {
if (condition()) {
try {
something();
}
catch (ProblemException e) {
recover();
}
}
else if (otherCondition()) {
somethingElse();
}
else {
lastThing();
}
}
};
if (int foo == 0 &&
int bar == 0)
{
doSomething();
}
Empty blocks may follow Stroustrup style as detailed above, or may be closed immediately after it is opened with no character or line break between the opening and closing braces.
The exception to this is if it is part of a multi-block statement such as if/else
or try/catch/finally
, in which case it must follow Stroustrup style.
Each time a new block or block-like construct is opened, indentation increases by 1 tab. Do not use spaces for indentation.
Each statement is followed by a line break. Do not put multiple statements on a single line.
Columns are limited to 160 characters. Except for the exceptions listed below, any line which would exceed this limit must be line-wrapped.
Exceptions:
- Lines where a break would be impossible or unreasonable.
- Package and import declarations
When code that might otherwise legally occupy a single line is divided into multiple lines, this activity is called line-wrapping.
- If the line break is performed at an operator, the break comes after the operator.
- If the line break is performed at a dot separator, the break comes before the "."
- A method or constructor stays attached to the parenthesis "(" that follows it.
- A comma "," stays attached to the token that preceded it.
- When line wrapping, a closing brace or parenthesis stays attached to the token which preceded it.
If a method is line-wrapped to multiple lines, the arguments should be grouped as is logical. For example, coordinates should be kept together unless the group is long enough to itself be line-wrapped.
Each continuation line is indented by 2 tabs.
A single blank line always appears:
- Between consecutive members or initializers of a class: fields, constructors, methods, nested classes, static initializers, and instance initializers.
- Exception: Blank lines between two consecutive fields are optional. Blank lines may be used to create logical groupings.
- As otherwise required by this document.
A single blank line may also be included anywhere it improves readability, such as by grouping statements into logical subsections.
A blank line before the first member or initializer, or after the last method or initializer, is discouraged.
Multiple consecutive blank lines are discouraged.
Beyond where required by the language or other style rules, and apart from literals, comments and Javadoc, a single ASCII space also appears in the following places only:
- Separating any reserved word such as
if
,for
, orcatch
, from an open parenthesis "(" that follows it on that line. - Before any opening brace "{".
- On both sides or a binary or ternary operator.
- After ,:; or the closing parenthesis ")" of a cast.
- Between the type and variable of a declaration:
List<String> list
- On both sides of a varargs declaration:
Object ... varargs
A space after the "//" preceding a single line comment is allowed but not required.
Space between parenthesis or braces and the inner contents is not allowed e.g. foo( x )
Trailing whitespace is not allowed.
Each entry to an enum is always follwoed by a line break. An additional single blank line is also allowed.
Each variable declaration line only declares a single variable.
- Exception: Block or Item prototype fields may be grouped due to the large number of them which may be present.
Local variables are declared close to where they are first used (within reason) to minimize scope. They are not to be declared at the top of the block they are contained in.
Array initializers can optionally be block-like, in which case brace convention follows that of non-empty blocks stated above.
The following are all valid:
new int[] {
1,
2,
3,
4
};
new int[] {
1, 2,
3, 4
};
new int[] {
1, 2, 3, 4
};
The square brackets form a part of the type, not the variable: String[] args
, not String args[]
.
As with any other block, the contents of a case statement are indented by 1 tab. However, case
and default
statements may be placed at the same level of indentation as the switch
statement.
Case and default statements should be placed on their own lines. No additional blank lines are present before or after each case.
Annotations applying to a class, method, or constructor appear immediately before the declaration, with a line break after each annotation.
Annotation applying to a field may appear each on the same line, but a line break follows the last annotation.
Comments should be preceded by a single blank line, and should not have any blank lines following them.
Class and member modifiers, when present, appear in the order recommended by the Java Language Specification:
public protected private abstract default static final transient volatile synchronized native strictfp
Numeric literals, if present, always use capital letters to denote their type e.g. 1.5F or 300000000L
A large class may be segmented into logical blocks for improved readability.
These blocks should be separated by a double slash "//" followed by six dashes "------", a space, the header name, a space, six more dashes, and another double slash. Further hierarchical divisions may be created by increasing the number of dashes used (e.g. from six to twelve).
Fields should always be declared at the top of the segment they belong to.
Identifiers use only ASCII letters and digits, and, in a small number of cases noted below, underscores.
Use of Hungarian notation or any other prefixes is not allowed. For example, do not prefix variables with their type, and do not use m_ to denote fields.
When converting a phrase into camel case, acronyms should be treated as a single letter. If a name in lower camel case begins with an acronym, the acronym should be all lowercase. Otherwise the acronym should be all uppercase.
Package names are all lowercase, with no underscores.
Class names are written in UpperCamelCase
Methods are named using lowerCamelCase. They do not begin with a capital letter, and do not use underscores, with the following expcetion:
- A private variant of a public method which contains the actual logic (with the public method handling translation to the private method) may use the suffix
_do
Constant names use CONSTANT_CASE.
A constant is any static final field which is immutable and whose methods have no side-effects. If any part of the instance's observable state can change, then it is not a constant.
Non-constant field names use lowerCamelCase.
Parameter names use lowerCamelCase.
Local variables use lowerCamelCase.
Even when final and immutable, local variables are not considered constants and should not be styled as such.
Packages are to use only lowercase letters in their names, and should generally use singular nouns as names, e.g. btw.block.tileentity
.
When creating a package to hold a collection of similar objects, such as Block or Item definitions, the package name may be plural, e.g. btw.item.items
.
Exceptions to the package naming conventions may also be made if it would increase clarity.
Class names are to use conversational order as much as possible e.g. RoughStoneBlock
instead of BlockStoneRough
. Exception to this may be made when grouping classes together, e.g. BucketBlockWater
and BucketBlockLava
, in which case either style is allowed.
Enums and interfaces should not be preceded by any prefixes such as "I" or "Enum".
Boolean getters and setters should be preceded by is
(or another question such as has
) and set
, respectively.
Example:
public boolean isFoo() {
return foo;
}
public void setFoo(boolean foo) {
this.foo = foo;
}
Do not use getIs
or setIs
for boolean getters or setters.
Single character field, parameter, or local variable names should not be used, except in the case of immediately obvious names such as x, y, and z for coordinates.
Do not prefix temp variables with "temp" unless omitting the prefix would cause ambiguity. Even in such cases, this practice is discouraged and other naming conventions should be used.
x, y, and z should be used for coordinates. i, j, and k should not be used except as local coordinates with respect to x, y, and z.
More specific coordinate names should have the coordinate at the end of the name. e.g. velocityX
not xVelocity
Always use @Override wherever it is legal.
Static members should always be qualified using the class. Never use an instance to refer to a static member.
it is very rarely correct to do nothing in response to a caught exception. (Typical responses are to log it, or if it is considered "impossible", rethrow it as an AssertionError.)
When it truly is appropriate to take no action whatsoever in a catch block, the reason this is justified is explained in a comment.