GhidraDocs/GhidraCodingStandards.html
The purpose of this document is to record the Ghidra team's accepted rules for code formatting, naming conventions, code complexity, and other best practices. Many of the rules listed in this document are not universal absolutes and many blur into areas of personal preferences. The purpose of these types of rules is not to definitely state that one way is better than another, but that we are consistent throughout the team.
Most of these rules came from one or more of the listed references at the end of this document. Many of these rules were listed in just about every guide. Where they disagreed, We generally went with the majority. Some rules seem arbitrary as to the actual value used, but that a value was needed seemed universal. For example, just about every reference stated a maximum character line length. We think all were either 80 or 100. So everyone seems to think it is important to have some limit, but they don't agree to the actual number.
The following exceptions are allowed (The list can be expanded with majority approval)
For example, use fooUrl, not fooURL.
Examples: Table, FoldingTable, WoodTable
For example, if the base class is "Truck", the subclasses would have names like "DumpTruck", "DeliveryTruck", or "FlyingTruck".
public Foo buildFoo() { // returns a Foo so method name is based on Foo
...
}
public int getSize() { // returns a primitive, which is the size, so name is based on "size"
...
}
public void startServer() { // doesn't return anything so name it based on what it does
...
}
public boolean installHandler(Handler handler) { // even though it returns a boolean, its not about returning
... // a boolean, so name it based on what it does
}
public enum AnalyzerStatus {
ENABLED, DELAYED, DISABLED
}
Examples: MAXIMUM_VELOCITY, or DEFAULT_COLOR
A single Capital Letter, optionally followed by a single number (e.g., T, X, V, T2)
A name in the form used for classes followed by the capital letter T (e.g., ActionT, RowT, ColumnT). Try to avoid using this full name form unless it greatly enhances readability.
Most of these are handled by the Eclipse formatter and are here to document the Ghidra formatting style. The Eclipse formatter can be found in the _ support/eclipse/ _ directory of a Ghidra release, or in the _ eclipse/ _ directory of the Ghidra source repository.
public String toString() { **//@formatter:off** return "{\n" + "\tname: " + name + ",\n" + "\tmodelColumn" + modelIndex + ",\n" + "\tviewColumn: " + viewIndex + ",\n" + "\tconstraints: " + CollectionUtils.collect(applicableConstraints, c -> c.asString()) +"\n" + "}"; **//@formatter:on** }void doNothing() { // comment as to why we are doing nothing } ### White Space #### A single blank line should be used to separate the following sections: - Copyright notice - Package statement - Import section - Class declarations - Methods - Constructors #### A single blank line should be used: - Between statements as needed to break code into logical sections. - Between import statements as needed to break into logical groups. - Between fields as needed to break into logical groups. - Between the javadoc description and the javadoc tag section. #### A single space should be used: - To separate keywords from neighboring opening or closing brackets and braces. - Before and after all binary operators - After a // that starts a comment - Before a // that starts an end of line comment - After semicolons separating parts of a "for" loop ### Variable Assignment #### Each variable should be declared on its own line. don't: int i,j; do: int i; int j; ## Comments ### Javadoc #### Javadoc blocks are normally of the form /*** Some description with normal * wrapping. */ #### Javadoc paragraphs should be separated by a single blank line (Starts with an aligned *) and each paragraph other than the initial description should start with <p>. #### When referencing other methods, use links (e.g., {@link #method(type1, type2, ...} or {@link Classname#method(type1, type2, ...}). #### Block tags should never appear without a description. #### Descriptions in block tags should not end in a period, unless followed by another sentence. #### Block tags that are used should appear in the following order: - @param - @return - @throws - @see - @deprecated #### The Javadoc block should begin with a brief summary fragment. This fragment should be a noun phrase or a verb phrase and not a complete sentence. However, the fragment is capitalized and punctuated as if it were a complete sentence. For example, do /** * Sets the warning level for the messaging system. */ not /** * This method sets the warning level for the messaging system. */ #### Javadoc should be present for every public class and every public or protected method with the following exceptions: - Methods that override a super method. ### Code Comments #### Block comments are indented at the same level as the surrounding code. #### Block comments should be preceded by a blank line unless it is the first line of the block. #### Block comments should be one of the following forms: /* * This is // I like this * nice. // also. */ #### Any empty code block should have a comment so that the reader will know it was intentional. Also, the comment should not be something like "// empty" or "don't care", but instead should state why it is empty or why you don't care. #### Comments should indicate the 'why' you are doing something, not just 'what' you are doing. The code tells us what it is doing. Comments should not be pseudo code. #### Prefer creating a descriptive method to using a block comment. So if you feel that a block comment is needed to explain the next block of code, then it probably would be better off moved to a method with a name that says what the code does. #### Use of comments in code should be minimized by making the code self-documenting by appropriate name choices and an explicit logical structure. #### Tricky code should not be commented. Instead, it should be rewritten. ## Complexity ### Method Size #### Avoid long methods. - Methods should perform one clearly defined task. - Methods should generally fit on one page (approximately 30 lines). ### Method Complexity #### A method should be completely understandable (what, how, why) in about 30 seconds. #### Method Complexity should be kept low, according to the following scale: - 0-5: The method is *probably* fine - 6-10: The method is questionable; seek to simplify - 11+: OMG! Unacceptable!Calculating Complexity:
Start with one.
Add one for each of the following.
// example of mixed levels:
void doDailyChores() {
dust();
vacuum();
mopFloor();
addDirtyClothesToWashingMachine();
placeDetergentInWashingMachine();
closeWashingMachineDoor();
startWashingMachine();
cleanToilet();
}
// fixed
void doDailyChores() {
dust();
vacuum();
mopFloor();
washClothes();
cleanToilet();
}
Notes:
'The McCabe measure of complexity isn't the only sound measure, but it's the measure most discussed in computing literature and it's especially helpful when you're thinking about control flow. Other measures include the amount of data used, the number of nesting levels in control constructs, the number of lines of code, the number of lines between successive references to variables ("span"), the number of lines that a variable is in use ("live time"), and the amount of input and output. Some researchers have developed composite metrics based on combinations of these simpler ones.' (McCabe)
'Moving part of a routine into another routine doesn't reduce the overall complexity of the program; it just moves the decision points around. But it reduces the amount of complexity you have to deal with at any one time. Since the important goal is to minimize the number of items you have to juggle mentally, reducing the complexity of a given routine is worthwhile.' (McCabe)
'Excessive indentation, or "nesting," has been pilloried in computing literature for 25 years and is still one of the chief culprits in confusing code. Studies by Noam Chomsky and Gerald Weinberg suggest that few people can understand more than three levels of nested ifs (Yourdon 1986a), and many researchers recommend avoiding nesting to more than three or four levels (Myers 1976, Marca 1981, and Ledgard and Tauer 1987a). Deep nesting works against what Chapter 5, describes as Software's Primary Technical Imperative: Managing Complexity. That is reason enough to avoid deep nesting.' (McCabe)
'There is no code so big, twisted, or complex that maintenance can't make it worse.'
References: