diff --git a/Rguide.xml b/Rguide.xml deleted file mode 100644 index add76d3..0000000 --- a/Rguide.xml +++ /dev/null @@ -1,447 +0,0 @@ - - - - - - Google's R Style Guide - - - - -

Google's R Style Guide

- -

- R is a high-level programming language used primarily for - statistical computing and graphics. The goal of the R - Programming Style Guide is to make our R code easier to read, - share, and verify. The rules below were designed in - collaboration with the entire R user community at Google. - -

- - - - - - -

Summary: R Style Rules

- -
    -
  1. File Names: end in .R
  2. -
  3. Identifiers: variable.name - (or variableName), - FunctionName, kConstantName
  4. -
  5. Line Length: maximum 80 characters
  6. -
  7. Indentation: two spaces, no tabs
  8. -
  9. Spacing
  10. -
  11. Curly Braces: first on same line, last on - own line
  12. -
  13. else: Surround else with braces
  14. -
  15. Assignment: use <-, not - =
  16. -
  17. Semicolons: don't use them
  18. -
  19. General Layout and Ordering
  20. -
  21. Commenting Guidelines: all comments begin - with # followed by a space; inline comments need two - spaces before the #
  22. -
  23. Function Definitions and Calls
  24. -
  25. Function Documentation
  26. -
  27. Example Function
  28. -
  29. TODO Style: TODO(username)
  30. -
- -

Summary: R Language Rules

-
    -
  1. attach: avoid using it
  2. -
  3. Functions: - errors should be raised using stop()
  4. -
  5. Objects and Methods: avoid S4 objects and - methods when possible; never mix S3 and S4
  6. -
- -

Notation and Naming

- -

File Names

-

- File names should end in .R and, of course, be - meaningful. -
GOOD: predict_ad_revenue.R -
BAD: foo.R -

- -

Identifiers

-

- Don't use underscores ( _ ) or hyphens - ( - ) in identifiers. - Identifiers should be named according to the following conventions. - The preferred form for variable names is all lower case - letters and words separated with dots - (variable.name), but variableName - is also accepted; - function names have initial capital letters and no dots - (FunctionName); - constants are named like functions but with an initial - k. -

- - - -

Syntax

- -

Line Length

-

- The maximum line length is 80 characters. -

- -

Indentation

-

- When indenting your code, use two spaces. Never use tabs or mix - tabs and spaces. -
Exception: When a line break occurs inside parentheses, - align the wrapped line with the first character inside the - parenthesis. -

- -

Spacing

-

- Place spaces around all binary operators (=, - +, -, <-, etc.). -
Exception: Spaces around ='s are - optional when passing parameters in a function call. -

-

- Do not place a space before a comma, but always place one after a - comma. -

GOOD: -

-
tab.prior <- table(df[df$days.from.opt < 0, "campaign.id"])
-total <- sum(x[, 1])
-total <- sum(x[1, ])
-

- BAD: -

-
tab.prior <- table(df[df$days.from.opt<0, "campaign.id"])  # Needs spaces around '<'
-tab.prior <- table(df[df$days.from.opt < 0,"campaign.id"])  # Needs a space after the comma
-tab.prior<- table(df[df$days.from.opt < 0, "campaign.id"])  # Needs a space before <-
-tab.prior<-table(df[df$days.from.opt < 0, "campaign.id"])  # Needs spaces around <-
-total <- sum(x[,1])  # Needs a space after the comma
-total <- sum(x[ ,1])  # Needs a space after the comma, not before
-
-

- Place a space before left parenthesis, except in a function call. -

-

- GOOD: -
if (debug) -

-

- BAD: -
if(debug) -

-

- Extra spacing (i.e., more than one space in a row) is okay if it - improves alignment of equals signs or arrows (<-). -

-
plot(x    = x.coord,
-     y    = data.mat[, MakeColName(metric, ptiles[1], "roiOpt")],
-     ylim = ylim,
-     xlab = "dates",
-     ylab = metric,
-     main = (paste(metric, " for 3 samples ", sep = "")))
-
-

- Do not place spaces around code in parentheses or square brackets. -
Exception: Always place a space after a comma. -

-

- GOOD:

if (debug)
-x[1, ]
-

- BAD:

if ( debug )  # No spaces around debug
-x[1,]  # Needs a space after the comma 
- -

Curly Braces

-

- An opening curly brace should never go on its own line; a closing - curly brace should always go on its own line. You may omit curly - braces when a block consists of a single statement; however, you - must consistently either use or not use curly braces for - single statement blocks. -

-
-if (is.null(ylim)) {
-  ylim <- c(0, 0.06)
-}
-

- xor (but not both) -

-
-if (is.null(ylim))
-  ylim <- c(0, 0.06)
-

- Always begin the body of a block on a new line. -

-

- BAD: -
if (is.null(ylim)) - ylim <- c(0, 0.06) -
if (is.null(ylim)) - {ylim <- c(0, 0.06)} -

- -

Surround else with braces

-

- An else statement should always be surrounded on the - same line by curly braces.

-
-if (condition) {
-  one or more lines
-} else {
-  one or more lines
-}
-
-

- BAD:
-

-
-if (condition) {
-  one or more lines
-}
-else {
-  one or more lines
-}
-
-

- BAD:
-

-
-if (condition)
-  one line
-else
-  one line
-
- -

Assignment

-

- Use <-, not =, for assignment. -

-

- GOOD: -
x <- 5 -

-

- BAD: -
x = 5 -

-

Semicolons

-

- Do not terminate your lines with semicolons or use semicolons to - put more than one command on the same line. (Semicolons are not - necessary, and are omitted for consistency with other Google style - guides.) -

- - -

Organization

-

General Layout and Ordering

-

- If everyone uses the same general ordering, we'll be able to - read and understand each other's scripts faster and more easily. -

-
    -
  1. Copyright statement comment
  2. -
  3. Author comment
  4. -
  5. File description comment, including purpose of - program, inputs, and outputs
  6. -
  7. source() and library() statements
  8. -
  9. Function definitions
  10. -
  11. Executed statements, if applicable (e.g., - print, plot)
  12. -
-

- Unit tests should go in a separate file named - originalfilename_test.R. -

-

Commenting Guidelines

-

- Comment your code. Entire commented lines should begin with - # and one space. -

-

- Short comments can be placed after code preceded by two spaces, - #, and then one space. -

-
# Create histogram of frequency of campaigns by pct budget spent.
-hist(df$pct.spent,
-     breaks = "scott",  # method for choosing number of buckets
-     main   = "Histogram: fraction budget spent by campaignid",
-     xlab   = "Fraction of budget spent",
-     ylab   = "Frequency (count of campaignids)")
-
-

Function Definitions and - Calls

-

- Function definitions should first list arguments without default - values, followed by those with default values. -

-

- In both function definitions and function calls, multiple - arguments per line are allowed; line breaks are only allowed - between assignments. -
GOOD: -

-
PredictCTR <- function(query, property, num.days,
-                       show.plot = TRUE)
-
- BAD: -
PredictCTR <- function(query, property, num.days, show.plot =
-                       TRUE)
-
-

Ideally, unit tests should serve as sample function calls (for - shared library routines). -

-

Function Documentation

-

Functions should contain a comments section immediately below - the function definition line. These comments should consist of a - one-sentence description of the function; a list of the function's - arguments, denoted by Args:, with a description of - each (including the data type); and a description of the return - value, denoted by Returns:. The comments should be - descriptive enough that a caller can use the function without - reading any of the function's code. -

- -

Example Function

-
-CalculateSampleCovariance <- function(x, y, verbose = TRUE) {
-  # Computes the sample covariance between two vectors.
-  #
-  # Args:
-  #   x: One of two vectors whose sample covariance is to be calculated.
-  #   y: The other vector. x and y must have the same length, greater than one,
-  #      with no missing values.
-  #   verbose: If TRUE, prints sample covariance; if not, not. Default is TRUE.
-  #
-  # Returns:
-  #   The sample covariance between x and y.
-  n <- length(x)
-  # Error handling
-  if (n <= 1 || n != length(y)) {
-    stop("Arguments x and y have different lengths: ",
-         length(x), " and ", length(y), ".")
-  }
-  if (TRUE %in% is.na(x) || TRUE %in% is.na(y)) {
-    stop(" Arguments x and y must not have missing values.")
-  }
-  covariance <- var(x, y)
-  if (verbose)
-    cat("Covariance = ", round(covariance, 4), ".\n", sep = "")
-  return(covariance)
-}
-
- -

TODO Style

- -

- Use a consistent style for TODOs throughout your code. -
TODO(username): Explicit description of action to - be taken -

- - -

Language

- -

Attach

-

The possibilities for creating errors when using - attach are numerous. Avoid it.

-

Functions

-

Errors should be raised using stop().

-

Objects and Methods

-

The S language has two object systems, S3 and S4, both of which - are available in R. S3 methods are more interactive and flexible, - whereas S4 methods are more formal and rigorous. (For an illustration - of the two systems, see Thomas Lumley's - "Programmer's Niche: A Simple - Class, in S3 and S4" in R News 4/1, 2004, pgs. 33 - 36: - - http://cran.r-project.org/doc/Rnews/Rnews_2004-1.pdf.) -

-

Use S3 objects and methods unless there is a strong reason to use - S4 objects or methods. A primary justification for an S4 object - would be to use objects directly in C++ code. A primary - justification for an S4 generic/method would be to dispatch on two - arguments. -

-

Avoid mixing S3 and S4: S4 methods ignore S3 inheritance and - vice-versa. -

- - -

Exceptions

- -

- The coding conventions described above should be followed, unless - there is good reason to do otherwise. Exceptions include legacy - code and modifying third-party code. -

- - -

Parting Words

- -

- Use common sense and BE CONSISTENT. -

-

- If you are editing code, take a few minutes to look at the code around - you and determine its style. If others use spaces around their - if - clauses, you should, too. If their comments have little boxes of stars - around them, make your comments have little boxes of stars around them, - too. -

-

- The point of having style guidelines is to have a common vocabulary of - coding so people can concentrate on what you are saying, - rather than on how you are saying it. We present global style - rules here so people - know the vocabulary. But local style is also important. If code you add - to a file looks drastically different from the existing code around it, - the discontinuity will throw readers out of their rhythm when they go to - read it. Try to avoid this. -

- -

- OK, enough writing about writing code; the code itself is much more - interesting. Have fun! -

- - -

References

- -

- - http://www.maths.lth.se/help/R/RCC/ - R Coding Conventions -

-

- http://ess.r-project.org/ - For - emacs users. This runs R in your emacs and has an emacs mode. -

- - - - diff --git a/angularjs-google-style.html b/angularjs-google-style.html deleted file mode 100644 index 47db589..0000000 --- a/angularjs-google-style.html +++ /dev/null @@ -1,395 +0,0 @@ - - - - - - - - - - Google's AngularJS Style Guide - - - -

An AngularJS Style Guide for Closure Users at Google

- -

This is the external version of a document that was primarily written for Google - engineers. It describes a recommended style for AngularJS apps that use Closure, as used - internally at Google. Members of the broader AngularJS community should feel free to apply - (or not apply) these recommendations, as relevant to their own use cases.

- -

This document describes style for AngularJS apps in google3. This guide - supplements and extends the - Google JavaScript Style Guide. -

- -

Style Note: Examples on the AngularJS external webpage, and many external apps, are - written in a style that freely uses closures, favors functional inheritance, and does not often use - - JavaScript types. Google follows a more rigorous Javascript style to support JSCompiler - optimizations and large code bases - see the javascript-style mailing list. - This is not an Angular-specific issue, and is not discussed further in this style guide. - (But if you want further reading: - Martin Fowler on closures, - much longer description, appendix A of the - - closure book has a good description of inheritance patterns and why it prefers - pseudoclassical, - - Javascript, the Good Parts as a counter.)

- -
1 Angular Language Rules
- -
2 Angular Style Rules
- -
3 Angular Tips, Tricks, and Best Practices
- - -
4 Best practices links and docs
- -

1 Angular Language Rules

- -

Manage dependencies with Closure's goog.require and goog.provide

-

Choose a namespace for your project, and use goog.provide and goog.require.

-
-goog.provide('hello.about.AboutCtrl');
-goog.provide('hello.versions.Versions');
-
- -

Why? - Google BUILD rules integrate nicely with closure provide/require.

- -

Modules

- -

Your main application module should be in your root client directory. A module should never be - altered other than the one where it is defined.

- -

Modules may either be defined in the same file as their components (this works well for a module - that contains exactly one service) or in a separate file for wiring pieces together.

- -

Why? - A module should be consistent for anyone that wants to include it as a reusable component. - If a module can mean different things depending on which files are included, it is not consistent. -

- -

- Modules should reference other modules using the Angular Module's "name" property -

- -

For example:

- -
-// file submodulea.js:
-  goog.provide('my.submoduleA');
-
-  my.submoduleA = angular.module('my.submoduleA', []);
-  // ...
-
-// file app.js
-  goog.require('my.submoduleA');
-
-  Yes: my.application.module = angular.module('hello', [my.submoduleA.name]);
-  
-      No: my.application.module = angular.module('hello', ['my.submoduleA']);
-  
- -

Why? - Using a property of my.submoduleA prevents Closure presubmit failures complaining that the file is - required but never used. Using the .name property avoids duplicating strings.

- -

Use a common externs file

- -

This maximally allows the JS compiler to enforce type safety in the presence of externally - provided types from Angular, and means you don't have to worry about Angular vars being obfuscated - in a confusing way.

- -

Note to readers outside Google: the current externs file is located in an internal-to-Google - directory, but an example can be found on github - here.

- -

JSCompiler Flags

-

Reminder: According to the JS style guide, customer facing code must be compiled.

- -

Recommended: Use the JSCompiler (the closure compiler that works with js_binary by - default) and ANGULAR_COMPILER_FLAGS_FULL from //javascript/angular/build_defs/build_defs for - your base flags. -

- -

Note - if you are using @export for methods, you will need to add the compiler flag

-
-"--generate_exports",
-
- -

If you are using @export for properties, you will need to add the flags:

-
-"--generate_exports",
-"--remove_unused_prototype_props_in_externs=false",
-"--export_local_property_definitions",
-
- -

Controllers and Scopes

-

Controllers are classes. Methods should be defined on MyCtrl.prototype. - See - the JavaScript style guide

- -

Google Angular applications should use the 'controller as' style to export the controller - onto the scope. This is fully implemented in Angular 1.2 and can be mimicked in pre-Angular 1.2 - builds. -

- -

Pre Angular 1.2, this looks like:

-
-/**
- * Home controller.
- *
- * @param {!angular.Scope} $scope
- * @constructor
- * @ngInject
- * @export
- */
-hello.mainpage.HomeCtrl = function($scope) {
-  /** @export */
-  $scope.homeCtrl = this; // This is a bridge until Angular 1.2 controller-as
-
-  /**
-   * @type {string}
-   * @export
-   */
-  this.myColor = 'blue';
-};
-
-
-/**
- * @param {number} a
- * @param {number} b
- * @export
- */
-hello.mainpage.HomeCtrl.prototype.add = function(a, b) {
-  return a + b;
-};
-
- -

And the template:

- -
-<div ng-controller="hello.mainpage.HomeCtrl"/>
-  <span ng-class="homeCtrl.myColor">I'm in a color!</span>
-  <span>{{homeCtrl.add(5, 6)}}</span>
-</div>
-
- -

After Angular 1.2, this looks like:

- -
-/**
- * Home controller.
- *
- * @constructor
- * @ngInject
- * @export
- */
-hello.mainpage.HomeCtrl = function() {
-  /**
-   * @type {string}
-   * @export
-   */
-  this.myColor = 'blue';
-};
-
-
-/**
- * @param {number} a
- * @param {number} b
- * @export
- */
-hello.mainpage.HomeCtrl.prototype.add = function(a, b) {
-  return a + b;
-};
-
- -

If you are compiling with property renaming, expose properties and methods using the @export - annotation. Remember to @export the constructor as well.

- -

And in the template:

- -
-<div ng-controller="hello.mainpage.HomeCtrl as homeCtrl"/>
-  <span ng-class="homeCtrl.myColor">I'm in a color!</span>
-  <span>{{homeCtrl.add(5, 6)}}</span>
-</div>
-
- -

Why? - Putting methods and properties directly onto the controller, instead of building up a scope - object, fits better with the Google Closure class style. Additionally, using 'controller as' - makes it obvious which controller you are accessing when multiple controllers apply to an element. - Since there is always a '.' in the bindings, you don't have to worry about prototypal inheritance - masking primitives.

- -

Directives

- -

All DOM manipulation should be done inside directives. Directives should be kept small and use - composition. Files defining directives should goog.provide a static function which returns the - directive definition object.

- -
-goog.provide('hello.pane.paneDirective');
-
-/**
- * Description and usage
- * @return {angular.Directive} Directive definition object.
- */
-hello.pane.paneDirective = function() {
-  // ...
-};
-
- -

Exception: DOM manipulation may occur in services for DOM elements disconnected from the - rest of the view, e.g. dialogs or keyboard shortcuts.

- -

Services

- -

Services registered on the module with module.service are classes. - Use module.service instead of module.provider or - module.factory unless you need to do initialization beyond just creating a - new instance of the class.

- -
-/**
- * @param {!angular.$http} $http The Angular http service.
- * @constructor
- */
-hello.request.Request = function($http) {
-  /** @type {!angular.$http} */
-  this.http_ = $http;
-};
-
-hello.request.Request.prototype.get = function() {/*...*/};
-
- -

In the module:

- -
-module.service('request', hello.request.Request);
-
- - -

2 Angular Style Rules

- -

Reserve $ for Angular properties and services

-

Do not use $ to prepend your own object properties and service identifiers. Consider this style - of naming reserved by AngularJS and jQuery.

- -

Yes:

-
-  $scope.myModel = { value: 'foo' }
-  myModule.service('myService', function() { /*...*/ });
-  var MyCtrl = function($http) {this.http_ = $http;};
-
- -

No:

-
-  $scope.$myModel = { value: 'foo' } // BAD
-  $scope.myModel = { $value: 'foo' } // BAD
-  myModule.service('$myService', function() { ... }); // BAD
-  var MyCtrl = function($http) {this.$http_ = $http;}; // BAD
-
- -

Why? - It's useful to distinguish between Angular / jQuery builtins and things you add yourself. - In addition, $ is not an acceptable character for variables names in the JS style guide. -

- -

Custom elements

- -

For custom elements (e.g. <ng-include src="template"></ng-include>), IE8 - requires special support (html5shiv-like hacks) to enable css styling. Be aware of this - restriction in apps targeting old versions of IE.

- -

3 Angular Tips, Tricks, and Best Practices

- -

These are not strict style guide rules, but are placed here as reference for folks getting - started with Angular at Google.

- -

Testing

- -

Angular is designed for test-driven development.

- -

The recommended unit testing setup is Jasmine + Karma (though you could use closure tests - or js_test)

- -

Angular provides easy adapters to load modules and use the injector in Jasmine tests. -

-

- - -

Consider using the Best Practices for App Structure

-

- This directory structure doc describes how to structure your application with controllers in - nested subdirectories and all components (e.g. services and directives) in a 'components' dir. -

- - -

Be aware of how scope inheritance works

- -

See - The Nuances of Scope Prototypal Inheritance

- -

Use @ngInject for easy dependency injection compilation

-

This removes the need to add myCtrl['$inject'] = ... to prevent minification from - messing up Angular's dependency injection.

- -

Usage:

-
-/**
- * My controller.
- * @param {!angular.$http} $http
- * @param {!my.app.myService} myService
- * @constructor
- * @export
- * @ngInject
- */
-my.app.MyCtrl = function($http, myService) {
-  //...
-};
-
- -

4 Best practices links and docs

- - -
- Last modified Feb 07 2013 -
- - diff --git a/cppguide.html b/cppguide.html deleted file mode 100644 index 3674ac0..0000000 --- a/cppguide.html +++ /dev/null @@ -1,6117 +0,0 @@ - - - - -Google C++ Style Guide - - - - -
-

Google C++ Style Guide

-
- -
- - - -

C++ is the main development language used by -many of Google's open-source projects. As every C++ -programmer knows, the language has many powerful features, but -this power brings with it complexity, which in turn can make -code more bug-prone and harder to read and maintain.

- -

The goal of this guide is to manage this complexity by -describing in detail the dos and don'ts of writing C++ code. -These rules exist to -keep the code base manageable while still allowing -coders to use C++ language features productively.

- -

Style, also known as readability, is what we call -the conventions that govern our C++ code. The term Style is a -bit of a misnomer, since these conventions cover far more than -just source file formatting.

- -

-Most open-source projects developed by -Google conform to the requirements in this guide. -

- - - - - -

Note that this guide is not a C++ tutorial: we assume that -the reader is familiar with the language.

- -

Goals of the Style Guide

-
-

Why do we have this document?

- -

There are a few core goals that we believe this guide should -serve. These are the fundamental whys that -underlie all of the individual rules. By bringing these ideas to -the fore, we hope to ground discussions and make it clearer to our -broader community why the rules are in place and why particular -decisions have been made. If you understand what goals each rule is -serving, it should be clearer to everyone when a rule may be waived -(some can be), and what sort of argument or alternative would be -necessary to change a rule in the guide.

- -

The goals of the style guide as we currently see them are as follows:

-
-
Style rules should pull their weight
-
The benefit of a style rule -must be large enough to justify asking all of our engineers to -remember it. The benefit is measured relative to the codebase we would -get without the rule, so a rule against a very harmful practice may -still have a small benefit if people are unlikely to do it -anyway. This principle mostly explains the rules we don’t have, rather -than the rules we do: for example, goto contravenes many -of the following principles, but is already vanishingly rare, so the Style -Guide doesn’t discuss it.
- -
Optimize for the reader, not the writer
-
Our codebase (and most individual components submitted to it) is -expected to continue for quite some time. As a result, more time will -be spent reading most of our code than writing it. We explicitly -choose to optimize for the experience of our average software engineer -reading, maintaining, and debugging code in our codebase rather than -ease when writing said code. "Leave a trace for the reader" is a -particularly common sub-point of this principle: When something -surprising or unusual is happening in a snippet of code (for example, -transfer of pointer ownership), leaving textual hints for the reader -at the point of use is valuable (std::unique_ptr -demonstrates the ownership transfer unambiguously at the call -site).
- -
Be consistent with existing code
-
Using one style consistently through our codebase lets us focus on -other (more important) issues. Consistency also allows for -automation: tools that format your code or adjust -your #includes only work properly when your code is -consistent with the expectations of the tooling. In many cases, rules -that are attributed to "Be Consistent" boil down to "Just pick one and -stop worrying about it"; the potential value of allowing flexibility -on these points is outweighed by the cost of having people argue over -them.
- -
Be consistent with the broader C++ community when appropriate
-
Consistency with the way other organizations use C++ has value for -the same reasons as consistency within our code base. If a feature in -the C++ standard solves a problem, or if some idiom is widely known -and accepted, that's an argument for using it. However, sometimes -standard features and idioms are flawed, or were just designed without -our codebase's needs in mind. In those cases (as described below) it's -appropriate to constrain or ban standard features. In some cases we -prefer a homegrown or third-party library over a library defined in -the C++ Standard, either out of perceived superiority or insufficient -value to transition the codebase to the standard interface.
- -
Avoid surprising or dangerous constructs
-
C++ has features that are more surprising or dangerous than one -might think at a glance. Some style guide restrictions are in place to -prevent falling into these pitfalls. There is a high bar for style -guide waivers on such restrictions, because waiving such rules often -directly risks compromising program correctness. -
- -
Avoid constructs that our average C++ programmer would find tricky -or hard to maintain
-
C++ has features that may not be generally appropriate because of -the complexity they introduce to the code. In widely used -code, it may be more acceptable to use -trickier language constructs, because any benefits of more complex -implementation are multiplied widely by usage, and the cost in understanding -the complexity does not need to be paid again when working with new -portions of the codebase. When in doubt, waivers to rules of this type -can be sought by asking -your project leads. This is specifically -important for our codebase because code ownership and team membership -changes over time: even if everyone that works with some piece of code -currently understands it, such understanding is not guaranteed to hold a -few years from now.
- -
Be mindful of our scale
-
With a codebase of 100+ million lines and thousands of engineers, -some mistakes and simplifications for one engineer can become costly -for many. For instance it's particularly important to -avoid polluting the global namespace: name collisions across a -codebase of hundreds of millions of lines are difficult to work with -and hard to avoid if everyone puts things into the global -namespace.
- -
Concede to optimization when necessary
-
Performance optimizations can sometimes be necessary and -appropriate, even when they conflict with the other principles of this -document.
-
- -

The intent of this document is to provide maximal guidance with -reasonable restriction. As always, common sense and good taste should -prevail. By this we specifically refer to the established conventions -of the entire Google C++ community, not just your personal preferences -or those of your team. Be skeptical about and reluctant to use -clever or unusual constructs: the absence of a prohibition is not the -same as a license to proceed. Use your judgment, and if you are -unsure, please don't hesitate to ask your project leads to get additional -input.

- -
- - - -

Header Files

- -

In general, every .cc file should have an -associated .h file. There are some common -exceptions, such as unittests and -small .cc files containing just a -main() function.

- -

Correct use of header files can make a huge difference to -the readability, size and performance of your code.

- -

The following rules will guide you through the various -pitfalls of using header files.

- - -

Self-contained Headers

- -
-

Header files should be self-contained and end in .h. Files that -are meant for textual inclusion, but are not headers, should end in -.inc. Separate -inl.h headers are disallowed.

-
- -
-

All header files should be self-contained. In other -words, users and refactoring tools should not have to adhere to special -conditions in order to include the header. Specifically, a -header should have header guards, -should include all other headers it needs, and should not require any -particular symbols to be defined.

- -

There are rare cases where a file is not meant to be self-contained, but -instead is meant to be textually included at a specific point in the code. -Examples are files that need to be included multiple times or -platform-specific extensions that essentially are part of other headers. Such -files should use the file extension .inc.

- -

If a template or inline function is declared in a .h file, -define it in that same file. The definitions of these constructs must -be included into every .cc file that uses them, or the -program may fail to link in some build configurations. Do not move these -definitions to separate -inl.h files.

- -

As an exception, a function template that is explicitly -instantiated for all relevant sets of template arguments, or -that is a private member of a class, may -be defined in the only .cc file that -instantiates the template.

- -
- -

The #define Guard

- -
-

All header files should have #define guards to -prevent multiple inclusion. The format of the symbol name -should be -<PROJECT>_<PATH>_<FILE>_H_.

-
- -
- - - -

To guarantee uniqueness, they should -be based on the full path in a project's source tree. For -example, the file foo/src/bar/baz.h in -project foo should have the following -guard:

- -
#ifndef FOO_BAR_BAZ_H_
-#define FOO_BAR_BAZ_H_
-
-...
-
-#endif  // FOO_BAR_BAZ_H_
-
- - - - -
- -

Forward Declarations

- -
-

Avoid using forward declarations where possible. - Just #include the headers you need.

-
- -
- -
-

A "forward declaration" is a declaration of a class, -function, or template without an associated definition.

-
- -
-
    -
  • Forward declarations can save compile time, as - #includes force the compiler to open - more files and process more input.
  • - -
  • Forward declarations can save on unnecessary - recompilation. #includes can force - your code to be recompiled more often, due to unrelated - changes in the header.
  • -
-
- -
-
    -
  • Forward declarations can hide a dependency, allowing - user code to skip necessary recompilation when headers - change.
  • - -
  • A forward declaration may be broken by subsequent - changes to the library. Forward declarations of functions - and templates can prevent the header owners from making - otherwise-compatible changes to their APIs, such as - widening a parameter type, adding a template parameter - with a default value, or migrating to a new namespace.
  • - -
  • Forward declaring symbols from namespace - std:: yields undefined behavior.
  • - -
  • It can be difficult to determine whether a forward - declaration or a full #include is needed. - Replacing an #include with a forward - declaration can silently change the meaning of - code: -
          // b.h:
    -      struct B {};
    -      struct D : B {};
    -
    -      // good_user.cc:
    -      #include "b.h"
    -      void f(B*);
    -      void f(void*);
    -      void test(D* x) { f(x); }  // calls f(B*)
    -      
    - If the #include was replaced with forward - decls for B and D, - test() would call f(void*). -
  • - -
  • Forward declaring multiple symbols from a header - can be more verbose than simply - #includeing the header.
  • - -
  • Structuring code to enable forward declarations - (e.g. using pointer members instead of object members) - can make the code slower and more complex.
  • - - -
-
- -
-
    -
  • Try to avoid forward declarations of entities - defined in another project.
  • - -
  • When using a function declared in a header file, - always #include that header.
  • - -
  • When using a class template, prefer to - #include its header file.
  • -
- -

Please see Names and Order -of Includes for rules about when to #include a header.

-
- -
- -

Inline Functions

- -
-

Define functions inline only when they are small, say, 10 -lines or less.

-
- -
- -
-

You can declare functions in a way that allows the compiler to expand -them inline rather than calling them through the usual -function call mechanism.

-
- -
-

Inlining a function can generate more efficient object -code, as long as the inlined function is small. Feel free -to inline accessors and mutators, and other short, -performance-critical functions.

-
- -
-

Overuse of inlining can actually make programs slower. -Depending on a function's size, inlining it can cause the -code size to increase or decrease. Inlining a very small -accessor function will usually decrease code size while -inlining a very large function can dramatically increase -code size. On modern processors smaller code usually runs -faster due to better use of the instruction cache.

-
- -
-

A decent rule of thumb is to not inline a function if -it is more than 10 lines long. Beware of destructors, -which are often longer than they appear because of -implicit member- and base-destructor calls!

- -

Another useful rule of thumb: it's typically not cost -effective to inline functions with loops or switch -statements (unless, in the common case, the loop or -switch statement is never executed).

- -

It is important to know that functions are not always -inlined even if they are declared as such; for example, -virtual and recursive functions are not normally inlined. -Usually recursive functions should not be inline. The -main reason for making a virtual function inline is to -place its definition in the class, either for convenience -or to document its behavior, e.g., for accessors and -mutators.

-
- -
- -

Names and Order of Includes

- -
-

Use standard order for readability and to avoid hidden -dependencies: Related header, C library, C++ library, other libraries' -.h, your project's .h.

-
- -
-

-All of a project's header files should be -listed as descendants of the project's source -directory without use of UNIX directory shortcuts -. (the current directory) or .. -(the parent directory). For example, - -google-awesome-project/src/base/logging.h -should be included as:

- -
#include "base/logging.h"
-
- -

In dir/foo.cc or -dir/foo_test.cc, whose main -purpose is to implement or test the stuff in -dir2/foo2.h, order your includes -as follows:

- -
    -
  1. dir2/foo2.h.
  2. - -
  3. C system files.
  4. - -
  5. C++ system files.
  6. - -
  7. Other libraries' .h - files.
  8. - -
  9. - Your project's .h - files.
  10. -
- -

With the preferred ordering, if -dir2/foo2.h omits any necessary -includes, the build of dir/foo.cc -or dir/foo_test.cc will break. -Thus, this rule ensures that build breaks show up first -for the people working on these files, not for innocent -people in other packages.

- -

dir/foo.cc and -dir2/foo2.h are usually in the same -directory (e.g. base/basictypes_test.cc and -base/basictypes.h), but may sometimes be in different -directories too.

- - - -

Within each section the includes should be ordered -alphabetically. Note that older code might not conform to -this rule and should be fixed when convenient.

- -

You should include all the headers that define the symbols you rely -upon, except in the unusual case of forward -declaration. If you rely on symbols from bar.h, -don't count on the fact that you included foo.h which -(currently) includes bar.h: include bar.h -yourself, unless foo.h explicitly demonstrates its intent -to provide you the symbols of bar.h. However, any -includes present in the related header do not need to be included -again in the related cc (i.e., foo.cc can -rely on foo.h's includes).

- -

For example, the includes in - -google-awesome-project/src/foo/internal/fooserver.cc -might look like this:

- - -
#include "foo/server/fooserver.h"
-
-#include <sys/types.h>
-#include <unistd.h>
-#include <hash_map>
-#include <vector>
-
-#include "base/basictypes.h"
-#include "base/commandlineflags.h"
-#include "foo/server/bar.h"
-
- -

Sometimes, system-specific code needs -conditional includes. Such code can put conditional -includes after other includes. Of course, keep your -system-specific code small and localized. Example:

- -
#include "foo/public/fooserver.h"
-
-#include "base/port.h"  // For LANG_CXX11.
-
-#ifdef LANG_CXX11
-#include <initializer_list>
-#endif  // LANG_CXX11
-
- -
- -

Scoping

- -

Namespaces

- -
-

With few exceptions, place code in a namespace. Namespaces -should have unique names based on the project name, and possibly -its path. Unnamed namespaces in .cc files are -encouraged. Do not use using-directives. Do not use -inline namespaces.

-
- -
- -
-

Namespaces subdivide the global scope -into distinct, named scopes, and so are useful for preventing -name collisions in the global scope.

-
- -
- -

Namespaces provide a method for preventing name conflicts -in large programs while allowing most code to use reasonably -short names.

- -

For example, if two different projects have a class -Foo in the global scope, these symbols may -collide at compile time or at runtime. If each project -places their code in a namespace, project1::Foo -and project2::Foo are now distinct symbols that -do not collide, and code within each project's namespace -can continue to refer to Foo without the prefix.

- -

Inline namespaces automatically place their names in -the enclosing scope. Consider the following snippet, for -example:

- -
namespace X {
-inline namespace Y {
-  void foo();
-}
-}
-
- -

The expressions X::Y::foo() and -X::foo() are interchangeable. Inline -namespaces are primarily intended for ABI compatibility -across versions.

-
- -
- -

Namespaces can be confusing, because they complicate -the mechanics of figuring out what definition a name refers -to.

- -

Inline namespaces, in particular, can be confusing -because names aren't actually restricted to the namespace -where they are declared. They are only useful as part of -some larger versioning policy.

- -

Use of unnamed namespaces in header files can easily -cause violations of the C++ One Definition Rule -(ODR).

- -

In some contexts, it's necessary to repeatedly refer to -symbols by their fully-qualified names. For deeply-nested -namespaces, this can add a lot of clutter.

-
- -
- -

Use namespaces according to the policy described -below. Terminate namespaces with comments as shown in the -given examples. See also the rules on -Namespace Names.

-
- -

Unnamed Namespaces

- -
    -
  • -

    Unnamed namespaces are allowed and even encouraged - in .cc files, to avoid link time naming - conflicts:

    - -
    namespace {                           // This is in a .cc file.
    -
    -// The content of a namespace is not indented.
    -//
    -// This function is guaranteed not to generate a colliding symbol
    -// with other symbols at link time, and is only visible to
    -// callers in this .cc file.
    -bool UpdateInternals(Frobber* f, int newval) {
    -  ...
    -}
    -
    -}  // namespace
    -
    -
  • - -
  • Do not use unnamed namespaces in .h - files.
  • -
- -

Named Namespaces

- -

Named namespaces should be used as follows:

- -
    -
  • - -

    Namespaces wrap the entire source file after - includes, - - gflags definitions/declarations - and forward declarations of classes from other namespaces.

    - -
    // In the .h file
    -namespace mynamespace {
    -
    -// All declarations are within the namespace scope.
    -// Notice the lack of indentation.
    -class MyClass {
    - public:
    -  ...
    -  void Foo();
    -};
    -
    -}  // namespace mynamespace
    -
    - -
    // In the .cc file
    -namespace mynamespace {
    -
    -// Definition of functions is within scope of the namespace.
    -void MyClass::Foo() {
    -  ...
    -}
    -
    -}  // namespace mynamespace
    -
    - -

    More complex .cc files might have additional details, - like flags or using-declarations.

    - -
    #include "a.h"
    -
    -DEFINE_bool(someflag, false, "dummy flag");
    -
    -using ::foo::bar;
    -
    -namespace a {
    -
    -...code for a...         // Code goes against the left margin.
    -
    -}  // namespace a
    -
    -
  • - - - -
  • Do not declare anything in namespace - std, including forward declarations of - standard library classes. Declaring entities in - namespace std is undefined behavior, i.e., - not portable. To declare entities from the standard - library, include the appropriate header file.
  • - -
  • You may not use a using-directive - to make all names from a namespace available.

    - -
    // Forbidden -- This pollutes the namespace.
    -using namespace foo;
    -
    -
  • - -
  • You may use a using-declaration - anywhere in a .cc file (including in - the global namespace), and in functions, - methods, classes, or within internal namespaces in - .h files.

    - -

    Do not use using-declarations in .h - files except in explicitly marked internal-only - namespaces, because anything imported into a namespace - in a .h file becomes part of the public - API exported by that file.

    - -
    // OK in .cc files.
    -// Must be in a function, method, internal namespace, or
    -// class in .h files.
    -using ::foo::bar;
    -
    -
  • - -
  • Namespace aliases are allowed anywhere where - a using-declaration is allowed. In particular, - namespace aliases should not be used at namespace scope - in .h files except in explicitly marked - internal-only namespaces.

    - -
    // Shorten access to some commonly used names in .cc files.
    -namespace baz = ::foo::bar::baz;
    -
    - -
    // Shorten access to some commonly used names (in a .h file).
    -namespace librarian {
    -namespace impl {  // Internal, not part of the API.
    -namespace sidetable = ::pipeline_diagnostics::sidetable;
    -}  // namespace impl
    -
    -inline void my_inline_function() {
    -  // namespace alias local to a function (or method).
    -  namespace baz = ::foo::bar::baz;
    -  ...
    -}
    -}  // namespace librarian
    -
    - -
  • Do not use inline namespaces.
  • -
- -

Nonmember, Static Member, and Global Functions

- -
-

Prefer placing nonmember functions in a namespace; use completely global -functions rarely. Prefer grouping functions with a namespace instead of -using a class as if it were a namespace. Static methods of a class should -generally be closely related to instances of the class or the class's static -data.

-
- -
- -
-

Nonmember and static member functions can be useful in - some situations. Putting nonmember functions in a - namespace avoids polluting the global namespace.

-
- -
-

Nonmember and static member functions may make more sense -as members of a new class, especially if they access -external resources or have significant dependencies.

-
- -
-

Sometimes it is useful, or even necessary, to define a -function not bound to a class instance. Such a function -can be either a static member or a nonmember function. -Nonmember functions should not depend on external -variables, and should nearly always exist in a namespace. -Rather than creating classes only to group static member -functions which do not share static data, use -namespaces instead. For a header -myproject/foo_bar.h, for example, write

-
namespace myproject {
-namespace foo_bar {
-void Function1();
-void Function2();
-}
-}
-
-

instead of

-
namespace myproject {
-class FooBar {
- public:
-  static void Function1();
-  static void Function2();
-};
-}
-
- -

If you must define a nonmember function and it is only -needed in its .cc file, use an unnamed -namespace or -static linkage (eg static int Foo() -{...}) to limit its scope.

-
- -
- -

Local Variables

- -
-

Place a function's variables in the narrowest scope -possible, and initialize variables in the declaration.

-
- -
- -

C++ allows you to declare variables anywhere in a -function. We encourage you to declare them in as local a -scope as possible, and as close to the first use as -possible. This makes it easier for the reader to find the -declaration and see what type the variable is and what it -was initialized to. In particular, initialization should -be used instead of declaration and assignment, e.g.:

- -
int i;
-i = f();      // Bad -- initialization separate from declaration.
-
- -
int j = g();  // Good -- declaration has initialization.
-
- -
vector<int> v;
-v.push_back(1);  // Prefer initializing using brace initialization.
-v.push_back(2);
-
- -
vector<int> v = {1, 2};  // Good -- v starts initialized.
-
- -

Variables needed for if, while -and for statements should normally be declared -within those statements, so that such variables are confined -to those scopes. E.g.:

- -
while (const char* p = strchr(str, '/')) str = p + 1;
-
- -

There is one caveat: if the variable is an object, its -constructor is invoked every time it enters scope and is -created, and its destructor is invoked every time it goes -out of scope.

- -
// Inefficient implementation:
-for (int i = 0; i < 1000000; ++i) {
-  Foo f;  // My ctor and dtor get called 1000000 times each.
-  f.DoSomething(i);
-}
-
- -

It may be more efficient to declare such a variable -used in a loop outside that loop:

- -
Foo f;  // My ctor and dtor get called once each.
-for (int i = 0; i < 1000000; ++i) {
-  f.DoSomething(i);
-}
-
- -
- -

Static and Global Variables

- -
-

Variables of class type with - static storage duration are forbidden: they cause hard-to-find bugs due - to indeterminate order of construction and destruction. However, such - variables are allowed if they are constexpr: they have no - dynamic initialization or destruction.

-
- -
- -

Objects with static storage duration, including global -variables, static variables, static class member -variables, and function static variables, must be Plain -Old Data (POD): only ints, chars, floats, or pointers, or -arrays/structs of POD.

- -

The order in which class constructors and initializers -for static variables are called is only partially -specified in C++ and can even change from build to build, -which can cause bugs that are difficult to find. -Therefore in addition to banning globals of class type, -we do not allow static POD variables to be initialized -with the result of a function, unless that function (such -as getenv(), or getpid()) does not itself depend on any -other globals. (This prohibition does not apply to a static -variable within function scope, since its initialization -order is well-defined and does not occur until control -passes through its declaration.)

- -

Likewise, global and static variables are destroyed -when the program terminates, regardless of whether the -termination is by returning from main() or -by calling exit(). The order in which -destructors are called is defined to be the reverse of -the order in which the constructors were called. Since -constructor order is indeterminate, so is destructor -order. For example, at program-end time a static variable -might have been destroyed, but code still running -— perhaps in another thread -— tries to access it and fails. Or the -destructor for a static string variable -might be run prior to the destructor for another variable -that contains a reference to that string.

- -

One way to alleviate the destructor problem is to -terminate the program by calling -quick_exit() instead of exit(). -The difference is that quick_exit() does not -invoke destructors and does not invoke any handlers that -were registered by calling atexit(). If you -have a handler that needs to run when a program -terminates via quick_exit() (flushing logs, -for example), you can register it using -at_quick_exit(). (If you have a handler that -needs to run at both exit() and -quick_exit(), you need to register it in -both places.)

- -

As a result we only allow static variables to contain -POD data. This rule completely disallows -vector (use C arrays instead), or -string (use const char []).

- - - -

If you need a static or global -variable of a class type, consider initializing a pointer -(which will never be freed), from either your main() -function or from pthread_once(). Note that this must be a -raw pointer, not a "smart" pointer, since the smart -pointer's destructor will have the order-of-destructor -issue that we are trying to avoid.

- - - - - -
- -

Classes

- -

Classes are the fundamental unit of code in C++. Naturally, -we use them extensively. This section lists the main dos and -don'ts you should follow when writing a class.

- -

Doing Work in Constructors

- -
-

Avoid virtual method calls in constructors, and avoid -initialization that can fail if you can't signal an error.

-
- -
- -
-

It is possible to perform arbitrary initialization in the body -of the constructor.

-
- -
-
    -
  • No need to worry about whether the class has been initialized or - not.
  • - -
  • Objects that are fully initialized by constructor call can - be const and may also be easier to use with standard containers - or algorithms.
  • -
- -
- -
-

The problems with doing work in constructors are:

- -
    -
  • If the work calls virtual functions, these calls - will not get dispatched to the subclass - implementations. Future modification to your class can - quietly introduce this problem even if your class is - not currently subclassed, causing much confusion.
  • - -
  • There is no easy way for constructors to signal errors, short of - crashing the program (not always appropriate) or using exceptions - (which are forbidden).
  • - -
  • If the work fails, we now have an object whose initialization - code failed, so it may be an unusual state requiring a bool - IsValid() state checking mechanism (or similar) which is easy - to forget to call.
  • - -
  • You cannot take address of a constructor, so whatever work is done in - the constructor cannot easily be handed off to, for example, another - thread.
  • -
-
- - -
-

Constructors should never call virtual functions. If appropriate -for your code -, -terminating the program may be an appropriate error handling -response. Otherwise, consider a factory function -or Init() method. Avoid Init() methods on objects with -no other states that affect which public methods may be called -(semi-constructed objects of this form are particularly hard to work -with correctly).

-
- -
- - -

Implicit Conversions

- -
-

Do not define implicit conversions. Use the explicit -keyword for conversion operators and single-argument -constructors.

-
- -
- -
-

Implicit conversions allow an -object of one type (called the source type) to -be used where a different type (called the destination -type) is expected, such as when passing an -int argument to a function that takes a -double parameter.

- -

In addition to the implicit conversions defined by the language, -users can define their own, by adding appropriate members to the -class definition of the source or destination type. An implicit -conversion in the source type is defined by a type conversion operator -named after the destination type (e.g. operator -bool()). An implicit conversion in the destination -type is defined by a converting constructor, which -is a constructor that can take the source type as its only -argument. Note that a multi-parameter constructor can still -be a converting constructor, if all but the first parameter -have default values.

- -

The explicit keyword can be applied to a constructor -or (since C++11) a conversion operator, to ensure that it can only be -used when the destination type is explicit at the point of use, -e.g. with a cast. This applies not only to implicit conversions, but to -C++11's list initialization syntax:

-
class Foo {
-  explicit Foo(int x, double y);
-  ...
-};
-
-void Func(Foo f);
-
-
Func({42, 3.14});  // Error
-
-This kind of code isn't technically an implicit conversion, but the -language treats it as one as far as explicit is concerned. -
- -
-
    -
  • Implicit conversions can make a type more usable and - expressive by eliminating the need to explicitly name a type - when it's obvious.
  • -
  • Implicit conversions can be a simpler alternative to - overloading.
  • -
  • List initialization syntax is a concise and expressive - way of initializing objects.
  • -
-
- -
-
    -
  • Implicit conversions can hide type-mismatch bugs, where the - destination type does not match the user's expectation, or - the user is unaware that any conversion will take place.
  • - -
  • Implicit conversions can make code harder to read, particularly - in the presence of overloading, by making it less obvious what - code is actually getting called.
  • - -
  • Constructors that take a single argument may accidentally - be usable as implicit type conversions, even if they are not - intended to do so.
  • - -
  • When a single-argument constructor is not marked - explicit, there's no reliable way to tell whether - it's intended to define an implicit conversion, or the author - simply forgot to mark it.
  • - -
  • It's not always clear which type should provide the conversion, - and if they both do, the code becomes ambiguous.
  • - -
  • List initialization can suffer from the same problems if - the destination type is implicit, particularly if the - list has only a single element.
  • -
-
- -
-

Type conversion operators, and constructors that are -callable with a single argument, must be marked -explicit in the class definition. As an -exception, copy and move constructors should not be -explicit, since they do not perform type -conversion. Implicit conversions can sometimes be necessary and -appropriate for types that are designed to transparently wrap other -types. In that case, contact -your project leads to request -a waiver of this rule.

- -

Constructors that cannot be called with a single argument -should usually omit explicit. Constructors that -take a single std::initializer_list parameter should -also omit explicit, in order to support copy-initialization -(e.g. MyType m = {1, 2};).

-
- -
- -

Copyable and Movable Types

- -
-

Support copying and/or moving if it makes sense for your type. -Otherwise, disable the implicitly generated special -functions that perform copies and moves.

-
- -
- -
-

A copyable type allows its objects to be initialized or assigned -from any other object of the same type, without changing the value of the source. -For user-defined types, the copy behavior is defined by the copy -constructor and the copy-assignment operator. -string is an example of a copyable type.

- -

A movable type is one that can be initialized and assigned -from temporaries (all copyable types are therefore movable). -std::unique_ptr<int> is an example of a movable but not -copyable type. For user-defined types, the move behavior is defined by the move -constructor and the move-assignment operator.

- -

The copy/move constructors can be implicitly invoked by the compiler -in some situations, e.g. when passing objects by value.

-
- -
-

Objects of copyable and movable types can be passed and returned -by value, which makes APIs simpler, safer, and more general. -Unlike when passing pointers or references, there's no risk of -confusion over ownership, lifetime, mutability, and similar -issues, and no need to specify them in the contract. It also -prevents non-local interactions between the client and the -implementation, which makes them easier to understand and -maintain. Such objects can be used with generic -APIs that require pass-by-value, such as most containers.

- -

Copy/move constructors and assignment operators are usually -easier to define correctly than alternatives -like Clone(), CopyFrom() or Swap(), -because they can be generated by the compiler, either implicitly or -with = default. They are concise, and ensure -that all data members are copied. Copy and move -constructors are also generally more efficient, because they don't -require heap allocation or separate initialization and assignment -steps, and they're eligible for optimizations such as - - -copy elision.

- -

Move operations allow the implicit and efficient transfer of -resources out of rvalue objects. This allows a plainer coding style -in some cases.

-
- -
-

Many types do not need to be copyable, and providing copy -operations for them can be confusing, nonsensical, or outright -incorrect. Copy/assigment operations for base class types are -hazardous, because use of them can lead to -object -slicing. Defaulted or carelessly-implemented copy operations -can be incorrect, and the resulting bugs can be confusing and -difficult to diagnose.

- -

Copy constructors are invoked implicitly, which makes the -invocation easy to miss. This may cause confusion, particularly -for programmers used to languages where pass-by-reference is -conventional or mandatory. It may also encourage excessive -copying, which can cause performance problems.

- - -
- -
- -

Make your type copyable/movable if it will be useful, and if it makes sense -in the context of the rest of the API. As a rule of thumb, if the behavior -(including computational complexity) of a copy isn't immediately obvious to -users of your type, your type shouldn't be copyable. If you define a copy or -move constructor, define the corresponding assignment operator, and vice-versa. -If your type is copyable, do not define move operations unless they are -significantly more efficient than the corresponding copy operations. If your -type is not copyable, but the correctness of a move is obvious to users of the -type, you may make the type move-only by defining both of the move operations. -

- -

If your type provides copy operations, it is recommended that you design -your class so that the default implementation of those operations is correct -and that you explicitly define them with = default. Remember to -review the correctness of any defaulted operations as you would any other -code.

- -
class Foo {  // Copyable and movable type.
- public:
-  Foo(Foo&& other) = default;
-  Foo(const Foo& other) = default;
-  Foo& operator=(Foo&& other) = default;
-  Foo& operator=(const Foo& other) = default;
-
- private:
-  string field_;
-};
-
- -
class Foo {
- public:
-  Foo(Foo&& other) : field_(other.field) {}
-  // Bad, defines only move constructor, but not operator=.
-
- private:
-  Field field_;
-};
-
- -

Due to the risk of slicing, avoid providing an assignment -operator or public copy/move constructor for a class that's -intended to be derived from (and avoid deriving from a class -with such members). If your base class needs to be -copyable, provide a public virtual Clone() -method, and a protected copy constructor that derived classes -can use to implement it.

- -

If you do not want to support copy/move operations on -your type, explicitly disable them using = delete or -whatever -other mechanism your project uses. - -

-
- -

Delegating and Inheriting Constructors

- -
-

Use delegating and inheriting -constructors when they reduce code duplication.

-
- -
- -
- -

Delegating and inheriting constructors are two -different features, both introduced in C++11, for -reducing code duplication in constructors. Delegating -constructors allow one of a class's constructors to -forward work to one of the class's other constructors, -using a special variant of the initialization list -syntax. For example:

- -
X::X(const string& name) : name_(name) {
-  ...
-}
-
-X::X() : X("") {}
-
- -

Inheriting constructors allow a derived class to have -its base class's constructors available directly, just as -with any of the base class's other member functions, -instead of having to redeclare them. This is especially -useful if the base has multiple constructors. For -example:

- -
class Base {
- public:
-  Base();
-  Base(int n);
-  Base(const string& s);
-  ...
-};
-
-class Derived : public Base {
- public:
-  using Base::Base;  // Base's constructors are redeclared here.
-};
-
- -

This is especially useful when Derived's -constructors don't have to do anything more than calling -Base's constructors.

-
- -
-

Delegating and inheriting constructors reduce -verbosity and boilerplate, which can improve -readability.

- -

Delegating constructors are familiar to Java -programmers.

-
- -
-

It's possible to approximate the behavior of -delegating constructors by using a helper function.

- -

Inheriting constructors may be confusing if a derived -class introduces new member variables, since the base -class constructor doesn't know about them.

-
- -
-

Use delegating and inheriting constructors when they reduce -boilerplate and improve readability. -Be cautious about inheriting constructors when your derived class has -new member variables. Inheriting constructors may still be appropriate -in that case if you can use in-class member initialization -for the derived class's member variables.

-
- -
- -

Structs vs. Classes

- -
-

Use a struct only for passive objects that - carry data; everything else is a class.

-
- -
- -

The struct and class -keywords behave almost identically in C++. We add our own -semantic meanings to each keyword, so you should use the -appropriate keyword for the data-type you're -defining.

- -

structs should be used for passive -objects that carry data, and may have associated -constants, but lack any functionality other than -access/setting the data members. The accessing/setting of -fields is done by directly accessing the fields rather -than through method invocations. Methods should not -provide behavior but should only be used to set up the -data members, e.g., constructor, destructor, -Initialize(), Reset(), -Validate().

- -

If more functionality is required, a -class is more appropriate. If in doubt, make -it a class.

- -

For consistency with STL, you can use -struct instead of class for -functors and traits.

- -

Note that member variables in structs and classes have -different naming rules.

- -
- -

Inheritance

- -
-

Composition is often more appropriate than inheritance. -When using inheritance, make it public.

-
- -
- -
-

When a sub-class -inherits from a base class, it includes the definitions -of all the data and operations that the parent base class -defines. In practice, inheritance is used in two major -ways in C++: implementation inheritance, in which actual -code is inherited by the child, and -interface inheritance, in which -only method names are inherited.

-
- -
-

Implementation inheritance reduces code size by re-using -the base class code as it specializes an existing type. -Because inheritance is a compile-time declaration, you -and the compiler can understand the operation and detect -errors. Interface inheritance can be used to -programmatically enforce that a class expose a particular -API. Again, the compiler can detect errors, in this case, -when a class does not define a necessary method of the -API.

-
- -
-

For implementation inheritance, because the code -implementing a sub-class is spread between the base and -the sub-class, it can be more difficult to understand an -implementation. The sub-class cannot override functions -that are not virtual, so the sub-class cannot change -implementation. The base class may also define some data -members, so that specifies physical layout of the base -class.

-
- -
- -

All inheritance should be public. If you -want to do private inheritance, you should be including -an instance of the base class as a member instead.

- -

Do not overuse implementation inheritance. Composition -is often more appropriate. Try to restrict use of -inheritance to the "is-a" case: Bar -subclasses Foo if it can reasonably be said -that Bar "is a kind of" -Foo.

- -

Make your destructor virtual if -necessary. If your class has virtual methods, its -destructor should be virtual.

- -

Limit the use of protected to those -member functions that might need to be accessed from -subclasses. Note that data -members should be private.

- -

Explicitly annotate overrides of virtual functions -or virtual destructors with an override -or (less frequently) final specifier. -Older (pre-C++11) code will use the -virtual keyword as an inferior -alternative annotation. For clarity, use exactly one of -override, final, or -virtual when declaring an override. -Rationale: A function or destructor marked -override or final that is -not an override of a base class virtual function will -not compile, and this helps catch common errors. The -specifiers serve as documentation; if no specifier is -present, the reader has to check all ancestors of the -class in question to determine if the function or -destructor is virtual or not.

-
- -
- -

Multiple Inheritance

- -
-

Only very rarely is multiple implementation inheritance -actually useful. We allow multiple inheritance only when at -most one of the base classes has an implementation; all -other base classes must be pure -interface classes tagged with the -Interface suffix.

-
- -
- -
-

Multiple inheritance allows a sub-class to have more than -one base class. We distinguish between base classes that are -pure interfaces and those that have an -implementation.

-
- -
-

Multiple implementation inheritance may let you re-use -even more code than single inheritance (see Inheritance).

-
- -
-

Only very rarely is multiple implementation -inheritance actually useful. When multiple implementation -inheritance seems like the solution, you can usually find -a different, more explicit, and cleaner solution.

-
- -
-

Multiple inheritance is allowed only when all -superclasses, with the possible exception of the first one, -are pure interfaces. In order to -ensure that they remain pure interfaces, they must end with -the Interface suffix.

-
- -
-

There is an exception to -this rule on Windows.

-
- -
- -

Interfaces

- -
-

Classes that satisfy certain conditions are allowed, but -not required, to end with an Interface suffix.

-
- -
- -
-

A class is a pure interface if it meets the following -requirements:

- -
    -
  • It has only public pure virtual ("= - 0") methods and static methods (but see below - for destructor).
  • - -
  • It may not have non-static data members.
  • - -
  • It need not have any constructors defined. If a - constructor is provided, it must take no arguments and - it must be protected.
  • - -
  • If it is a subclass, it may only be derived from - classes that satisfy these conditions and are tagged - with the Interface suffix.
  • -
- -

An interface class can never be directly instantiated -because of the pure virtual method(s) it declares. To -make sure all implementations of the interface can be -destroyed correctly, the interface must also declare a -virtual destructor (in an exception to the first rule, -this should not be pure). See Stroustrup, The C++ -Programming Language, 3rd edition, section 12.4 -for details.

-
- -
-

Tagging a class with the Interface suffix -lets others know that they must not add implemented -methods or non static data members. This is particularly -important in the case of multiple inheritance. -Additionally, the interface concept is already -well-understood by Java programmers.

-
- -
-

The Interface suffix lengthens the class -name, which can make it harder to read and understand. -Also, the interface property may be considered an -implementation detail that shouldn't be exposed to -clients.

-
- -
-

A class may end -with Interface only if it meets the above -requirements. We do not require the converse, however: -classes that meet the above requirements are not required -to end with Interface.

-
- -
- -

Operator Overloading

- -
-

Overload operators judiciously. Do not create user-defined literals.

-
- -
- -
-

C++ permits user code to -declare -overloaded versions of the built-in operators using the -operator keyword, so long as one of the parameters -is a user-defined type. The operator keyword also -permits user code to define new kinds of literals using -operator"", and to define type-conversion functions -such as operator bool().

-
- -
-

Operator overloading can make code more concise and -intuitive by enabling user-defined types to behave the same -as built-in types. Overloaded operators are the idiomatic names -for certain operations (e.g. ==, <, -=, and <<), and adhering to -those conventions can make user-defined types more readable -and enable them to interoperate with libraries that expect -those names.

- -

User-defined literals are a very concise notation for -creating objects of user-defined types.

-
- -
-
    -
  • Providing a correct, consistent, and unsurprising - set of operator overloads requires some care, and failure - to do so can lead to confusion and bugs.
  • - -
  • Overuse of operators can lead to obfuscated code, - particularly if the overloaded operator's semantics - don't follow convention.
  • - -
  • The hazards of function overloading apply just as - much to operator overloading, if not more so.
  • - -
  • Operator overloads can fool our intuition into - thinking that expensive operations are cheap, built-in - operations.
  • - -
  • Finding the call sites for overloaded operators may - requre a search tool that's aware of C++ syntax, rather - than e.g. grep.
  • - -
  • If you get the argument type of an overloaded operator - wrong, you may get a different overload rather than a - compiler error. For example, foo < bar - may do one thing, while &foo < &bar - does something totally different.
  • - -
  • Certain operator overloads are inherently hazardous. - Overloading unary & can cause the same - code to have different meanings depending on whether - the overload declaration is visible. Overloads of - &&, ||, and , - (comma) cannot match the evaluation-order semantics of the - built-in operators.
  • - -
  • Operators are often defined outside the class, - so there's a risk of different files introducing - different definitions of the same operator. If both - definitions are linked into the same binary, this results - in undefined behavior, which can manifest as subtle - run-time bugs.
  • - -
  • User-defined literals allow the creation of new - syntactic forms that are unfamiliar even to experienced C++ - programmers.
  • -
-
- -
-

Define overloaded operators only if their meaning is -obvious, unsurprising, and consistent with the corresponding -built-in operators. For example, use | as a -bitwise- or logical-or, not as a shell-style pipe.

- -

Define operators only on your own types. More precisely, -define them in the same headers, .cc files, and namespaces -as the types they operate on. That way, the operators are available -wherever the type is, minimizing the risk of multiple -definitions. If possible, avoid defining operators as templates, -because they must satisfy this rule for any possible template -arguments. If you define an operator, also define -any related operators that make sense, and make sure they -are defined consistently. For example, if you overload -<, overload all the comparison operators, -and make sure < and > never -return true for the same arguments.

- -

Prefer to define non-modifying binary operators as -non-member functions. If a binary operator is defined as a -class member, implicit conversions will apply to the -right-hand argument, but not the left-hand one. It will -confuse your users if a < b compiles but -b < a doesn't.

- -

Don't go out of your way to avoid defining operator -overloads. For example, prefer to define ==, -=, and <<, rather than -Equals(), CopyFrom(), and -PrintTo(). Conversely, don't define -operator overloads just because other libraries expect -them. For example, if your type doesn't have a natural -ordering, but you want to store it in a std::set, -use a custom comparator rather than overloading -<.

- -

Do not overload &&, ||, -, (comma), or unary &. Do not overload -operator"", i.e. do not introduce user-defined -literals.

- -

Type conversion operators are covered in the section on -implicit conversions. -The = operator is covered in the section on -copy constructors. Overloading -<< for use with streams is covered in the -section on streams. See also the rules on -function overloading, which -apply to operator overloading as well.

-
- -
- -

Access Control

- -
-

Make data members private, unless they are -static const (and follow the -naming convention for constants). For technical -reasons, we allow data members of a test fixture class to -be protected when using - - -Google -Test).

-
- -

Declaration Order

- -
-

Use the specified order of declarations within a class: -public: before private:, methods -before data members (variables), etc.

-
- -
- -

Your class definition should start with its -public: section, followed by its -protected: section and then its -private: section. If any of these sections -are empty, omit them.

- -

Within each section, the declarations generally should -be in the following order:

- -
    -
  • Typedefs and Enums
  • - -
  • Constants (static const data - members)
  • - -
  • Constructors
  • - -
  • Destructor
  • - -
  • Methods, including static methods
  • - -
  • Data Members (except static const data - members)
  • -
- -

If copying and assignment are disabled with a macro such as -DISALLOW_COPY_AND_ASSIGN, it should be -at the end of the private: section, and should be -the last thing in the class. See -Copyable and Movable Types.

- -

Do not put large method definitions inline in the -class definition. Usually, only trivial or -performance-critical, and very short, methods may be -defined inline. See Inline -Functions for more details.

- -
- -

Functions

- -

Parameter Ordering

- -
-

When defining a function, parameter order is: inputs, then -outputs.

-
- -
-

Parameters to C/C++ functions are either input to the -function, output from the function, or both. Input -parameters are usually values or const -references, while output and input/output parameters will -be non-const pointers. When ordering -function parameters, put all input-only parameters before -any output parameters. In particular, do not add new -parameters to the end of the function just because they -are new; place new input-only parameters before the -output parameters.

- -

This is not a hard-and-fast rule. Parameters that are -both input and output (often classes/structs) muddy the -waters, and, as always, consistency with related -functions may require you to bend the rule.

- -
- -

Write Short Functions

- -
-

Prefer small and focused functions.

-
- -
-

We recognize that long functions are sometimes -appropriate, so no hard limit is placed on functions -length. If a function exceeds about 40 lines, think about -whether it can be broken up without harming the structure -of the program.

- -

Even if your long function works perfectly now, -someone modifying it in a few months may add new -behavior. This could result in bugs that are hard to -find. Keeping your functions short and simple makes it -easier for other people to read and modify your code.

- -

You could find long and complicated functions when -working with -some code. Do not be -intimidated by modifying existing code: if working with -such a function proves to be difficult, you find that -errors are hard to debug, or you want to use a piece of -it in several different contexts, consider breaking up -the function into smaller and more manageable pieces.

- -
- -

Reference Arguments

- -
-

All parameters passed by reference must be labeled -const.

-
- -
- -
-

In C, if a -function needs to modify a variable, the parameter must -use a pointer, eg int foo(int *pval). In -C++, the function can alternatively declare a reference -parameter: int foo(int &val).

-
- -
-

Defining a parameter as reference avoids ugly code like -(*pval)++. Necessary for some applications -like copy constructors. Makes it clear, unlike with -pointers, that a null pointer is not a possible -value.

-
- -
-

References can be confusing, as they have value syntax -but pointer semantics.

-
- -
-

Within function parameter lists all references must be -const:

- -
void Foo(const string &in, string *out);
-
- -

In fact it is a very strong convention in Google code -that input arguments are values or const -references while output arguments are pointers. Input -parameters may be const pointers, but we -never allow non-const reference parameters -except when required by convention, e.g., -swap().

- -

However, there are some instances where using -const T* is preferable to const -T& for input parameters. For example:

- -
    -
  • You want to pass in a null pointer.
  • - -
  • The function saves a pointer or reference to the - input.
  • -
- -

Remember that most of the time input -parameters are going to be specified as const -T&. Using const T* instead -communicates to the reader that the input is somehow -treated differently. So if you choose const -T* rather than const T&, do so -for a concrete reason; otherwise it will likely confuse -readers by making them look for an explanation that -doesn't exist.

-
- -
- -

Function Overloading

- -
-

Use overloaded functions (including constructors) only if a -reader looking at a call site can get a good idea of what -is happening without having to first figure out exactly -which overload is being called.

-
- -
- -
-

You may write a function that takes a const -string& and overload it with another that -takes const char*.

- -
class MyClass {
- public:
-  void Analyze(const string &text);
-  void Analyze(const char *text, size_t textlen);
-};
-
-
- -
-

Overloading can make code more intuitive by allowing an -identically-named function to take different arguments. -It may be necessary for templatized code, and it can be -convenient for Visitors.

-
- -
-

If a function is overloaded by the argument types alone, -a reader may have to understand C++'s complex matching -rules in order to tell what's going on. Also many people -are confused by the semantics of inheritance if a derived -class overrides only some of the variants of a -function.

-
- -
-

If you want to overload a function, consider qualifying -the name with some information about the arguments, e.g., -AppendString(), AppendInt() -rather than just Append(). If you are -overloading a function to support variable number of -arguments of the same type, consider making it take a -vector so that the user can use an -initializer list - to specify the arguments.

-
- -
- -

Default Arguments

- -
-

We do not allow default function parameters, except in -limited situations as explained below. Simulate them with -function overloading instead, if appropriate.

-
- -
- -
-

Often you have a function that uses default values, but -occasionally you want to override the defaults. Default -parameters allow an easy way to do this without having to -define many functions for the rare exceptions. Compared -to overloading the function, default arguments have a -cleaner syntax, with less boilerplate and a clearer -distinction between 'required' and 'optional' -arguments.

-
- -
-

Function pointers are confusing in the presence of -default arguments, since the function signature often -doesn't match the call signature. Adding a default -argument to an existing function changes its type, which -can cause problems with code taking its address. Adding -function overloads avoids these problems. In addition, -default parameters may result in bulkier code since they -are replicated at every call-site -- as opposed to -overloaded functions, where "the default" appears only in -the function definition.

-
- -
-

While the cons above are not that onerous, they still -outweigh the (small) benefits of default arguments over -function overloading. So except as described below, we -require all arguments to be explicitly specified.

- -

One specific exception is when the function is a -static function (or in an unnamed namespace) in a .cc -file. In this case, the cons don't apply since the -function's use is so localized.

- -

In addition, default function parameters are allowed in -constructors. Most of the cons listed above don't apply to -constructors because it's impossible to take their address.

- -

Another specific exception is when default arguments -are used to simulate variable-length argument lists.

- - -
// Support up to 4 params by using a default empty AlphaNum.
-string StrCat(const AlphaNum &a,
-              const AlphaNum &b = gEmptyAlphaNum,
-              const AlphaNum &c = gEmptyAlphaNum,
-              const AlphaNum &d = gEmptyAlphaNum);
-
-
- -
- -

Trailing Return Type Syntax

-
-

Use trailing return types only where using the ordinary syntax (leading - return types) is impractical or much less readable.

-
- -
-

C++ allows two different forms of function declarations. In the older - form, the return type appears before the function name. For example:

-
int foo(int x);
-
-

The new form, introduced in C++11, uses the auto - keyword before the function name and a trailing return type after - the argument list. For example, the declaration above could - equivalently be written:

-
auto foo(int x) -> int;
-
-

The trailing return type is in the function's scope. This doesn't - make a difference for a simple case like int but it matters - for more complicated cases, like types declared in class scope or - types written in terms of the function parameters.

-
- -
-
-

Trailing return types are the only way to explicitly specify the - return type of a lambda expression. - In some cases the compiler is able to deduce a lambda's return type, - but not in all cases. Even when the compiler can deduce it automatically, - sometimes specifying it explicitly would be clearer for readers. -

-

Sometimes it's easier and more readable to specify a return type - after the function's parameter list has already appeared. This is - particularly true when the return type depends on template parameters. - For example:

-
template <class T, class U> auto add(T t, U u) -> decltype(t + u);
- versus -
template <class T, class U> decltype(declval<T&>() + declval<U&>()) add(T t, U u);
-
- -
-

Trailing return type syntax is relatively new and it has no - analogue in C++-like languages like C and Java, so some readers may - find it unfamiliar.

-

Existing code bases have an enormous number of function - declarations that aren't going to get changed to use the new syntax, - so the realistic choices are using the old syntax only or using a mixture - of the two. Using a single version is better for uniformity of style.

-
- -
-

In most cases, continue to use the older style of function - declaration where the return type goes before the function name. - Use the new trailing-return-type form only in cases where it's - required (such as lambdas) or where, by putting the type after the - function's parameter list, it allows you to write the type in a much - more readable way. The latter case should be rare; it's mostly an - issue in fairly complicated template code, which is - discouraged in most cases.

- -
-
- -

Google-Specific Magic

- - - -

There are various tricks and utilities that -we use to make C++ code more robust, and various ways we use -C++ that may differ from what you see elsewhere.

- - - -

Ownership and Smart Pointers

- -
-

Prefer to have single, fixed owners for dynamically -allocated objects. Prefer to transfer ownership with smart -pointers.

-
- -
- -
-

"Ownership" is a bookkeeping technique for managing -dynamically allocated memory (and other resources). The -owner of a dynamically allocated object is an object or -function that is responsible for ensuring that it is -deleted when no longer needed. Ownership can sometimes be -shared, in which case the last owner is typically -responsible for deleting it. Even when ownership is not -shared, it can be transferred from one piece of code to -another.

- -

"Smart" pointers are classes that act like pointers, -e.g. by overloading the * and --> operators. Some smart pointer types -can be used to automate ownership bookkeeping, to ensure -these responsibilities are met. - -std::unique_ptr is a smart pointer type -introduced in C++11, which expresses exclusive ownership -of a dynamically allocated object; the object is deleted -when the std::unique_ptr goes out of scope. -It cannot be copied, but can be moved to -represent ownership transfer. - -std::shared_ptr is a smart pointer type -that expresses shared ownership of -a dynamically allocated object. std::shared_ptrs -can be copied; ownership of the object is shared among -all copies, and the object is deleted when the last -std::shared_ptr is destroyed.

-
- -
-
    -
  • It's virtually impossible to manage dynamically - allocated memory without some sort of ownership - logic.
  • - -
  • Transferring ownership of an object can be cheaper - than copying it (if copying it is even possible).
  • - -
  • Transferring ownership can be simpler than - 'borrowing' a pointer or reference, because it reduces - the need to coordinate the lifetime of the object - between the two users.
  • - -
  • Smart pointers can improve readability by making - ownership logic explicit, self-documenting, and - unambiguous.
  • - -
  • Smart pointers can eliminate manual ownership - bookkeeping, simplifying the code and ruling out large - classes of errors.
  • - -
  • For const objects, shared ownership can be a simple - and efficient alternative to deep copying.
  • -
-
- -
-
    -
  • Ownership must be represented and transferred via - pointers (whether smart or plain). Pointer semantics - are more complicated than value semantics, especially - in APIs: you have to worry not just about ownership, - but also aliasing, lifetime, and mutability, among - other issues.
  • - -
  • The performance costs of value semantics are often - overestimated, so the performance benefits of ownership - transfer might not justify the readability and - complexity costs.
  • - -
  • APIs that transfer ownership force their clients - into a single memory management model.
  • - -
  • Code using smart pointers is less explicit about - where the resource releases take place.
  • - -
  • std::unique_ptr expresses ownership - transfer using C++11's move semantics, which are - relatively new and may confuse some programmers.
  • - -
  • Shared ownership can be a tempting alternative to - careful ownership design, obfuscating the design of a - system.
  • - -
  • Shared ownership requires explicit bookkeeping at - run-time, which can be costly.
  • - -
  • In some cases (e.g. cyclic references), objects - with shared ownership may never be deleted.
  • - -
  • Smart pointers are not perfect substitutes for - plain pointers.
  • -
-
- -
-

If dynamic allocation is necessary, prefer to keep -ownership with the code that allocated it. If other code -needs access to the object, consider passing it a copy, -or passing a pointer or reference without transferring -ownership. Prefer to use std::unique_ptr to -make ownership transfer explicit. For example:

- -
std::unique_ptr<Foo> FooFactory();
-void FooConsumer(std::unique_ptr<Foo> ptr);
-
- - - -

Do not design your code to use shared ownership -without a very good reason. One such reason is to avoid -expensive copy operations, but you should only do this if -the performance benefits are significant, and the -underlying object is immutable (i.e. -std::shared_ptr<const Foo>). If you -do use shared ownership, prefer to use -std::shared_ptr.

- -

Do not use scoped_ptr in new code unless -you need to be compatible with older versions of C++. -Never use std::auto_ptr. Instead, use -std::unique_ptr.

- - -
- -
- -

cpplint

- -
-

Use cpplint.py -to detect style errors.

-
- -
- -

cpplint.py -is a tool that reads a source file and identifies many -style errors. It is not perfect, and has both false -positives and false negatives, but it is still a valuable -tool. False positives can be ignored by putting // -NOLINT at the end of the line or -// NOLINTNEXTLINE in the previous line.

- - - -

Some projects have instructions on -how to run cpplint.py from their project -tools. If the project you are contributing to does not, -you can download - -cpplint.py separately.

- -
- - - -

Other C++ Features

- -

Rvalue References

- -
-

Use rvalue references only to define move constructors and move assignment -operators, or for perfect forwarding. -

-
- -
- -
-

Rvalue references -are a type of reference that can only bind to temporary -objects. The syntax is similar to traditional reference -syntax. For example, void f(string&& -s); declares a function whose argument is an -rvalue reference to a string.

-
- -
-
    -
  • Defining a move constructor (a constructor taking - an rvalue reference to the class type) makes it - possible to move a value instead of copying it. If - v1 is a vector<string>, - for example, then auto v2(std::move(v1)) - will probably just result in some simple pointer - manipulation instead of copying a large amount of data. - In some cases this can result in a major performance - improvement.
  • - -
  • Rvalue references make it possible to write a - generic function wrapper that forwards its arguments to - another function, and works whether or not its - arguments are temporary objects. (This is sometimes called - "perfect forwarding".)
  • - -
  • Rvalue references make it possible to implement - types that are movable but not copyable, which can be - useful for types that have no sensible definition of - copying but where you might still want to pass them as - function arguments, put them in containers, etc.
  • - -
  • std::move is necessary to make - effective use of some standard-library types, such as - std::unique_ptr.
  • -
-
- -
-
    -
  • Rvalue references are a relatively new feature - (introduced as part of C++11), and not yet widely - understood. Rules like reference collapsing, and - automatic synthesis of move constructors, are - complicated.
  • -
-
- -
-

Use rvalue references only to define move constructors and move assignment - operators (as described in Copyable and - Movable Types) and, in conjunction with std::forward, -to support perfect forwarding. You may use std::move to express -moving a value from one object to another rather than copying it.

-
- -
- -

- Variable-Length Arrays and alloca()

- -
-

We do not allow variable-length arrays or -alloca().

-
- -
- -
-

Variable-length arrays have natural-looking syntax. Both -variable-length arrays and alloca() are very -efficient.

-
- -
-

Variable-length arrays and alloca are not part of -Standard C++. More importantly, they allocate a -data-dependent amount of stack space that can trigger -difficult-to-find memory overwriting bugs: "It ran fine -on my machine, but dies mysteriously in production".

-
- -
- - -

Use a safe allocator instead, such as -vector or -std::unique_ptr<T[]>.

-
- -
- -

Friends

- -
-

We allow use of friend classes and functions, -within reason.

-
- -
- -

Friends should usually be defined in the same file so -that the reader does not have to look in another file to -find uses of the private members of a class. A common use -of friend is to have a -FooBuilder class be a friend of -Foo so that it can construct the inner state -of Foo correctly, without exposing this -state to the world. In some cases it may be useful to -make a unittest class a friend of the class it tests.

- -

Friends extend, but do not break, the encapsulation -boundary of a class. In some cases this is better than -making a member public when you want to give only one -other class access to it. However, most classes should -interact with other classes solely through their public -members.

- -
- -

Exceptions

- -
-

We do not use C++ exceptions.

-
- -
- -
-
    -
  • Exceptions allow higher levels of an application to - decide how to handle "can't happen" failures in deeply - nested functions, without the obscuring and error-prone - bookkeeping of error codes.
  • - - - -
  • Exceptions are used by most other - modern languages. Using them in C++ would make it more - consistent with Python, Java, and the C++ that others - are familiar with.
  • - -
  • Some third-party C++ libraries use exceptions, and - turning them off internally makes it harder to - integrate with those libraries.
  • - -
  • Exceptions are the only way for a constructor to - fail. We can simulate this with a factory function or - an Init() method, but these require heap - allocation or a new "invalid" state, respectively.
  • - -
  • Exceptions are really handy in testing - frameworks.
  • -
-
- -
-
    -
  • When you add a throw statement to an - existing function, you must examine all of its - transitive callers. Either they must make at least the - basic exception safety guarantee, or they must never - catch the exception and be happy with the program - terminating as a result. For instance, if - f() calls g() calls - h(), and h throws an - exception that f catches, g - has to be careful or it may not clean up properly.
  • - -
  • More generally, exceptions make the control flow of - programs difficult to evaluate by looking at code: - functions may return in places you don't expect. This - causes maintainability and debugging difficulties. You - can minimize this cost via some rules on how and where - exceptions can be used, but at the cost of more that a - developer needs to know and understand.
  • - -
  • Exception safety requires both RAII and different - coding practices. Lots of supporting machinery is - needed to make writing correct exception-safe code - easy. Further, to avoid requiring readers to understand - the entire call graph, exception-safe code must isolate - logic that writes to persistent state into a "commit" - phase. This will have both benefits and costs (perhaps - where you're forced to obfuscate code to isolate the - commit). Allowing exceptions would force us to always - pay those costs even when they're not worth it.
  • - -
  • Turning on exceptions adds data to each binary - produced, increasing compile time (probably slightly) - and possibly increasing address space pressure. -
  • - -
  • The availability of exceptions may encourage - developers to throw them when they are not appropriate - or recover from them when it's not safe to do so. For - example, invalid user input should not cause exceptions - to be thrown. We would need to make the style guide - even longer to document these restrictions!
  • -
-
- -
-

On their face, the benefits of using exceptions -outweigh the costs, especially in new projects. However, -for existing code, the introduction of exceptions has -implications on all dependent code. If exceptions can be -propagated beyond a new project, it also becomes -problematic to integrate the new project into existing -exception-free code. Because most existing C++ code at -Google is not prepared to deal with exceptions, it is -comparatively difficult to adopt new code that generates -exceptions.

- -

Given that Google's existing code is not -exception-tolerant, the costs of using exceptions are -somewhat greater than the costs in a new project. The -conversion process would be slow and error-prone. We -don't believe that the available alternatives to -exceptions, such as error codes and assertions, introduce -a significant burden.

- -

Our advice against using exceptions is not predicated -on philosophical or moral grounds, but practical ones. - Because we'd like to use our open-source -projects at Google and it's difficult to do so if those -projects use exceptions, we need to advise against -exceptions in Google open-source projects as well. -Things would probably be different if we had to do it all -over again from scratch.

- -

This prohibition also applies to the exception-related -features added in C++11, such as noexcept, -std::exception_ptr, and -std::nested_exception.

- -

There is an exception to -this rule (no pun intended) for Windows code.

-
- -
- -

Run-Time Type -Information (RTTI)

- -
-

Avoid using Run Time Type Information (RTTI).

-
- -
- -
-

RTTI allows a -programmer to query the C++ class of an object at run -time. This is done by use of typeid or -dynamic_cast.

-
- -
-

Querying the type of an object at run-time frequently -means a design problem. Needing to know the type of an -object at runtime is often an indication that the design -of your class hierarchy is flawed.

- -

Undisciplined use of RTTI makes code hard to maintain. -It can lead to type-based decision trees or switch -statements scattered throughout the code, all of which -must be examined when making further changes.

-
- -
-

The standard alternatives to RTTI (described below) -require modification or redesign of the class hierarchy -in question. Sometimes such modifications are infeasible -or undesirable, particularly in widely-used or mature -code.

- -

RTTI can be useful in some unit tests. For example, it -is useful in tests of factory classes where the test has -to verify that a newly created object has the expected -dynamic type. It is also useful in managing the -relationship between objects and their mocks.

- -

RTTI is useful when considering multiple abstract -objects. Consider

- -
bool Base::Equal(Base* other) = 0;
-bool Derived::Equal(Base* other) {
-  Derived* that = dynamic_cast<Derived*>(other);
-  if (that == NULL)
-    return false;
-  ...
-}
-
-
- -
-

RTTI has legitimate uses but is prone to abuse, so you -must be careful when using it. You may use it freely in -unittests, but avoid it when possible in other code. In -particular, think twice before using RTTI in new code. If -you find yourself needing to write code that behaves -differently based on the class of an object, consider one -of the following alternatives to querying the type:

- -
    -
  • Virtual methods are the preferred way of executing - different code paths depending on a specific subclass - type. This puts the work within the object itself.
  • - -
  • If the work belongs outside the object and instead - in some processing code, consider a double-dispatch - solution, such as the Visitor design pattern. This - allows a facility outside the object itself to - determine the type of class using the built-in type - system.
  • -
- -

When the logic of a program guarantees that a given -instance of a base class is in fact an instance of a -particular derived class, then a -dynamic_cast may be used freely on the -object. Usually one -can use a static_cast as an alternative in -such situations.

- -

Decision trees based on type are a strong indication -that your code is on the wrong track.

- -
if (typeid(*data) == typeid(D1)) {
-  ...
-} else if (typeid(*data) == typeid(D2)) {
-  ...
-} else if (typeid(*data) == typeid(D3)) {
-...
-
- -

Code such as this usually breaks when additional -subclasses are added to the class hierarchy. Moreover, -when properties of a subclass change, it is difficult to -find and modify all the affected code segments.

- -

Do not hand-implement an RTTI-like workaround. The -arguments against RTTI apply just as much to workarounds -like class hierarchies with type tags. Moreover, -workarounds disguise your true intent.

-
- -
- -

Casting

- -
-

Use C++ casts like static_cast<>(). Do -not use other cast formats like int y = -(int)x; or int y = int(x);.

-
- -
- -
-

C++ introduced a -different cast system from C that distinguishes the types -of cast operations.

-
- -
-

The problem with C casts is the ambiguity of the -operation; sometimes you are doing a conversion -(e.g., (int)3.5) and sometimes you are doing -a cast (e.g., (int)"hello"); C++ -casts avoid this. Additionally C++ casts are more visible -when searching for them.

-
- -
-

The syntax is nasty.

-
- -
-

Do not use C-style casts. Instead, use these C++-style -casts.

- -
    - - -
  • Use static_cast as the equivalent of a - C-style cast that does value conversion, or when you need to explicitly up-cast a - pointer from a class to its superclass.
  • - -
  • Use const_cast to remove the - const qualifier (see const).
  • - - - - - -
  • Use reinterpret_cast to do unsafe - conversions of pointer types to and from integer and - other pointer types. Use this only if you know what you - are doing and you understand the aliasing issues. -
  • -
- -

See the -RTTI section for guidance on the use of -dynamic_cast.

-
- -
- -

Streams

- -
-

Use streams where appropriate, and stick to "simple" -usages.

-
- -
- -
-

Streams are the standard I/O abstraction in C++, as -exemplified by the standard header <iostream>. -They are widely used in Google code, but only for debug logging -and test diagnostics.

-
- -
-

The << and >> -stream operators provide an API for formatted I/O that -is easily learned, portable, reusable, and extensible. -printf, by contrast, doesn't even support -string, to say nothing of user-defined types, -and is very difficult to use portably. -printf also obliges you to choose among the -numerous slightly different versions of that function, -and navigate the dozens of conversion specifiers.

- -

Streams provide first-class support for console I/O -via std::cin, std::cout, -std::cerr, and std::clog. -The C APIs do as well, but are hampered by the need to -manually buffer the input.

-
- -
-
    -
  • Stream formatting can be configured by mutating the -state of the stream. Such mutations are persistent, so -the behavior of your code can be affected by the entire -previous history of the stream, unless you go out of your -way to restore it to a known state every time other code -might have touched it. User code can not only modify the -built-in state, it can add new state variables and behaviors -through a registration system.
  • - -
  • It is difficult to precisely control stream output, due -to the above issues, the way code and data are mixed in -streaming code, and the use of operator overloading (which -may select a different overload than you expect).
  • - -
  • The practice of building up output through chains -of << operators interferes with -internationalization, because it bakes word order into the -code, and streams' support for localization is -flawed.
  • - - - - - -
  • The streams API is subtle and complex, so programmers must -develop experience with it in order to use it effectively. -However, streams were historically banned in Google code (except -for logging and diagnostics), so Google engineers tend not to -have that experience. Consequently, streams-based code is likely -to be less readable and maintainable by Googlers than code based -on more familiar abstractions.
  • - -
  • Resolving the many overloads of << is -extremely costly for the compiler. When used pervasively in a -large code base, it can consume as much as 20% of the parsing -and semantic analysis time.
  • -
-
- -
-

Use streams only when they are the best tool for the job. -This is typically the case when the I/O is ad-hoc, local, -human-readable, and targeted at other developers rather than -end-users. Be consistent with the code around you, and with the -codebase as a whole; if there's an established tool for -your problem, use that tool instead.

- -

Avoid using streams for I/O that faces external users or -handles untrusted data. Instead, find and use the appropriate -templating libraries to handle issues like internationalization, -localization, and security hardening.

- -

If you do use streams, avoid the stateful parts of the -streams API (other than error state), such as imbue(), -xalloc(), and register_callback(). -Use explicit formatting functions rather than -stream manipulators or formatting flags to control formatting -details such as number base, precision, or padding.

- -

Overload << as a streaming operator -for your type only if your type represents a value, and -<< writes out a human-readable string -representation of that value. Avoid exposing implementation -details in the output of <<; if you need to print -object internals for debugging, use named functions instead -(a method named DebugString() is the most common -convention).

-
- -
- -

Preincrement and Predecrement

- -
-

Use prefix form (++i) of the increment and -decrement operators with iterators and other template -objects.

-
- -
- -
-

When a variable -is incremented (++i or i++) or -decremented (--i or i--) and -the value of the expression is not used, one must decide -whether to preincrement (decrement) or postincrement -(decrement).

-
- -
-

When the return value is ignored, the "pre" form -(++i) is never less efficient than the -"post" form (i++), and is often more -efficient. This is because post-increment (or decrement) -requires a copy of i to be made, which is -the value of the expression. If i is an -iterator or other non-scalar type, copying i -could be expensive. Since the two types of increment -behave the same when the value is ignored, why not just -always pre-increment?

-
- -
-

The tradition developed, in C, of using post-increment -when the expression value is not used, especially in -for loops. Some find post-increment easier -to read, since the "subject" (i) precedes -the "verb" (++), just like in English.

-
- -
-

For simple scalar -(non-object) values there is no reason to prefer one form -and we allow either. For iterators and other template -types, use pre-increment.

-
- -
- -

Use of const

- -
-

Use const whenever it makes sense. With C++11, -constexpr is a better choice for some uses of -const.

-
- -
- -
-

Declared variables and parameters can be preceded -by the keyword const to indicate the variables -are not changed (e.g., const int foo). Class -functions can have the const qualifier to -indicate the function does not change the state of the -class member variables (e.g., class Foo { int -Bar(char c) const; };).

-
- -
-

Easier for people to understand how variables are being -used. Allows the compiler to do better type checking, -and, conceivably, generate better code. Helps people -convince themselves of program correctness because they -know the functions they call are limited in how they can -modify your variables. Helps people know what functions -are safe to use without locks in multi-threaded -programs.

-
- -
-

const is viral: if you pass a -const variable to a function, that function -must have const in its prototype (or the -variable will need a const_cast). This can -be a particular problem when calling library -functions.

-
- -
-

const variables, data members, methods -and arguments add a level of compile-time type checking; -it is better to detect errors as soon as possible. -Therefore we strongly recommend that you use -const whenever it makes sense to do so:

- -
    -
  • If a function does not modify an argument passed by - reference or by pointer, that argument should be - const.
  • - -
  • Declare methods to be const whenever - possible. Accessors should almost always be - const. Other methods should be const if - they do not modify any data members, do not call any - non-const methods, and do not return a - non-const pointer or - non-const reference to a data member.
  • - -
  • Consider making data members const - whenever they do not need to be modified after - construction.
  • -
- -

The mutable keyword is allowed but is -unsafe when used with threads, so thread safety should be -carefully considered first.

-
- -
-

Where to put the const

- -

Some people favor the form int const *foo -to const int* foo. They argue that this is -more readable because it's more consistent: it keeps the -rule that const always follows the object -it's describing. However, this consistency argument -doesn't apply in codebases with few deeply-nested pointer -expressions since most const expressions -have only one const, and it applies to the -underlying value. In such cases, there's no consistency -to maintain. Putting the const first is -arguably more readable, since it follows English in -putting the "adjective" (const) before the -"noun" (int).

- -

That said, while we encourage putting -const first, we do not require it. But be -consistent with the code around you!

-
- -
- -

Use of constexpr

- -
-

In C++11, use constexpr to define true -constants or to ensure constant initialization.

-
- -
- -
-

Some variables can be declared constexpr -to indicate the variables are true constants, i.e. fixed at -compilation/link time. Some functions and constructors -can be declared constexpr which enables them -to be used in defining a constexpr -variable.

-
- -
-

Use of constexpr enables definition of -constants with floating-point expressions rather than -just literals; definition of constants of user-defined -types; and definition of constants with function -calls.

-
- -
-

Prematurely marking something as constexpr may cause -migration problems if later on it has to be downgraded. -Current restrictions on what is allowed in constexpr -functions and constructors may invite obscure workarounds -in these definitions.

-
- -
-

constexpr definitions enable a more -robust specification of the constant parts of an -interface. Use constexpr to specify true -constants and the functions that support their -definitions. Avoid complexifying function definitions to -enable their use with constexpr. Do not use -constexpr to force inlining.

-
- -
- -

Integer Types

- -
-

Of the built-in C++ integer types, the only one used - is -int. If a program needs a variable of a -different size, use -a precise-width integer type from -<stdint.h>, such as -int16_t. If your variable represents a -value that could ever be greater than or equal to 2^31 -(2GiB), use a 64-bit type such as -int64_t. -Keep in mind that even if your value won't ever be too large -for an int, it may be used in intermediate -calculations which may require a larger type. When in doubt, -choose a larger type.

-
- -
- -
-

C++ does not specify the sizes of its integer types. -Typically people assume that short is 16 bits, -int is 32 bits, long is 32 bits -and long long is 64 bits.

-
- -
-

Uniformity of declaration.

-
- -
-

The sizes of integral types in C++ can vary based on -compiler and architecture.

-
- -
- -

-<stdint.h> defines types -like int16_t, uint32_t, -int64_t, etc. You should always use -those in preference to short, unsigned -long long and the like, when you need a guarantee -on the size of an integer. Of the C integer types, only -int should be used. When appropriate, you -are welcome to use standard types like -size_t and ptrdiff_t.

- -

We use int very often, for integers we -know are not going to be too big, e.g., loop counters. -Use plain old int for such things. You -should assume that an int is - -at least 32 bits, but don't -assume that it has more than 32 bits. If you need a 64-bit -integer type, use -int64_t -or -uint64_t.

- -

For integers we know can be "big", - use -int64_t. -

- -

You should not use the unsigned integer types such as -uint32_t, unless there is a valid -reason such as representing a bit pattern rather than a -number, or you need defined overflow modulo 2^N. In -particular, do not use unsigned types to say a number -will never be negative. Instead, use -assertions for this.

- - - -

If your code is a container that returns a size, be -sure to use a type that will accommodate any possible -usage of your container. When in doubt, use a larger type -rather than a smaller type.

- -

Use care when converting integer types. Integer -conversions and promotions can cause non-intuitive -behavior.

-
- -
- -

On Unsigned Integers

- -

Some people, including some textbook authors, -recommend using unsigned types to represent numbers that -are never negative. This is intended as a form of -self-documentation. However, in C, the advantages of such -documentation are outweighed by the real bugs it can -introduce. Consider:

- -
for (unsigned int i = foo.Length()-1; i >= 0; --i) ...
-
- -

This code will never terminate! Sometimes gcc will -notice this bug and warn you, but often it will not. -Equally bad bugs can occur when comparing signed and -unsigned variables. Basically, C's type-promotion scheme -causes unsigned types to behave differently than one -might expect.

- -

So, document that a variable is non-negative using -assertions. Don't use an unsigned -type.

-
- -
- -

64-bit Portability

- -
-

Code should be 64-bit and 32-bit friendly. Bear in mind -problems of printing, comparisons, and structure alignment.

-
- -
- -
    -
  • -

    printf() specifiers for some types - are not cleanly portable between 32-bit and 64-bit - systems. C99 defines some portable format specifiers. - Unfortunately, MSVC 7.1 does not understand some of - these specifiers and the standard is missing a few, - so we - have to define our own ugly versions in some cases - (in the style of the standard include file - inttypes.h):

    - -
    -
    // printf macros for size_t, in the style of inttypes.h
    -#ifdef _LP64
    -#define __PRIS_PREFIX "z"
    -#else
    -#define __PRIS_PREFIX
    -#endif
    -
    -// Use these macros after a % in a printf format string
    -// to get correct 32/64 bit behavior, like this:
    -// size_t size = records.size();
    -// printf("%" PRIuS "\n", size);
    -
    -#define PRIdS __PRIS_PREFIX "d"
    -#define PRIxS __PRIS_PREFIX "x"
    -#define PRIuS __PRIS_PREFIX "u"
    -#define PRIXS __PRIS_PREFIX "X"
    -#define PRIoS __PRIS_PREFIX "o"
    -  
    -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    TypeDO NOT useDO useNotes
    void * (or any pointer)%lx%p
    int64_t%qd, %lld%" PRId64 "
    uint64_t%qu, %llu, - %llx%" PRIu64 ", - %" PRIx64 "
    size_t%u%" PRIuS ", %" PRIxS " - C99 specifies %zu
    ptrdiff_t%d%" PRIdS " - C99 specifies %td
    - -

    Note that the PRI* macros expand to - independent strings which are concatenated by the - compiler. Hence if you are using a non-constant - format string, you need to insert the value of the - macro into the format, rather than the name. Note also - that spaces are required around the macro identifier to - separate it from the string literal. It is - still possible, as usual, to include length - specifiers, etc., after the % when using - the PRI* macros. So, e.g. - printf("x = %30" PRIuS "\n", x) would - expand on 32-bit Linux to printf("x = %30" "u" - "\n", x), which the compiler will treat as - printf("x = %30u\n", x).

    - - -
  • - -
  • Remember that sizeof(void *) != - sizeof(int). Use intptr_t if - you want a pointer-sized integer.
  • - -
  • You may need to be careful with structure - alignments, particularly for structures being stored on - disk. Any class/structure with a - int64_t/uint64_t - member will by default end up being 8-byte aligned on a - 64-bit system. If you have such structures being shared - on disk between 32-bit and 64-bit code, you will need - to ensure that they are packed the same on both - architectures. - Most compilers offer a way to - alter structure alignment. For gcc, you can use - __attribute__((packed)). MSVC offers - #pragma pack() and - __declspec(align()).
  • - -
  • -

    Use the LL or ULL - suffixes as needed to create 64-bit constants. For - example:

    - - -
    int64_t my_value = 0x123456789LL;
    -uint64_t my_mask = 3ULL << 48;
    -
    -
  • -
- -
- -

Preprocessor Macros

- -
-

Be very cautious with macros. Prefer inline functions, -enums, and const variables to macros.

-
- -
- -

Macros mean that the code you see is not the same as -the code the compiler sees. This can introduce unexpected -behavior, especially since macros have global scope.

- -

Luckily, macros are not nearly as necessary in C++ as -they are in C. Instead of using a macro to inline -performance-critical code, use an inline function. -Instead of using a macro to store a constant, use a -const variable. Instead of using a macro to -"abbreviate" a long variable name, use a reference. -Instead of using a macro to conditionally compile code -... well, don't do that at all (except, of course, for -the #define guards to prevent double -inclusion of header files). It makes testing much more -difficult.

- -

Macros can do things these other techniques cannot, -and you do see them in the codebase, especially in the -lower-level libraries. And some of their special features -(like stringifying, concatenation, and so forth) are not -available through the language proper. But before using a -macro, consider carefully whether there's a non-macro way -to achieve the same result.

- -

The following usage pattern will avoid many problems -with macros; if you use macros, follow it whenever -possible:

- -
    -
  • Don't define macros in a .h file.
  • - -
  • #define macros right before you use - them, and #undef them right after.
  • - -
  • Do not just #undef an existing macro - before replacing it with your own; instead, pick a name - that's likely to be unique.
  • - -
  • Try not to use macros that expand to unbalanced C++ - constructs, or at least document that behavior - well.
  • - -
  • Prefer not using ## to generate - function/class/variable names.
  • -
- -
- -

0 and nullptr/NULL

- -
-

Use 0 for integers, 0.0 for -reals, nullptr (or NULL) for -pointers, and '\0' for chars.

-
- -
- -

Use 0 for integers and 0.0 -for reals. This is not controversial.

- -

For -pointers (address values), there is a choice between -0, NULL, and -nullptr. For projects that allow C++11 -features, use nullptr. For C++03 projects, -we prefer NULL because it looks like a -pointer. In fact, some C++ compilers provide special -definitions of NULL which enable them to -give useful warnings, particularly in situations where -sizeof(NULL) is not equal to -sizeof(0).

- -

Use '\0' for chars. This is the correct -type and also makes code more readable.

- -
- -

sizeof

- -
-

Prefer sizeof(varname) to -sizeof(type).

-
- -
- -

Use sizeof(varname) when you -take the size of a particular variable. -sizeof(varname) will update -appropriately if someone changes the variable type either -now or later. You may use -sizeof(type) for code unrelated -to any particular variable, such as code that manages an -external or internal data format where a variable of an -appropriate C++ type is not convenient.

- -
Struct data;
-memset(&data, 0, sizeof(data));
-
- -
memset(&data, 0, sizeof(Struct));
-
- -
if (raw_size < sizeof(int)) {
-  LOG(ERROR) << "compressed record not big enough for count: " << raw_size;
-  return false;
-}
-
- -
- -

auto

- -
-

Use auto to avoid type names that are just -clutter. Continue to use manifest type declarations when it -helps readability, and never use auto for -anything but local variables.

-
- -
- -
-

In C++11, a variable whose type is given as auto -will be given a type that matches that of the expression used to -initialize it. You can use auto either to -initialize a variable by copying, or to bind a -reference.

- -
vector<string> v;
-...
-auto s1 = v[0];  // Makes a copy of v[0].
-const auto& s2 = v[0];  // s2 is a reference to v[0].
-
-
- -

The auto keyword is also used in an -unrelated C++11 feature: it's part of the syntax for a -new kind of function declaration with a -trailing return type.

- - -
-

C++ type names can sometimes be long and cumbersome, -especially when they involve templates or namespaces. In -a statement like:

- -
sparse_hash_map<string, int>::iterator iter = m.find(val);
-
-
- -

the return type is hard to read, and obscures the -primary purpose of the statement. Changing it to:

- -
auto iter = m.find(val);
-
- -

makes it more readable.

- -

Without auto we are sometimes forced to -write a type name twice in the same expression, adding no -value for the reader, as in:

- -
diagnostics::ErrorStatus* status = new diagnostics::ErrorStatus("xyz");
-
- -

Using auto makes it easier to use -intermediate variables when appropriate, by reducing the -burden of writing their types explicitly.

- -
- -

Sometimes code is clearer when types are manifest, -especially when a variable's initialization depends on -things that were declared far away. In an expression -like:

- - -
auto i = x.Lookup(key);
-
- -

it may not be obvious what i's type is, -if x was declared hundreds of lines earlier.

- -

Programmers have to understand the difference between -auto and const auto& or -they'll get copies when they didn't mean to.

- -

The interaction between auto and C++11 -brace-initialization can be confusing. The exact -rules have been in flux, and compilers don't all -implement the final rules yet. -The declarations:

- -
auto x{3};
-auto y = {3};
-
- -

mean different things — -x is an int, while -y is a std::initializer_list<int>. -The same applies to other normally-invisible proxy types. -

- -

If an auto variable is used as part of an -interface, e.g. as a constant in a header, then a -programmer might change its type while only intending to -change its value, leading to a more radical API change -than intended.

-
- -
- -

auto is permitted, for local variables -only. Do not use auto for file-scope or -namespace-scope variables, or for class members. Never -initialize an auto-typed variable with -a braced initializer list. -

- -
- -

Braced Initializer List

- -
-

You may use braced initializer lists.

-
- -
- -

In C++03, aggregate types (arrays and structs with no -constructor) could be initialized with braced initializer lists. -

- -
struct Point { int x; int y; };
-Point p = {1, 2};
-
- -

In C++11, this syntax was generalized, and any object type can now -be created with a braced initializer list, known as a -braced-init-list in the C++ grammar. Here are a few examples -of its use.

- -
// Vector takes a braced-init-list of elements.
-vector<string> v{"foo", "bar"};
-
-// Basically the same, ignoring some small technicalities.
-// You may choose to use either form.
-vector<string> v = {"foo", "bar"};
-
-// Usable with 'new' expressions.
-auto p = new vector<string>{"foo", "bar"};
-
-// A map can take a list of pairs. Nested braced-init-lists work.
-map<int, string> m = {{1, "one"}, {2, "2"}};
-
-// A braced-init-list can be implicitly converted to a return type.
-vector<int> test_function() { return {1, 2, 3}; }
-
-// Iterate over a braced-init-list.
-for (int i : {-1, -2, -3}) {}
-
-// Call a function using a braced-init-list.
-void TestFunction2(vector<int> v) {}
-TestFunction2({1, 2, 3});
-
- -

A user-defined type can also define a constructor and/or assignment operator -that take std::initializer_list<T>, which is automatically -created from braced-init-list:

- -
class MyType {
- public:
-  // std::initializer_list references the underlying init list.
-  // It should be passed by value.
-  MyType(std::initializer_list<int> init_list) {
-    for (int i : init_list) append(i);
-  }
-  MyType& operator=(std::initializer_list<int> init_list) {
-    clear();
-    for (int i : init_list) append(i);
-  }
-};
-MyType m{2, 3, 5, 7};
-
- -

Finally, brace initialization can also call ordinary -constructors of data types, even if they do not have -std::initializer_list<T> constructors.

- -
double d{1.23};
-// Calls ordinary constructor as long as MyOtherType has no
-// std::initializer_list constructor.
-class MyOtherType {
- public:
-  explicit MyOtherType(string);
-  MyOtherType(int, string);
-};
-MyOtherType m = {1, "b"};
-// If the constructor is explicit, you can't use the "= {}" form.
-MyOtherType m{"b"};
-
- -

Never assign a braced-init-list to an auto -local variable. In the single element case, what this -means can be confusing.

- -
auto d = {1.23};        // d is a std::initializer_list<double>
-
- -
auto d = double{1.23};  // Good -- d is a double, not a std::initializer_list.
-
- -

See Braced_Initializer_List_Format for formatting.

- -
- -

Lambda expressions

- -
-

Use lambda expressions where appropriate. Avoid -default lambda captures when capturing this or -if the lambda will escape the current scope.

-
- -
- -
- -

Lambda expressions are a concise way of creating anonymous -function objects. They're often useful when passing -functions as arguments. For example:

- -
std::sort(v.begin(), v.end(), [](int x, int y) {
-  return Weight(x) < Weight(y);
-});
-
- -They further allow capturing variables from the enclosing scope either -explicitly by name, or implicitly using a default capture. Default captures -implicitly capture any variable referenced in the lambda body, including -this if any members are used. The default capture must come -first and be one of & for capture by reference or -= for capture by value, followed by any explicit captures which -differ from the default: - -
int weight = 3;
-int sum = 0;
-// Captures `weight` (implicitly) by value and `sum` by reference.
-std::for_each(v.begin(), v.end(), [=, &sum](int x) {
-  sum += weight * x;
-});
-
- -

Lambdas were introduced in C++11 along with a set of utilities -for working with function objects, such as the polymorphic -wrapper std::function. -

-
- -
-
    -
  • Lambdas are much more concise than other ways of - defining function objects to be passed to STL - algorithms, which can be a readability - improvement.
  • - -
  • Appropriate use of default captures can remove - redundancy and highlight important exceptions from - the default.
  • - -
  • Lambdas, std::function, and - std::bind can be used in combination as a - general purpose callback mechanism; they make it easy - to write functions that take bound functions as - arguments.
  • -
-
- -
-
    -
  • Default captures make it easy to overlook an - implicit capture and use of this. -
  • - -
  • Variable capture in lambdas can be tricky, and - might be a new source of dangling-pointer bugs, - particularly if a lambda escapes the current scope.
  • - -
  • It's possible for use of lambdas to get out of - hand; very long nested anonymous functions can make - code harder to understand.
  • - - -
-
- -
-
    -
  • Use lambda expressions where appropriate, with formatting as -described below.
  • -
  • Use default captures judiciously, when it aids readability. -In particular, prefer to write lambda captures explicitly when -capturing this or if the lambda will escape the -current scope. For example, instead of: -
    {
    -  Foo foo;
    -  ...
    -  executor->Schedule([&] { Frobnicate(foo); })
    -  ...
    -}
    -// BAD! `Frobnicate` may be a member function and `foo` may be destroyed
    -// by the time the lambda runs.
    -
    -prefer to write: -
    {
    -  Foo foo;
    -  ...
    -  executor->Schedule([&foo] { Frobnicate(foo); })
    -  ...
    -}
    -// GOOD - The lambda cannot accidentally capture `this` and
    -// the explicit by-reference capture is more obvious and therefore
    -// more likely to be checked for correctness.
    -
    -
  • -
  • Keep unnamed lambdas short. If a lambda body is more than -maybe five lines long, prefer to give the lambda a name, or to -use a named function instead of a lambda.
  • -
  • Specify the return type of the lambda explicitly if that will -make it more obvious to readers, as with -auto.
  • -
-
- -
- -

Template metaprogramming

-
-

Avoid complicated template programming.

-
- -
- -
-

Template metaprogramming refers to a family of techniques that -exploit the fact that the C++ template instantiation mechanism is -Turing complete and can be used to perform arbitrary compile-time -computation in the type domain.

-
- -
-

Template metaprogramming allows extremely flexible interfaces that -are type safe and high performance. Facilities like - -Google Test, -std::tuple, std::function, and -Boost.Spirit would be impossible without it.

-
- -
-

The techniques used in template metaprogramming are often obscure -to anyone but language experts. Code that uses templates in -complicated ways is often unreadable, and is hard to debug or -maintain.

- -

Template metaprogramming often leads to extremely poor compiler -time error messages: even if an interface is simple, the complicated -implementation details become visible when the user does something -wrong.

- -

Template metaprogramming interferes with large scale refactoring by -making the job of refactoring tools harder. First, the template code -is expanded in multiple contexts, and it's hard to verify that the -transformation makes sense in all of them. Second, some refactoring -tools work with an AST that only represents the structure of the code -after template expansion. It can be difficult to automatically work -back to the original source construct that needs to be -rewritten.

-
- -
-

Template metaprogramming sometimes allows cleaner and easier-to-use -interfaces than would be possible without it, but it's also often a -temptation to be overly clever. It's best used in a small number of -low level components where the extra maintenance burden is spread out -over a large number of uses.

- -

Think twice before using template metaprogramming or other -complicated template techniques; think about whether the average -member of your team will be able to understand your code well enough -to maintain it after you switch to another project, or whether a -non-C++ programmer or someone casually browsing the code base will be -able to understand the error messages or trace the flow of a function -they want to call. If you're using recursive template instantiations -or type lists or metafunctions or expression templates, or relying on -SFINAE or on the sizeof trick for detecting function -overload resolution, then there's a good chance you've gone too -far.

- -

If you use template metaprogramming, you should expect to put -considerable effort into minimizing and isolating the complexity. You -should hide metaprogramming as an implementation detail whenever -possible, so that user-facing headers are readable, and you should -make sure that tricky code is especially well commented. You should -carefully document how the code is used, and you should say something -about what the "generated" code looks like. Pay extra attention to the -error messages that the compiler emits when users make mistakes. The -error messages are part of your user interface, and your code should -be tweaked as necessary so that the error messages are understandable -and actionable from a user point of view.

- -
-
- - -

Boost

- -
-

Use only approved libraries from the Boost library -collection.

-
- -
- -
-

The - -Boost library collection is a popular collection of -peer-reviewed, free, open-source C++ libraries.

-
- -
-

Boost code is generally very high-quality, is widely -portable, and fills many important gaps in the C++ -standard library, such as type traits and better binders.

-
- -
-

Some Boost libraries encourage coding practices which can -hamper readability, such as metaprogramming and other -advanced template techniques, and an excessively -"functional" style of programming.

-
- -
- - - -
-

In order to maintain a high level of readability for -all contributors who might read and maintain code, we -only allow an approved subset of Boost features. -Currently, the following libraries are permitted:

- -
    -
  • - - Call Traits from boost/call_traits.hpp
  • - -
  • - Compressed Pair from boost/compressed_pair.hpp
  • - -
  • - The Boost Graph Library (BGL) from boost/graph, - except serialization (adj_list_serialize.hpp) and - parallel/distributed algorithms and data structures - (boost/graph/parallel/* and - boost/graph/distributed/*).
  • - -
  • - Property Map from boost/property_map, except - parallel/distributed property maps (boost/property_map/parallel/*).
  • - -
  • - Iterator from boost/iterator
  • - -
  • The part of - Polygon that deals with Voronoi diagram - construction and doesn't depend on the rest of - Polygon: - boost/polygon/voronoi_builder.hpp, - boost/polygon/voronoi_diagram.hpp, and - boost/polygon/voronoi_geometry_type.hpp
  • - -
  • - Bimap from boost/bimap
  • - -
  • - Statistical Distributions and Functions from - boost/math/distributions
  • - -
  • - Multi-index from boost/multi_index
  • - -
  • - Heap from boost/heap
  • - -
  • The flat containers from - Container: - boost/container/flat_map, and - boost/container/flat_set
  • - -
  • - Intrusive from boost/intrusive.
  • -
- -

We are actively considering adding other Boost -features to the list, so this list may be expanded in -the future.

-
- -

The following libraries are permitted, but their use -is discouraged because they've been superseded by -standard libraries in C++11:

- - -
- -
- - - -

std::hash

- -
-

Do not define specializations of std::hash.

-
- -
- -
-

std::hash<T> is the function object that the -C++11 hash containers use to hash keys of type T, -unless the user explicitly specifies a different hash function. For -example, std::unordered_map<int, string> is a hash -map that uses std::hash<int> to hash its keys, -whereas std::unordered_map<int, string, MyIntHash> -uses MyIntHash.

- -

std::hash is defined for all integral, floating-point, -pointer, and enum types, as well as some standard library -types such as string and unique_ptr. Users -can enable it to work for their own types by defining specializations -of it for those types.

-
- -
-

std::hash is easy to use, and simplifies the code -since you don't have to name it explicitly. Specializing -std::hash is the standard way of specifying how to -hash a type, so it's what outside resources will teach, and what -new engineers will expect.

-
- -
-

std::hash is hard to specialize. It requires a lot -of boilerplate code, and more importantly, it combines responsibility -for identifying the hash inputs with responsibility for executing the -hashing algorithm itself. The type author has to be responsible for -the former, but the latter requires expertise that a type author -usually doesn't have, and shouldn't need. The stakes here are high -because low-quality hash functions can be security vulnerabilities, -due to the emergence of - -hash flooding attacks.

- -

Even for experts, std::hash specializations are -inordinately difficult to implement correctly for compound types, -because the implementation cannot recursively call std::hash -on data members. High-quality hash algorithms maintain large -amounts of internal state, and reducing that state to the -size_t bytes that std::hash -returns is usually the slowest part of the computation, so it -should not be done more than once.

- -

Due to exactly that issue, std::hash does not work -with std::pair or std::tuple, and the -language does not allow us to extend it to support them.

-
- -
-

You can use std::hash with the types that it supports -"out of the box", but do not specialize it to support additional types. -If you need a hash table with a key type that std::hash -does not support, consider using legacy hash containers (e.g. -hash_map) for now; they use a different default hasher, -which is unaffected by this prohibition.

- -

If you want to use the standard hash containers anyway, you will -need to specify a custom hasher for the key type, e.g.

-
std::unordered_map<MyKeyType, Value, MyKeyTypeHasher> my_map;
-

-Consult with the type's owners to see if there is an existing hasher -that you can use; otherwise work with them to provide one, - or roll your own.

- -

We are planning to provide a hash function that can work with any type, -using a new customization mechanism that doesn't have the drawbacks of -std::hash.

-
- -
- -

C++11

- -
-

Use libraries and language extensions from C++11 when appropriate. -Consider portability to other environments -before using C++11 features in your -project.

- -
- -
- -
-

C++11 contains -significant changes both to the language and -libraries.

-
- -
-

C++11 was the official standard until august 2014, and -is supported by most C++ compilers. It standardizes -some common C++ extensions that we use already, allows -shorthands for some operations, and has some performance -and safety improvements.

-
- -
-

The C++11 standard is substantially more complex than -its predecessor (1,300 pages versus 800 pages), and is -unfamiliar to many developers. The long-term effects of -some features on code readability and maintenance are -unknown. We cannot predict when its various features will -be implemented uniformly by tools that may be of -interest, particularly in the case of projects that are -forced to use older versions of tools.

- -

As with Boost, some C++11 -extensions encourage coding practices that hamper -readability—for example by removing -checked redundancy (such as type names) that may be -helpful to readers, or by encouraging template -metaprogramming. Other extensions duplicate functionality -available through existing mechanisms, which may lead to confusion -and conversion costs.

- - -
- -
- -

C++11 features may be used unless specified otherwise. -In addition to what's described in the rest of the style -guide, the following C++11 features may not be used:

- -
    - - - - - - - - -
  • Compile-time rational numbers - (<ratio>), because of concerns that - it's tied to a more template-heavy interface - style.
  • - -
  • The <cfenv> and - <fenv.h> headers, because many - compilers do not support those features reliably.
  • - -
-
- -
- -

Naming

- -

The most important consistency rules are those that govern -naming. The style of a name immediately informs us what sort of -thing the named entity is: a type, a variable, a function, a -constant, a macro, etc., without requiring us to search for the -declaration of that entity. The pattern-matching engine in our -brains relies a great deal on these naming rules. -

- -

Naming rules are pretty arbitrary, but - we feel that -consistency is more important than individual preferences in this -area, so regardless of whether you find them sensible or not, -the rules are the rules.

- -

General Naming Rules

- -
-

Names should be descriptive; eschew abbreviation.

-
- -
-

Give as descriptive a name as possible, within reason. -Do not worry about saving horizontal space as it is far -more important to make your code immediately -understandable by a new reader. Do not use abbreviations -that are ambiguous or unfamiliar to readers outside your -project, and do not abbreviate by deleting letters within -a word.

- -
int price_count_reader;    // No abbreviation.
-int num_errors;            // "num" is a widespread convention.
-int num_dns_connections;   // Most people know what "DNS" stands for.
-
- -
int n;                     // Meaningless.
-int nerr;                  // Ambiguous abbreviation.
-int n_comp_conns;          // Ambiguous abbreviation.
-int wgc_connections;       // Only your group knows what this stands for.
-int pc_reader;             // Lots of things can be abbreviated "pc".
-int cstmr_id;              // Deletes internal letters.
-
- -
- -

File Names

- -
-

Filenames should be all lowercase and can include -underscores (_) or dashes (-). -Follow the convention that your - -project uses. If there is no consistent -local pattern to follow, prefer "_".

-
- -
- -

Examples of acceptable file names:

- -
    -
  • my_useful_class.cc
  • -
  • my-useful-class.cc
  • -
  • myusefulclass.cc
  • -
  • myusefulclass_test.cc // _unittest and _regtest are deprecated.
  • -
- -

C++ files should end in .cc and header files should end in -.h. Files that rely on being textually included at specific points -should end in .inc (see also the section on -self-contained headers).

- -

Do not use filenames that already exist in -/usr/include, such as db.h.

- -

In general, make your filenames very specific. For -example, use http_server_logs.h rather than -logs.h. A very common case is to have a pair -of files called, e.g., foo_bar.h and -foo_bar.cc, defining a class called -FooBar.

- -

Inline functions must be in a .h file. If -your inline functions are very short, they should go -directly into your .h file.

- -
- -

Type Names

- -
-

Type names start with a capital letter and have a capital -letter for each new word, with no underscores: -MyExcitingClass, MyExcitingEnum.

-
- -
- -

The names of all types — classes, structs, typedefs, -enums, and type template parameters — have the same naming convention. -Type names should start with a capital letter and have a capital letter -for each new word. No underscores. For example:

- -
// classes and structs
-class UrlTable { ...
-class UrlTableTester { ...
-struct UrlTableProperties { ...
-
-// typedefs
-typedef hash_map<UrlTableProperties *, string> PropertiesMap;
-
-// enums
-enum UrlTableErrors { ...
-
- -
- -

Variable Names

- -
-

The names of variables and data members are all lowercase, with -underscores between words. Data members of classes (but not structs) -additionally have trailing underscores. For instance: -a_local_variable, a_struct_data_member, -a_class_data_member_.

-
- -
- -

Common Variable names

- -

For example:

- -
string table_name;  // OK - uses underscore.
-string tablename;   // OK - all lowercase.
-
- -
string tableName;   // Bad - mixed case.
-
- -

Class Data Members

- -

Data members of classes, both static and non-static, are -named like ordinary nonmember variables, but with a -trailing underscore.

- -
class TableInfo {
-  ...
- private:
-  string table_name_;  // OK - underscore at end.
-  string tablename_;   // OK.
-  static Pool<TableInfo>* pool_;  // OK.
-};
-
- -

Struct Data Members

- -

Data members of structs, both static and non-static, -are named like ordinary nonmember variables. They do not have -the trailing underscores that data members in classes have.

- -
struct UrlTableProperties {
-  string name;
-  int num_entries;
-  static Pool<UrlTableProperties>* pool;
-};
-
- - -

See Structs vs. -Classes for a discussion of when to use a struct -versus a class.

- -

Global Variables

- -

There are no special requirements for global -variables, which should be rare in any case, but if you -use one, consider prefixing it with g_ or -some other marker to easily distinguish it from local -variables.

- -
- -

Constant Names

- -
-

Variables declared constexpr or const, and whose value is fixed for - the duration of the program, are named with a leading "k" followed - by mixed case. For example:

-
- -
const int kDaysInAWeek = 7;
-
- -
- -

All such variables with static storage duration (i.e. statics and globals, - see - Storage Duration for details) should be named this way. This - convention is optional for variables of other storage classes, e.g. automatic - variables, otherwise the usual variable naming rules apply.

- -

- -

Function Names

- -
-

Regular functions have mixed case; "cheap" functions may -use lower case with underscores.

-
- -
- -

Ordinarily, functions should start with a capital letter and have -a capital letter for each new word (a.k.a. "upper camel case" or "Pascal case"). -Such names should not have underscores. Prefer to capitalize acronyms as -single words (i.e. StartRpc(), not StartRPC()).

- -
AddTableEntry()
-DeleteUrl()
-OpenFileOrDie()
-
- -

Functions that are very cheap to call may instead follow the style -for variable names (all lower-case, with underscores between words). -The rule of thumb is that such a function should be so cheap that you -normally wouldn't bother caching its return value when calling it in -a loop. A canonical example is an inline method that just returns one -of the class's member variables.

- -
class MyClass {
- public:
-  ...
-  bool is_empty() const { return num_entries_ == 0; }
-
- private:
-  int num_entries_;
-};
-
-
- -

Namespace Names

- -
-Namespace names are all lower-case. Top-level -namespace names are based on the project name -. -
- -
-

The name of a top-level namespace should usually be the -name of the project or team whose code is contained in that -namespace. The code in that namespace should usually be in -a directory whose basename matches the namespace name (or -subdirectories thereof).

- - - - - -

Keep in mind that the rule -against abbreviated names applies to namespaces just as much -as variable names. Code inside the namespace seldom needs to -mention the namespace name, so there's usually no particular need -for abbreviation anyway.

- -

Naming conventions for nested namespaces are at the discretion -of the team owning the enclosing namespace. If a nested namespace -is used to group related functions in a single header file, consider basing -its name on the header name, e.g. namespace foo::bar -for functions defined in the header file bar.h. -If the nested namespace is being used to distinguish implementation -details from user-facing declarations, one common choice is -internal.

- -
- -

Enumerator Names

- -
-

Enumerators should be named either like -constants or like -macros: either kEnumName or -ENUM_NAME.

-
- -
- -

Preferably, the individual enumerators should be named -like constants. However, it -is also acceptable to name them like -macros. The enumeration name, -UrlTableErrors (and -AlternateUrlTableErrors), is a type, and -therefore mixed case.

- -
enum UrlTableErrors {
-  kOK = 0,
-  kErrorOutOfMemory,
-  kErrorMalformedInput,
-};
-enum AlternateUrlTableErrors {
-  OK = 0,
-  OUT_OF_MEMORY = 1,
-  MALFORMED_INPUT = 2,
-};
-
- -

Until January 2009, the style was to name enum values -like macros. This caused -problems with name collisions between enum values and -macros. Hence, the change to prefer constant-style naming -was put in place. New code should prefer constant-style -naming if possible. However, there is no reason to change -old code to use constant-style names, unless the old -names are actually causing a compile-time problem.

- - - -
- -

Macro Names

- -
-

You're not really going to -define a macro, are you? If you do, they're like this: -MY_MACRO_THAT_SCARES_SMALL_CHILDREN.

-
- -
- -

Please see the description -of macros; in general macros should not be used. -However, if they are absolutely needed, then they should be -named with all capitals and underscores.

- -
#define ROUND(x) ...
-#define PI_ROUNDED 3.0
-
- -
- -

Exceptions to Naming Rules

- -
-

If you are naming something that is analogous to an -existing C or C++ entity then you can follow the existing -naming convention scheme.

-
- -
- -
-
bigopen()
-
function name, follows form of open()
- -
uint
-
typedef
- -
bigpos
-
struct or class, follows - form of pos
- -
sparse_hash_map
-
STL-like entity; follows STL naming conventions
- -
LONGLONG_MAX
-
a constant, as in INT_MAX
-
- -
- -

Comments

- -

Though a pain to write, comments are absolutely vital to -keeping our code readable. The following rules describe what -you should comment and where. But remember: while comments are -very important, the best code is self-documenting. Giving -sensible names to types and variables is much better than using -obscure names that you must then explain through comments.

- -

When writing your comments, write for your audience: the -next -contributor who will need to -understand your code. Be generous — the next -one may be you!

- -

Comment Style

- -
-

Use either the // or /* */ -syntax, as long as you are consistent.

-
- -
- -

You can use either the // or the /* -*/ syntax; however, // is -much more common. Be consistent with how you -comment and what style you use where.

- -
- -

File Comments

- -
-

Start each file with license -boilerplate, followed by a description of its -contents.

-
- -
- -

Legal Notice and Author -Line

- - - -

Every file should contain license -boilerplate. Choose the appropriate boilerplate for the -license used by the project (for example, Apache 2.0, -BSD, LGPL, GPL).

- -

If you make significant changes to a file with an -author line, consider deleting the author line.

- -

File Contents

- -

Every file should have a comment at the top describing -its contents, unless the specific conditions described below apply.

- -

A file-level comment in a .h should broadly describe -the contents of the file. If the file declares multiple abstractions, the -file-level comment should document how they are related. A 1 or 2 sentence -file-level comment may be sufficient. The detailed documentation about -individual abstractions belongs with those abstractions, not at the file -level.

- -

Do not duplicate comments in both the .h and the -.cc. Duplicated comments diverge.

- -

A file-level comment may be omitted if the file declares, implements, or -tests exactly one abstraction that is documented by a comment at the point -of declaration.

- -

- -

Class Comments

- -
-

Every class definition should have an accompanying comment -that describes what it is for and how it should be used.

-
- -
- -
// Iterates over the contents of a GargantuanTable.
-// Example:
-//    GargantuanTableIterator* iter = table->NewIterator();
-//    for (iter->Seek("foo"); !iter->done(); iter->Next()) {
-//      process(iter->key(), iter->value());
-//    }
-//    delete iter;
-class GargantuanTableIterator {
-  ...
-};
-
- -

The class comment should provide the reader with enough information to know -how and when to use the class, as well as any additional considerations -necessary to correctly use the class. Document the synchronization assumptions -the class makes, if any. If an instance of the class can be accessed by -multiple threads, take extra care to document the rules and invariants -surrounding multithreaded use.

- -

The class comment is often a good place for a small example code snippet -demonstrating a simple and focused usage of the class.

- -
- -

Function Comments

- -
-

Declaration comments describe use of the function; comments -at the definition of a function describe operation.

-
- -
- -

Function Declarations

- -

Every function declaration should have comments -immediately preceding it that describe what the function -does and how to use it. These comments should be -descriptive ("Opens the file") rather than imperative -("Open the file"); the comment describes the function, it -does not tell the function what to do. In general, these -comments do not describe how the function performs its -task. Instead, that should be left to comments in the -function definition.

- -

Types of things to mention in comments at the function -declaration:

- -
    -
  • What the inputs and outputs are.
  • - -
  • For class member functions: whether the object - remembers reference arguments beyond the duration of - the method call, and whether it will free them or - not.
  • - -
  • If the function allocates memory that the caller - must free.
  • - -
  • Whether any of the arguments can be a null - pointer.
  • - -
  • If there are any performance implications of how a - function is used.
  • - -
  • If the function is re-entrant. What are its - synchronization assumptions?
  • -
- -

Here is an example:

- -
// Returns an iterator for this table.  It is the client's
-// responsibility to delete the iterator when it is done with it,
-// and it must not use the iterator once the GargantuanTable object
-// on which the iterator was created has been deleted.
-//
-// The iterator is initially positioned at the beginning of the table.
-//
-// This method is equivalent to:
-//    Iterator* iter = table->NewIterator();
-//    iter->Seek("");
-//    return iter;
-// If you are going to immediately seek to another place in the
-// returned iterator, it will be faster to use NewIterator()
-// and avoid the extra seek.
-Iterator* GetIterator() const;
-
- -

However, do not be unnecessarily verbose or state the -completely obvious. Notice below that it is not necessary - to say "returns false otherwise" because this is -implied.

- -
// Returns true if the table cannot hold any more entries.
-bool IsTableFull();
-
- -

When documenting function overrides, focus on the -specifics of the override itself, rather than repeating -the comment from the overriden function. In many of these -cases, the override needs no additional documentation and -thus no comment is required.

- -

When commenting constructors and destructors, remember -that the person reading your code knows what constructors -and destructors are for, so comments that just say -something like "destroys this object" are not useful. -Document what constructors do with their arguments (for -example, if they take ownership of pointers), and what -cleanup the destructor does. If this is trivial, just -skip the comment. It is quite common for destructors not -to have a header comment.

- -

Function Definitions

- -

If there is anything tricky about how a function does -its job, the function definition should have an -explanatory comment. For example, in the definition -comment you might describe any coding tricks you use, -give an overview of the steps you go through, or explain -why you chose to implement the function in the way you -did rather than using a viable alternative. For instance, -you might mention why it must acquire a lock for the -first half of the function but why it is not needed for -the second half.

- -

Note you should not just repeat the comments -given with the function declaration, in the -.h file or wherever. It's okay to -recapitulate briefly what the function does, but the -focus of the comments should be on how it does it.

- -
- -

Variable Comments

- -
-

In general the actual name of the variable should be -descriptive enough to give a good idea of what the variable -is used for. In certain cases, more comments are required.

-
- -
- -

Class Data Members

- -

Each class data member (also called an instance -variable or member variable) should have a comment -describing what it is used for. If the variable can take -sentinel values with special meanings, such as a null -pointer or -1, document this. For example:

- - -
private:
- // Keeps track of the total number of entries in the table.
- // Used to ensure we do not go over the limit. -1 means
- // that we don't yet know how many entries the table has.
- int num_total_entries_;
-
- -

Global Variables

- -

As with data members, all global variables should have -a comment describing what they are and what they are used -for. For example:

- -
// The total number of tests cases that we run through in this regression test.
-const int kNumTestCases = 6;
-
- -
- -

Implementation Comments

- -
-

In your implementation you should have comments in tricky, -non-obvious, interesting, or important parts of your code.

-
- -
- -

Explanatory Comments

- -

Tricky or complicated code blocks should have comments -before them. Example:

- -
// Divide result by two, taking into account that x
-// contains the carry from the add.
-for (int i = 0; i < result->size(); i++) {
-  x = (x << 8) + (*result)[i];
-  (*result)[i] = x >> 1;
-  x &= 1;
-}
-
- -

Line Comments

- -

Also, lines that are non-obvious should get a comment -at the end of the line. These end-of-line comments should -be separated from the code by 2 spaces. Example:

- -
// If we have enough memory, mmap the data portion too.
-mmap_budget = max<int64>(0, mmap_budget - index_->length());
-if (mmap_budget >= data_size_ && !MmapData(mmap_chunk_bytes, mlock))
-  return;  // Error already logged.
-
- -

Note that there are both comments that describe what -the code is doing, and comments that mention that an -error has already been logged when the function -returns.

- -

If you have several comments on subsequent lines, it -can often be more readable to line them up:

- -
DoSomething();                  // Comment here so the comments line up.
-DoSomethingElseThatIsLonger();  // Two spaces between the code and the comment.
-{ // One space before comment when opening a new scope is allowed,
-  // thus the comment lines up with the following comments and code.
-  DoSomethingElse();  // Two spaces before line comments normally.
-}
-vector<string> list{// Comments in braced lists describe the next element ..
-                    "First item",
-                    // .. and should be aligned appropriately.
-                    "Second item"};
-DoSomething(); /* For trailing block comments, one space is fine. */
-
- -

Function Argument Comments

- -

When the meaning of a function argument is nonobvious, consider -one of the following remedies:

- -
    -
  • If the argument is a literal constant, and the same constant is - used in multiple function calls in a way that tacitly assumes they're - the same, you should use a named constant to make that constraint - explicit, and to guarantee that it holds.
  • - -
  • Consider changing the function signature to replace a bool - argument with an enum argument. This will make the argument - values self-describing.
  • - -
  • For functions that have several configuration options, consider - defining a single class or struct to hold all the options - , - and pass an instance of that. - This approach has several advantages. Options are referenced by name - at the call site, which clarifies their meaning. It also reduces - function argument count, which makes function calls easier to read and - write. As an added benefit, you don't have to change call sites when - you add another option. -
  • - -
  • Replace large or complex nested expressions with named variables.
  • - -
  • As a last resort, use comments to clarify argument meanings at the - call site.
  • -
- -Consider the following example: - -
// What are these arguments?
-const DecimalNumber product = CalculateProduct(values, 7, false, nullptr);
-
- -

versus:

- -
ProductOptions options;
-options.set_precision_decimals(7);
-options.set_use_cache(ProductOptions::kDontUseCache);
-const DecimalNumber product =
-    CalculateProduct(values, options, /*completion_callback=*/nullptr);
-
- -

Don'ts

- -

Do not state the obvious. In particular, don't literally describe what -code does, unless the behavior is nonobvious to a reader who understands -C++ well. Instead, provide higher level comments that describe why -the code does what it does, or make the code self describing.

- -Compare this: - -
// Find the element in the vector.  <-- Bad: obvious!
-auto iter = std::find(v.begin(), v.end(), element);
-if (iter != v.end()) {
-  Process(element);
-}
-
- -To this: - -
// Process "element" unless it was already processed.
-auto iter = std::find(v.begin(), v.end(), element);
-if (iter != v.end()) {
-  Process(element);
-}
-
- -Self-describing code doesn't need a comment. The comment from -the example above would be obvious: - -
if (!IsAlreadyProcessed(element)) {
-  Process(element);
-}
-
- -
- -

Punctuation, Spelling and Grammar

- -
-

Pay attention to punctuation, spelling, and grammar; it is -easier to read well-written comments than badly written -ones.

-
- -
- -

Comments should be as readable as narrative text, with -proper capitalization and punctuation. In many cases, -complete sentences are more readable than sentence -fragments. Shorter comments, such as comments at the end -of a line of code, can sometimes be less formal, but you -should be consistent with your style.

- -

Although it can be frustrating to have a code reviewer -point out that you are using a comma when you should be -using a semicolon, it is very important that source code -maintain a high level of clarity and readability. Proper -punctuation, spelling, and grammar help with that -goal.

- -
- -

TODO Comments

- -
-

Use TODO comments for code that is temporary, -a short-term solution, or good-enough but not perfect.

-
- -
- -

TODOs should include the string -TODO in all caps, followed by the - -name, e-mail address, or other -identifier of the person - with the best context -about the problem referenced by the TODO. The -main purpose is to have a consistent TODO that -can be searched to find out how to get more details upon -request. A TODO is not a commitment that the -person referenced will fix the problem. Thus when you create -a TODO, it is almost always your - -name -that is given.

- - - -
-
// TODO(kl@gmail.com): Use a "*" here for concatenation operator.
-// TODO(Zeke) change this to use relations.
-
-
- -

If your TODO is of the form "At a future -date do something" make sure that you either include a -very specific date ("Fix by November 2005") or a very -specific event ("Remove this code when all clients can -handle XML responses.").

- -
- -

Deprecation Comments

- -
-

Mark deprecated interface points with DEPRECATED -comments.

-
- -
- -

You can mark an interface as deprecated by writing a -comment containing the word DEPRECATED in -all caps. The comment goes either before the declaration -of the interface or on the same line as the -declaration.

- - - -

After the word -DEPRECATED, write your name, e-mail address, -or other identifier in parentheses.

- -

A deprecation comment must include simple, clear -directions for people to fix their callsites. In C++, you -can implement a deprecated function as an inline function -that calls the new interface point.

- -

Marking an interface point DEPRECATED -will not magically cause any callsites to change. If you -want people to actually stop using the deprecated -facility, you will have to fix the callsites yourself or -recruit a crew to help you.

- -

New code should not contain calls to deprecated -interface points. Use the new interface point instead. If -you cannot understand the directions, find the person who -created the deprecation and ask them for help using the -new interface point.

- - - -
- -

Formatting

- -

Coding style and formatting are pretty arbitrary, but a - -project is much easier to follow -if everyone uses the same style. Individuals may not agree with every -aspect of the formatting rules, and some of the rules may take -some getting used to, but it is important that all - -project contributors follow the -style rules so that -they can all read and understand -everyone's code easily.

- - - -

To help you format code correctly, we've -created a - -settings file for emacs.

- -

Line Length

- -
-

Each line of text in your code should be at most 80 -characters long.

-
- -
- - - -

We recognize that this rule is -controversial, but so much existing code already adheres -to it, and we feel that consistency is important.

- -
-

Those who favor this rule -argue that it is rude to force them to resize -their windows and there is no need for anything longer. -Some folks are used to having several code windows -side-by-side, and thus don't have room to widen their -windows in any case. People set up their work environment -assuming a particular maximum window width, and 80 -columns has been the traditional standard. Why change -it?

-
- -
-

Proponents of change argue that a wider line can make -code more readable. The 80-column limit is an hidebound -throwback to 1960s mainframes; modern equipment has wide screens that -can easily show longer lines.

-
- -
-

80 characters is the maximum.

- -

Comment lines can be longer than 80 -characters if it is not feasible to split them without -harming readability, ease of cut and paste or auto-linking --- e.g. if a line contains an example command or a literal -URL longer than 80 characters.

- -

A raw-string literal may have content -that exceeds 80 characters. Except for test code, such literals -should appear near top of a file.

- -

An #include statement with a -long path may exceed 80 columns.

- -

You needn't be concerned about -header guards that exceed -the maximum length.

-
- -
- -

Non-ASCII Characters

- -
-

Non-ASCII characters should be rare, and must use UTF-8 -formatting.

-
- -
- -

You shouldn't hard-code user-facing text in source, -even English, so use of non-ASCII characters should be -rare. However, in certain cases it is appropriate to -include such words in your code. For example, if your -code parses data files from foreign sources, it may be -appropriate to hard-code the non-ASCII string(s) used in -those data files as delimiters. More commonly, unittest -code (which does not need to be localized) might -contain non-ASCII strings. In such cases, you should use -UTF-8, since that is an encoding -understood by most tools able to handle more than just -ASCII.

- -

Hex encoding is also OK, and encouraged where it -enhances readability — for example, -"\xEF\xBB\xBF", or, even more simply, -u8"\uFEFF", is the Unicode zero-width -no-break space character, which would be invisible if -included in the source as straight UTF-8.

- -

Use the u8 prefix -to guarantee that a string literal containing -\uXXXX escape sequences is encoded as UTF-8. -Do not use it for strings containing non-ASCII characters -encoded as UTF-8, because that will produce incorrect -output if the compiler does not interpret the source file -as UTF-8.

- -

You shouldn't use the C++11 char16_t and -char32_t character types, since they're for -non-UTF-8 text. For similar reasons you also shouldn't -use wchar_t (unless you're writing code that -interacts with the Windows API, which uses -wchar_t extensively).

- -
- -

Spaces vs. Tabs

- -
-

Use only spaces, and indent 2 spaces at a time.

-
- -
- -

We use spaces for indentation. Do not use tabs in your -code. You should set your editor to emit spaces when you -hit the tab key.

- -
- -

Function Declarations and Definitions

- -
-

Return type on the same line as function name, parameters -on the same line if they fit. Wrap parameter lists which do -not fit on a single line as you would wrap arguments in a -function call.

-
- -
- -

Functions look like this:

- - -
ReturnType ClassName::FunctionName(Type par_name1, Type par_name2) {
-  DoSomething();
-  ...
-}
-
- -

If you have too much text to fit on one line:

- -
ReturnType ClassName::ReallyLongFunctionName(Type par_name1, Type par_name2,
-                                             Type par_name3) {
-  DoSomething();
-  ...
-}
-
- -

or if you cannot fit even the first parameter:

- -
ReturnType LongClassName::ReallyReallyReallyLongFunctionName(
-    Type par_name1,  // 4 space indent
-    Type par_name2,
-    Type par_name3) {
-  DoSomething();  // 2 space indent
-  ...
-}
-
- -

Some points to note:

- -
    -
  • Choose good parameter names.
  • - -
  • Parameter names may be omitted only if the parameter is unused and its - purpose is obvious.
  • - -
  • If you cannot fit the return type and the function - name on a single line, break between them.
  • - -
  • If you break after the return type of a function - declaration or definition, do not indent.
  • - -
  • The open parenthesis is always on the same line as - the function name.
  • - -
  • There is never a space between the function name - and the open parenthesis.
  • - -
  • There is never a space between the parentheses and - the parameters.
  • - -
  • The open curly brace is always on the end of the last line of the function - declaration, not the start of the next line.
  • - -
  • The close curly brace is either on the last line by - itself or on the same line as the open curly brace.
  • - -
  • There should be a space between the close - parenthesis and the open curly brace.
  • - -
  • All parameters should be aligned if possible.
  • - -
  • Default indentation is 2 spaces.
  • - -
  • Wrapped parameters have a 4 space indent.
  • -
- -

Unused parameters that are obvious from context may be omitted:

- -
class Foo {
- public:
-  Foo(Foo&&) = default;
-  Foo(const Foo&) = default;
-  Foo& operator=(Foo&&) = default;
-  Foo& operator=(const Foo&) = default;
-};
-
- -

Unused parameters that might not be obvious should comment out the variable -name in the function definition:

- -
class Shape {
- public:
-  virtual void Rotate(double radians) = 0;
-};
-
-class Circle : public Shape {
- public:
-  void Rotate(double radians) override;
-};
-
-void Circle::Rotate(double /*radians*/) {}
-
- -
// Bad - if someone wants to implement later, it's not clear what the
-// variable means.
-void Circle::Rotate(double) {}
-
- -
- -

Lambda Expressions

- -
-

Format parameters and bodies as for any other function, and capture -lists like other comma-separated lists.

-
- -
-

For by-reference captures, do not leave a space between the -ampersand (&) and the variable name.

-
int x = 0;
-auto add_to_x = [&x](int n) { x += n; };
-
-

Short lambdas may be written inline as function arguments.

-
set<int> blacklist = {7, 8, 9};
-vector<int> digits = {3, 9, 1, 8, 4, 7, 1};
-digits.erase(std::remove_if(digits.begin(), digits.end(), [&blacklist](int i) {
-               return blacklist.find(i) != blacklist.end();
-             }),
-             digits.end());
-
- -
- -

Function Calls

- -
-

Either write the call all on a single line, wrap the -arguments at the parenthesis, or start the arguments on a new -line indented by four spaces and continue at that 4 space -indent. In the absence of other considerations, use the -minimum number of lines, including placing multiple arguments -on each line where appropriate.

-
- -
- -

Function calls have the following format:

-
bool result = DoSomething(argument1, argument2, argument3);
-
- -

If the arguments do not all fit on one line, they -should be broken up onto multiple lines, with each -subsequent line aligned with the first argument. Do not -add spaces after the open paren or before the close -paren:

-
bool result = DoSomething(averyveryveryverylongargument1,
-                          argument2, argument3);
-
- -

Arguments may optionally all be placed on subsequent -lines with a four space indent:

-
if (...) {
-  ...
-  ...
-  if (...) {
-    bool result = DoSomething(
-        argument1, argument2,  // 4 space indent
-        argument3, argument4);
-    ...
-  }
-
- -

Put multiple arguments on a single line to reduce the -number of lines necessary for calling a function unless -there is a specific readability problem. Some find that -formatting with strictly one argument on each line is -more readable and simplifies editing of the arguments. -However, we prioritize for the reader over the ease of -editing arguments, and most readability problems are -better addressed with the following techniques.

- -

If having multiple arguments in a single line decreases -readability due to the complexity or confusing nature of the -expressions that make up some arguments, try creating -variables that capture those arguments in a descriptive name:

-
int my_heuristic = scores[x] * y + bases[x];
-bool result = DoSomething(my_heuristic, x, y, z);
-
- -

Or put the confusing argument on its own line with -an explanatory comment:

-
bool result = DoSomething(scores[x] * y + bases[x],  // Score heuristic.
-                          x, y, z);
-
- -

If there is still a case where one argument is -significantly more readable on its own line, then put it on -its own line. The decision should be specific to the argument -which is made more readable rather than a general policy.

- -

Sometimes arguments form a structure that is important -for readability. In those cases, feel free to format the -arguments according to that structure:

-
// Transform the widget by a 3x3 matrix.
-my_widget.Transform(x1, x2, x3,
-                    y1, y2, y3,
-                    z1, z2, z3);
-
- -
- -

Braced Initializer List Format

- -
-

Format a braced initializer list -exactly like you would format a function call in its place.

-
- -
- -

If the braced list follows a name (e.g. a type or -variable name), format as if the {} were the -parentheses of a function call with that name. If there -is no name, assume a zero-length name.

- -
// Examples of braced init list on a single line.
-return {foo, bar};
-functioncall({foo, bar});
-pair<int, int> p{foo, bar};
-
-// When you have to wrap.
-SomeFunction(
-    {"assume a zero-length name before {"},
-    some_other_function_parameter);
-SomeType variable{
-    some, other, values,
-    {"assume a zero-length name before {"},
-    SomeOtherType{
-        "Very long string requiring the surrounding breaks.",
-        some, other values},
-    SomeOtherType{"Slightly shorter string",
-                  some, other, values}};
-SomeType variable{
-    "This is too long to fit all in one line"};
-MyType m = {  // Here, you could also break before {.
-    superlongvariablename1,
-    superlongvariablename2,
-    {short, interior, list},
-    {interiorwrappinglist,
-     interiorwrappinglist2}};
-
- -
- -

Conditionals

- -
-

Prefer no spaces inside parentheses. The if -and else keywords belong on separate lines.

-
- -
- -

There are two acceptable formats for a basic -conditional statement. One includes spaces between the -parentheses and the condition, and one does not.

- -

The most common form is without spaces. Either is -fine, but be consistent. If you are modifying a -file, use the format that is already present. If you are -writing new code, use the format that the other files in -that directory or project use. If in doubt and you have -no personal preference, do not add the spaces.

- -
if (condition) {  // no spaces inside parentheses
-  ...  // 2 space indent.
-} else if (...) {  // The else goes on the same line as the closing brace.
-  ...
-} else {
-  ...
-}
-
- -

If you prefer you may add spaces inside the -parentheses:

- -
if ( condition ) {  // spaces inside parentheses - rare
-  ...  // 2 space indent.
-} else {  // The else goes on the same line as the closing brace.
-  ...
-}
-
- -

Note that in all cases you must have a space between -the if and the open parenthesis. You must -also have a space between the close parenthesis and the -curly brace, if you're using one.

- -
if(condition) {   // Bad - space missing after IF.
-if (condition){   // Bad - space missing before {.
-if(condition){    // Doubly bad.
-
- -
if (condition) {  // Good - proper space after IF and before {.
-
- -

Short conditional statements may be written on one -line if this enhances readability. You may use this only -when the line is brief and the statement does not use the -else clause.

- -
if (x == kFoo) return new Foo();
-if (x == kBar) return new Bar();
-
- -

This is not allowed when the if statement has an -else:

- -
// Not allowed - IF statement on one line when there is an ELSE clause
-if (x) DoThis();
-else DoThat();
-
- -

In general, curly braces are not required for -single-line statements, but they are allowed if you like -them; conditional or loop statements with complex -conditions or statements may be more readable with curly -braces. Some -projects require that an -if must always always have an accompanying -brace.

- -
if (condition)
-  DoSomething();  // 2 space indent.
-
-if (condition) {
-  DoSomething();  // 2 space indent.
-}
-
- -

However, if one part of an -if-else statement uses curly -braces, the other part must too:

- -
// Not allowed - curly on IF but not ELSE
-if (condition) {
-  foo;
-} else
-  bar;
-
-// Not allowed - curly on ELSE but not IF
-if (condition)
-  foo;
-else {
-  bar;
-}
-
- -
// Curly braces around both IF and ELSE required because
-// one of the clauses used braces.
-if (condition) {
-  foo;
-} else {
-  bar;
-}
-
- -
- -

Loops and Switch Statements

- -
-

Switch statements may use braces for blocks. Annotate -non-trivial fall-through between cases. -Braces are optional for single-statement loops. -Empty loop bodies should use {} or continue.

-
- -
- -

case blocks in switch -statements can have curly braces or not, depending on -your preference. If you do include curly braces they -should be placed as shown below.

- -

If not conditional on an enumerated value, switch -statements should always have a default case -(in the case of an enumerated value, the compiler will -warn you if any values are not handled). If the default -case should never execute, simply -assert:

- - - -
-
switch (var) {
-  case 0: {  // 2 space indent
-    ...      // 4 space indent
-    break;
-  }
-  case 1: {
-    ...
-    break;
-  }
-  default: {
-    assert(false);
-  }
-}
-
-
- - - - - -

Braces are optional for single-statement loops.

- -
for (int i = 0; i < kSomeNumber; ++i)
-  printf("I love you\n");
-
-for (int i = 0; i < kSomeNumber; ++i) {
-  printf("I take it back\n");
-}
-
- - -

Empty loop bodies should use {} or -continue, but not a single semicolon.

- -
while (condition) {
-  // Repeat test until it returns false.
-}
-for (int i = 0; i < kSomeNumber; ++i) {}  // Good - empty body.
-while (condition) continue;  // Good - continue indicates no logic.
-
- -
while (condition);  // Bad - looks like part of do/while loop.
-
- -
- -

Pointer and Reference Expressions

- -
-

No spaces around period or arrow. Pointer operators do not -have trailing spaces.

-
- -
- -

The following are examples of correctly-formatted -pointer and reference expressions:

- -
x = *p;
-p = &x;
-x = r.y;
-x = r->y;
-
- -

Note that:

- -
    -
  • There are no spaces around the period or arrow when - accessing a member.
  • - -
  • Pointer operators have no space after the - * or &.
  • -
- -

When declaring a pointer variable or argument, you may -place the asterisk adjacent to either the type or to the -variable name:

- -
// These are fine, space preceding.
-char *c;
-const string &str;
-
-// These are fine, space following.
-char* c;    // but remember to do "char* c, *d, *e, ...;"!
-const string& str;
-
- -
char * c;  // Bad - spaces on both sides of *
-const string & str;  // Bad - spaces on both sides of &
-
- -

You should do this consistently within a single -file, -so, when modifying an existing file, use the style in -that file.

- -
- -

Boolean Expressions

- -
-

When you have a boolean expression that is longer than the -standard line length, be -consistent in how you break up the lines.

-
- -
- -

In this example, the logical AND operator is always at -the end of the lines:

- -
if (this_one_thing > this_other_thing &&
-    a_third_thing == a_fourth_thing &&
-    yet_another && last_one) {
-  ...
-}
-
- -

Note that when the code wraps in this example, both of -the && logical AND operators are at -the end of the line. This is more common in Google code, -though wrapping all operators at the beginning of the -line is also allowed. Feel free to insert extra -parentheses judiciously because they can be very helpful -in increasing readability when used -appropriately. Also note that you should always use -the punctuation operators, such as -&& and ~, rather than -the word operators, such as and and -compl.

- -
- -

Return Values

- -
-

Do not needlessly surround the return -expression with parentheses.

-
- -
- -

Use parentheses in return expr; only -where you would use them in x = expr;.

- -
return result;                  // No parentheses in the simple case.
-// Parentheses OK to make a complex expression more readable.
-return (some_long_condition &&
-        another_condition);
-
- -
return (value);                // You wouldn't write var = (value);
-return(result);                // return is not a function!
-
- -
- - - -

Variable and Array Initialization

- -
-

Your choice of =, (), or -{}.

-
- -
- -

You may choose between =, -(), and {}; the following are -all correct:

- -
int x = 3;
-int x(3);
-int x{3};
-string name = "Some Name";
-string name("Some Name");
-string name{"Some Name"};
-
- -

Be careful when using a braced initialization list {...} -on a type with an std::initializer_list constructor. -A nonempty braced-init-list prefers the -std::initializer_list constructor whenever -possible. Note that empty braces {} are special, and -will call a default constructor if available. To force the -non-std::initializer_list constructor, use parentheses -instead of braces.

- -
vector<int> v(100, 1);  // A vector of 100 1s.
-vector<int> v{100, 1};  // A vector of 100, 1.
-
- -

Also, the brace form prevents narrowing of integral -types. This can prevent some types of programming -errors.

- -
int pi(3.14);  // OK -- pi == 3.
-int pi{3.14};  // Compile error: narrowing conversion.
-
- -
- -

Preprocessor Directives

- -
-

The hash mark that starts a preprocessor directive should -always be at the beginning of the line.

-
- -
- -

Even when preprocessor directives are within the body -of indented code, the directives should start at the -beginning of the line.

- -
// Good - directives at beginning of line
-  if (lopsided_score) {
-#if DISASTER_PENDING      // Correct -- Starts at beginning of line
-    DropEverything();
-# if NOTIFY               // OK but not required -- Spaces after #
-    NotifyClient();
-# endif
-#endif
-    BackToNormal();
-  }
-
- -
// Bad - indented directives
-  if (lopsided_score) {
-    #if DISASTER_PENDING  // Wrong!  The "#if" should be at beginning of line
-    DropEverything();
-    #endif                // Wrong!  Do not indent "#endif"
-    BackToNormal();
-  }
-
- -
- -

Class Format

- -
-

Sections in public, protected and -private order, each indented one space.

-
- -
- -

The basic format for a class declaration (lacking the -comments, see Class -Comments for a discussion of what comments are -needed) is:

- -
class MyClass : public OtherClass {
- public:      // Note the 1 space indent!
-  MyClass();  // Regular 2 space indent.
-  explicit MyClass(int var);
-  ~MyClass() {}
-
-  void SomeFunction();
-  void SomeFunctionThatDoesNothing() {
-  }
-
-  void set_some_var(int var) { some_var_ = var; }
-  int some_var() const { return some_var_; }
-
- private:
-  bool SomeInternalFunction();
-
-  int some_var_;
-  int some_other_var_;
-};
-
- -

Things to note:

- -
    -
  • Any base class name should be on the same line as - the subclass name, subject to the 80-column limit.
  • - -
  • The public:, protected:, - and private: keywords should be indented - one space.
  • - -
  • Except for the first instance, these keywords - should be preceded by a blank line. This rule is - optional in small classes.
  • - -
  • Do not leave a blank line after these - keywords.
  • - -
  • The public section should be first, - followed by the protected and finally the - private section.
  • - -
  • See Declaration - Order for rules on ordering declarations within - each of these sections.
  • -
- -
- -

Constructor Initializer Lists

- -
-

Constructor initializer lists can be all on one line or -with subsequent lines indented four spaces.

-
- -
- -

The acceptable formats for initializer lists are:

- -
// When everything fits on one line:
-MyClass::MyClass(int var) : some_var_(var) {
-  DoSomething();
-}
-
-// If the signature and initializer list are not all on one line,
-// you must wrap before the colon and indent 4 spaces:
-MyClass::MyClass(int var)
-    : some_var_(var), some_other_var_(var + 1) {
-  DoSomething();
-}
-
-// When the list spans multiple lines, put each member on its own line
-// and align them:
-MyClass::MyClass(int var)
-    : some_var_(var),             // 4 space indent
-      some_other_var_(var + 1) {  // lined up
-  DoSomething();
-}
-
-// As with any other code block, the close curly can be on the same
-// line as the open curly, if it fits.
-MyClass::MyClass(int var)
-    : some_var_(var) {}
-
- -
- -

Namespace Formatting

- -
-

The contents of namespaces are not indented.

-
- -
- -

Namespaces do not add an -extra level of indentation. For example, use:

- -
namespace {
-
-void foo() {  // Correct.  No extra indentation within namespace.
-  ...
-}
-
-}  // namespace
-
- -

Do not indent within a namespace:

- -
namespace {
-
-  // Wrong.  Indented when it should not be.
-  void foo() {
-    ...
-  }
-
-}  // namespace
-
- -

When declaring nested namespaces, put each namespace -on its own line.

- -
namespace foo {
-namespace bar {
-
- -
- -

Horizontal Whitespace

- -
-

Use of horizontal whitespace depends on location. Never put -trailing whitespace at the end of a line.

-
- -
- -

General

- -
void f(bool b) {  // Open braces should always have a space before them.
-  ...
-int i = 0;  // Semicolons usually have no space before them.
-// Spaces inside braces for braced-init-list are optional.  If you use them,
-// put them on both sides!
-int x[] = { 0 };
-int x[] = {0};
-
-// Spaces around the colon in inheritance and initializer lists.
-class Foo : public Bar {
- public:
-  // For inline function implementations, put spaces between the braces
-  // and the implementation itself.
-  Foo(int b) : Bar(), baz_(b) {}  // No spaces inside empty braces.
-  void Reset() { baz_ = 0; }  // Spaces separating braces from implementation.
-  ...
-
- -

Adding trailing whitespace can cause extra work for -others editing the same file, when they merge, as can -removing existing trailing whitespace. So: Don't -introduce trailing whitespace. Remove it if you're -already changing that line, or do it in a separate -clean-up -operation (preferably when no-one -else is working on the file).

- -

Loops and Conditionals

- -
if (b) {          // Space after the keyword in conditions and loops.
-} else {          // Spaces around else.
-}
-while (test) {}   // There is usually no space inside parentheses.
-switch (i) {
-for (int i = 0; i < 5; ++i) {
-// Loops and conditions may have spaces inside parentheses, but this
-// is rare.  Be consistent.
-switch ( i ) {
-if ( test ) {
-for ( int i = 0; i < 5; ++i ) {
-// For loops always have a space after the semicolon.  They may have a space
-// before the semicolon, but this is rare.
-for ( ; i < 5 ; ++i) {
-  ...
-
-// Range-based for loops always have a space before and after the colon.
-for (auto x : counts) {
-  ...
-}
-switch (i) {
-  case 1:         // No space before colon in a switch case.
-    ...
-  case 2: break;  // Use a space after a colon if there's code after it.
-
- -

Operators

- -
// Assignment operators always have spaces around them.
-x = 0;
-
-// Other binary operators usually have spaces around them, but it's
-// OK to remove spaces around factors.  Parentheses should have no
-// internal padding.
-v = w * x + y / z;
-v = w*x + y/z;
-v = w * (x + z);
-
-// No spaces separating unary operators and their arguments.
-x = -5;
-++x;
-if (x && !y)
-  ...
-
- -

Templates and Casts

- -
// No spaces inside the angle brackets (< and >), before
-// <, or between >( in a cast
-vector<string> x;
-y = static_cast<char*>(x);
-
-// Spaces between type and pointer are OK, but be consistent.
-vector<char *> x;
-set<list<string>> x;        // Permitted in C++11 code.
-set<list<string> > x;       // C++03 required a space in > >.
-
-// You may optionally use symmetric spacing in < <.
-set< list<string> > x;
-
- -
- -

Vertical Whitespace

- -
-

Minimize use of vertical whitespace.

-
- -
- -

This is more a principle than a rule: don't use blank -lines when you don't have to. In particular, don't put -more than one or two blank lines between functions, -resist starting functions with a blank line, don't end -functions with a blank line, and be discriminating with -your use of blank lines inside functions.

- -

The basic principle is: The more code that fits on one -screen, the easier it is to follow and understand the -control flow of the program. Of course, readability can -suffer from code being too dense as well as too spread -out, so use your judgement. But in general, minimize use -of vertical whitespace.

- -

Some rules of thumb to help when blank lines may be -useful:

- -
    -
  • Blank lines at the beginning or end of a function - very rarely help readability.
  • - -
  • Blank lines inside a chain of if-else blocks may - well help readability.
  • -
- -
- -

Exceptions to the Rules

- -

The coding conventions described above are mandatory. -However, like all good rules, these sometimes have exceptions, -which we discuss here.

- - - -
-

Existing Non-conformant Code

- -
-

You may diverge from the rules when dealing with code that -does not conform to this style guide.

-
- -
- -

If you find yourself modifying code that was written -to specifications other than those presented by this -guide, you may have to diverge from these rules in order -to stay consistent with the local conventions in that -code. If you are in doubt about how to do this, ask the -original author or the person currently responsible for -the code. Remember that consistency includes -local consistency, too.

- -
-
- - - -

Windows Code

- -
-

Windows -programmers have developed their own set of coding -conventions, mainly derived from the conventions in Windows -headers and other Microsoft code. We want to make it easy -for anyone to understand your code, so we have a single set -of guidelines for everyone writing C++ on any platform.

-
- -
-

It is worth reiterating a few of the guidelines that -you might forget if you are used to the prevalent Windows -style:

- -
    -
  • Do not use Hungarian notation (for example, naming - an integer iNum). Use the Google naming - conventions, including the .cc extension - for source files.
  • - -
  • Windows defines many of its own synonyms for - primitive types, such as DWORD, - HANDLE, etc. It is perfectly acceptable, - and encouraged, that you use these types when calling - Windows API functions. Even so, keep as close as you - can to the underlying C++ types. For example, use - const TCHAR * instead of - LPCTSTR.
  • - -
  • When compiling with Microsoft Visual C++, set the - compiler to warning level 3 or higher, and treat all - warnings as errors.
  • - -
  • Do not use #pragma once; instead use - the standard Google include guards. The path in the - include guards should be relative to the top of your - project tree.
  • - -
  • In fact, do not use any nonstandard extensions, - like #pragma and __declspec, - unless you absolutely must. Using - __declspec(dllimport) and - __declspec(dllexport) is allowed; however, - you must use them through macros such as - DLLIMPORT and DLLEXPORT, so - that someone can easily disable the extensions if they - share the code.
  • -
- -

However, there are just a few rules that we -occasionally need to break on Windows:

- -
    -
  • Normally we forbid - the use of multiple implementation inheritance; - however, it is required when using COM and some ATL/WTL - classes. You may use multiple implementation - inheritance to implement COM or ATL/WTL classes and - interfaces.
  • - -
  • Although you should not use exceptions in your own - code, they are used extensively in the ATL and some - STLs, including the one that comes with Visual C++. - When using the ATL, you should define - _ATL_NO_EXCEPTIONS to disable exceptions. - You should investigate whether you can also disable - exceptions in your STL, but if not, it is OK to turn on - exceptions in the compiler. (Note that this is only to - get the STL to compile. You should still not write - exception handling code yourself.)
  • - -
  • The usual way of working with precompiled headers - is to include a header file at the top of each source - file, typically with a name like StdAfx.h - or precompile.h. To make your code easier - to share with other projects, avoid including this file - explicitly (except in precompile.cc), and - use the /FI compiler option to include the - file automatically.
  • - -
  • Resource headers, which are usually named - resource.h and contain only macros, do not - need to conform to these style guidelines.
  • -
- -
- - - -

Use common sense and BE CONSISTENT.

- -

If you are editing code, take a few minutes to look at the -code around you and determine its style. If they use spaces -around their if clauses, you should, too. If their -comments have little boxes of stars around them, make your -comments have little boxes of stars around them too.

- -

The point of having style guidelines is to have a common -vocabulary of coding so people can concentrate on what you are -saying, rather than on how you are saying it. We present global -style rules here so people know the vocabulary. But local style -is also important. If code you add to a file looks drastically -different from the existing code around it, the discontinuity -throws readers out of their rhythm when they go to read it. Try -to avoid this.

- - - -

OK, enough writing about writing code; the code itself is much -more interesting. Have fun!

- -
- -
-
- - diff --git a/cppguide.xml b/cppguide.xml deleted file mode 100644 index 8efc102..0000000 --- a/cppguide.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - Redirecting - - - - Redirecting you to cppguide.html. - - diff --git a/docguide/README.md b/docguide/README.md deleted file mode 100644 index 39fe2ec..0000000 --- a/docguide/README.md +++ /dev/null @@ -1,10 +0,0 @@ -# Google documentation guide - -* [Markdown styleguide](style.md) -* [Best practices](best_practices.md) -* [README files](READMEs.md) -* [Philosophy](philosophy.md) - -## See also - -* [How to update this guide](https://goto.google.com/doc-guide), for Googlers. diff --git a/docguide/READMEs.md b/docguide/READMEs.md deleted file mode 100644 index 5854af2..0000000 --- a/docguide/READMEs.md +++ /dev/null @@ -1,69 +0,0 @@ -# README.md files - -About README.md files. - -1. [Overview](#overview) -1. [Guidelines](#guidelines) -1. [Filename](#filename) -1. [Contents](#contents) -1. [Example](#example) - -## Overview - -`README.md` files are Markdown files that describe a directory. -GitHub and Gitiles renders it when you browse the directory. - -For example, the file /README.md is rendered when you view the contents of the -containing directory: - -https://github.com/google/styleguide/tree/gh-pages - -Also `README.md` at `HEAD` ref is rendered by Gitiles when displaying repository -index: - -https://gerrit.googlesource.com/gitiles/ - -## Guidelines - -**`README.md` files are intended to provide orientation for engineers browsing -your code, especially first-time users.** The `README.md` is likely the first -file a reader encounters when they browse a directory that -contains your code. In this way, it acts as a landing page for the directory. - -We recommend that top-level directories for your code have an up-to-date -`README.md` file. This is especially important for package directories that -provide interfaces for other teams. - -### Filename - -Use `README.md`. - -Files named `README` are not displayed in the directory view in Gitiles. - -### Contents - -At minimum, every package-level `README.md` should include or point to the -following information: - -1. **What** is in this package/library and what's it used for. -2. **Who** to contact. -3. **Status**: whether this package/library is deprecated, or not for general - release, etc. -4. **More info**: where to go for more detailed documentation, such as: - * An overview.md file for more detailed conceptual information. - * Any API documentation for using this package/library. - -## Example - -```markdown -# APIs - -This is the top-level directory for all externally-visible APIs, plus some -private APIs under `internal/` directories. -See [API Style Guide](docs/apistyle.md) for more information. - -*TL;DR*: API definitions and configurations should be defined in `.proto` files, -checked into `apis/`. - -... -``` diff --git a/docguide/VERSION b/docguide/VERSION deleted file mode 100644 index d3827e7..0000000 --- a/docguide/VERSION +++ /dev/null @@ -1 +0,0 @@ -1.0 diff --git a/docguide/best_practices.md b/docguide/best_practices.md deleted file mode 100644 index 97f7a09..0000000 --- a/docguide/best_practices.md +++ /dev/null @@ -1,115 +0,0 @@ -# Documentation Best Practices - -"Say what you mean, simply and directly." - [Brian Kernighan] -(http://en.wikipedia.org/wiki/The_Elements_of_Programming_Style) - -Contents: - -1. [Minimum viable documentation](#minimum-viable-documentation) -1. [Update docs with code](#update-docs-with-code) -1. [Delete dead documentation](#delete-dead-documentation) -1. [Documentation is the story of your code](#documentation-is-the-story-of-your-code) - -## Minimum viable documentation - -A small set of fresh and accurate docs are better than a sprawling, loose -assembly of "documentation" in various states of disrepair. - -Write short and useful documents. Cut out everything unnecessary, while also -making a habit of continually massaging and improving every doc to suit your -changing needs. **Docs work best when they are alive but frequently trimmed, -like a bonsai tree**. - -This guide encourages engineers to take ownership of their docs and keep -them up to date with the same zeal we keep our tests in good order. Strive for -this. - -* Identify what you really need: release docs, API docs, testing guidelines. -* Delete cruft frequently and in small batches. - -## Update docs with code - -**Change your documentation in the same CL as the code change**. This keeps your -docs fresh, and is also a good place to explain to your reviewer what you're -doing. - -A good reviewer can at least insist that docstrings, header files, README.md -files, and any other docs get updated alongside the CL. - -## Delete dead documentation - -Dead docs are bad. They misinform, they slow down, they incite despair in -engineers and laziness in team leads. They set a precedent for leaving behind -messes in a code base. If your home is clean, most guests will be clean without -being asked. - -Just like any big cleaning project, **it's easy to be overwhelmed**. If your -docs are in bad shape: - -* Take it slow, doc health is a gradual accumulation. -* First delete what you're certain is wrong, ignore what's unclear. -* Get your whole team involved. Devote time to quickly scan every doc and make - a simple decision: Keep or delete? -* Default to delete or leave behind if migrating. Stragglers can always be - recovered. -* Iterate. - -## Prefer the good over the perfect - -Your documentation should be as good as possible within a reasonable time frame. -The standards for an documentation review are different from the -standards for code reviews. Reviewers can and should ask for improvements, but -in general, the author should always be able to invoke the "Good Over Perfect -Rule". It's preferable to allow authors to quickly submit changes that improve -the document, instead of forcing rounds of review until it's "perfect". Docs are -never perfect, and tend to gradually improve as the team learns what they really -need to write down. - -## Documentation is the story of your code - -Writing excellent code doesn't end when your code compiles or even if your -test coverage reaches 100%. It's easy to write something a computer understands, -it's much harder to write something both a human and a computer understand. Your -mission as a Code Health-conscious engineer is to **write for humans first, -computers second.** Documentation is an important part of this skill. - -There's a spectrum of engineering documentation that ranges from terse comments -to detailed prose: - -1. **Inline comments**: The primary purpose of inline comments is to provide - information that the code itself cannot contain, such as why the code is - there. - -2. **Method and class comments**: - - * **Method API documentation**: The header / Javadoc / docstring - comments that say what methods do and how to use them. This - documentation is **the contract of how your code must behave**. The - intended audience is future programmers who will use and modify your - code. - - It is often reasonable to say that any behavior documented here should - have a test verifying it. This documentation details what arguments the - method takes, what it returns, any "gotchas" or restrictions, and what - exceptions it can throw or errors it can return. It does not usually - explain why code behaves a particular way unless that's relevant to a - developer's understanding of how to use the method. "Why" explanations - are for inline comments. Think in practical terms when writing method - documentation: "This is a hammer. You use it to pound nails." - - * **Class / Module API documentation**: The header / Javadoc / docstring - comments for a class or a whole file. This documentation gives a brief - overview of what the class / file does and often gives a few short - examples of how you might use the class / file. - - Examples are particularly relevant when there's several distinct ways to - use the class (some advanced, some simple). Always list the simplest - use case first. - -3. **README.md**: A good README.md orients the new user to the directory and - points to more detailed explanation and user guides: - * What is this directory intended to hold? - * Which files should the developer look at first? Are some files an API? - * Who maintains this directory and where I can learn more? - - See the [README.md guidelines](READMEs.md). diff --git a/docguide/philosophy.md b/docguide/philosophy.md deleted file mode 100644 index 0937c5b..0000000 --- a/docguide/philosophy.md +++ /dev/null @@ -1,71 +0,0 @@ -# Philosophy - -埏埴以為器,當其無,有器之用. - -*Clay becomes pottery through craft, but it's the emptiness that makes a pot -useful.* - -\- [Laozi](http://ctext.org/dictionary.pl?if=en&id=11602) - -Contents: - -1. [Radical simplicity](#radical-simplicity) -1. [Readable source text](#readable-source-text) -1. [Minimum viable documentation](#minimum-viable-documentation) -1. [Better is better than perfect](#better-is-better-than-perfect) - -## Radical simplicity - -* **Scalability and interoperability** are more important than a menagerie of - unessential features. Scale comes from simplicity, speed, and ease. - Interoperability comes from unadorned, digestable content. - -* **Fewer distractions** make for better writing and more productive reading. - -* **New features should never interfere with the simplest use case** and should - remain invisible to users who don't need them. - -* **This guide is designed for the average engineer** -- the busy, - just-want-to-go-back-to-coding engineer. Large and complex documentation is - possible but not the primary focus. - -* **Minimizing context switching makes people happier.** Engineers should be - able to interact with documentation using the same tools they use to read and - write code. - -## Readable source text - -* **Plain text not only suffices, it is superior**. Markdown itself is not - essential to this formula, but it is the best and most widely supported - solution right now. HTML is generally not encouraged. - -* **Content and presentation should not mingle**. It should always be possible - to ditch the renderer and read the essential information at source. Users - should never have to touch the presentation layer if they don't want to. - -* **Portability and future-proofing leave room for the unimagined integrations - to come**, and are best achieved by keeping the source as human-readable as - possible. - -* **Static content is better than dynamic**, because content should not depend - on the features of any one server. However, **fresh is better than stale**. We - strive to balance these needs. - -## Minimum viable documentation - -* **Docs thrive when they're treated like tests**: a necessary chore one learns - to savor because it rewards over time. - See [Best Practices](best_practices.md). - -* **Brief and utilitarian is better than long and exhaustive**. The vast - majority of users need only a small fraction of the author's total knowledge, - but they need it quickly and often. - -## Better is better than perfect - -* **Incremental improvement is better than prolonged debate**. Patience and - tolerance of imperfection allow projects to evolve organically. - -* **Don't lick the cookie, pass the plate**. We're drowning in potentially - impactful projects. Choose only those you can really handle and release those - you can't. diff --git a/docguide/style.md b/docguide/style.md deleted file mode 100644 index ba29925..0000000 --- a/docguide/style.md +++ /dev/null @@ -1,420 +0,0 @@ -# Markdown style guide - -Much of what makes Markdown great is the ability to write plain text, and get -great formatted output as a result. To keep the slate clean for the next author, -your Markdown should be simple and consistent with the whole corpus wherever -possible. - -We seek to balance three goals: - -1. *Source text is readable and portable.* -2. *Markdown files are maintainable over time and across teams.* -3. *The syntax is simple and easy to remember.* - -Contents: - -1. [Document layout](#document-layout) -1. [Character line limit](#character-line-limit) -1. [Trailing whitespace](#trailing-whitespace) -1. [Headings](#headings) - 1. [ATX-style headings](#atx-style-headings) - 1. [Add spacing to headings](#add-spacing-to-headings) -1. [Lists](#lists) - 1. [Use lazy numbering for long lists](#use-lazy-numbering-for-long-lists) - 1. [Nested list spacing](#nested-list-spacing) -1. [Code](#code) - 1. [Inline](#inline) - 1. [Codeblocks](#codeblocks) - 1. [Declare the language](#declare-the-language) - 1. [Escape newlines](#escape-newlines) - 1. [Nest codeblocks within lists](#nest-codeblocks-within-lists) -1. [Links](#links) - 1. [Use informative Markdown link titles](#use-informative-markdown-link-titles) -1. [Images](#images) -1. [Prefer lists to tables](#prefer-lists-to-tables) -1. [Strongly prefer Markdown to HTML](#strongly-prefer-markdown-to-html) - -## Document layout - -In general, most documents benefit from some variation of the following layout: - -```markdown -# Document Title - -Short introduction. - -[TOC] - -## Topic - -Content. - -## See also - -* https://link-to-more-info -``` - -1. `# Document Title`: The first heading should be a level one heading, and - should ideally be the same or nearly the same as the filename. The first - level one heading is used as the page ``. - -1. `author`: *Optional*. If you'd like to claim ownership of the document or - if you are very proud of it, add yourself under the title. However, - revision history generally suffices. - -1. `Short introduction.` 1-3 sentences providing a high-level overview of the - topic. Imagine yourself as a complete newbie, who landed on your "Extending - Foo" doc and needs to know the most basic assumptions you take for granted. - "What is Foo? Why would I extend it?" - -1. `[TOC]`: if you use hosting that supports table of contents, such as Gitiles, - put `[TOC]` after the short introduction. See - [`[TOC]` documentation](https://gerrit.googlesource.com/gitiles/+/master/Documentation/markdown.md#Table-of-contents). - -1. `## Topic`: The rest of your headings should start from level 2. - -1. `## See also`: Put miscellaneous links at the bottom for the user who wants - to know more or didn't find what she needed. - -## Character line limit - -Obey projects' character line limit wherever possible. Long URLs and tables are -the usual suspects when breaking the rule. (Headings also can't be wrapped, but -we encourage keeping them short). Otherwise, wrap your text: - -```markdown -Lorem ipsum dolor sit amet, nec eius volumus patrioque cu, nec et commodo -hendrerit, id nobis saperet fuisset ius. - -* Malorum moderatius vim eu. In vix dico persecuti. Te nam saperet percipitur - interesset. See the [foo docs](https://gerrit.googlesource.com/gitiles/+/master/Documentation/markdown.md). -``` - -Often, inserting a newline before a long link preserves readability while -minimizing the overflow: - -```markdown -Lorem ipsum dolor sit amet. See the -[foo docs](https://gerrit.googlesource.com/gitiles/+/master/Documentation/markdown.md) -for details. -``` - -## Trailing whitespace - -Don't use trailing whitespace, use a trailing backslash. - -The [CommonMark spec](http://spec.commonmark.org/0.20/#hard-line-breaks) decrees -that two spaces at the end of a line should insert a `<br />` tag. However, many -directories have a trailing whitespace presubmit check in place, and many IDEs -will clean it up anyway. - -Best practice is to avoid the need for a `<br />` altogether. Markdown creates -paragraph tags for you simply with newlines: get used to that. - -## Headings - -### ATX-style headings - -```markdown -## Heading 2 -``` - -Headings with `=` or `-` underlines can be annoying to maintain and don't fit -with the rest of the heading syntax. The user has to ask: Does `---` mean H1 or -H2? - -```markdown -Heading - do you remember what level? DO NOT DO THIS. ---------- -``` - -### Add spacing to headings - -Prefer spacing after `#` and newlines before and after: - -```markdown -...text before. - -# Heading 1 - -Text after... -``` - -Lack of spacing makes it a little harder to read in source: - -```markdown -...text before. - -#Heading 1 -Text after... DO NOT DO THIS. -``` - -## Lists - -### Use lazy numbering for long lists - -Markdown is smart enough to let the resulting HTML render your numbered lists -correctly. For longer lists that may change, especially long nested lists, use -"lazy" numbering: - -```markdown -1. Foo. -1. Bar. - 1. Foofoo. - 1. Barbar. -1. Baz. -``` - -However, if the list is small and you don't anticipate changing it, prefer fully -numbered lists, because it's nicer to read in source: - -```markdown -1. Foo. -2. Bar. -3. Baz. -``` - -### Nested list spacing - -When nesting lists, use a 4 space indent for both numbered and bulleted lists: - -```markdown -1. 2 spaces after a numbered list. - 4 space indent for wrapped text. -2. 2 spaces again. - -* 3 spaces after a bullet. - 4 space indent for wrapped text. - 1. 2 spaces after a numbered list. - 8 space indent for the wrapped text of a nested list. - 2. Looks nice, don't it? -* 3 spaces after a bullet. -``` - -The following works, but it's very messy: - -```markdown -* One space, -with no indent for wrapped text. - 1. Irregular nesting... DO NOT DO THIS. -``` - -Even when there's no nesting, using the 4 space indent makes layout consistent -for wrapped text: - -```markdown -* Foo, - wrapped. - -1. 2 spaces - and 4 space indenting. -2. 2 spaces again. -``` - -However, when lists are small, not nested, and a single line, one space can -suffice for both kinds of lists: - -```markdown -* Foo -* Bar -* Baz. - -1. Foo. -2. Bar. -``` - -## Code - -### Inline - -`Backticks` designate `inline code`, and will render all wrapped content -literally. Use them for short code quotations and field names: - -```markdown -You'll want to run `really_cool_script.sh arg`. - -Pay attention to the `foo_bar_whammy` field in that table. -``` - -Use inline code when referring to file types in an abstract sense, rather than a -specific file: - -```markdown -Be sure to update your `README.md`! -``` - -Backticks are the most common approach for "escaping" Markdown metacharacters; -in most situations where escaping would be needed, code font just makes sense -anyway. - -### Codeblocks - -For code quotations longer than a single line, use a codeblock: - -<pre> -```python -def Foo(self, bar): - self.bar = bar -``` -</pre> - -#### Declare the language - -It is best practice to explicitly declare the language, so that neither the -syntax highlighter nor the next editor must guess. - -#### Indented codeblocks are sometimes cleaner - -Four-space indenting is also interpreted as a codeblock. These can look -cleaner and be easier to read in source, but there is no way to specify the -language. We encourage their use when writing many short snippets: - -```markdown -You'll need to run: - - bazel run :thing -- --foo - -And then: - - bazel run :another_thing -- --bar - -And again: - - bazel run :yet_again -- --baz -``` - -#### Escape newlines - -Because most commandline snippets are intended to be copied and pasted directly -into a terminal, it's best practice to escape any newlines. Use a single -backslash at the end of the line: - -<pre> -```shell -bazel run :target -- --flag --foo=longlonglonglonglongvalue \ ---bar=anotherlonglonglonglonglonglonglonglonglonglongvalue -``` -</pre> - -#### Nest codeblocks within lists - -If you need a codeblock within a list, make sure to indent it so as to not break -the list: - -```markdown -* Bullet. - - ```c++ - int foo; - ``` - -* Next bullet. -``` - -You can also create a nested code block with 4 spaces. Simply indent 4 -additional spaces from the list indentation: - -```markdown -* Bullet. - - int foo; - -* Next bullet. -``` - -## Links - -Long links make source Markdown difficult to read and break the 80 character -wrapping. **Wherever possible, shorten your links**. - -### Use informative Markdown link titles - -Markdown link syntax allows you to set a link title, just as HTML does. Use it -wisely. - -Titling your links as "link" or "here" tells the reader precisely nothing when -quickly scanning your doc and is a waste of space: - -```markdown -See the syntax guide for more info: [link](syntax_guide.md). -Or, check out the style guide [here](style_guide.md). -DO NOT DO THIS. -``` - -Instead, write the sentence naturally, then go back and wrap the most -appropriate phrase with the link: - -```markdown -See the [syntax guide](syntax_guide.md) for more info. -Or, check out the [style guide](style_guide.md). -``` - -## Images - -Use images sparingly, and prefer simple screenshots. This guide is designed -around the idea that plain text gets users down to the business of communication -faster with less reader distraction and author procrastination. However, it's -sometimes very helpful to show what you mean. - -See [image syntax](https://gerrit.googlesource.com/gitiles/+/master/Documentation/markdown.md#Images). - -## Prefer lists to tables - -Any tables in your Markdown should be small. Complex, large tables are difficult -to read in source and most importantly, **a pain to modify later**. - -```markdown -Fruit | Attribute | Notes ---- | --- | --- | --- -Apple | [Juicy](http://example.com/SomeReallyReallyReallyReallyReallyReallyReallyReallyLongQuery), Firm, Sweet | Apples keep doctors away. -Banana | [Convenient](http://example.com/SomeDifferentReallyReallyReallyReallyReallyReallyReallyReallyLongQuery), Soft, Sweet | Contrary to popular belief, most apes prefer mangoes. - -DO NOT DO THIS -``` - -[Lists](#lists) and subheadings usually suffice to present the same information -in a slightly less compact, though much more edit-friendly way: - -```markdown -## Fruits - -### Apple - -* [Juicy](http://SomeReallyReallyReallyReallyReallyReallyReallyReallyReallyReallyReallyReallyReallyReallyReallyReallyLongURL) -* Firm -* Sweet - -Apples keep doctors away. - -### Banana - -* [Convenient](http://example.com/SomeDifferentReallyReallyReallyReallyReallyReallyReallyReallyLongQuery) -* Soft -* Sweet - -Contrary to popular belief, most apes prefer mangoes. -``` - -However, there are times when a small table is called for: - -```markdown -Transport | Favored by | Advantages ---- | --- | --- -Swallow | Coconuts | Otherwise unladen -Bicycle | Miss Gulch | Weatherproof -X-34 landspeeder | Whiny farmboys | Cheap since the X-38 came out -``` - -## Strongly prefer Markdown to HTML - -Please prefer standard Markdown syntax wherever possible and avoid HTML hacks. -If you can't seem to accomplish what you want, reconsider whether you really -need it. Except for [big tables](#prefer-lists-to-tables), Markdown meets almost -all needs already. - -Every bit of HTML or Javascript hacking reduces the readability and portability. -This in turn limits the usefulness of integrations with -other tools, which may either present the source as plain text or render it. See -[Philosophy](philosophy.md). - -Gitiles does not render HTML. diff --git a/eclipse-cpp-google-style.xml b/eclipse-cpp-google-style.xml deleted file mode 100644 index aa05a81..0000000 --- a/eclipse-cpp-google-style.xml +++ /dev/null @@ -1,167 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<profiles version="1"> -<profile kind="CodeFormatterProfile" name="Google C++" version="1"> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_new_line_in_empty_block" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.lineSplit" value="80"/> -<setting id="org.eclipse.cdt.core.formatter.alignment_for_member_access" value="16"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_base_types" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.keep_else_statement_on_same_line" value="false"/> -<setting id="org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/> -<setting id="org.eclipse.cdt.core.formatter.alignment_for_constructor_initializer_list" value="83"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_exception_specification" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_base_types" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_access_specifier" value="true"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_exception_specification" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_arguments" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_colon_in_case" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.comment.min_distance_between_code_and_line_comment" value="2"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_declarator_list" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_bracket" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.tabulation.size" value="2"/> -<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.alignment_for_enumerator_list" value="51"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.alignment_for_declarator_list" value="16"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.indent_empty_lines" value="false"/> -<setting id="org.eclipse.cdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/> -<setting id="org.eclipse.cdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.put_empty_statement_on_new_line" value="true"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_semicolon" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_arguments" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_base_clause" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.indent_breaks_compare_to_cases" value="true"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.join_wrapped_lines" value="true"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_declarator_list" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.alignment_for_arguments_in_method_invocation" value="18"/> -<setting id="org.eclipse.cdt.core.formatter.comment.never_indent_line_comments_on_first_column" value="true"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_brackets" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_bracket" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.alignment_for_parameters_in_method_declaration" value="18"/> -<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_closing_brace_in_array_initializer" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.number_of_empty_lines_to_preserve" value="1"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.brace_position_for_block" value="end_of_line"/> -<setting id="org.eclipse.cdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="true"/> -<setting id="org.eclipse.cdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_assignment_operator" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_arguments" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_expression_list" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_parameters" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.continuation_indentation" value="2"/> -<setting id="org.eclipse.cdt.core.formatter.alignment_for_expression_list" value="0"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_parameters" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_binary_operator" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.alignment_for_conditional_expression" value="34"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.format_guardian_clause_on_one_line" value="false"/> -<setting id="org.eclipse.cdt.core.formatter.indent_access_specifier_extra_spaces" value="1"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.indent_access_specifier_compare_to_type_header" value="false"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.indent_body_declarations_compare_to_namespace_header" value="false"/> -<setting id="org.eclipse.cdt.core.formatter.alignment_for_compact_if" value="0"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_assignment_operator" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.alignment_for_assignment" value="16"/> -<setting id="org.eclipse.cdt.core.formatter.alignment_for_conditional_expression_chain" value="18"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_template_parameters" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_expression_list" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_exception_specification" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_binary_operator" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_identifier_in_function_declaration" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.alignment_for_base_clause_in_type_declaration" value="16"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_between_empty_parens_in_exception_specification" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.indent_declaration_compare_to_template_header" value="false"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.indent_statements_compare_to_body" value="true"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.alignment_for_binary_expression" value="16"/> -<setting id="org.eclipse.cdt.core.formatter.indent_statements_compare_to_block" value="true"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_template_arguments" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_angle_bracket_in_template_parameters" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.tabulation.char" value="space"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_parameters" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_colon_in_constructor_initializer_list" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/> -<setting id="org.eclipse.cdt.core.formatter.compact_else_if" value="true"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_new_line_after_template_declaration" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_colon_in_base_clause" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.keep_then_statement_on_same_line" value="false"/> -<setting id="org.eclipse.cdt.core.formatter.brace_position_for_switch" value="end_of_line"/> -<setting id="org.eclipse.cdt.core.formatter.alignment_for_overloaded_left_shift_chain" value="18"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.keep_imple_if_on_one_line" value="false"/> -<setting id="org.eclipse.cdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.indentation.size" value="2"/> -<setting id="org.eclipse.cdt.core.formatter.brace_position_for_namespace_declaration" value="end_of_line"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_angle_bracket_in_template_arguments" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_brace_in_namespace_declaration" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_closing_bracket" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_closing_angle_bracket_in_template_parameters" value="insert"/> -<setting id="org.eclipse.cdt.core.formatter.insert_space_after_opening_angle_bracket_in_template_arguments" value="do not insert"/> -</profile> -</profiles> diff --git a/eclipse-java-google-style.xml b/eclipse-java-google-style.xml deleted file mode 100644 index 08d930a..0000000 --- a/eclipse-java-google-style.xml +++ /dev/null @@ -1,337 +0,0 @@ -<?xml version="1.0" encoding="UTF-8" standalone="no"?> -<profiles version="13"> -<profile kind="CodeFormatterProfile" name="GoogleStyle" version="13"> -<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_before_root_tags" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.disabling_tag" value="@formatter:off"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_annotation" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_parameters" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_type_declaration" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_arguments" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.brace_position_for_anonymous_type_declaration" value="end_of_line"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_case" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_brace_in_array_initializer" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_block_boundaries" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_cascading_method_invocation_with_arguments.count_dependent" value="16|-1|16"/> -<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_annotation_declaration" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_annotation" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_field" value="0"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_while" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.use_on_off_tags" value="false"/> -<setting id="org.eclipse.jdt.core.formatter.wrap_prefer_two_fragments" value="false"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_annotation_type_member_declaration" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_else_in_if_statement" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_prefix_operator" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.keep_else_statement_on_same_line" value="false"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_ellipsis" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.comment.insert_new_line_for_parameter" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.wrap_comment_inline_tags" value="false"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_annotation_type_declaration" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.indent_breaks_compare_to_cases" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_local_variable_declaration" value="16"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields" value="16"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter" value="1040"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer" value="16"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type.count_dependent" value="1585|-1|1585"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_conditional_expression" value="80"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_for" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_multiple_fields.count_dependent" value="16|-1|16"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_binary_operator" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_wildcard" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.brace_position_for_array_initializer" value="end_of_line"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_enum_constant" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_finally_in_try_statement" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_local_variable" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_catch_in_try_statement" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_while" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_package" value="1"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression.count_dependent" value="16|4|80"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration.count_dependent" value="16|4|48"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_type_parameters" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.continuation_indentation" value="2"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration.count_dependent" value="16|4|49"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_postfix_operator" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation" value="16"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_arguments" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_superinterfaces" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_new_chunk" value="1"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_binary_operator" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_package" value="0"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_cascading_method_invocation_with_arguments" value="16"/> -<setting id="org.eclipse.jdt.core.compiler.source" value="1.7"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration.count_dependent" value="16|4|48"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_constant_arguments" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_constructor_declaration" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.comment.format_line_comments" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_arguments" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_enum_declarations" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.join_wrapped_lines" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_block" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call" value="16"/> -<setting id="org.eclipse.jdt.core.formatter.wrap_non_simple_local_variable_annotation" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_invocation_arguments" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.align_type_members_on_columns" value="false"/> -<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_member_type" value="0"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_enum_constant" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants.count_dependent" value="16|5|48"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_for" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_method_declaration" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation" value="16"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_switch" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_unary_operator" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_case" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.comment.indent_parameter_description" value="false"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_declaration" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_switch" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_declaration" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_parameters" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_block_comment" value="false"/> -<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_type_declaration" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.lineSplit" value="100"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_if" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_selector_in_method_invocation.count_dependent" value="16|4|48"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_between_brackets_in_array_type_reference" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_parenthesized_expression" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_explicitconstructorcall_arguments" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_constructor_declaration" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_first_class_body_declaration" value="0"/> -<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_method" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.indentation.size" value="4"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_declaration" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.enabling_tag" value="@formatter:on"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_enum_constant" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package" value="1585"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_superclass_in_type_declaration" value="16"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_assignment" value="16"/> -<setting id="org.eclipse.jdt.core.compiler.problem.assertIdentifier" value="error"/> -<setting id="org.eclipse.jdt.core.formatter.tabulation.char" value="space"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_try_resources" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_parameters" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_prefix_operator" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_body" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_method" value="1"/> -<setting id="org.eclipse.jdt.core.formatter.wrap_outer_expressions_when_nested" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.wrap_non_simple_type_annotation" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.format_guardian_clause_on_one_line" value="false"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_for" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_field_declaration" value="16"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_cast" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration" value="16"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_labeled_statement" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.brace_position_for_annotation_type_declaration" value="end_of_line"/> -<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_method_body" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_method_declaration" value="0"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_try" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_method_invocation" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_allocation_expression" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_enum_constant" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_annotation" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_at_in_annotation_type_declaration" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_throws" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_if" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.brace_position_for_switch" value="end_of_line"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_throws" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_return" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_conditional" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_question_in_wildcard" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_try" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_allocation_expression" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.comment.preserve_white_space_between_code_and_line_comments" value="false"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_parenthesized_expression_in_throw" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_type_arguments" value="do not insert"/> -<setting id="org.eclipse.jdt.core.compiler.problem.enumIdentifier" value="error"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_generic_type_arguments" value="16"/> -<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_switch" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.comment_new_line_at_start_of_html_paragraph" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_ellipsis" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block" value="end_of_line"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comment_prefix" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_inits" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.brace_position_for_method_declaration" value="end_of_line"/> -<setting id="org.eclipse.jdt.core.formatter.compact_else_if" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.wrap_non_simple_parameter_annotation" value="false"/> -<setting id="org.eclipse.jdt.core.formatter.wrap_before_or_operator_multicatch" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_array_initializer" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_increments" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method" value="1585"/> -<setting id="org.eclipse.jdt.core.formatter.format_line_comment_starting_on_first_column" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_bracket_in_array_reference" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_field" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.comment.indent_root_tags" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_constant" value="end_of_line"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_declarations" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_union_type_in_multicatch" value="16"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_explicitconstructorcall_arguments" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_switch" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_method_declaration_parameters" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_superinterfaces" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_allocation_expression" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.tabulation.size" value="2"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_type_reference" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_opening_brace_in_array_initializer" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_brace_in_block" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_reference" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_constant" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_arguments" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_constructor_declaration" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_throws" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_if" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_method_invocation.count_dependent" value="16|5|80"/> -<setting id="org.eclipse.jdt.core.formatter.comment.clear_blank_lines_in_javadoc_comment" value="false"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_parameter.count_dependent" value="1040|-1|1040"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_constructor_declaration" value="16"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_assignment_operator" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_assignment_operator" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_package.count_dependent" value="1585|-1|1585"/> -<setting id="org.eclipse.jdt.core.formatter.indent_empty_lines" value="false"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_synchronized" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_paren_in_cast" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_declaration_parameters" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.force_if_else_statement_brace" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.brace_position_for_block_in_case" value="end_of_line"/> -<setting id="org.eclipse.jdt.core.formatter.number_of_empty_lines_to_preserve" value="3"/> -<setting id="org.eclipse.jdt.core.formatter.wrap_non_simple_package_annotation" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_declaration" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_catch" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_constructor_declaration" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_method_invocation" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_bracket_in_array_reference" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_qualified_allocation_expression" value="16"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation.count_dependent" value="16|-1|16"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_and_in_type_parameter" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_type" value="1585"/> -<setting id="org.eclipse.jdt.core.compiler.compliance" value="1.7"/> -<setting id="org.eclipse.jdt.core.formatter.continuation_indentation_for_array_initializer" value="2"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_brackets_in_array_allocation_expression" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_at_in_annotation_type_declaration" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression" value="16"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_cast" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_unary_operator" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_new_anonymous_class" value="20"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_parameterized_type_reference" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable.count_dependent" value="1585|-1|1585"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_anonymous_type_declaration" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.keep_empty_array_initializer_on_one_line" value="false"/> -<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_enum_declaration" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field.count_dependent" value="1585|-1|1585"/> -<setting id="org.eclipse.jdt.core.formatter.keep_imple_if_on_one_line" value="false"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_constructor_declaration_parameters" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_closing_angle_bracket_in_type_parameters" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_labeled_statement" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_new_line_at_end_of_file_if_missing" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_for" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_parameterized_type_reference" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_constructor_declaration.count_dependent" value="16|5|80"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration" value="16"/> -<setting id="org.eclipse.jdt.core.formatter.brace_position_for_enum_declaration" value="end_of_line"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression" value="16"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_while" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_type" value="insert"/> -<setting id="org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode" value="enabled"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_try" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.put_empty_statement_on_new_line" value="false"/> -<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_label" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_parameter" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_type_parameters" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_method_invocation" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.comment.format_javadoc_comments" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant" value="16"/> -<setting id="org.eclipse.jdt.core.formatter.insert_new_line_before_while_in_do_statement" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_enum_constant.count_dependent" value="16|-1|16"/> -<setting id="org.eclipse.jdt.core.formatter.comment.line_length" value="100"/> -<setting id="org.eclipse.jdt.core.formatter.insert_new_line_after_annotation_on_package" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_import_groups" value="1"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_enum_constant_arguments" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.brace_position_for_constructor_declaration" value="end_of_line"/> -<setting id="org.eclipse.jdt.core.formatter.number_of_blank_lines_at_beginning_of_method_body" value="0"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_conditional" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_type_header" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_annotation_type_member_declaration" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.wrap_before_binary_operator" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.blank_lines_between_type_declarations" value="2"/> -<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_declaration_header" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_synchronized" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_enum_declaration" value="16"/> -<setting id="org.eclipse.jdt.core.formatter.indent_statements_compare_to_block" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.join_lines_in_comments" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_question_in_conditional" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_field_declarations" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_compact_if" value="16"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_for_inits" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.indent_switchstatements_compare_to_cases" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_array_initializer" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_default" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_and_in_type_parameter" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_parens_in_constructor_declaration" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.blank_lines_before_imports" value="0"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_assert" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_field" value="1585"/> -<setting id="org.eclipse.jdt.core.formatter.comment.format_html" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_throws_clause_in_method_declaration" value="16"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_angle_bracket_in_type_parameters" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_bracket_in_array_allocation_expression" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_anonymous_type_declaration" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_colon_in_conditional" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_for" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_expressions_in_array_initializer.count_dependent" value="16|5|80"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_postfix_operator" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.comment.format_source_code" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_synchronized" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_allocation_expression" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_constructor_declaration_throws" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration" value="16"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_brace_in_array_initializer" value="do not insert"/> -<setting id="org.eclipse.jdt.core.compiler.codegen.targetPlatform" value="1.7"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_resources_in_try" value="80"/> -<setting id="org.eclipse.jdt.core.formatter.use_tabs_only_for_leading_indentations" value="false"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_annotation" value="16"/> -<setting id="org.eclipse.jdt.core.formatter.comment.format_header" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.comment.format_block_comments" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_enum_constant" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_enum_constants" value="0"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_parenthesized_expression" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_annotation_declaration_header" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.insert_new_line_in_empty_block" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_parenthesized_expression" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_catch" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_multiple_local_declarations" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_superinterfaces_in_type_declaration.count_dependent" value="16|4|48"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_switch" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_comma_in_for_increments" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_method.count_dependent" value="1585|-1|1585"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_invocation" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_colon_in_assert" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.brace_position_for_type_declaration" value="end_of_line"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_brace_in_array_initializer" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_between_empty_braces_in_array_initializer" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_binary_expression.count_dependent" value="16|-1|16"/> -<setting id="org.eclipse.jdt.core.formatter.wrap_non_simple_member_annotation" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_annotations_on_local_variable" value="1585"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_opening_paren_in_method_declaration" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_for" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_explicit_constructor_call.count_dependent" value="16|5|80"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_paren_in_catch" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_parameterized_type_reference" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_field_declarations" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_closing_paren_in_annotation" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_generic_type_arguments.count_dependent" value="16|-1|16"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_parameterized_type_reference" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_arguments_in_allocation_expression.count_dependent" value="16|5|80"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_method_invocation_arguments" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_parameters_in_method_declaration.count_dependent" value="16|5|80"/> -<setting id="org.eclipse.jdt.core.formatter.comment.new_lines_at_javadoc_boundaries" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.blank_lines_after_imports" value="1"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_comma_in_multiple_local_declarations" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.indent_body_declarations_compare_to_enum_constant_header" value="true"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_after_semicolon_in_for" value="insert"/> -<setting id="org.eclipse.jdt.core.formatter.never_indent_line_comments_on_first_column" value="false"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_semicolon_in_try_resources" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.alignment_for_for_statement" value="16"/> -<setting id="org.eclipse.jdt.core.formatter.insert_space_before_opening_angle_bracket_in_type_arguments" value="do not insert"/> -<setting id="org.eclipse.jdt.core.formatter.never_indent_block_comments_on_first_column" value="false"/> -<setting id="org.eclipse.jdt.core.formatter.keep_then_statement_on_same_line" value="false"/> -</profile> -</profiles> diff --git a/google-c-style.el b/google-c-style.el deleted file mode 100644 index 9bb12c6..0000000 --- a/google-c-style.el +++ /dev/null @@ -1,151 +0,0 @@ -;;; google-c-style.el --- Google's C/C++ style for c-mode - -;; Keywords: c, tools - -;; google-c-style.el is Copyright (C) 2008 Google Inc. All Rights Reserved. -;; -;; It is free software; you can redistribute it and/or modify it under the -;; terms of either: -;; -;; a) the GNU General Public License as published by the Free Software -;; Foundation; either version 1, or (at your option) any later version, or -;; -;; b) the "Artistic License". - -;;; Commentary: - -;; Provides the google C/C++ coding style. You may wish to add -;; `google-set-c-style' to your `c-mode-common-hook' after requiring this -;; file. For example: -;; -;; (add-hook 'c-mode-common-hook 'google-set-c-style) -;; -;; If you want the RETURN key to go to the next line and space over -;; to the right place, add this to your .emacs right after the load-file: -;; -;; (add-hook 'c-mode-common-hook 'google-make-newline-indent) - -;;; Code: - -;; For some reason 1) c-backward-syntactic-ws is a macro and 2) under Emacs 22 -;; bytecode cannot call (unexpanded) macros at run time: -(eval-when-compile (require 'cc-defs)) - -;; Wrapper function needed for Emacs 21 and XEmacs (Emacs 22 offers the more -;; elegant solution of composing a list of lineup functions or quantities with -;; operators such as "add") -(defun google-c-lineup-expression-plus-4 (langelem) - "Indents to the beginning of the current C expression plus 4 spaces. - -This implements title \"Function Declarations and Definitions\" -of the Google C++ Style Guide for the case where the previous -line ends with an open parenthese. - -\"Current C expression\", as per the Google Style Guide and as -clarified by subsequent discussions, means the whole expression -regardless of the number of nested parentheses, but excluding -non-expression material such as \"if(\" and \"for(\" control -structures. - -Suitable for inclusion in `c-offsets-alist'." - (save-excursion - (back-to-indentation) - ;; Go to beginning of *previous* line: - (c-backward-syntactic-ws) - (back-to-indentation) - (cond - ;; We are making a reasonable assumption that if there is a control - ;; structure to indent past, it has to be at the beginning of the line. - ((looking-at "\\(\\(if\\|for\\|while\\)\\s *(\\)") - (goto-char (match-end 1))) - ;; For constructor initializer lists, the reference point for line-up is - ;; the token after the initial colon. - ((looking-at ":\\s *") - (goto-char (match-end 0)))) - (vector (+ 4 (current-column))))) - -;;;###autoload -(defconst google-c-style - `((c-recognize-knr-p . nil) - (c-enable-xemacs-performance-kludge-p . t) ; speed up indentation in XEmacs - (c-basic-offset . 2) - (indent-tabs-mode . nil) - (c-comment-only-line-offset . 0) - (c-hanging-braces-alist . ((defun-open after) - (defun-close before after) - (class-open after) - (class-close before after) - (inexpr-class-open after) - (inexpr-class-close before) - (namespace-open after) - (inline-open after) - (inline-close before after) - (block-open after) - (block-close . c-snug-do-while) - (extern-lang-open after) - (extern-lang-close after) - (statement-case-open after) - (substatement-open after))) - (c-hanging-colons-alist . ((case-label) - (label after) - (access-label after) - (member-init-intro before) - (inher-intro))) - (c-hanging-semi&comma-criteria - . (c-semi&comma-no-newlines-for-oneline-inliners - c-semi&comma-inside-parenlist - c-semi&comma-no-newlines-before-nonblanks)) - (c-indent-comments-syntactically-p . t) - (comment-column . 40) - (c-indent-comment-alist . ((other . (space . 2)))) - (c-cleanup-list . (brace-else-brace - brace-elseif-brace - brace-catch-brace - empty-defun-braces - defun-close-semi - list-close-comma - scope-operator)) - (c-offsets-alist . ((arglist-intro google-c-lineup-expression-plus-4) - (func-decl-cont . ++) - (member-init-intro . ++) - (inher-intro . ++) - (comment-intro . 0) - (arglist-close . c-lineup-arglist) - (topmost-intro . 0) - (block-open . 0) - (inline-open . 0) - (substatement-open . 0) - (statement-cont - . - (,(when (fboundp 'c-no-indent-after-java-annotations) - 'c-no-indent-after-java-annotations) - ,(when (fboundp 'c-lineup-assignments) - 'c-lineup-assignments) - ++)) - (label . /) - (case-label . +) - (statement-case-open . +) - (statement-case-intro . +) ; case w/o { - (access-label . /) - (innamespace . 0)))) - "Google C/C++ Programming Style.") - -;;;###autoload -(defun google-set-c-style () - "Set the current buffer's c-style to Google C/C++ Programming - Style. Meant to be added to `c-mode-common-hook'." - (interactive) - (make-local-variable 'c-tab-always-indent) - (setq c-tab-always-indent t) - (c-add-style "Google" google-c-style t)) - -;;;###autoload -(defun google-make-newline-indent () - "Sets up preferred newline behavior. Not set by default. Meant - to be added to `c-mode-common-hook'." - (interactive) - (define-key c-mode-base-map "\C-m" 'newline-and-indent) - (define-key c-mode-base-map [ret] 'newline-and-indent)) - -(provide 'google-c-style) -;;; google-c-style.el ends here diff --git a/google-r-style.html b/google-r-style.html deleted file mode 100644 index 21a73f6..0000000 --- a/google-r-style.html +++ /dev/null @@ -1,18 +0,0 @@ -<!DOCTYPE html> -<html> -<head> - <meta charset="utf8"> - <meta http-equiv="content-type" content="text/html;charset=utf-8"> - <meta http-equiv="refresh" content="1; url=Rguide.xml"> - <title>Redirecting - - - - Redirecting you to Rguide.xml. - - diff --git a/google_python_style.vim b/google_python_style.vim deleted file mode 100644 index a8feea9..0000000 --- a/google_python_style.vim +++ /dev/null @@ -1,36 +0,0 @@ -" Indent Python in the Google way. - -setlocal indentexpr=GetGooglePythonIndent(v:lnum) - -let s:maxoff = 50 " maximum number of lines to look backwards. - -function GetGooglePythonIndent(lnum) - - " Indent inside parens. - " Align with the open paren unless it is at the end of the line. - " E.g. - " open_paren_not_at_EOL(100, - " (200, - " 300), - " 400) - " open_paren_at_EOL( - " 100, 200, 300, 400) - call cursor(a:lnum, 1) - let [par_line, par_col] = searchpairpos('(\|{\|\[', '', ')\|}\|\]', 'bW', - \ "line('.') < " . (a:lnum - s:maxoff) . " ? dummy :" - \ . " synIDattr(synID(line('.'), col('.'), 1), 'name')" - \ . " =~ '\\(Comment\\|String\\)$'") - if par_line > 0 - call cursor(par_line, 1) - if par_col != col("$") - 1 - return par_col - endif - endif - - " Delegate the rest to the original function. - return GetPythonIndent(a:lnum) - -endfunction - -let pyindent_nested_paren="&sw*2" -let pyindent_open_paren="&sw*2" diff --git a/htmlcssguide.xml b/htmlcssguide.xml deleted file mode 100644 index d8caf13..0000000 --- a/htmlcssguide.xml +++ /dev/null @@ -1,1117 +0,0 @@ - - - -

- - Revision 2.23 -

- - - - - - This style guide contains many details that are initially - hidden from view. They are marked by the triangle icon, which you - see here on your left. Click it now. - You should see “Hooray” appear below. - - -

- Hooray! Now you know you can expand points to get more - details. Alternatively, there’s a “toggle all” at the - top of this document. -

- -
-
- - -

- This document defines formatting and style rules for HTML and - CSS. It aims at improving collaboration, code quality, and - enabling supporting infrastructure. It applies to raw, - working files that use HTML and CSS, including GSS - files. Tools are free to obfuscate, minify, and compile as - long as the general code quality is maintained. -

- - -
-
- - - - - Omit the protocol from embedded resources. - - -

- Omit the protocol portion (http:, - https:) from URLs pointing to images and other - media files, style sheets, and scripts unless the respective - files are not available over both protocols. -

-

- Omitting the protocol—which makes the URL - relative—prevents mixed content issues and results in - minor file size savings. -

- - <!-- Not recommended --> - <script src="http://www.google.com/js/gweb/analytics/autotrack.js"></script> - - - <!-- Recommended --> - <script src="//www.google.com/js/gweb/analytics/autotrack.js"></script> - - - /* Not recommended */ - .example { - background: url(http://www.google.com/images/example); - } - - - /* Recommended */ - .example { - background: url(//www.google.com/images/example); - } - - -
- -
- - - - - Indent by 2 spaces at a time. - - -

- Don’t use tabs or mix tabs and spaces for indentation. -

- - <ul> - <li>Fantastic - <li>Great - </ul> - - - .example { - color: blue; - } - - -
- - - Use only lowercase. - - -

- All code has to be lowercase: This applies to HTML element names, - attributes, attribute values (unless - text/CDATA), CSS selectors, properties, and - property values (with the exception of strings). -

- - <!-- Not recommended --> - <A HREF="/">Home</A> - - - <!-- Recommended --> - <img src="google.png" alt="Google"> - - - /* Not recommended */ - color: #E5E5E5; - - - /* Recommended */ - color: #e5e5e5; - - -
- - - Remove trailing white spaces. - - -

- Trailing white spaces are unnecessary and can complicate - diffs. -

- - <!-- Not recommended --> - <p>What?_ - - - <!-- Recommended --> - <p>Yes please. - - -
-
- - - - - Use UTF-8 (no BOM). - - -

- Make sure your editor uses UTF-8 as character encoding, - without a byte order mark. -

-

- Specify the encoding in HTML templates and documents via - <meta charset="utf-8">. Do not specify - the encoding of style sheets as these assume UTF-8. -

-

- (More on encodings and when and how to specify them can be - found in Handling - character encodings in HTML and CSS.) -

- -
- - - Explain code as needed, where possible. - - -

- Use comments to explain code: What does it cover, what - purpose does it serve, why is respective solution used or - preferred? -

-

- (This item is optional as it is not deemed a realistic - expectation to always demand fully documented code. Mileage - may vary heavily for HTML and CSS code and depends on the - project’s complexity.) -

- -
- - - Mark todos and action items with TODO. - - -

- Highlight todos by using the keyword TODO only, - not other common formats like @@. -

-

- Append a contact (username or mailing list) in parentheses - as with the format TODO(contact). -

-

- Append action items after a colon as in TODO: action - item. -

- - - {# TODO(john.doe): revisit centering #} - <center>Test</center> - - - - <!-- TODO: remove optional tags --> - <ul> - <li>Apples</li> - <li>Oranges</li> - </ul> - - -
-
- - - - - Use HTML5. - - -

- HTML5 (HTML syntax) is preferred for all HTML documents: - <!DOCTYPE html>. -

-

- (It’s recommended to use HTML, as text/html. Do not use - XHTML. XHTML, as application/xhtml+xml, - lacks both browser and infrastructure support and offers - less room for optimization than HTML.) -

-

- Although fine with HTML, do not close void elements, i.e. write - <br>, not <br />. -

- -
- - - Use valid HTML where possible. - - -

- Use valid HTML code unless that is not possible due to - otherwise unattainable performance goals regarding file size. -

- -

- Use tools such as the W3C - HTML validator to test. -

-

- Using valid HTML is a measurable baseline quality attribute - that contributes to learning about technical requirements - and constraints, and that ensures proper HTML usage. -

- - <!-- Not recommended --> - <title>Test</title> - <article>This is only a test. - - - <!-- Recommended --> - <!DOCTYPE html> - <meta charset="utf-8"> - <title>Test</title> - <article>This is only a test.</article> - - -
- - - Use HTML according to its purpose. - - -

- Use elements (sometimes incorrectly called “tags”) for what - they have been created for. For example, use heading - elements for headings, p elements for - paragraphs, a elements for anchors, etc. -

-

- Using HTML according to its purpose is important for - accessibility, reuse, and code efficiency reasons. -

- - - <!-- Not recommended --> - <div onclick="goToRecommendations();">All recommendations</div> - - - <!-- Recommended --> - <a href="recommendations/">All recommendations</a> - - -
- - - Provide alternative contents for multimedia. - - -

- For multimedia, such as images, videos, animated objects via - canvas, make sure to offer alternative - access. For images that means use of meaningful alternative - text (alt) and for video and audio transcripts - and captions, if available. -

-

- Providing alternative contents is important for - accessibility reasons: A blind user has few cues to tell - what an image is about without @alt, and other - users may have no way of understanding what video or audio - contents are about either. -

-

- (For images whose alt attributes would - introduce redundancy, and for images whose purpose is purely - decorative which you cannot immediately use CSS for, use no - alternative text, as in alt="".) -

- - - <!-- Not recommended --> - <img src="spreadsheet.png"> - - - <!-- Recommended --> - <img src="spreadsheet.png" alt="Spreadsheet screenshot."> - - -
- - - - Separate structure from presentation from behavior. - - -

- Strictly keep structure (markup), presentation (styling), - and behavior (scripting) apart, and try to keep the - interaction between the three to an absolute minimum. -

-

- That is, make sure documents and templates contain only HTML - and HTML that is solely serving structural purposes. Move - everything presentational into style sheets, and everything - behavioral into scripts. -

-

- In addition, keep the contact area as small as possible by - linking as few style sheets and scripts as possible from - documents and templates. -

-

- Separating structure from presentation from behavior is - important for maintenance reasons. It is always more - expensive to change HTML documents and templates than it is - to update style sheets and scripts. -

- - - <!-- Not recommended --> - <!DOCTYPE html> - <title>HTML sucks</title> - <link rel="stylesheet" href="base.css" media="screen"> - <link rel="stylesheet" href="grid.css" media="screen"> - <link rel="stylesheet" href="print.css" media="print"> - <h1 style="font-size: 1em;">HTML sucks</h1> - <p>I’ve read about this on a few sites but now I’m sure: - <u>HTML is stupid!!1</u> - <center>I can’t believe there’s no way to control the styling of - my website without doing everything all over again!</center> - - - <!-- Recommended --> - <!DOCTYPE html> - <title>My first CSS-only redesign</title> - <link rel="stylesheet" href="default.css"> - <h1>My first CSS-only redesign</h1> - <p>I’ve read about this on a few sites but today I’m actually - doing it: separating concerns and avoiding anything in the HTML of - my website that is presentational. - <p>It’s awesome! - - -
- - - Do not use entity references. - - -

- There is no need to use entity references like - &mdash;, &rdquo;, or - &#x263a;, assuming the same encoding - (UTF-8) is used for files and editors as well as among - teams. -

-

- The only exceptions apply to characters with special meaning - in HTML (like < and &) as - well as control or “invisible” characters (like no-break - spaces). -

- - <!-- Not recommended --> - The currency symbol for the Euro is &ldquo;&eur;&rdquo;. - - - <!-- Recommended --> - The currency symbol for the Euro is “€”. - - -
- - - Omit optional tags (optional). - - -

- For file size optimization and scannability purposes, - consider omitting optional tags. - The HTML5 - specification defines what tags can be omitted. -

-

- (This approach may require a grace period to be established - as a wider guideline as it’s significantly different - from what web developers are typically taught. For - consistency and simplicity reasons it’s best served - omitting all optional tags, not just a selection.) -

- - <!-- Not recommended --> - <!DOCTYPE html> - <html> - <head> - <title>Spending money, spending bytes</title> - </head> - <body> - <p>Sic.</p> - </body> - </html> - - - <!-- Recommended --> - <!DOCTYPE html> - <title>Saving money, saving bytes</title> - <p>Qed. - - -
- - - Omit type attributes for style sheets and scripts. - - -

- Do not use type attributes for style sheets - (unless not using CSS) and scripts (unless not using - JavaScript). -

-

- Specifying type attributes in these contexts is - not necessary as HTML5 implies - text/css - and - text/javascript - as defaults. This can be safely done even for older browsers. -

- - <!-- Not recommended --> - <link rel="stylesheet" href="//www.google.com/css/maia.css" - type="text/css"> - - - <!-- Recommended --> - <link rel="stylesheet" href="//www.google.com/css/maia.css"> - - - <!-- Not recommended --> - <script src="//www.google.com/js/gweb/analytics/autotrack.js" - type="text/javascript"></script> - - - <!-- Recommended --> - <script src="//www.google.com/js/gweb/analytics/autotrack.js"></script> - - -
-
- - - - - Use a new line for every block, list, or table element, and - indent every such child element. - - -

- Independent of the styling of an element (as CSS allows - elements to assume a different role per display - property), put every block, list, or table element on a new - line. -

-

- Also, indent them if they are child elements of a block, - list, or table element. -

-

- (If you run into issues around whitespace between list items - it’s acceptable to put all li elements in one - line. A linter is encouraged to throw a warning instead of - an error.) -

- - <blockquote> - <p><em>Space</em>, the final frontier.</p> - </blockquote> - - - <ul> - <li>Moe - <li>Larry - <li>Curly - </ul> - - - <table> - <thead> - <tr> - <th scope="col">Income - <th scope="col">Taxes - <tbody> - <tr> - <td>$ 5.00 - <td>$ 4.50 - </table> - - -
- - - When quoting attributes values, use double quotation marks. - - -

- Use double ("") rather than single quotation marks - ('') around attribute values. -

- - <!-- Not recommended --> - <a class='maia-button maia-button-secondary'>Sign in</a> - - - <!-- Recommended --> - <a class="maia-button maia-button-secondary">Sign in</a> - - -
-
- - - - - Use valid CSS where possible. - - -

- Unless dealing with CSS validator bugs or requiring - proprietary syntax, use valid CSS code. -

- -

- Use tools such as the W3C - CSS validator to test. -

-

- Using valid CSS is a measurable baseline quality attribute - that allows to spot CSS code that may not have any effect - and can be removed, and that ensures proper CSS usage. -

- -
- - - Use meaningful or generic ID and class names. - - -

- Instead of presentational or cryptic names, always use ID - and class names that reflect the purpose of the element in - question, or that are otherwise generic. -

-

- Names that are specific and reflect the purpose of the - element should be preferred as these are most understandable - and the least likely to change. -

-

- Generic names are simply a fallback for elements that have no - particular or no meaning different from their siblings. They are - typically needed as “helpers.” -

-

- Using functional or generic names reduces the probability of - unnecessary document or template changes. -

- - /* Not recommended: meaningless */ - #yee-1901 {} - - /* Not recommended: presentational */ - .button-green {} - .clear {} - - - /* Recommended: specific */ - #gallery {} - #login {} - .video {} - - /* Recommended: generic */ - .aux {} - .alt {} - - -
- - - Use ID and class names that are as short as possible but as long as - necessary. - - -

- Try to convey what an ID or class is about while being as - brief as possible. -

-

- Using ID and class names this way contributes to acceptable - levels of understandability and code efficiency. -

- - /* Not recommended */ - #navigation {} - .atr {} - - - /* Recommended */ - #nav {} - .author {} - - -
- - - - Avoid qualifying ID and class names with type selectors. - - -

Unless necessary (for example with helper classes), do not - use element names in conjunction with IDs or classes. -

-

- Avoiding unnecessary ancestor selectors is useful for performance - reasons. -

- - /* Not recommended */ - ul#example {} - div.error {} - - - /* Recommended */ - #example {} - .error {} - - -
- - - Use shorthand properties where possible. - - -

- CSS offers a variety of shorthand - properties (like font) - that should be used whenever possible, even in cases where - only one value is explicitly set. -

-

- Using shorthand properties is useful for code efficiency and - understandability. -

- - /* Not recommended */ - border-top-style: none; - font-family: palatino, georgia, serif; - font-size: 100%; - line-height: 1.6; - padding-bottom: 2em; - padding-left: 1em; - padding-right: 1em; - padding-top: 0; - - - /* Recommended */ - border-top: 0; - font: 100%/1.6 palatino, georgia, serif; - padding: 0 1em 2em; - - -
- - - Omit unit specification after “0” values. - - -

- Do not use units after 0 values unless they are - required. -

- - margin: 0; - padding: 0; - - -
- - - Omit leading “0”s in values. - - -

- Do not use put 0s in front of values or lengths - between -1 and 1. -

- - font-size: .8em; - - -
- - - Use 3 character hexadecimal notation where possible. - - -

- For color values that permit it, 3 character hexadecimal - notation is shorter and more succinct. -

- - /* Not recommended */ - color: #eebbcc; - - - /* Recommended */ - color: #ebc; - - -
- - - Prefix selectors with an application-specific prefix (optional). - - -

- In large projects as well as for code that gets embedded in - other projects or on external sites use prefixes (as - namespaces) for ID and class names. Use short, unique - identifiers followed by a dash. -

- - -

- Using namespaces helps preventing naming conflicts and can - make maintenance easier, for example in search and replace - operations. -

- - .adw-help {} /* AdWords */ - #maia-note {} /* Maia */ - - -
- - - Separate words in ID and class names by a hyphen. - - -

- Do not concatenate words and abbreviations in selectors by - any characters (including none at all) other than hyphens, - in order to improve understanding and scannability. -

- - /* Not recommended: does not separate the words “demo” and “image” */ - .demoimage {} - - /* Not recommended: uses underscore instead of hyphen */ - .error_status {} - - - /* Recommended */ - #video-id {} - .ads-sample {} - - -
- - - Avoid user agent detection as well as CSS “hacks”—try a different - approach first. - - -

- It’s tempting to address styling differences over user - agent detection or special CSS filters, workarounds, and - hacks. Both approaches should be considered last resort in - order to achieve and maintain an efficient and manageable - code base. Put another way, giving detection and hacks a - free pass will hurt projects in the long run as projects - tend to take the way of least resistance. That is, allowing - and making it easy to use detection and hacks means using - detection and hacks more frequently—and more frequently - is too frequently. -

- - - -
-
- - - - - Alphabetize declarations. - - -

- Put declarations in alphabetical order in order to achieve - consistent code in a way that is easy to remember and - maintain. -

-

- Ignore vendor-specific prefixes for sorting purposes. However, - multiple vendor-specific prefixes for a certain CSS property should - be kept sorted (e.g. -moz prefix comes before -webkit). -

- - background: fuchsia; - border: 1px solid; - -moz-border-radius: 4px; - -webkit-border-radius: 4px; - border-radius: 4px; - color: black; - text-align: center; - text-indent: 2em; - - -
- - - Indent all block content. - - -

- Indent all block - content, that is rules within rules as well as declarations, so to - reflect hierarchy and improve understanding. -

- - @media screen, projection { - - html { - background: #fff; - color: #444; - } - - } - - -
- - - Use a semicolon after every declaration. - - -

- End every declaration with a semicolon for consistency and - extensibility reasons. -

- - /* Not recommended */ - .test { - display: block; - height: 100px - } - - - /* Recommended */ - .test { - display: block; - height: 100px; - } - - -
- - - Use a space after a property name’s colon. - - -

- Always use a single space between property and value (but no - space between property and colon) for consistency reasons. -

- - /* Not recommended */ - h3 { - font-weight:bold; - } - - - /* Recommended */ - h3 { - font-weight: bold; - } - - -
- - - Use a space between the last selector and the declaration block. - - -

- Always use a single space between the last selector and the opening - brace that begins the declaration - block. -

-

- The opening brace should be on the same line as the last selector in a - given rule. -

- - /* Not recommended: missing space */ - #video{ - margin-top: 1em; - } - - /* Not recommended: unnecessary line break */ - #video - { - margin-top: 1em; - } - - - /* Recommended */ - #video { - margin-top: 1em; - } - - -
- - - Separate selectors and declarations by new lines. - - -

- Always start a new line for each selector and declaration. -

- - /* Not recommended */ - a:focus, a:active { - position: relative; top: 1px; - } - - - /* Recommended */ - h1, - h2, - h3 { - font-weight: normal; - line-height: 1.2; - } - - -
- - - Separate rules by new lines. - - -

- Always put a blank line (two line breaks) between rules. -

- - html { - background: #fff; - } - - body { - margin: auto; - width: 50%; - } - - -
- - - Use single quotation marks for attribute selectors and property values. - - -

- Use single ('') rather than double ("") - quotation marks for attribute selectors or property values. Do not - use quotation marks in URI values (url()). -

-

- Exception: If you do need to use the @charset rule, - use double quotation marks—single - quotation marks are not permitted. -

- - /* Not recommended */ - @import url("//www.google.com/css/maia.css"); - - html { - font-family: "open sans", arial, sans-serif; - } - - - /* Recommended */ - @import url(//www.google.com/css/maia.css); - - html { - font-family: 'open sans', arial, sans-serif; - } - - -
-
- - - - - - Group sections by a section comment (optional). - - -

- If possible, group style sheet sections together by using - comments. Separate sections with new lines. -

- - /* Header */ - - #adw-header {} - - /* Footer */ - - #adw-footer {} - - /* Gallery */ - - .adw-gallery {} - - -
-
- - - - -

- Be consistent. -

-

- If you’re editing code, take a few minutes to look at the code - around you and determine its style. If they use spaces around - all their arithmetic operators, you should too. If their - comments have little boxes of hash marks around them, make your - comments have little boxes of hash marks around them too. -

-

- The point of having style guidelines is to have a common vocabulary - of coding so people can concentrate on what you’re saying rather - than on how you’re saying it. We present global style rules here so - people know the vocabulary, but local style is also important. If - code you add to a file looks drastically different from the existing - code around it, it throws readers out of their rhythm when they go to - read it. Avoid this. -

-
- -

- Revision 2.23 -

- -
diff --git a/include/link.png b/include/link.png deleted file mode 100644 index 75d5c7b..0000000 Binary files a/include/link.png and /dev/null differ diff --git a/include/styleguide.css b/include/styleguide.css deleted file mode 100644 index ef62024..0000000 --- a/include/styleguide.css +++ /dev/null @@ -1,261 +0,0 @@ -/* General CSS */ - -body { - background-color: #fff; - color: #333; - font-family: sans-serif; - font-size: 10pt; - margin-right: 100px; - margin-left: 100px; -} - -h1 { - text-align: center; - font-size: 18pt; -} - -h1, h2, h3, h4, h5, h6 { - color: #06c; - margin-top: 2em; - margin-bottom: 1em; - padding: 25px; - font-weight:bold; -} - -h2, -h3, -h4, -h5, -h6 { - margin-top:1.5em; - margin-bottom:.75em; -} - -h1 {font-size:200%;} -h2 {font-size:167%;} -h3 {font-size:133%;} -h4 {font-size:120%;} -h5 {font-size:110%;} - - -table { - border: 1px solid #bbb; - border-spacing: 0; - border-collapse: collapse; - margin: 0 0 1.5em; - vertical-align: middle; - width: 100% -} - -td, th { - border: 1px solid #ccc; - padding: 2px 12px; - font-size: 10pt; -} - -code, samp, var { - background-color:#FAFAFA; - white-space: nowrap -} - -pre { - padding:6px 10px; - background-color:#FAFAFA; - border:1px solid #bbb; - overflow:auto; -} - -pre.prettyprint { - padding:6px 10px !important; - border:1px solid #bbb !important; -} - -code.bad, code.badcode { - color: magenta; -} - -pre.bad, pre.badcode { - background-color:#ffe6d8; - border-top:1px inset #a03; - border-left:1px inset #a03; -} - -hr { - margin-top: 3.5em; - border-width: 1px; - color: #fff; -} - -/* TOC CSS */ - -table.columns { - border: none; -} - -td.two_columns { - -webkit-column-count: 2; - column-count: 2; -} - -.toc_category { - font-size: 10pt; - padding-top: 1em; - padding-bottom: 1em; - border-left-width: 2px; - border-right-width: 2px; - border-color: grey; -} - -.toc_stylepoint { - font-size: 10pt; - padding-top: 1em; - padding-bottom: 1em; -} - -li.toc_entry { - padding-right: 1em; - display: inline; - list-style-type: none; -} - -/* - * This space is required to trigger the linewrap on the links - * at href boundaries - */ -li.toc_entry::after { - content: " "; - } - -li.toc_entry a { - white-space: nowrap; -} - -/* Horizontal TOC */ -.toc td, .toc th { - border-width: 1px 5px; - overflow: hidden; -} - -/* Vertical TOC */ - -.toc td.two_columns { - border-width: 0px; -} - -/* Special Sections */ - -address { - text-align: right; -} - -.revision { - text-align: right; -} - -.headerbox { - margin-left: 50%; - font-size: 75%; -} - -.legend { - padding-top: 1em; - margin-left: 50%; - font-size: 10pt; -} - -.link_button { - float: left; - display: none; - background-color: #f8f8ff; - border-color: #f0f0ff; - border-style: solid; - border-width: 1px; - font-size: 75%; - margin-top: 0; - margin-left: -50px; - padding: 24px; - border-radius: 3px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; -} - -.ignoreLink { - padding: 0px; -} - -.divider{ - width:5px; - height:auto; - display:inline-block; -} - -/* Style Guide semantic CSS */ - -.summary { - margin-top: 1em; - margin-bottom: 1em; -} - -.stylebody { - margin-top: 1em; - margin-bottom: 1em; -} - -.stylepoint_section { - display: block; - margin-bottom: 1em; - font-family: sans-serif; - font-weight: bold; -} - -.stylepoint_subsection { - display: block; - margin-bottom: 1em; -} - -.stylepoint_subsubsection { - display: block; - margin-bottom: 1em; -} - -.definition:before { - content: "Definition: "; - font-weight: bold; - display: block; - margin-bottom: 1em; -} - -.pros:before { - content: "Pros: "; - font-weight: bold; - display: block; - margin-bottom: 1em; -} - -.cons:before { - content: "Cons: "; - font-weight: bold; - display: block; - margin-bottom: 1em; -} - -.decision:before { - content: "Decision: "; - font-weight: bold; - display: block; - margin-bottom: 1em; -} - -.exception:before { - content: "Exception: "; - font-weight: bold; - display: block; - margin-bottom: 1em; -} - -.note:before { - content: "Note: "; - font-weight: bold; - display: block; - margin-bottom: 1em; -} diff --git a/include/styleguide.js b/include/styleguide.js deleted file mode 100644 index accb779..0000000 --- a/include/styleguide.js +++ /dev/null @@ -1,289 +0,0 @@ -TocTypeEnum = { - VERTICAL: 1, - HORIZONTAL: 2 -}; - -function CreateTOC(tocElement) { - - // Find the toc element DIV. We'll place our TOC there. - var toc = document.getElementById(tocElement); - - var tocTypeClass = toc.className; - var tocType; - - switch (tocTypeClass) { - case 'horizontal_toc': - tocType = TocTypeEnum.HORIZONTAL; - break; - case 'vertical_toc': - tocType = TocTypeEnum.VERTICAL; - break; - default: - tocType = TocTypeEnum.VERTICAL; - break; - } - - // If toc_levels is defined, set headingLevels to it. - // Otherwise, use default value of "h2,h3" - var headingLevels; - if (typeof toc_levels === 'undefined') { - headingLevels = 'h2,h3'; - } else { - - } - - // Collect all section heading elements in an array - var headings = document.querySelectorAll(headingLevels); - - // Add TOC title elements - var tocHeadingDiv = document.createElement('div'); - toc.appendChild(tocHeadingDiv); - tocHeadingDiv.className = 'toc_title'; - var tocHeading = document.createElement('h3'); - toc.appendChild(tocHeading); - tocHeading.className = 'ignoreLink'; - tocHeading.id = 'toc'; - var tocText = document.createTextNode('Table of Contents'); - tocHeading.appendChild(tocText); - - // Add table and tbody - var tocTable = document.createElement('table'); - if (tocType == TocTypeEnum.VERTICAL) { - tocTable.className = 'columns'; - } - toc.appendChild(tocTable); - - var tbody_element = document.createElement('tbody'); - tbody_element.setAttribute('valign', 'top'); - tbody_element.className = 'toc'; - tocTable.appendChild(tbody_element); - - // Get the highest level heading - var firstHeading = headings[0]; - var masterLevel = parseInt(headingLevels.charAt(1)); - - // Get the lowest heading level - var lowestLevel = parseInt(headingLevels.charAt(headingLevels - 1)); - - switch (tocType) { - case TocTypeEnum.HORIZONTAL: - CreateHorizontalTOC(headings, masterLevel, lowestLevel, tbody_element); - break; - case TocTypeEnum.VERTICAL: - CreateVerticalTOC(headings, masterLevel, lowestLevel, tbody_element); - break; - default: - } -} - -function CreateHorizontalTOC( - headings, masterLevel, lowestLevel, tbody_element) { - - // Initialize the header counter - var h = 0; - var ignoreChildren = false; - - while (h < headings.length) { - // Get current heading - var heading = headings[h]; - - // Get the current heading level - var level = parseInt(heading.tagName.charAt(1)); - - if (isNaN(level) || level < 1 || level > lowestLevel) continue; - - // If level is a masterLevel, make it a TOC parent category - if ((level == masterLevel) && (!hasClass(heading, 'ignoreLink'))) { - toc_current_row = AddTOCMaster(tbody_element, heading); - ignoreChildren = false; - } - - if ((level == masterLevel) && (hasClass(heading, 'ignoreLink'))) { - ignoreChildren = true; - } - - if ((level != masterLevel) && (!ignoreChildren)) { - AddTOCElements(toc_current_row, heading); - } - - // Advance the header counter - h++; - } -} - -// Adds a master Table of Content heading -function AddTOCMaster(tocTable, heading) { - - // Add the table row scaffolding - var toc_tr = document.createElement('tr'); - tocTable.appendChild(toc_tr); - toc_tr.setAttribute('valign', 'top'); - var toc_tr_td = document.createElement('td'); - toc_tr.appendChild(toc_tr_td); - var toc_category = document.createElement('div'); - toc_tr_td.appendChild(toc_category); - toc_category.className = 'toc_category'; - - // Create the link to this header - var link = document.createElement('a'); - link.href = '#' + heading.id; // Create the anchor link - link.textContent = heading.textContent; // Link text is same as heading - toc_category.appendChild(link); - - // Add the container table cell for its children - var toc_td = document.createElement('td'); - toc_tr.appendChild(toc_td); - var toc_td_div = document.createElement('div'); - toc_td_div.className = 'toc_stylepoint'; - toc_td.appendChild(toc_td_div); - - return (toc_td_div); -} - -// Adds Table of Contents element to a master heading as children -function AddTOCElements(toc_div, heading) { - - if (heading.offsetParent === null) { - // The element is currently hidden, so don't create a TOC entry - } else { - // Create the list item element - var toc_list_element = document.createElement('li'); - toc_list_element.className = 'toc_entry'; - toc_div.appendChild(toc_list_element); - - // Create the link to this header - var link = document.createElement('a'); - link.href = '#' + heading.id; // Create the anchor link - link.textContent = heading.textContent; // Link text is same as heading - toc_list_element.appendChild(link); - } -} - -function CreateVerticalTOC(headings, masterLevel, lowestLevel, tbody_element) { - - // Create the Column scaffolding - var toc_tr = document.createElement('tr'); - tbody_element.appendChild(toc_tr); - var toc_tr_td = document.createElement('td'); - toc_tr_td.className = 'two_columns'; - toc_tr.appendChild(toc_tr_td); - - - // Initialize the header counter and the current row - var h = 0; - var toc_current_col = null; - var ignoreChildren = false; - - while (h < headings.length) { - // Get current heading - var heading = headings[h]; - - // Get the current heading level - var level = parseInt(heading.tagName.charAt(1)); - - if (isNaN(level) || level < 1 || level > lowestLevel) continue; - - // If level is a masterLevel, make it a TOC parent category - if ((level == masterLevel) && (!hasClass(heading, 'ignoreLink'))) { - if (heading.offsetParent === null) { - // The element is currently hidden, so don't create a TOC entry - } else { - var td_dl = document.createElement('dl'); - toc_tr_td.appendChild(td_dl); - var td_dt = document.createElement('dt'); - td_dl.appendChild(td_dt); - toc_current_col = td_dl; - - // Create the link to this header - var link = document.createElement('a'); - link.href = '#' + heading.id; // Create the anchor link - link.textContent = heading.textContent; // Link text is same as heading - td_dt.appendChild(link); - ignoreChildren = false; - } - } - - // If level is a masterLevel but it's specified to ignore links, skip it - // and its children. - if ((level == masterLevel) && (hasClass(heading, 'ignoreLink'))) { - ignoreChildren = true; - } - - if ((level != masterLevel) && (!ignoreChildren)) { - if (heading.offsetParent === null) { - // The element is currently hidden, so don't create a TOC entry - } else { - var td_dd = document.createElement('dd'); - toc_current_col.appendChild(td_dd); - // Create the link to this header - var link = document.createElement('a'); - link.href = '#' + heading.id; // Create the anchor link - link.textContent = heading.textContent; // Link text is same as heading - td_dd.appendChild(link); - } - } - - // Advance the header counter - h++; - } -} - -/* - * Utility function for finding elements with a given - * class. - */ -function hasClass(element, cls) { - return (' ' + element.className + ' ').indexOf(' ' + cls + ' ') > -1; -} - -/* - * Linkify all h2 through h4 headers, except for those marked - * "ignoreLink" - */ - -// Add the link image to the element. -function LinkifyHeader(header, fileName, sizePixels) { - var link = document.createElement('a'); - link.href = '#' + header.id; - link.alt = 'link to ' + header.id; - link.innerHTML = - ''; - header.appendChild(link); -} - -// Find all elements of the given tag and linkify if -// they don't have 'ignoreLink' in their class. -function LinkifyHeadersForTag(tagName) { - var headers = document.getElementsByTagName(tagName); - var header; - for (var j = 0; j != headers.length; j++) { - header = headers[j]; - if (!hasClass(header, 'ignoreLink') && ('id' in header)) { - if (header.id != '') { - LinkifyHeader(header, 'link.png', 21); - header.style.left = '-46px'; - header.style.position = 'relative'; - } - } - } -} - -// Linkify all h2, h3, and h4s. h1s are titles. -function LinkifyHeaders() { - LinkifyHeadersForTag('h2'); - LinkifyHeadersForTag('h3'); - LinkifyHeadersForTag('h4'); -} - -/* - * Initialize the style guide by showing all internal - * elements and then linkifying the headers. - */ - -function initStyleGuide() { - LinkifyHeaders(); - CreateTOC('tocDiv'); -} diff --git a/intellij-java-google-style.xml b/intellij-java-google-style.xml deleted file mode 100644 index 7299533..0000000 --- a/intellij-java-google-style.xml +++ /dev/null @@ -1,476 +0,0 @@ - - - - - - diff --git a/javaguide.css b/javaguide.css deleted file mode 100644 index c42ba83..0000000 --- a/javaguide.css +++ /dev/null @@ -1,515 +0,0 @@ -table { - border-collapse: collapse; -} - -td, th { - border: 1px solid #ccc; - padding: 2px 12px; - font-size: 10pt; -} - -code, samp, var { - color: #060; -} - -pre { - font-size: 10pt; - display: block; - color: #060; - background-color: #e8fff6; - border-color: #f0fff0; - border-style: solid; - border-top-width: 1px; - border-bottom-width: 1px; - border-right-width: 1px; - border-left-width: 5px; - padding-left: 12px; - padding-right: 12px; - padding-top: 4px; - padding-bottom: 4px; -} - -pre.badcode { - color: #c00; - background-color: #ffe6d8; - border-color: #fff0f0; -} - -hr { - margin-top: 3.5em; - border-width: 1px; - color: #fff; -} - -html { - margin-top:2em; - margin-left:10%; - margin-right:10%; - padding:0; -} - -.bp-reset-element, -body, -h1, -h2, -h3, -h4, -h5, -h6, -article, -aside, -details, -figcaption, -figure, -footer, -header, -hgroup, -menu, -nav, -section, -summary, -blockquote, -q, -th, -td, -caption, -table, -div, -span, -object, -iframe, -p, -pre, -a, -abbr, -acronym, -address, -code, -del, -dfn, -em, -img, -dl, -dt, -dd, -ol, -ul, -li, -fieldset, -form, -label, -legend, -caption, -tbody, -tfoot, -thead, -tr { - margin:0; - padding:0; - border:0; - font-weight:inherit; - font-style:inherit; - font-size:100%; - font-family:inherit; - vertical-align:baseline; -} - -body { - font-family:'Arial', sans-serif; - font-size:81.25%; - color:#222; - background-color:#fff; - line-height:1.67; - overflow: auto; -} - -.change { - text-align: right; - margin-bottom:1em; -} - -em { - font-style: italic -} - -h1, -h2, -h3, -h4, -h5, -h6 { - font-weight:bold; -} - -h1 { - margin-bottom:.50em; - text-align: center -} - -h2, -h3, -h4, -h5, -h6 { - margin-top:1.5em; - margin-bottom:.75em; -} - -h1 {font-size:200%;} -h2 {font-size:167%;} -h3 {font-size:133%;} -h4 {font-size:120%;} -h5 {font-size:110%;} - -p { - margin:0 0 1.5em; -} - -a[href=''] { - cursor:default; -} - -h1 img, -h2 img, -h3 img, -h4 img, -h5 img, -h6 img { - margin:0; -} - -a img { - border:none; -} - -pre { - margin:1.5em 0; - white-space:pre; -} - -pre, -code, -kbd, -tt { - font:1em 'Droid Sans Mono', monospace; - line-height:1.5; -} - -dl { - margin:0 0 1.5em 0; -} - -dl dt { - font-weight:bold; -} - -dd { - margin-left:1.5em; -} - -dd.toc3 { - margin-left:3em; -} - -hr { - height:0; - border:0; - border-top:1px solid #ccc; - background-color:#ccc; -} - -table { - border:1px solid #bbb; - border-spacing:0; - border-collapse:collapse; - margin:0 0 1.5em; - vertical-align:middle; - width:100%; -} - -table.unlined, -table.unlined th, -table.unlined tr, -table.unlined td { - border:0; -} - -th, -td, -caption { - float:none !important; - text-align:left; - font-weight:normal; - vertical-align:middle; - padding:4px; -} - -caption { - padding:0; -} - -td { - border:1px solid #bbb; - vertical-align:top; -} - -th { - border:0; - border-bottom:1px solid black; - font-weight:bold; - background:rgb(229, 236, 249); -} - -table th code { - background-color:inherit; - color:inherit; -} - -table tfoot th { - border:1px solid #bbb; -} - -tfoot { - font-style:italic; -} - -caption { - background:#eee; -} - -table[border='0'] { - border:none; -} - -table[border='0']>tbody>tr>td, -table[border='0']>tr>td { - border:none; -} - -tr.alt td, -td.alt { - background-color:#efefef; -} - -table.striped tr:nth-child(even) td, -table tr.even td { - background:#efefef; -} - -table.columns { - border:none; -} - -table.columns>tbody>tr>td, -table.columns>tr>td { - border:none; - padding:0 3em 0 0; -} - -table.columns>tbody>tr>td:last-child, -table.columns>tr>td:last-child { - border:none; - padding:0; -} - -ul, -ol { - margin:0 1.5em 1.5em 0; - padding-left:2em; -} - -li ul, -li ol { - margin:0; -} - -ul { - list-style-type:disc; -} - -ol { - list-style-type:decimal; -} - -ul { - list-style-type:disc; -} - -ul ul { - list-style-type:circle; -} - -ul ul ul { - list-style-type:square; -} - -ul.disc { - list-style-type:disc; -} - -ul.circle { - list-style-type:circle; -} - -ul.square { - list-style-type:square; -} - -ol { - list-style-type:decimal; -} - -ol ol { - list-style-type:lower-alpha; -} - -ol ol ol { - list-style-type:lower-roman; -} - -ol ul { - list-style-type:circle; -} - -ol.decimal { - list-style-type:decimal; -} - -ol.upper-alpha { - list-style-type:upper-alpha; -} - -ol.lower-alpha { - list-style-type:lower-alpha; -} - -ol.upper-roman { - list-style-type:upper-roman; -} - -ol.lower-roman { - list-style-type:lower-roman; -} - -ol.nolist, -ul.nolist { - padding-left:0; - list-style-image:none; - list-style-type:none; - margin-left:0; -} - -.center { - text-align:center; -} - -code, -kbd, -pre { - color:#009900; -} - -kbd { - font-weight: bold; -} - -table.striped code { - background-color:inherit; -} - -pre { - padding:6px 10px; - background-color:#FAFAFA; - border:1px solid #bbb; - overflow:auto; -} - -pre.prettyprint { - padding:6px 10px !important; - border:1px solid #bbb !important; -} - -code.bad, code.badcode { - color: magenta; -} -pre.bad, pre.badcode { - background-color:#ffe6d8; - border-top:1px inset #a03; - border-left:1px inset #a03; -} - -.tip { - background-color:#fffbd9; - padding:6px 8px 6px 10px; - border-left:6px solid #ffef70; -} - -.note { - background-color:#e5ecf9; - padding:6px 8px 6px 10px; - border-left:6px solid #36c; -} - -@media print { - - .str { - color:#060; - } - - .kwd { - color:#006; - font-weight:bold; - } - - .com { - color:#600; - font-style:italic; - } - - .typ { - color:#404; - font-weight:bold; - } - - .lit { - color:#044; - } - - .pun, - .opn, - .clo { - color:#440; - } - - .pln { - color:#000; - } - - .tag { - color:#006; - font-weight:bold; - } - - .atn { - color:#404; - } - - .atv { - color:#060; - } - - h1 { - font-style:italic; - } -} - -ol.linenums { - margin-top:0; - margin-bottom:0; -} - -code { - background-color:#FAFAFA; - padding: 0.25em 0.5em; - white-space: nowrap -} diff --git a/javaguide.html b/javaguide.html deleted file mode 100644 index 74bfbad..0000000 --- a/javaguide.html +++ /dev/null @@ -1,793 +0,0 @@ - - - - - - - Google Java Style - - -

Google Java Style

-
Last changed: March 21, 2014
- - - - -
-
-
-
-1 Introduction -
-
-1.1 Terminology notes -
-
-1.2 Guide notes -
-
-
-2 Source file basics -
-
-2.1 File name -
-
-2.2 File encoding: UTF-8 -
-
-2.3 Special characters -
-
-2.3.1 Whitespace characters -
-
-2.3.2 Special escape sequences -
-
-2.3.3 Non-ASCII characters -
-
-
-3 Source file structure -
-
-3.1 License or copyright information, if present -
-
-3.2 Package statement -
-
-3.3 Import statements -
-
-3.3.1 No wildcard imports -
-
-3.3.2 No line-wrapping -
-
-3.3.3 Ordering and spacing -
-
-3.4 Class declaration -
-
-3.4.1 Exactly one top-level class declaration -
-
-3.4.2 Class member ordering -
-
-
-
-
-
-4 Formatting -
-
-4.1 Braces -
-
-4.1.1 Braces are used where optional -
-
-4.1.2 Nonempty blocks: K & R style -
-
-4.1.3 Empty blocks: may be concise -
-
-4.2 Block indentation: +2 spaces -
-
-4.3 One statement per line -
-
-4.4 Column limit: 80 or 100 -
-
-4.5 Line-wrapping -
-
-4.5.1 Where to break -
-
-4.5.2 Indent continuation lines at least +4 spaces -
-
-4.6 Whitespace -
-
-4.6.1 Vertical Whitespace -
-
-4.6.2 Horizontal whitespace -
-
-4.6.3 Horizontal alignment: never required -
-
-4.7 Grouping parentheses: recommended -
-
-4.8 Specific constructs -
-
-4.8.1 Enum classes -
-
-4.8.2 Variable declarations -
-
-4.8.3 Arrays -
-
-4.8.4 Switch statements -
-
-4.8.5 Annotations -
-
-4.8.6 Comments -
-
-4.8.7 Modifiers -
-
-4.8.8 Numeric Literals -
-
-
-
-
-
-5 Naming -
-
-5.1 Rules common to all identifiers -
-
-5.2 Rules by identifier type -
-
-5.2.1 Package names -
-
-5.2.2 Class names -
-
-5.2.3 Method names -
-
-5.2.4 Constant names -
-
-5.2.5 Non-constant field names -
-
-5.2.6 Parameter names -
-
-5.2.7 Local variable names -
-
-5.2.8 Type variable names -
-
-5.3 Camel case: defined -
-
-
-6 Programming Practices -
-
-6.1 @Override: always used -
-
-6.2 Caught exceptions: not ignored -
-
-6.3 Static members: qualified using class -
-
-6.4 Finalizers: not used -
-
-
-7 Javadoc -
-
-7.1 Formatting -
-
-7.1.1 General form -
-
-7.1.2 Paragraphs -
-
-7.1.3 At-clauses -
-
-7.2 The summary fragment -
-
-7.3 Where Javadoc is used -
-
-7.3.1 Exception: self-explanatory methods -
-
-7.3.2 Exception: overrides -
-
-
-
-

1 Introduction 

-

This document serves as the complete definition of Google's coding standards for -source code in the Java™ Programming Language. A Java source file is described as being in -Google Style if and only if it adheres to the rules herein.

Like other programming style guides, the issues covered span not only aesthetic issues of -formatting, but other types of conventions or coding standards as well. However, this document -focuses primarily on the hard-and-fast rules that we follow universally, and -avoids giving advice that isn't clearly enforceable (whether by human or tool). -

-

1.1 Terminology notes 

-

In this document, unless otherwise clarified:

  1. The term class is used inclusively to mean an "ordinary" class, enum class, - interface or annotation type (@interface).
  2. The term comment always refers to implementation comments. We do not - use the phrase "documentation comments", instead using the common term "Javadoc."

Other "terminology notes" will appear occasionally throughout the document.

-

1.2 Guide notes 

-

Example code in this document is non-normative. That is, while the examples -are in Google Style, they may not illustrate the only stylish way to represent the -code. Optional formatting choices made in examples should not be enforced as rules.

-

2 Source file basics 

- -

2.1 File name 

-

The source file name consists of the case-sensitive name of the top-level class it contains, -plus the .java extension.

-

2.2 File encoding: UTF-8 

-

Source files are encoded in UTF-8.

-

2.3 Special characters 

- -

2.3.1 Whitespace characters 

-

Aside from the line terminator sequence, the ASCII horizontal space -character (0x20) is the only whitespace character that appears -anywhere in a source file. This implies that:

  1. All other whitespace characters in string and character literals are escaped.
  2. Tab characters are not used for indentation.
-

2.3.2 Special escape sequences 

-

For any character that has a special escape sequence -(\b, -\t, -\n, -\f, -\r, -\", -\' and -\\), that sequence -is used rather than the corresponding octal -(e.g. \012) or Unicode -(e.g. \u000a) escape.

-

2.3.3 Non-ASCII characters 

-

For the remaining non-ASCII characters, either the actual Unicode character -(e.g. ) or the equivalent Unicode escape -(e.g. \u221e) is used, depending only on which -makes the code easier to read and understand.

Tip: In the Unicode escape case, and occasionally even when actual -Unicode characters are used, an explanatory comment can be very helpful.

Examples:

ExampleDiscussion
String unitAbbrev = "μs";Best: perfectly clear even without a comment.
String unitAbbrev = "\u03bcs"; // "μs"Allowed, but there's no reason to do this.
String unitAbbrev = "\u03bcs"; - // Greek letter mu, "s"Allowed, but awkward and prone to mistakes.
String unitAbbrev = "\u03bcs";Poor: the reader has no idea what this is.
return '\ufeff' + content; - // byte order markGood: use escapes for non-printable characters, and comment if necessary.

Tip: Never make your code less readable simply out of fear that -some programs might not handle non-ASCII characters properly. If that should happen, those -programs are broken and they must be fixed.

-

3 Source file structure 

-

A source file consists of, in order:

  1. License or copyright information, if present
  2. Package statement
  3. Import statements
  4. Exactly one top-level class

Exactly one blank line separates each section that is present.

-

3.1 License or copyright information, if present 

-

If license or copyright information belongs in a file, it belongs here.

-

3.2 Package statement 

-

The package statement is not line-wrapped. The column limit (Section 4.4, -Column limit: 80 or 100) does not apply to package statements.

-

3.3 Import statements 

- -

3.3.1 No wildcard imports 

-

Wildcard imports, static or otherwise, are not used.

-

3.3.2 No line-wrapping 

-

Import statements are not line-wrapped. The column limit (Section 4.4, -Column limit: 80 or 100) does not apply to import -statements.

-

3.3.3 Ordering and spacing 

-

Import statements are divided into the following groups, in this order, with each group -separated by a single blank line:

  1. All static imports in a single group
  2. com.google imports - (only if this source file is in the com.google package - space)
  3. Third-party imports, one group per top-level package, in ASCII sort order -
    • for example: android, com, junit, org, - sun
  4. java imports
  5. javax imports

Within a group there are no blank lines, and the imported names appear in ASCII sort -order. (Note: this is not the same as the import statements being in -ASCII sort order; the presence of semicolons warps the result.)

-

3.4 Class declaration 

- -

3.4.1 Exactly one top-level class declaration 

-

Each top-level class resides in a source file of its own.

-

3.4.2 Class member ordering 

-

The ordering of the members of a class can have a great effect on learnability, but there is -no single correct recipe for how to do it. Different classes may order their members -differently.

What is important is that each class order its members in some logical -order, which its maintainer could explain if asked. For example, new methods are not -just habitually added to the end of the class, as that would yield "chronological by date -added" ordering, which is not a logical ordering.

-
3.4.2.1 Overloads: never split 
-

When a class has multiple constructors, or multiple methods with the same name, these appear -sequentially, with no intervening members.

-

4 Formatting 

-

Terminology Note: block-like construct refers to -the body of a class, method or constructor. Note that, by Section 4.8.3.1 on -array initializers, any array initializer -may optionally be treated as if it were a block-like construct.

-

4.1 Braces 

- -

4.1.1 Braces are used where optional 

-

Braces are used with -if, -else, -for, -do and -while statements, even when the -body is empty or contains only a single statement.

-

4.1.2 Nonempty blocks: K & R style 

-

Braces follow the Kernighan and Ritchie style -("Egyptian brackets") -for nonempty blocks and block-like constructs:

Example:

-return new MyClass() {
-  @Override public void method() {
-    if (condition()) {
-      try {
-        something();
-      } catch (ProblemException e) {
-        recover();
-      }
-    }
-  }
-};
-

A few exceptions for enum classes are given in Section 4.8.1, -Enum classes.

-

4.1.3 Empty blocks: may be concise 

-

An empty block or block-like construct may be closed immediately after it is -opened, with no characters or line break in between -({}), unless it is part of a -multi-block statement (one that directly contains multiple blocks: -if/else-if/else or -try/catch/finally).

Example:

-  void doNothing() {}
-
-

4.2 Block indentation: +2 spaces 

-

Each time a new block or block-like construct is opened, the indent increases by two -spaces. When the block ends, the indent returns to the previous indent level. The indent level -applies to both code and comments throughout the block. (See the example in Section 4.1.2, -Nonempty blocks: K & R Style.)

-

4.3 One statement per line 

-

Each statement is followed by a line-break.

-

4.4 Column limit: 80 or 100 

-

- Projects are free to choose a column limit of either 80 or 100 characters. - -Except as noted below, any line that would exceed this limit must be line-wrapped, as explained in -Section 4.5, Line-wrapping. -

Exceptions:

  1. Lines where obeying the column limit is not possible (for example, a long URL in Javadoc, - or a long JSNI method reference).
  2. package and - import statements (see Sections - 3.2 Package statement and - 3.3 Import statements).
  3. Command lines in a comment that may be cut-and-pasted into a shell.
-

4.5 Line-wrapping 

-

Terminology Note: When code that might otherwise legally -occupy a single line is divided into multiple lines, typically to avoid overflowing the column -limit, this activity is called -line-wrapping.

There is no comprehensive, deterministic formula showing exactly how to line-wrap in -every situation. Very often there are several valid ways to line-wrap the same piece of code.

Tip: Extracting a method or local variable may solve the problem -without the need to line-wrap.

-

4.5.1 Where to break 

-

The prime directive of line-wrapping is: prefer to break at a -higher syntactic level. Also:

  1. When a line is broken at a non-assignment operator the break comes before - the symbol. (Note that this is not the same practice used in Google style for other languages, - such as C++ and JavaScript.) -
    • This also applies to the following "operator-like" symbols: the dot separator - (.), the ampersand in type bounds - (<T extends Foo & Bar>), and the pipe in - catch blocks - (catch (FooException | BarException e)).
  2. When a line is broken at an assignment operator the break typically comes - after the symbol, but either way is acceptable. -
    • This also applies to the "assignment-operator-like" colon in an enhanced - for ("foreach") statement.
  3. A method or constructor name stays attached to the open parenthesis - (() that follows it.
  4. A comma (,) stays attached to the token that - precedes it.
-

4.5.2 Indent continuation lines at least +4 spaces 

-

When line-wrapping, each line after the first (each continuation line) is indented -at least +4 from the original line.

When there are multiple continuation lines, indentation may be varied beyond +4 as -desired. In general, two continuation lines use the same indentation level if and only if they -begin with syntactically parallel elements.

Section 4.6.3 on Horizontal alignment addresses -the discouraged practice of using a variable number of spaces to align certain tokens with -previous lines.

-

4.6 Whitespace 

- -

4.6.1 Vertical Whitespace 

-

A single blank line appears:

  1. Between consecutive members (or initializers) of a class: fields, constructors, - methods, nested classes, static initializers, instance initializers. -
    • Exception: A blank line between two consecutive - fields (having no other code between them) is optional. Such blank lines are used as needed to - create logical groupings of fields.
  2. Within method bodies, as needed to create logical groupings of statements.
  3. Optionally before the first member or after the last member of the class (neither - encouraged nor discouraged).
  4. As required by other sections of this document (such as Section 3.3, - Import statements).

Multiple consecutive blank lines are permitted, but never required (or encouraged).

-

4.6.2 Horizontal whitespace 

-

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.

  1. Separating any reserved word, such as - if, - for or - catch, from an open parenthesis - (() - that follows it on that line
  2. Separating any reserved word, such as - else or - catch, from a closing curly brace - (}) that precedes it on that line
  3. Before any open curly brace - ({), with two exceptions: -
    • @SomeAnnotation({a, b}) (no space is used)
    • String[][] x = {{"foo"}}; (no space is required - between {{, by item 8 below)
  4. On both sides of any binary or ternary operator. This also applies to the following - "operator-like" symbols: -
    • the ampersand in a conjunctive type bound: - <T extends Foo & Bar>
    • the pipe for a catch block that handles multiple exceptions: - catch (FooException | BarException e)
    • the colon (:) in an enhanced - for ("foreach") statement
  5. After ,:; or the closing parenthesis - ()) of a cast
  6. On both sides of the double slash (//) that - begins an end-of-line comment. Here, multiple spaces are allowed, but not required.
  7. Between the type and variable of a declaration: - List<String> list
  8. Optional just inside both braces of an array initializer -
    • new int[] {5, 6} and - new int[] { 5, 6 } are both valid

Note: This rule never requires or forbids additional space at the -start or end of a line, only interior space.

-

4.6.3 Horizontal alignment: never required 

-

Terminology Note: Horizontal alignment is the -practice of adding a variable number of additional spaces in your code with the goal of making -certain tokens appear directly below certain other tokens on previous lines.

This practice is permitted, but is never required by Google Style. It is not -even required to maintain horizontal alignment in places where it was already used.

Here is an example without alignment, then using alignment:

-private int x; // this is fine
-private Color color; // this too
-
-private int   x;      // permitted, but future edits
-private Color color;  // may leave it unaligned
-

Tip: Alignment can aid readability, but it creates problems for -future maintenance. Consider a future change that needs to touch just one line. This change may -leave the formerly-pleasing formatting mangled, and that is allowed. More often -it prompts the coder (perhaps you) to adjust whitespace on nearby lines as well, possibly -triggering a cascading series of reformattings. That one-line change now has a "blast radius." -This can at worst result in pointless busywork, but at best it still corrupts version history -information, slows down reviewers and exacerbates merge conflicts.

-

4.7 Grouping parentheses: recommended 

-

Optional grouping parentheses are omitted only when author and reviewer agree that there is no -reasonable chance the code will be misinterpreted without them, nor would they have made the code -easier to read. It is not reasonable to assume that every reader has the entire Java -operator precedence table memorized.

-

4.8 Specific constructs 

- -

4.8.1 Enum classes 

-

After each comma that follows an enum constant, a line-break is optional.

An enum class with no methods and no documentation on its constants may optionally be formatted -as if it were an array initializer (see Section 4.8.3.1 on -array initializers).

-private enum Suit { CLUBS, HEARTS, SPADES, DIAMONDS }
-

Since enum classes are classes, all other rules for formatting classes apply.

-

4.8.2 Variable declarations 

- -
4.8.2.1 One variable per declaration 
-

Every variable declaration (field or local) declares only one variable: declarations such as -int a, b; are not used.

-
4.8.2.2 Declared when needed, initialized as soon as -possible 
-

Local variables are not habitually declared at the start of their containing -block or block-like construct. Instead, local variables are declared close to the point they are -first used (within reason), to minimize their scope. Local variable declarations typically have -initializers, or are initialized immediately after declaration.

-

4.8.3 Arrays 

- -
4.8.3.1 Array initializers: can be "block-like" 
-

Any array initializer may optionally be formatted as if it were a "block-like -construct." For example, the following are all valid (not an exhaustive -list):

-new int[] {           new int[] {
-  0, 1, 2, 3            0,
-}                       1,
-                        2,
-new int[] {             3,
-  0, 1,               }
-  2, 3
-}                     new int[]
-                          {0, 1, 2, 3}
-
-
4.8.3.2 No C-style array declarations 
-

The square brackets form a part of the type, not the variable: -String[] args, not -String args[].

-

4.8.4 Switch statements 

-

Terminology Note: Inside the braces of a -switch block are one or more statement groups. Each statement group consists of -one or more switch labels (either case FOO: or -default:), followed by one or more statements.

-
4.8.4.1 Indentation 
-

As with any other block, the contents of a switch block are indented +2.

After a switch label, a newline appears, and the indentation level is increased +2, exactly as -if a block were being opened. The following switch label returns to the previous indentation -level, as if a block had been closed.

-
4.8.4.2 Fall-through: commented 
-

Within a switch block, each statement group either terminates abruptly (with a -break, -continue, -return or thrown exception), or is marked with a comment -to indicate that execution will or might continue into the next statement group. Any -comment that communicates the idea of fall-through is sufficient (typically -// fall through). This special comment is not required in -the last statement group of the switch block. Example:

-switch (input) {
-  case 1:
-  case 2:
-    prepareOneOrTwo();
-    // fall through
-  case 3:
-    handleOneTwoOrThree();
-    break;
-  default:
-    handleLargeNumber(input);
-}
-
-
4.8.4.3 The default case is present 
-

Each switch statement includes a default statement -group, even if it contains no code.

-

4.8.5 Annotations 

-

Annotations applying to a class, method or constructor appear immediately after the -documentation block, and each annotation is listed on a line of its own (that is, one annotation -per line). These line breaks do not constitute line-wrapping (Section -4.5, Line-wrapping), so the indentation level is not -increased. Example:

-@Override
-@Nullable
-public String getNameIfPresent() { ... }
-

Exception: A single parameterless annotation -may instead appear together with the first line of the signature, for example:

-@Override public int hashCode() { ... }
-

Annotations applying to a field also appear immediately after the documentation block, but in -this case, multiple annotations (possibly parameterized) may be listed on the same line; -for example:

-@Partial @Mock DataLoader loader;
-

There are no specific rules for formatting parameter and local variable annotations.

-

4.8.6 Comments 

- -
4.8.6.1 Block comment style 
-

Block comments are indented at the same level as the surrounding code. They may be in -/* ... */ style or -// ... style. For multi-line -/* ... */ comments, subsequent lines must start with -* aligned with the * on the previous line.

-/*
- * This is          // And so           /* Or you can
- * okay.            // is this.          * even do this. */
- */
-

Comments are not enclosed in boxes drawn with asterisks or other characters.

Tip: When writing multi-line comments, use the -/* ... */ style if you want automatic code formatters to -re-wrap the lines when necessary (paragraph-style). Most formatters don't re-wrap lines in -// ... style comment blocks.

-

4.8.7 Modifiers 

-

Class and member modifiers, when present, appear in the order -recommended by the Java Language Specification: -

-public protected private abstract static final transient volatile synchronized native strictfp
-
-

4.8.8 Numeric Literals 

-

long-valued integer literals use an uppercase L suffix, never -lowercase (to avoid confusion with the digit 1). For example, 3000000000L -rather than 3000000000l.

-

5 Naming 

- -

5.1 Rules common to all identifiers 

-

Identifiers use only ASCII letters and digits, and in two cases noted below, underscores. Thus -each valid identifier name is matched by the regular expression \w+ .

In Google Style special prefixes or -suffixes, like those seen in the examples name_, -mName, s_name and -kName, are not used.

-

5.2 Rules by identifier type 

- -

5.2.1 Package names 

-

Package names are all lowercase, with consecutive words simply concatenated together (no -underscores). For example, com.example.deepspace, not -com.example.deepSpace or -com.example.deep_space.

-

5.2.2 Class names 

-

Class names are written in UpperCamelCase.

Class names are typically nouns or noun phrases. For example, -Character or -ImmutableList. Interface names may also be nouns or -noun phrases (for example, List), but may sometimes be -adjectives or adjective phrases instead (for example, -Readable).

There are no specific rules or even well-established conventions for naming annotation types.

Test classes are named starting with the name of the class they are testing, and ending -with Test. For example, -HashTest or -HashIntegrationTest.

-

5.2.3 Method names 

-

Method names are written in lowerCamelCase.

Method names are typically verbs or verb phrases. For example, -sendMessage or -stop.

Underscores may appear in JUnit test method names to separate logical components of the -name. One typical pattern is test<MethodUnderTest>_<state>, -for example testPop_emptyStack. There is no One Correct -Way to name test methods.

-

5.2.4 Constant names 

-

Constant names use CONSTANT_CASE: all uppercase -letters, with words separated by underscores. But what is a constant, exactly?

Every constant is a static final field, but not all static final fields are constants. Before -choosing constant case, consider whether the field really feels like a constant. For -example, if any of that instance's observable state can change, it is almost certainly not a -constant. Merely intending to never mutate the object is generally not -enough. Examples:

-// Constants
-static final int NUMBER = 5;
-static final ImmutableList<String> NAMES = ImmutableList.of("Ed", "Ann");
-static final Joiner COMMA_JOINER = Joiner.on(',');  // because Joiner is immutable
-static final SomeMutableType[] EMPTY_ARRAY = {};
-enum SomeEnum { ENUM_CONSTANT }
-
-// Not constants
-static String nonFinal = "non-final";
-final String nonStatic = "non-static";
-static final Set<String> mutableCollection = new HashSet<String>();
-static final ImmutableSet<SomeMutableType> mutableElements = ImmutableSet.of(mutable);
-static final Logger logger = Logger.getLogger(MyClass.getName());
-static final String[] nonEmptyArray = {"these", "can", "change"};
-

These names are typically nouns or noun phrases.

-

5.2.5 Non-constant field names 

-

Non-constant field names (static or otherwise) are written -in lowerCamelCase.

These names are typically nouns or noun phrases. For example, -computedValues or -index.

-

5.2.6 Parameter names 

-

Parameter names are written in lowerCamelCase.

One-character parameter names should be avoided.

-

5.2.7 Local variable names 

-

Local variable names are written in lowerCamelCase, and can be -abbreviated more liberally than other types of names.

However, one-character names should be avoided, except for temporary and looping variables.

Even when final and immutable, local variables are not considered to be constants, and should not -be styled as constants.

-

5.2.8 Type variable names 

-

Each type variable is named in one of two styles:

-

5.3 Camel case: defined 

-

Sometimes there is more than one reasonable way to convert an English phrase into camel case, -such as when acronyms or unusual constructs like "IPv6" or "iOS" are present. To improve -predictability, Google Style specifies the following (nearly) deterministic scheme.

Beginning with the prose form of the name:

  1. Convert the phrase to plain ASCII and remove any apostrophes. For example, "Müller's - algorithm" might become "Muellers algorithm".
  2. Divide this result into words, splitting on spaces and any remaining punctuation (typically - hyphens). - -
    • Recommended: if any word already has a conventional camel-case appearance in common - usage, split this into its constituent parts (e.g., "AdWords" becomes "ad words"). Note - that a word such as "iOS" is not really in camel case per se; it defies any - convention, so this recommendation does not apply.
  3. Now lowercase everything (including acronyms), then uppercase only the first - character of: -
    • ... each word, to yield upper camel case, or
    • ... each word except the first, to yield lower camel case
  4. Finally, join all the words into a single identifier.

Note that the casing of the original words is almost entirely disregarded. Examples:

Prose formCorrectIncorrect
"XML HTTP request"XmlHttpRequestXMLHTTPRequest
"new customer ID"newCustomerIdnewCustomerID
"inner stopwatch"innerStopwatchinnerStopWatch
"supports IPv6 on iOS?"supportsIpv6OnIossupportsIPv6OnIOS
"YouTube importer"YouTubeImporter
YoutubeImporter*

*Acceptable, but not recommended.

Note: Some words are ambiguously hyphenated in the English -language: for example "nonempty" and "non-empty" are both correct, so the method names -checkNonempty and -checkNonEmpty are likewise both correct.

-

6 Programming Practices 

- -

6.1 @Override: always used 

-

A method is marked with the @Override annotation -whenever it is legal. This includes a class method overriding a superclass method, a class method -implementing an interface method, and an interface method respecifying a superinterface -method.

Exception:@Override may be omitted when the parent method is -@Deprecated.

-

6.2 Caught exceptions: not ignored 

-

Except as noted below, 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.

-try {
-  int i = Integer.parseInt(response);
-  return handleNumericResponse(i);
-} catch (NumberFormatException ok) {
-  // it's not numeric; that's fine, just continue
-}
-return handleTextResponse(response);
-

Exception: In tests, a caught exception may be ignored -without comment if it is named expected. The -following is a very common idiom for ensuring that the method under test does throw an -exception of the expected type, so a comment is unnecessary here.

-try {
-  emptyStack.pop();
-  fail();
-} catch (NoSuchElementException expected) {
-}
-
-

6.3 Static members: qualified using class 

-

When a reference to a static class member must be qualified, it is qualified with that class's -name, not with a reference or expression of that class's type.

-Foo aFoo = ...;
-Foo.aStaticMethod(); // good
-aFoo.aStaticMethod(); // bad
-somethingThatYieldsAFoo().aStaticMethod(); // very bad
-
-

6.4 Finalizers: not used 

-

It is extremely rare to override Object.finalize.

Tip: Don't do it. If you absolutely must, first read and understand -Effective Java -Item 7, "Avoid Finalizers," very carefully, and then don't do it.

-

7 Javadoc 

- -

7.1 Formatting 

- -

7.1.1 General form 

-

The basic formatting of Javadoc blocks is as seen in this example:

-/**
- * Multiple lines of Javadoc text are written here,
- * wrapped normally...
- */
-public int method(String p1) { ... }
-

... or in this single-line example:

-/** An especially short bit of Javadoc. */
-

The basic form is always acceptable. The single-line form may be substituted when there are no -at-clauses present, and the entirety of the Javadoc block (including comment markers) can fit on a -single line.

-

7.1.2 Paragraphs 

-

One blank line—that is, a line containing only the aligned leading asterisk -(*)—appears between paragraphs, and before the group of "at-clauses" if -present. Each paragraph but the first has <p> immediately before the first word, -with no space after.

-

7.1.3 At-clauses 

-

Any of the standard "at-clauses" that are used appear in the order @param, -@return, @throws, @deprecated, and these four types never -appear with an empty description. When an at-clause doesn't fit on a single line, continuation lines -are indented four (or more) spaces from the position of the @. -

-

7.2 The summary fragment 

-

The Javadoc for each class and member begins with a brief summary fragment. This -fragment is very important: it is the only part of the text that appears in certain contexts such as -class and method indexes.

This is a fragment—a noun phrase or verb phrase, not a complete sentence. It does -not begin with A {@code Foo} is a..., or -This method returns..., nor does it form a complete imperative sentence -like Save the record.. However, the fragment is capitalized and -punctuated as if it were a complete sentence.

Tip: A common mistake is to write simple Javadoc in the form -/** @return the customer ID */. This is incorrect, and should be -changed to /** Returns the customer ID. */.

-

7.3 Where Javadoc is used 

-

At the minimum, Javadoc is present for every -public class, and every -public or -protected member of such a class, with a few exceptions -noted below.

Other classes and members still have Javadoc as needed. Whenever an implementation -comment would be used to define the overall purpose or behavior of a class, method or field, that -comment is written as Javadoc instead. (It's more uniform, and more tool-friendly.)

-

7.3.1 Exception: self-explanatory methods 

-

Javadoc is optional for "simple, obvious" methods like -getFoo, in cases where there really and truly is -nothing else worthwhile to say but "Returns the foo".

Important: it is not appropriate to cite this exception to justify -omitting relevant information that a typical reader might need to know. For example, for a method -named getCanonicalName, don't omit its documentation -(with the rationale that it would say only -/** Returns the canonical name. */) if a typical reader may have no idea -what the term "canonical name" means!

-

7.3.2 Exception: overrides 

-

Javadoc is not always present on a method that overrides a supertype method. -


-
Last changed: March 21, 2014
- - diff --git a/javaguidelink.png b/javaguidelink.png deleted file mode 100644 index 75d5c7b..0000000 Binary files a/javaguidelink.png and /dev/null differ diff --git a/javascriptguide.xml b/javascriptguide.xml deleted file mode 100644 index a80a032..0000000 --- a/javascriptguide.xml +++ /dev/null @@ -1,3627 +0,0 @@ - - - -

- - Revision 2.93 -

- -
- Aaron Whyte
- Bob Jervis
- Dan Pupius
- Erik Arvidsson
- Fritz Schneider
- Robby Walker
-
- - - - - This style guide contains many details that are initially - hidden from view. They are marked by the triangle icon, which you - see here on your left. Click it now. - You should see "Hooray" appear below. - - -

- Hooray! Now you know you can expand points to get more - details. Alternatively, there's a "toggle all" at the - top of this document. -

- -
-
- -

- JavaScript is the main client-side scripting language used - - by many of Google's open-source - projects. - This style guide is a list of dos and don'ts for - JavaScript programs. -

- - - - - -
-
- - - - - - - - Declarations with var: Always - - - - When you fail to specify var, - the variable gets placed in the global context, potentially clobbering - existing values. Also, if there's no declaration, it's hard to tell in - what scope a variable lives (e.g., it could be in the Document or - Window just as easily as in the local scope). So always declare with - var. - - - - - - -
    -
  • Use NAMES_LIKE_THIS for constant values.
  • -
  • Use @const to indicate a constant (non-overwritable) - pointer (a variable or property).
  • -
  • Never use the - - const keyword - as it's not supported in Internet Explorer.
  • -
-
- - - - -

If a value is intended to be constant - and immutable, it should be given a name - in CONSTANT_VALUE_CASE. - ALL_CAPS additionally implies @const - (that the value is not overwritable). -

- -

Primitive types (number, string, - boolean) are constant values.

- -

Objects' - immutability is more subjective — objects should be - considered immutable only if they do not demonstrate observable - state change. This is not enforced by the compiler.

- - -
- - -

The @const annotation on a variable or property - implies that it is not overwritable. This is enforced by the - compiler at build time. This behavior is consistent with the - - const keyword (which we do not use due to the - lack of support in Internet Explorer).

- -

A @const annotation on a method additionally - implies that the method cannot not be overridden in subclasses. -

- -

A @const annotation on a constructor implies the - class cannot be subclassed (akin to final in Java). -

- -
- - - -

Note that @const does not necessarily imply - CONSTANT_VALUES_CASE. - - However, CONSTANT_VALUES_CASE - does imply @const. -

- - - /** - * Request timeout in milliseconds. - * @type {number} - */ - goog.example.TIMEOUT_IN_MILLISECONDS = 60; - - -

The number of seconds in a minute never changes. It is a - constant value. ALL_CAPS - also implies @const, so the constant cannot be - overwritten. -

- -

The open source compiler will allow the symbol to be - overwritten because the constant is - not marked as @const.

- - - /** - * Map of URL to response string. - * @const - */ - MyClass.fetchedUrlCache_ = new goog.structs.Map(); - - - - /** - * Class that cannot be subclassed. - * @const - * @constructor - */ - sloth.MyFinalClass = function() {}; - - -

In this case, the pointer can never be overwritten, but - value is highly mutable and not constant (and thus in - camelCase, not ALL_CAPS).

-
- -
- -
- - - - Always use semicolons. - - -

Relying on implicit insertion can cause subtle, hard to debug - problems. Don't do it. You're better than that.

-

There are a couple places where missing semicolons are particularly - dangerous:

- - // 1. - MyClass.prototype.myMethod = function() { - return 42; - } // No semicolon here. - - (function() { - // Some initialization code wrapped in a function to create a scope for locals. - })(); - - - var x = { - 'i': 1, - 'j': 2 - } // No semicolon here. - - // 2. Trying to do one thing on Internet Explorer and another on Firefox. - // I know you'd never write code like this, but throw me a bone. - [ffVersion, ieVersion][isIE](); - - - var THINGS_TO_EAT = [apples, oysters, sprayOnCheese] // No semicolon here. - - // 3. conditional execution a la bash - -1 == resultOfOperation() || die(); - - -
    -
  1. JavaScript error - first the function returning 42 is called - with the second function as a parameter, then the number 42 is - "called" resulting in an error.
  2. -
  3. You will most likely get a 'no such property in undefined' - error at runtime as it tries to call - x[ffVersion, ieVersion][isIE]().
  4. -
  5. die is always called since the array minus 1 is - NaN which is never equal to anything (not even if - resultOfOperation() returns NaN) and - THINGS_TO_EAT gets assigned the result of - die().
  6. -
-
- -

JavaScript requires statements to end with a semicolon, except when - it thinks it can safely infer their existence. In each of these - examples, a function declaration or object or array literal is used - inside a statement. The closing brackets are not enough to signal - the end of the statement. Javascript never ends a statement if the - next token is an infix or bracket operator.

-

This has really surprised people, so make sure your assignments end - with semicolons.

-
- -

Semicolons should be included at the end of function expressions, - but not at the end of function declarations. The distinction is - best illustrated with an example:

- - var foo = function() { - return true; - }; // semicolon here. - - function foo() { - return true; - } // no semicolon here. - -
- -
- - - Yes - -

Nested functions can be very useful, for example in the creation of - continuations and for the task of hiding helper functions. Feel free - to use them.

- -
- - - No - -

Do not do this:

- - if (x) { - function foo() {} - } - - -

While most script engines support Function Declarations within blocks - it is not part of ECMAScript (see - ECMA-262, - clause 13 and 14). Worse implementations are inconsistent with each - other and with future EcmaScript proposals. ECMAScript only allows for - Function Declarations in the root statement list of a script or - function. Instead use a variable initialized with a Function - Expression to define a function within a block:

- - if (x) { - var foo = function() {}; - } - - -
- - - Yes - -

You basically can't avoid exceptions if you're doing something - non-trivial (using an application development framework, etc.). - Go for it.

- -
- - - Yes - -

Without custom exceptions, returning error information from a - function that also returns a value can be tricky, not to mention - inelegant. Bad solutions include passing in a reference type to hold - error information or always returning Objects with a potential - error member. These basically amount to a primitive exception - handling hack. Feel free to use custom exceptions when - appropriate.

- -
- - - Always preferred over non-standards features - -

For maximum portability and compatibility, always prefer standards - features over non-standards features (e.g., - string.charAt(3) over string[3] and element - access with DOM functions instead of using an application-specific - shorthand).

- -
- - - No - -

There's no reason to use wrapper objects for primitive types, plus - they're dangerous:

- - var x = new Boolean(false); - if (x) { - alert('hi'); // Shows 'hi'. - } - -

Don't do it!

-

However type casting is fine.

- - var x = Boolean(0); - if (x) { - alert('hi'); // This will never be alerted. - } - typeof Boolean(0) == 'boolean'; - typeof new Boolean(0) == 'object'; - -

This is very useful for casting things to - number, string and boolean.

- -
- - - Not preferred - -

Multi-level prototype hierarchies are how JavaScript implements - inheritance. You have a multi-level hierarchy if you have a - user-defined class D with another user-defined class B as its - prototype. These hierarchies are much harder to get right than they - first appear!

- -

For that reason, it is best to use goog.inherits() from - - the Closure Library - - or a similar library function. -

- - function D() { - goog.base(this) - } - goog.inherits(D, B); - - D.prototype.method = function() { - ... - }; - - -
- - - /** @constructor */ - function SomeConstructor() { - this.someProperty = 1; - } - Foo.prototype.someMethod = function() { ... }; - -

While there are several ways to attach methods and properties to an - object created via "new", the preferred style for methods - is:

- - Foo.prototype.bar = function() { - /* ... */ - }; - -

The preferred style for other properties is to initialize the field - in the constructor:

- - /** @constructor */ - function Foo() { - this.bar = value; - } - - -

Current JavaScript engines optimize based on the "shape" - of an object, - adding a property to an object (including overriding - a value set on the prototype) changes the shape and can degrade - performance.

-
- -
- - - Prefer this.foo = null. - - - Foo.prototype.dispose = function() { - this.property_ = null; - }; - -

Instead of:

- - Foo.prototype.dispose = function() { - delete this.property_; - }; - -

In modern JavaScript engines, changing the number of properties on an - object is much slower than reassigning the values. The delete keyword - should be avoided except when it is necessary to remove a property - from an object's iterated list of keys, or to change the result of - if (key in obj).

- -
- - - Yes, but be careful. - -

The ability to create closures is perhaps the most useful and often - overlooked feature of JS. Here is - - a good description of how closures work.

-

One thing to keep in mind, however, is that a closure keeps a pointer - to its enclosing scope. As a result, attaching a closure to a DOM - element can create a circular reference and thus, a memory leak. For - example, in the following code:

- - function foo(element, a, b) { - element.onclick = function() { /* uses a and b */ }; - } - -

the function closure keeps a reference to element, - a, and b even if it never uses - element. Since element also keeps a - reference to the closure, we have a cycle that won't be cleaned up by - garbage collection. In these situations, the code can be structured - as follows:

- - function foo(element, a, b) { - element.onclick = bar(a, b); - } - - function bar(a, b) { - return function() { /* uses a and b */ }; - } - - -
- - - - Only for code loaders and REPL (Read–eval–print loop) - - -

eval() makes for confusing semantics and is dangerous - to use if the string being eval()'d contains user input. - There's usually a better, clearer, and safer way to write your code, - so its use is generally not permitted.

- -

For RPC you can always use JSON and read the result using - JSON.parse() instead of eval().

- -

Let's assume we have a server that returns something like this:

- - - { - "name": "Alice", - "id": 31502, - "email": "looking_glass@example.com" - } - - - - var userInfo = eval(feed); - var email = userInfo['email']; - - -

If the feed was modified to include malicious JavaScript code, then - if we use eval then that code will be executed.

- - - var userInfo = JSON.parse(feed); - var email = userInfo['email']; - - -

With JSON.parse, invalid JSON (including all executable - JavaScript) will cause an exception to be thrown.

- - -
- - - No - -

Using with clouds the semantics of your program. - Because the object of the with can have properties that - collide with local variables, it can drastically change the meaning - of your program. For example, what does this do?

- - with (foo) { - var x = 3; - return x; - } - -

Answer: anything. The local variable x could be - clobbered by a property of foo and perhaps it even has - a setter, in which case assigning 3 could cause lots of - other code to execute. Don't use with.

- -
- - - - Only in object constructors, methods, and in setting up closures - - -

The semantics of this can be tricky. At times it refers - to the global object (in most places), the scope of the caller (in - eval), a node in the DOM tree (when attached using an - event handler HTML attribute), a newly created object (in a - constructor), or some other object (if function was - call()ed or apply()ed).

-

Because this is so easy to get wrong, limit its use to those places - where it is required:

-
    -
  • in constructors
  • -
  • in methods of objects (including in the creation of closures)
  • -
- -
- - - - Only for iterating over keys in an object/map/hash - - -

for-in loops are often incorrectly used to loop over - the elements in an Array. This is however very error - prone because it does not loop from 0 to - length - 1 but over all the present keys in the object - and its prototype chain. Here are a few cases where it fails:

- - function printArray(arr) { - for (var key in arr) { - print(arr[key]); - } - } - - printArray([0,1,2,3]); // This works. - - var a = new Array(10); - printArray(a); // This is wrong. - - a = document.getElementsByTagName('*'); - printArray(a); // This is wrong. - - a = [0,1,2,3]; - a.buhu = 'wine'; - printArray(a); // This is wrong again. - - a = new Array; - a[3] = 3; - printArray(a); // This is wrong again. - -

Always use normal for loops when using arrays.

- - function printArray(arr) { - var l = arr.length; - for (var i = 0; i < l; i++) { - print(arr[i]); - } - } - - -
- - - - Never use Array as a map/hash/associative array - - -

Associative Arrays are not allowed... or more precisely - you are not allowed to use non number indexes for arrays. If you need - a map/hash use Object instead of Array in - these cases because the features that you want are actually features - of Object and not of Array. - Array just happens to extend Object (like - any other object in JS and therefore you might as well have used - Date, RegExp or String).

- -
- - - No - -

Do not do this:

- - var myString = 'A rather long string of English text, an error message \ - actually that just keeps going and going -- an error \ - message to make the Energizer bunny blush (right through \ - those Schwarzenegger shades)! Where was I? Oh yes, \ - you\'ve got an error and all the extraneous whitespace is \ - just gravy. Have a nice day.'; - -

The whitespace at the beginning of each line can't be safely stripped - at compile time; whitespace after the slash will result in tricky - errors; and while most script engines support this, it is not part - of ECMAScript.

-

Use string concatenation instead:

- - var myString = 'A rather long string of English text, an error message ' + - 'actually that just keeps going and going -- an error ' + - 'message to make the Energizer bunny blush (right through ' + - 'those Schwarzenegger shades)! Where was I? Oh yes, ' + - 'you\'ve got an error and all the extraneous whitespace is ' + - 'just gravy. Have a nice day.'; - - -
- - - Yes - -

Use Array and Object literals instead of - Array and Object constructors.

-

Array constructors are error-prone due to their arguments.

- - // Length is 3. - var a1 = new Array(x1, x2, x3); - - // Length is 2. - var a2 = new Array(x1, x2); - - // If x1 is a number and it is a natural number the length will be x1. - // If x1 is a number but not a natural number this will throw an exception. - // Otherwise the array will have one element with x1 as its value. - var a3 = new Array(x1); - - // Length is 0. - var a4 = new Array(); - -

Because of this, if someone changes the code to pass 1 argument - instead of 2 arguments, the array might not have the expected - length.

-

To avoid these kinds of weird cases, always use the more readable - array literal.

- - var a = [x1, x2, x3]; - var a2 = [x1, x2]; - var a3 = [x1]; - var a4 = []; - -

Object constructors don't have the same problems, but for readability - and consistency object literals should be used.

- - var o = new Object(); - - var o2 = new Object(); - o2.a = 0; - o2.b = 1; - o2.c = 2; - o2['strange key'] = 3; - -

Should be written as:

- - var o = {}; - - var o2 = { - a: 0, - b: 1, - c: 2, - 'strange key': 3 - }; - - -
- - - No - -

Modifying builtins like Object.prototype and - Array.prototype are strictly forbidden. Modifying other - builtins like Function.prototype is less dangerous but - still leads to hard to debug issues in production and should be - avoided.

- -
- - - No - -

Don't do this:

- - var f = function () { - /*@cc_on if (@_jscript) { return 2* @*/ 3; /*@ } @*/ - }; - -

Conditional Comments hinder automated tools as they can vary the - JavaScript syntax tree at runtime.

- -
-
- - - - -

In general, use - functionNamesLikeThis, - variableNamesLikeThis, - ClassNamesLikeThis, - EnumNamesLikeThis, - methodNamesLikeThis, - CONSTANT_VALUES_LIKE_THIS, - foo.namespaceNamesLikeThis.bar, and - filenameslikethis.js. -

-
- - -
    -
  • Private properties and methods should be named with a - trailing underscore. -
  • -
  • Protected properties and methods should be - named without a trailing underscore (like public ones).
  • -
-

For more information on private and protected, - read the section on - - visibility. -

- - - - -
- - -

Optional function arguments start with opt_.

-

Functions that take a variable number of arguments should have the - last argument named var_args. You may not refer to - var_args in the code; use the arguments - array.

-

Optional and variable arguments can also be specified in - @param annotations. Although either convention is - acceptable to the compiler, using both together is preferred.

- -
- - -

EcmaScript 5 getters and setters for properties are discouraged. - However, if they are used, then getters must not change observable - state.

- - /** - * WRONG -- Do NOT do this. - */ - var foo = { get next() { return this.nextId++; } }; - -
- - -

Getters and setters methods for properties are not required. - However, if they are used, then getters must be named - getFoo() and setters must be named - setFoo(value). (For boolean getters, - isFoo() is also acceptable, and often sounds more - natural.)

-
- - -

JavaScript has no inherent packaging or namespacing support.

-

Global name conflicts are difficult to debug, and can cause - intractable problems when two projects try to integrate. In order - to make it possible to share common JavaScript code, we've adopted - conventions to prevent collisions.

- -

ALWAYS prefix identifiers in the global scope with a - unique pseudo namespace related to the project or library. If you - are working on "Project Sloth", a reasonable pseudo namespace - would be sloth.*.

- - var sloth = {}; - - sloth.sleep = function() { - ... - }; - - - -

Many JavaScript libraries, including - - the Closure Library - - and - - Dojo toolkit - - give you high-level functions for declaring your namespaces. - Be consistent about how you declare your namespaces.

- - goog.provide('sloth'); - - sloth.sleep = function() { - ... - }; - -
- -

When choosing a child-namespace, make sure that the owners of the - parent namespace know what you are doing. If you start a project - that creates hats for sloths, make sure that the Sloth team knows - that you're using sloth.hats.

- -
- -

"External code" is code that comes from outside your codebase, - and is compiled independently. Internal and external names should - be kept strictly separate. If you're using an external library - that makes things available in foo.hats.*, your - internal code should not define all its symbols in - foo.hats.*, because it will break if the other - team defines new symbols.

- - foo.require('foo.hats'); - - /** - * WRONG -- Do NOT do this. - * @constructor - * @extends {foo.hats.RoundHat} - */ - foo.hats.BowlerHat = function() { - }; - -

If you need to define new APIs on an external namespace, then you - should explicitly export the public API functions, and only those - functions. Your internal code should call the internal APIs by - their internal names, for consistency and so that the compiler - can optimize them better.

- - foo.provide('googleyhats.BowlerHat'); - - foo.require('foo.hats'); - - /** - * @constructor - * @extends {foo.hats.RoundHat} - */ - googleyhats.BowlerHat = function() { - ... - }; - - goog.exportSymbol('foo.hats.BowlerHat', googleyhats.BowlerHat); - - - -
- -

Use local aliases for fully-qualified types if doing so improves - readability. The name of a local alias should match the last part - of the type.

- - /** - * @constructor - */ - some.long.namespace.MyClass = function() { - }; - - /** - * @param {some.long.namespace.MyClass} a - */ - some.long.namespace.MyClass.staticHelper = function(a) { - ... - }; - - myapp.main = function() { - var MyClass = some.long.namespace.MyClass; - var staticHelper = some.long.namespace.MyClass.staticHelper; - staticHelper(new MyClass()); - }; - -

Do not create local aliases of namespaces. Namespaces should only - be aliased using goog.scope.

- - myapp.main = function() { - var namespace = some.long.namespace; - namespace.MyClass.staticHelper(new namespace.MyClass()); - }; - -

Avoid accessing properties of an aliased type, unless it is an - enum.

- - /** @enum {string} */ - some.long.namespace.Fruit = { - APPLE: 'a', - BANANA: 'b' - }; - - myapp.main = function() { - var Fruit = some.long.namespace.Fruit; - switch (fruit) { - case Fruit.APPLE: - ... - case Fruit.BANANA: - ... - } - }; - - - myapp.main = function() { - var MyClass = some.long.namespace.MyClass; - MyClass.staticHelper(null); - }; - -

Never create aliases in the global scope. Use them only in - function blocks.

-
-
- -

Filenames should be all lowercase in order to avoid confusion on - case-sensitive platforms. Filenames should end in .js, - and should contain no punctuation except for - or - _ (prefer - to _).

-
- - -
- - - - Must always succeed without side effects. - - -

You can control how your objects string-ify themselves by defining a - custom toString() method. This is fine, but you need - to ensure that your method (1) always succeeds and (2) does not have - side-effects. If your method doesn't meet these criteria, it's very - easy to run into serious problems. For example, if - toString() calls a method that does an - assert, assert might try to output the name - of the object in which it failed, which of course requires calling - toString().

- -
- - - OK - -

It isn't always possible to initialize variables at the point of - declaration, so deferred initialization is fine.

- -
- - - Always - -

Always use explicit scope - doing so increases portability and - clarity. For example, don't rely on window being in the - scope chain. You might want to use your function in another - application for which window is not the content - window.

- -
- - - Expand for more information. - -

We follow the C++ formatting - rules in spirit, with the following additional clarifications.

- -

Because of implicit semicolon insertion, always start your curly - braces on the same line as whatever they're opening. For - example:

- - if (something) { - // ... - } else { - // ... - } - -
- -

Single-line array and object initializers are allowed when they - fit on a line:

- - var arr = [1, 2, 3]; // No space after [ or before ]. - var obj = {a: 1, b: 2, c: 3}; // No space after { or before }. - -

Multiline array initializers and object initializers are indented - 2 spaces, with the braces on their own line, just like blocks.

- - // Object initializer. - var inset = { - top: 10, - right: 20, - bottom: 15, - left: 12 - }; - - // Array initializer. - this.rows_ = [ - '"Slartibartfast" <fjordmaster@magrathea.com>', - '"Zaphod Beeblebrox" <theprez@universe.gov>', - '"Ford Prefect" <ford@theguide.com>', - '"Arthur Dent" <has.no.tea@gmail.com>', - '"Marvin the Paranoid Android" <marv@googlemail.com>', - 'the.mice@magrathea.com' - ]; - - // Used in a method call. - goog.dom.createDom(goog.dom.TagName.DIV, { - id: 'foo', - className: 'some-css-class', - style: 'display:none' - }, 'Hello, world!'); - -

Long identifiers or values present problems for aligned - initialization lists, so always prefer non-aligned initialization. - For example:

- - CORRECT_Object.prototype = { - a: 0, - b: 1, - lengthyName: 2 - }; - -

Not like this:

- - WRONG_Object.prototype = { - a : 0, - b : 1, - lengthyName: 2 - }; - -
- -

When possible, all function arguments should be listed on the same - line. If doing so would exceed the 80-column limit, the arguments - must be line-wrapped in a readable way. To save space, you may wrap - as close to 80 as possible, or put each argument on its own line to - enhance readability. The indentation may be either four spaces, or - aligned to the parenthesis. Below are the most common patterns for - argument wrapping:

- - // Four-space, wrap at 80. Works with very long function names, survives - // renaming without reindenting, low on space. - goog.foo.bar.doThingThatIsVeryDifficultToExplain = function( - veryDescriptiveArgumentNumberOne, veryDescriptiveArgumentTwo, - tableModelEventHandlerProxy, artichokeDescriptorAdapterIterator) { - // ... - }; - - // Four-space, one argument per line. Works with long function names, - // survives renaming, and emphasizes each argument. - goog.foo.bar.doThingThatIsVeryDifficultToExplain = function( - veryDescriptiveArgumentNumberOne, - veryDescriptiveArgumentTwo, - tableModelEventHandlerProxy, - artichokeDescriptorAdapterIterator) { - // ... - }; - - // Parenthesis-aligned indentation, wrap at 80. Visually groups arguments, - // low on space. - function foo(veryDescriptiveArgumentNumberOne, veryDescriptiveArgumentTwo, - tableModelEventHandlerProxy, artichokeDescriptorAdapterIterator) { - // ... - } - - // Parenthesis-aligned, one argument per line. Emphasizes each - // individual argument. - function bar(veryDescriptiveArgumentNumberOne, - veryDescriptiveArgumentTwo, - tableModelEventHandlerProxy, - artichokeDescriptorAdapterIterator) { - // ... - } - -

When the function call is itself indented, you're free to start the - 4-space indent relative to the beginning of the original statement - or relative to the beginning of the current function call. - The following are all acceptable indentation styles.

- - if (veryLongFunctionNameA( - veryLongArgumentName) || - veryLongFunctionNameB( - veryLongArgumentName)) { - veryLongFunctionNameC(veryLongFunctionNameD( - veryLongFunctioNameE( - veryLongFunctionNameF))); - } - -
- -

When declaring an anonymous function in the list of arguments for - a function call, the body of the function is indented two spaces - from the left edge of the statement, or two spaces from the left - edge of the function keyword. This is to make the body of the - anonymous function easier to read (i.e. not be all squished up into - the right half of the screen).

- - prefix.something.reallyLongFunctionName('whatever', function(a1, a2) { - if (a1.equals(a2)) { - someOtherLongFunctionName(a1); - } else { - andNowForSomethingCompletelyDifferent(a2.parrot); - } - }); - - var names = prefix.something.myExcellentMapFunction( - verboselyNamedCollectionOfItems, - function(item) { - return item.name; - }); - -
- - -

- goog.scope - may be used to shorten references to - namespaced symbols in programs using - the Closure - Library.

-

Only one goog.scope invocation may be added per - file. Always place it in the global scope.

-

The opening goog.scope(function() { invocation - must be preceded by exactly one blank line and follow any - goog.provide statements, goog.require - statements, or top-level comments. The invocation must be closed on - the last line in the file. Append // goog.scope to the - closing statement of the scope. Separate the comment from the - semicolon by two spaces.

-

Similar to C++ namespaces, do not indent under goog.scope - declarations. Instead, continue from the 0 column.

-

Only alias names that will not be re-assigned to another object - (e.g., most constructors, enums, and namespaces). Do not do - this (see below for how to alias a constructor):

- - - goog.scope(function() { - var Button = goog.ui.Button; - - Button = function() { ... }; - ... - - -

Names must be the same as the last property of the global that they - are aliasing.

- - - goog.provide('my.module.SomeType'); - - goog.require('goog.dom'); - goog.require('goog.ui.Button'); - - goog.scope(function() { - var Button = goog.ui.Button; - var dom = goog.dom; - - // Alias new types after the constructor declaration. - my.module.SomeType = function() { ... }; - var SomeType = my.module.SomeType; - - // Declare methods on the prototype as usual: - SomeType.prototype.findButton = function() { - // Button as aliased above. - this.button = new Button(dom.getElement('my-button')); - }; - ... - }); // goog.scope - -
- -

Except for array literals, - object literals, and anonymous functions, all wrapped lines - should be indented either left-aligned to a sibling expression - above, or four spaces (not two spaces) deeper than a parent - expression (where "sibling" and "parent" refer to parenthesis - nesting level). -

- - - someWonderfulHtml = '
' + - getEvenMoreHtml(someReallyInterestingValues, moreValues, - evenMoreParams, 'a duck', true, 72, - slightlyMoreMonkeys(0xfff)) + - '
'; - - thisIsAVeryLongVariableName = - hereIsAnEvenLongerOtherFunctionNameThatWillNotFitOnPrevLine(); - - thisIsAVeryLongVariableName = siblingOne + siblingTwo + siblingThree + - siblingFour + siblingFive + siblingSix + siblingSeven + - moreSiblingExpressions + allAtTheSameIndentationLevel; - - thisIsAVeryLongVariableName = operandOne + operandTwo + operandThree + - operandFour + operandFive * ( - aNestedChildExpression + shouldBeIndentedMore); - - someValue = this.foo( - shortArg, - 'Some really long string arg - this is a pretty common case, actually.', - shorty2, - this.bar()); - - if (searchableCollection(allYourStuff).contains(theStuffYouWant) && - !ambientNotification.isActive() && (client.isAmbientSupported() || - client.alwaysTryAmbientAnyways())) { - ambientNotification.activate(); - } -
-
- -

Use newlines to group logically related pieces of code. - For example:

- - doSomethingTo(x); - doSomethingElseTo(x); - andThen(x); - - nowDoSomethingWith(y); - - andNowWith(z); - -
- -

Always put the operator on the preceding line. Otherwise, - line breaks and indentation follow the same rules as in other - Google style guides. This operator placement was initially agreed - upon out of concerns about automatic semicolon insertion. In fact, - semicolon insertion cannot happen before a binary operator, but new - code should stick to this style for consistency.

- - var x = a ? b : c; // All on one line if it will fit. - - // Indentation +4 is OK. - var y = a ? - longButSimpleOperandB : longButSimpleOperandC; - - // Indenting to the line position of the first operand is also OK. - var z = a ? - moreComplicatedB : - moreComplicatedC; - -

This includes the dot operator.

- - var x = foo.bar(). - doSomething(). - doSomethingElse(); - -
- -
- - - Only where required - -

Use sparingly and in general only where required by the syntax - and semantics.

-

Never use parentheses for unary operators such as - delete, typeof and void or - after keywords such as return, throw as - well as others (case, in or - new).

- -
- - - Prefer ' over " - -

For consistency single-quotes (') are preferred to double-quotes ("). - This is helpful when creating strings that include HTML:

- - var msg = 'This is some HTML'; - - -
- - - Encouraged, use JSDoc annotations @private and - @protected - -

We recommend the use of the JSDoc annotations @private and - @protected to indicate visibility levels for classes, - functions, and properties.

-

The --jscomp_warning=visibility compiler flag turns on compiler - warnings for visibility violations. See - - Closure Compiler - Warnings. -

-

@private global variables and functions are only - accessible to code in the same file.

-

Constructors marked @private may only be instantiated by - code in the same file and by their static and instance members. - @private constructors may also be accessed anywhere in the - same file for their public static properties and by the - instanceof operator.

-

Global variables, functions, and constructors should never be - annotated @protected.

- - // File 1. - // AA_PrivateClass_ and AA_init_ are accessible because they are global - // and in the same file. - - /** - * @private - * @constructor - */ - AA_PrivateClass_ = function() { - }; - - /** @private */ - function AA_init_() { - return new AA_PrivateClass_(); - } - - AA_init_(); - -

@private properties are accessible to all code in the - same file, plus all static methods and instance methods of that class - that "owns" the property, if the property belongs to a class. They - cannot be accessed or overridden from a subclass in a different file.

-

@protected properties are accessible to all code in the - same file, plus any static methods and instance methods of any subclass - of a class that "owns" the property.

-

Note that these semantics differ from those of C++ and Java, in that - they grant private and protected access to all code in the same file, - not just in the same class or class hierarchy. Also, unlike in C++, - private properties cannot be overridden by a subclass. -

- - // File 1. - - /** @constructor */ - AA_PublicClass = function() { - /** @private */ - this.privateProp_ = 2; - - /** @protected */ - this.protectedProp = 4; - }; - - /** @private */ - AA_PublicClass.staticPrivateProp_ = 1; - - /** @protected */ - AA_PublicClass.staticProtectedProp = 31; - - /** @private */ - AA_PublicClass.prototype.privateMethod_ = function() {}; - - /** @protected */ - AA_PublicClass.prototype.protectedMethod = function() {}; - - // File 2. - - /** - * @return {number} The number of ducks we've arranged in a row. - */ - AA_PublicClass.prototype.method = function() { - // Legal accesses of these two properties. - return this.privateProp_ + AA_PublicClass.staticPrivateProp_; - }; - - // File 3. - - /** - * @constructor - * @extends {AA_PublicClass} - */ - AA_SubClass = function() { - // Legal access of a protected static property. - AA_PublicClass.staticProtectedProp = this.method(); - }; - goog.inherits(AA_SubClass, AA_PublicClass); - - /** - * @return {number} The number of ducks we've arranged in a row. - */ - AA_SubClass.prototype.method = function() { - // Legal access of a protected instance property. - return this.protectedProp; - }; - - -

Notice that in JavaScript, there is no distinction between a type - (like AA_PrivateClass_) and the constructor for that - type. There is no way to express both that a type is public and its - constructor is private (because the constructor could easily be aliased - in a way that would defeat the privacy check).

- -
- - - Encouraged and enforced by the compiler. - - -

When documenting a type in JSDoc, be as specific and accurate as - possible. The types we support are based on the - - EcmaScript 4 spec.

- -

The ES4 proposal contained a language for specifying JavaScript - types. We use this language in JsDoc to express the types of - function parameters and return values.

- -

As the ES4 proposal has evolved, this language has changed. The - compiler still supports old syntaxes for types, but those syntaxes - are deprecated.

- -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Syntax NameSyntaxDescriptionDeprecated Syntaxes
Primitive Type - There are 5 primitive types in JavaScript: - {null}, - {undefined}, - {boolean}, - {number}, and - {string}. - Simply the name of a type. -
Instance Type - {Object}
- An instance of Object or null.

- {Function}
- An instance of Function or null.

- {EventTarget}
- An instance of a constructor that implements the EventTarget - interface, or null. -

An instance of a constructor or interface function.

- - Constructor functions are functions defined with the - @constructor JSDoc tag. - Interface functions are functions defined with the - @interface JSDoc tag.

- - By default, instance types will accept null. This is the only - type syntax that makes the type nullable. Other type syntaxes - in this table will not accept null. -

-
Enum Type - {goog.events.EventType}
- One of the properties of the object literal initializer - of goog.events.EventType. -
An enum must be initialized as an object literal, or as - an alias of another enum, annotated with the @enum - JSDoc tag. The properties of this literal are the instances - of the enum. The syntax of the enum is defined - below.

- - Note that this is one of the few things in our type system - that were not in the ES4 spec. -

-
Type Application - {Array.<string>}
An array of strings.

- {Object.<string, number>} -
An object in which the keys are strings and the values - are numbers. -

Parameterizes a type, by applying a set of type arguments - to that type. The idea is analogous to generics in Java. - -
Type Union - {(number|boolean)}
A number or a boolean. -
Indicates that a value might have type A OR type B.

- - The parentheses may be omitted at the top-level - expression, but the parentheses should be included in - sub-expressions to avoid ambiguity.
- {number|boolean}
- {function(): (number|boolean)} -

- {(number,boolean)},
- {(number||boolean)} -
Nullable type - {?number}
A number or null. -
Shorthand for the union of the null type with any - other type. This is just syntactic sugar. - - {number?} -
Non-nullable type - {!Object}
An Object, but never the - null value. -
Filters null out of nullable types. Most often used - with instance types, which are nullable by default. - - {Object!} -
Record Type - {{myNum: number, myObject}} -
An anonymous type with the given type members. -
-

Indicates that the value has the specified members with the - specified types. In this case, myNum with a - type number and myObject with any - type.

-

Notice that the braces are part of the type syntax. For - example, to denote an Array of objects that - have a length property, you might write - Array.<{length}>.

-
-
Function Type - {function(string, boolean)}
- A function that takes two arguments (a string and a boolean), - and has an unknown return value.
-
Specifies a function. -
Function Return Type - {function(): number}
- A function that takes no arguments and returns a number.
-
Specifies a function return type. -
Function this Type - {function(this:goog.ui.Menu, string)}
- A function that takes one argument (a string), and executes - in the context of a goog.ui.Menu. -
Specifies the context type of a function type. -
Function new Type - {function(new:goog.ui.Menu, string)}
- A constructor that takes one argument (a string), and - creates a new instance of goog.ui.Menu when called - with the 'new' keyword. -
Specifies the constructed type of a constructor. -
Variable arguments - {function(string, ...[number]): number}
- A function that takes one argument (a string), and then a - variable number of arguments that must be numbers. -
Specifies variable arguments to a function. -
- - Variable arguments (in @param annotations) - - @param {...number} var_args
- A variable number of arguments to an annotated function. -
- Specifies that the annotated function accepts a variable - number of arguments. - -
Function optional arguments - {function(?string=, number=)}
- A function that takes one optional, nullable string and one - optional number as arguments. The = syntax is - only for function type declarations. -
Specifies optional arguments to a function. -
- - Function optional arguments - (in @param annotations) - - @param {number=} opt_argument
- An optional parameter of type number. -
Specifies that the annotated function accepts an optional - argument. -
The ALL type{*}Indicates that the variable can take on any type. -
The UNKNOWN type{?}Indicates that the variable can take on any type, - and the compiler should not type-check any uses of it. -
- - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Type ExampleValue ExamplesDescription
number - - 1 - 1.0 - -5 - 1e5 - Math.PI - - -
Number - - new Number(true) - - - - Number object - -
string - - 'Hello' - "World" - String(42) - - - String value -
String - - new String('Hello') - new String(42) - - - - String object - -
boolean - - true - false - Boolean(0) - - - Boolean value -
Boolean - - new Boolean(true) - - - - Boolean object - -
RegExp - - new RegExp('hello') - /world/g - -
Date - - new Date - new Date() - -
- - null - - - - null - - -
- - undefined - - - - undefined - - -
void - - function f() { - return; - } - - No return value
Array - - ['foo', 0.3, null] - [] - - Untyped Array
Array.<number> - - [11, 22, 33] - - - An Array of numbers -
Array.<Array.<string>> - - [['one', 'two', 'three'], ['foo', 'bar']] - - Array of Arrays of strings
Object - - {} - {foo: 'abc', bar: 123, baz: null} - - -
Object.<string> - - {'foo': 'bar'} - - - An Object in which the values are strings. -
Object.<number, string> - - var obj = {}; - obj[1] = 'bar'; - - - An Object in which the keys are numbers and the values are - strings.

Note that in JavaScript, the keys are always - implicitly converted to strings, so - obj['1'] == obj[1]. - So the key will always be a string in for...in loops. But the - compiler will verify the type of the key when indexing into - the object. -

Function - - function(x, y) { - return x * y; - } - - - - Function object - -
function(number, number): number - - function(x, y) { - return x * y; - } - - function value
SomeClass - - /** @constructor */ - function SomeClass() {} - - new SomeClass(); - - -
SomeInterface - - /** @interface */ - function SomeInterface() {} - - SomeInterface.prototype.draw = function() {}; - - -
project.MyClass - - /** @constructor */ - project.MyClass = function () {} - - new project.MyClass() - - -
project.MyEnum - - /** @enum {string} */ - project.MyEnum = { - /** The color blue. */ - BLUE: '#0000dd', - /** The color red. */ - RED: '#dd0000' - }; - - Enumeration

- JSDoc comments on enum values are optional. -

Element - - document.createElement('div') - - Elements in the DOM.
Node - - document.body.firstChild - - Nodes in the DOM.
HTMLInputElement - - htmlDocument.getElementsByTagName('input')[0] - - A specific type of DOM element.
- - - -

In cases where type-checking doesn't accurately infer the type of - an expression, it is possible to add a type cast comment by adding a - type annotation comment and enclosing the expression in - parentheses. The parentheses are required.

- - - /** @type {number} */ (x) - -
- - - -

Because JavaScript is a loosely-typed language, it is very - important to understand the subtle differences between optional, - nullable, and undefined function parameters and class - properties.

- -

Instances of classes and interfaces are nullable by default. - For example, the following declaration

- - - /** - * Some class, initialized with a value. - * @param {Object} value Some value. - * @constructor - */ - function MyClass(value) { - /** - * Some value. - * @type {Object} - * @private - */ - this.myValue_ = value; - } - - -

tells the compiler that the myValue_ property holds - either an Object or null. If myValue_ must never be - null, it should be declared like this:

- - - /** - * Some class, initialized with a non-null value. - * @param {!Object} value Some value. - * @constructor - */ - function MyClass(value) { - /** - * Some value. - * @type {!Object} - * @private - */ - this.myValue_ = value; - } - - -

This way, if the compiler can determine that somewhere in the code - MyClass is initialized with a null value, it will issue - a warning.

- - - -

Optional parameters to functions may be undefined at runtime, so if - they are assigned to class properties, those properties must be - declared accordingly:

- - - /** - * Some class, initialized with an optional value. - * @param {Object=} opt_value Some value (optional). - * @constructor - */ - function MyClass(opt_value) { - /** - * Some value. - * @type {Object|undefined} - * @private - */ - this.myValue_ = opt_value; - } - - -

This tells the compiler that myValue_ may hold an - Object, null, or remain undefined.

- -

Note that the optional parameter opt_value is declared - to be of type {Object=}, not - {Object|undefined}. This is because optional - parameters may, by definition, be undefined. While there is no harm - in explicitly declaring an optional parameter as possibly undefined, - it is both unnecessary and makes the code harder to read.

- -

Finally, note that being nullable and being optional are orthogonal - properties. The following four declarations are all different:

- - - /** - * Takes four arguments, two of which are nullable, and two of which are - * optional. - * @param {!Object} nonNull Mandatory (must not be undefined), must not be null. - * @param {Object} mayBeNull Mandatory (must not be undefined), may be null. - * @param {!Object=} opt_nonNull Optional (may be undefined), but if present, - * must not be null! - * @param {Object=} opt_mayBeNull Optional (may be undefined), may be null. - */ - function strangeButTrue(nonNull, mayBeNull, opt_nonNull, opt_mayBeNull) { - // ... - }; - -
- - - -

Sometimes types can get complicated. A function that accepts - content for an Element might look like:

- - - /** - * @param {string} tagName - * @param {(string|Element|Text|Array.<Element>|Array.<Text>)} contents - * @return {!Element} - */ - goog.createElement = function(tagName, contents) { - ... - }; - - -

You can define commonly used type expressions with a - @typedef tag. For example,

- - - /** @typedef {(string|Element|Text|Array.<Element>|Array.<Text>)} */ - goog.ElementContent; - - /** - * @param {string} tagName - * @param {goog.ElementContent} contents - * @return {!Element} - */ - goog.createElement = function(tagName, contents) { - ... - }; - - - - -
-

The compiler has limited support for template types. It can only - infer the type of this inside an anonymous function - literal from the type of the this argument and whether the - this argument is missing.

- - - /** - * @param {function(this:T, ...)} fn - * @param {T} thisObj - * @param {...*} var_args - * @template T - */ - goog.bind = function(fn, thisObj, var_args) { - ... - }; - // Possibly generates a missing property warning. - goog.bind(function() { this.someProperty; }, new SomeClass()); - // Generates an undefined this warning. - goog.bind(function() { this.someProperty; }); - - - -
- - - Use JSDoc - -

- We follow the - - C++ style for comments in spirit. -

- -

All files, classes, methods and properties should be documented with - JSDoc - comments with the appropriate tags - and types. Textual descriptions for properties, - methods, method parameters and method return values should be included - unless obvious from the property, method, or parameter name. -

- -

Inline comments should be of the // variety.

- -

Complete sentences are recommended but not required. - Complete sentences should use appropriate capitalization - and punctuation.

- - -

The JSDoc syntax is based on - - JavaDoc. Many tools extract metadata from JSDoc comments to - perform code validation and optimizations. These comments must be - well-formed.

- - - /** - * A JSDoc comment should begin with a slash and 2 asterisks. - * Inline tags should be enclosed in braces like {@code this}. - * @desc Block tags should always start on their own line. - */ - -
- - -

If you have to line break a block tag, you should treat this as - breaking a code statement and indent it four spaces.

- - - /** - * Illustrates line wrapping for long param/return descriptions. - * @param {string} foo This is a param with a description too long to fit in - * one line. - * @return {number} This returns something that has a description too long to - * fit in one line. - */ - project.MyClass.prototype.method = function(foo) { - return 5; - }; - - -

You should not indent the @fileoverview command. You do not have to - indent the @desc command.

- -

Even though it is not preferred, it is also acceptable to line up - the description.

- - - /** - * This is NOT the preferred indentation method. - * @param {string} foo This is a param with a description too long to fit in - * one line. - * @return {number} This returns something that has a description too long to - * fit in one line. - */ - project.MyClass.prototype.method = function(foo) { - return 5; - }; - -
- - -

Like JavaDoc, JSDoc supports many HTML tags, like <code>, - <pre>, <tt>, <strong>, <ul>, <ol>, - <li>, <a>, and others.

- -

This means that plaintext formatting is not respected. So, don't - rely on whitespace to format JSDoc:

- - - /** - * Computes weight based on three factors: - * items sent - * items received - * last timestamp - */ - - -

It'll come out like this:

- - - Computes weight based on three factors: items sent items received last timestamp - - -

Instead, do this:

- - - /** - * Computes weight based on three factors: - * <ul> - * <li>items sent - * <li>items received - * <li>last timestamp - * </ul> - */ - - - The - JavaDoc style guide is a useful resource on how to write - well-formed doc comments. -
- - -

- - A copyright notice and author information are optional. - File overviews are generally recommended whenever a file consists of - more than a single class definition. The top level comment is - designed to orient readers unfamiliar with the code to what is in - this file. If present, it should provide a description of the - file's contents and any dependencies or compatibility information. - As an example: -

- - - /** - * @fileoverview Description of file, its uses and information - * about its dependencies. - */ - - - -
- - -

Classes must be documented with a description and a - type tag that - identifies the constructor. -

- - - /** - * Class making something fun and easy. - * @param {string} arg1 An argument that makes this more interesting. - * @param {Array.<number>} arg2 List of numbers to be processed. - * @constructor - * @extends {goog.Disposable} - */ - project.MyClass = function(arg1, arg2) { - // ... - }; - goog.inherits(project.MyClass, goog.Disposable); - -
- - -

Parameter and return types should be documented. The method - description may be omitted if it is obvious from the parameter - or return type descriptions. Method descriptions should start - with a sentence written in the third person declarative voice.

- - /** - * Operates on an instance of MyClass and returns something. - * @param {project.MyClass} obj Instance of MyClass which leads to a long - * comment that needs to be wrapped to two lines. - * @return {boolean} Whether something occurred. - */ - function PR_someMethod(obj) { - // ... - } - -
- - - - /** @constructor */ - project.MyClass = function() { - /** - * Maximum number of things per pane. - * @type {number} - */ - this.someProperty = 4; - } - - - - - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
TagTemplate & ExamplesDescription
- @author - - - @author username@google.com (first last) -

For example:

- - /** - * @fileoverview Utilities for handling textareas. - * @author kuth@google.com (Uthur Pendragon) - */ - -
- Document the author of a file or the owner of a test, - generally only used in the @fileoverview comment. - -
@code - {@code ...} -

For example:

- - /** - * Moves to the next position in the selection. - * Throws {@code goog.iter.StopIteration} when it - * passes the end of the range. - * @return {Node} The node at the next position. - */ - goog.dom.RangeIterator.prototype.next = function() { - // ... - }; - -
- Indicates that a term in a JSDoc description is code so it may - be correctly formatted in generated documentation. -
@const - @const
- @const {type} -

For example:

- - /** @const */ var MY_BEER = 'stout'; - - /** - * My namespace's favorite kind of beer. - * @const {string} - */ - mynamespace.MY_BEER = 'stout'; - - /** @const */ MyClass.MY_BEER = 'stout'; - - /** - * Initializes the request. - * @const - */ - mynamespace.Request.prototype.initialize = function() { - // This method cannot be overridden in a subclass. - }; - -
-

Marks a variable (or property) as read-only and suitable - for inlining.

- -

A @const variable is an immutable pointer to - a value. If a variable or property marked as - @const is overwritten, JSCompiler will give - warnings.

- -

The type declaration of a constant value can be omitted - if it can be clearly inferred. An additional comment about - the variable is optional.

- -

When @const is applied to a method, it - implies the method is not only not overwritable, but also - that the method is finalized — - not overridable in subclasses.

- -

For more on @const, see the - Constants section.

- -
@constructor - @constructor -

For example:

- - /** - * A rectangle. - * @constructor - */ - function GM_Rect() { - ... - } - -
- Used in a class's documentation to indicate the constructor. -
@define - @define {Type} description -

For example:

- - /** @define {boolean} */ - var TR_FLAGS_ENABLE_DEBUG = true; - - /** - * @define {boolean} Whether we know at compile-time that - * the browser is IE. - */ - goog.userAgent.ASSUME_IE = false; - -
- Indicates a constant that can be overridden by the compiler at - compile-time. In the example, the compiler flag - --define='goog.userAgent.ASSUME_IE=true' - could be specified in the BUILD file to indicate that the - constant goog.userAgent.ASSUME_IE should be replaced - with true. -
@deprecated - @deprecated Description -

For example:

- - /** - * Determines whether a node is a field. - * @return {boolean} True if the contents of - * the element are editable, but the element - * itself is not. - * @deprecated Use isField(). - */ - BN_EditUtil.isTopEditableField = function(node) { - // ... - }; - -
- Used to tell that a function, method or property should not be - used any more. Always provide instructions on what callers - should use instead. -
@dict - @dict Description -

For example:

- - /** - * @constructor - * @dict - */ - function Foo(x) { - this['x'] = x; - } - var obj = new Foo(123); - var num = obj.x; // warning - - (/** @dict */ { x: 1 }).x = 123; // warning - -
- When a constructor (Foo in the example) is - annotated with @dict, you can only use the - bracket notation to access the properties of Foo - objects. - The annotation can also be used directly on object literals. -
@enum - @enum {Type} -

For example:

- - /** - * Enum for tri-state values. - * @enum {number} - */ - project.TriState = { - TRUE: 1, - FALSE: -1, - MAYBE: 0 - }; - -
@export - @export -

For example:

- - /** @export */ - foo.MyPublicClass.prototype.myPublicMethod = function() { - // ... - }; - -
-

Given the code on the left, when the compiler is run with - the --generate_exports flag, it will generate the - code:

- - goog.exportSymbol('foo.MyPublicClass.prototype.myPublicMethod', - foo.MyPublicClass.prototype.myPublicMethod); - -

which will export the symbols to uncompiled code. - Code that uses the @export annotation must either

-
    -
  1. include //javascript/closure/base.js, or
  2. -
  3. define both goog.exportSymbol and - goog.exportProperty with the same method - signature in their own codebase.
  4. -
-
@expose - @expose -

For example:

- - /** @expose */ - MyClass.prototype.exposedProperty = 3; - -
-

- Declares an exposed property. Exposed properties - will not be removed, or renamed, or collapsed, - or optimized in any way by the compiler. No properties - with the same name will be able to be optimized either. -

- -

- @expose should never be used in library code, - because it will prevent that property from ever getting - removed. -

-
@extends - - @extends Type
- @extends {Type} -
-

For example:

- - /** - * Immutable empty node list. - * @constructor - * @extends goog.ds.BasicNodeList - */ - goog.ds.EmptyNodeList = function() { - ... - }; - -
- Used with @constructor to indicate that a class - inherits from another class. Curly braces around the type are - optional. -
@externs - @externs -

For example:

- - /** - * @fileoverview This is an externs file. - * @externs - */ - - var document; - -
-

- Declares an - - externs file. -

- - -
@fileoverview - @fileoverview Description -

For example:

- - /** - * @fileoverview Utilities for doing things that require this very long - * but not indented comment. - * @author kuth@google.com (Uthur Pendragon) - */ - -
Makes the comment block provide file level information.
@implements - - @implements Type
- @implements {Type} -
-

For example:

- - /** - * A shape. - * @interface - */ - function Shape() {}; - Shape.prototype.draw = function() {}; - - /** - * @constructor - * @implements {Shape} - */ - function Square() {}; - Square.prototype.draw = function() { - ... - }; - -
- Used with @constructor to indicate that a class - implements an interface. Curly braces around the type are - optional. -
@inheritDoc - @inheritDoc -

For example:

- - /** @inheritDoc */ - project.SubClass.prototype.toString() { - // ... - }; - -
-

Deprecated. Use - @override instead.

- - Indicates that a method or property of a subclass - intentionally hides a method or property of the superclass, - and has exactly the same documentation. Notice that - @inheritDoc implies @override -
@interface - @interface -

For example:

- - /** - * A shape. - * @interface - */ - function Shape() {}; - Shape.prototype.draw = function() {}; - - /** - * A polygon. - * @interface - * @extends {Shape} - */ - function Polygon() {}; - Polygon.prototype.getSides = function() {}; - -
- Used to indicate that the function defines an interface. -
@lends - @lends objectName
- @lends {objectName} -

For example:

- - goog.object.extend( - Button.prototype, - /** @lends {Button.prototype} */ { - isButton: function() { return true; } - }); - -
- Indicates that the keys of an object literal should - be treated as properties of some other object. This annotation - should only appear on object literals.

- - Notice that the name in braces is not a type name like - in other annotations. It's an object name. It names - the object on which the properties are "lent". - For example, @type {Foo} means "an instance of Foo", - but @lends {Foo} means "the constructor Foo".

- - The - JSDoc Toolkit docs have more information on this - annotation. -

@license or - @preserve - @license Description -

For example:

- - /** - * @preserve Copyright 2009 SomeThirdParty. - * Here is the full license text and copyright - * notice for this file. Note that the notice can span several - * lines and is only terminated by the closing star and slash: - */ - -
- Anything marked by @license or - @preserve will be retained by the compiler and - output at the top of the compiled code for that file. This - annotation allows important notices (such as legal licenses or - copyright text) to survive compilation unchanged. Line breaks - are preserved. -
@noalias - @noalias -

For example:

- - /** @noalias */ - function Range() {} - -
- Used in an externs file to indicate to the compiler that the - variable or function should not be aliased as part of the - alias externals pass of the compiler. -
@nocompile - @nocompile -

For example:

- - /** @nocompile */ - - // JavaScript code - -
- Used at the top of a file to tell the compiler to parse this - file but not compile it. - Code that is not meant for compilation and should be omitted - from compilation tests (such as bootstrap code) uses this - annotation. - Use sparingly. -
@nosideeffects - @nosideeffects -

For example:

- - /** @nosideeffects */ - function noSideEffectsFn1() { - // ... - } - - /** @nosideeffects */ - var noSideEffectsFn2 = function() { - // ... - }; - - /** @nosideeffects */ - a.prototype.noSideEffectsFn3 = function() { - // ... - }; - -
- This annotation can be used as part of function and - constructor declarations to indicate that calls to the - declared function have no side-effects. This annotation - allows the compiler to remove calls to these functions if the - return value is not used. -
@override - @override -

For example:

- - /** - * @return {string} Human-readable representation of project.SubClass. - * @override - */ - project.SubClass.prototype.toString = function() { - // ... - }; - -
- Indicates that a method or property of a subclass - intentionally hides a method or property of the superclass. If - no other documentation is included, the method or property - also inherits documentation from its superclass. -
@param - @param {Type} varname Description -

For example:

- - /** - * Queries a Baz for items. - * @param {number} groupNum Subgroup id to query. - * @param {string|number|null} term An itemName, - * or itemId, or null to search everything. - */ - goog.Baz.prototype.query = function(groupNum, term) { - // ... - }; - -
- Used with method, function and constructor calls to document - the arguments of a function.

- - Type - names must be enclosed in curly braces. If the type - is omitted, the compiler will not type-check the parameter. -

@private - @private
- @private {type} -

For example:

- - /** - * Handlers that are listening to this logger. - * @private {!Array.<Function>} - */ - this.handlers_ = []; - -
- Used in conjunction with a trailing underscore on the method - or property name to indicate that the member is - private and final. -
@protected - @protected
- @protected {type} -

For example:

- - /** - * Sets the component's root element to the given element. - * @param {Element} element Root element for the component. - * @protected - */ - goog.ui.Component.prototype.setElementInternal = function(element) { - // ... - }; - -
- Used to indicate that the member or property is - protected. - Should be used in conjunction with names with no trailing - underscore. -
@public - @public
- @public {type} -

For example:

- - /** - * Whether to cancel the event in internal capture/bubble processing. - * @public {boolean} - * @suppress {visiblity} Referencing this outside this package is strongly - * discouraged. - */ - goog.events.Event.prototype.propagationStopped_ = false; - -
- Used to indicate that the member or property is public. Variables and - properties are public by default, so this annotation is rarely necessary. - Should only be used in legacy code that cannot be easily changed to - override the visibility of members that were named as private variables. -
@return - @return {Type} Description -

For example:

- - /** - * @return {string} The hex ID of the last item. - */ - goog.Baz.prototype.getLastId = function() { - // ... - return id; - }; - -
- Used with method and function calls to document the return - type. When writing descriptions for boolean parameters, - prefer "Whether the component is visible" to "True if the - component is visible, false otherwise". If there is no return - value, do not use an @return tag.

- - Type - names must be enclosed in curly braces. If the type - is omitted, the compiler will not type-check the return value. -

@see - @see Link -

For example:

- - /** - * Adds a single item, recklessly. - * @see #addSafely - * @see goog.Collect - * @see goog.RecklessAdder#add - ... - -
Reference a lookup to another class function or method.
@struct - @struct Description -

For example:

- - /** - * @constructor - * @struct - */ - function Foo(x) { - this.x = x; - } - var obj = new Foo(123); - var num = obj['x']; // warning - obj.y = "asdf"; // warning - - Foo.prototype = /** @struct */ { - method1: function() {} - }; - Foo.prototype.method2 = function() {}; // warning - -
- When a constructor (Foo in the example) is - annotated with @struct, you can only use the dot - notation to access the properties of Foo objects. - Also, you cannot add new properties to Foo - objects after they have been created. - The annotation can also be used directly on object literals. -
@supported - @supported Description -

For example:

- - /** - * @fileoverview Event Manager - * Provides an abstracted interface to the - * browsers' event systems. - * @supported So far tested in IE6 and FF1.5 - */ - -
- Used in a fileoverview to indicate what browsers are supported - by the file. -
@suppress - - @suppress {warning1|warning2} - - - @suppress {warning1,warning2} - -

For example:

- - /** - * @suppress {deprecated} - */ - function f() { - deprecatedVersionOfF(); - } - -
- Suppresses warnings from tools. Warning categories are - separated by | or ,. - -
@template - @template -

For example:

- - /** - * @param {function(this:T, ...)} fn - * @param {T} thisObj - * @param {...*} var_args - * @template T - */ - goog.bind = function(fn, thisObj, var_args) { - ... - }; - -
- This annotation can be used to declare a - template typename. -
@this - - @this Type
- @this {Type} -
-

For example:

- - pinto.chat.RosterWidget.extern('getRosterElement', - /** - * Returns the roster widget element. - * @this pinto.chat.RosterWidget - * @return {Element} - */ - function() { - return this.getWrappedComponent_().getElement(); - }); - -
- The type of the object in whose context a particular method is - called. Required when the this keyword is referenced - from a function that is not a prototype method. -
@type - - @type Type
- @type {Type} -
-

For example:

- - /** - * The message hex ID. - * @type {string} - */ - var hexId = hexId; - -
- Identifies the type of a variable, - property, or expression. Curly braces are not required around - most types, but some projects mandate them for all types, for - consistency. -
@typedef - @typedef -

For example:

- - /** @typedef {(string|number)} */ - goog.NumberLike; - - /** @param {goog.NumberLike} x A number or a string. */ - goog.readNumber = function(x) { - ... - } - -
- This annotation can be used to declare an alias of a more - complex type. -
- - - -

- You may also see other types of JSDoc annotations in third-party - code. These annotations appear in the - - JSDoc Toolkit Tag Reference - - but are currently discouraged in Google code. You should consider - them "reserved" names for future use. These include: -

    -
  • @augments
  • -
  • @argument
  • -
  • @borrows
  • -
  • @class
  • -
  • @constant
  • -
  • @constructs
  • -
  • @default
  • -
  • @event
  • -
  • @example
  • -
  • @field
  • -
  • @function
  • -
  • @ignore
  • -
  • @inner
  • -
  • @link
  • -
  • @memberOf
  • -
  • @name
  • -
  • @namespace
  • -
  • @property
  • -
  • @public
  • -
  • @requires
  • -
  • @returns
  • -
  • @since
  • -
  • @static
  • -
  • @version
  • -
-

-
- - - - - - Only provide top-level symbols. - - -

- All members defined on a class should be in the same file. So, only - top-level classes should be provided in a file that contains multiple - members defined on the same class (e.g. enums, inner classes, etc). -

-

Do this:

- - goog.provide('namespace.MyClass'); - -

Not this:

- - goog.provide('namespace.MyClass'); - goog.provide('namespace.MyClass.Enum'); - goog.provide('namespace.MyClass.InnerClass'); - goog.provide('namespace.MyClass.TypeDef'); - goog.provide('namespace.MyClass.CONSTANT'); - goog.provide('namespace.MyClass.staticMethod'); - -

- Members on namespaces may also be provided: -

- - goog.provide('foo.bar'); - goog.provide('foo.bar.method'); - goog.provide('foo.bar.CONSTANT'); - - -
- - - Required - - - -

Use of JS compilers such as the - Closure Compiler - is required for all customer-facing code.

- - - - - -
- - - JavaScript tidbits - - -

The following are all false in boolean expressions:

-
    -
  • null
  • -
  • undefined
  • -
  • '' the empty string
  • -
  • 0 the number
  • -
-

But be careful, because these are all true:

-
    -
  • '0' the string
  • -
  • [] the empty array
  • -
  • {} the empty object
  • -
- -

This means that instead of this:

- - while (x != null) { - -

you can write this shorter code (as long as you don't expect x to - be 0, or the empty string, or false):

- - while (x) { - - -

And if you want to check a string to see if it is null or empty, - you could do this:

- - if (y != null && y != '') { - -

But this is shorter and nicer:

- - if (y) { - - -

Caution: There are many unintuitive things about - boolean expressions. Here are some of them:

-
    -
  • - Boolean('0') == true
    - '0' != true
  • -
  • - 0 != null
    - 0 == []
    - 0 == false
  • -
  • - Boolean(null) == false
    - null != true
    - null != false
  • -
  • - Boolean(undefined) == false
    - undefined != true
    - undefined != false
  • -
  • - Boolean([]) == true
    - [] != true
    - [] == false
  • -
  • - Boolean({}) == true
    - {} != true
    - {} != false
  • -
-
- - -

Instead of this:

- - if (val) { - return foo(); - } else { - return bar(); - } - -

you can write this:

- - return val ? foo() : bar(); - - -

The ternary conditional is also useful when generating HTML:

- - var html = '<input type="checkbox"' + - (isChecked ? ' checked' : '') + - (isEnabled ? '' : ' disabled') + - ' name="foo">'; - -
- - -

These binary boolean operators are short-circuited, and evaluate - to the last evaluated term.

- -

"||" has been called the 'default' operator, because instead of - writing this:

- - /** @param {*=} opt_win */ - function foo(opt_win) { - var win; - if (opt_win) { - win = opt_win; - } else { - win = window; - } - // ... - } - -

you can write this:

- - /** @param {*=} opt_win */ - function foo(opt_win) { - var win = opt_win || window; - // ... - } - - -

"&&" is also useful for shortening code. For instance, - instead of this:

- - if (node) { - if (node.kids) { - if (node.kids[index]) { - foo(node.kids[index]); - } - } - } - - -

you could do this:

- - if (node && node.kids && node.kids[index]) { - foo(node.kids[index]); - } - - -

or this:

- - var kid = node && node.kids && node.kids[index]; - if (kid) { - foo(kid); - } - - -

However, this is going a little too far:

- - node && node.kids && node.kids[index] && foo(node.kids[index]); - -
- - -

Node lists are often implemented as node iterators with a filter. - This means that getting a property like length is O(n), and - iterating over the list by re-checking the length will be - O(n^2).

- - var paragraphs = document.getElementsByTagName('p'); - for (var i = 0; i < paragraphs.length; i++) { - doSomething(paragraphs[i]); - } - - -

It is better to do this instead:

- - var paragraphs = document.getElementsByTagName('p'); - for (var i = 0, paragraph; paragraph = paragraphs[i]; i++) { - doSomething(paragraph); - } - - -

This works well for all collections and arrays as long as the array - does not contain things that are treated as boolean false.

- -

In cases where you are iterating over the childNodes you can also - use the firstChild and nextSibling properties.

- - var parentNode = document.getElementById('foo'); - for (var child = parentNode.firstChild; child; child = child.nextSibling) { - doSomething(child); - } - -
- -
-
- - - - -

- BE CONSISTENT. -

- -

- If you're editing code, take a few minutes to look at the code - around you and determine its style. If they use spaces around - all their arithmetic operators, you should too. If their - comments have little boxes of hash marks around them, make your - comments have little boxes of hash marks around them too. -

- -

- The point of having style guidelines is to have a common vocabulary - of coding so people can concentrate on what you're saying rather - than on how you're saying it. We present global style rules here so - people know the vocabulary, but local style is also important. If - code you add to a file looks drastically different from the existing - code around it, it throws readers out of their rhythm when they go to - read it. Avoid this. -

- -
- -

- Revision 2.93 -

- - -
- Aaron Whyte
- Bob Jervis
- Dan Pupius
- Erik Arvidsson
- Fritz Schneider
- Robby Walker
-
-
diff --git a/jsoncstyleguide.html b/jsoncstyleguide.html deleted file mode 100644 index 1bef466..0000000 --- a/jsoncstyleguide.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - - Redirecting - - - - Redirecting you to jsoncstyleguide.xml. - - diff --git a/jsoncstyleguide.xml b/jsoncstyleguide.xml deleted file mode 100644 index 0835c26..0000000 --- a/jsoncstyleguide.xml +++ /dev/null @@ -1,1187 +0,0 @@ - - - - -

-Revision 0.9 -

- -
-
- - - - - -This style guide contains many details that are initially hidden from view. They are marked by the triangle icon, which you see here on your left. Click it now. You should see "Hooray" appear below. - - -

Hooray! Now you know you can expand points to get more details. Alternatively, there's an "expand all" at the top of this document.

- -
-
- -

This style guide documents guidelines and recommendations for building JSON APIs at Google. In general, JSON APIs should follow the spec found at JSON.org. This style guide clarifies and standardizes specific cases so that JSON APIs from Google have a standard look and feel. These guidelines are applicable to JSON requests and responses in both RPC-based and REST-based APIs.

-
- -

For the purposes of this style guide, we define the following terms:

  • property - a name/value pair inside a JSON object.
  • property name - the name (or key) portion of the property.
  • property value - the value portion of the property.
- -{ - // The name/value pair together is a "property". - "propertyName": "propertyValue" -} - - -

Javascript's number type encompasses all floating-point numbers, which is a broad designation. In this guide, number will refer to JavaScript's number type, while integer will refer to integers.

-
-
- - - -No comments in JSON objects. - - -

Comments should not be included in JSON objects. Some of the examples in this style guide include comments. However this is only to clarify the examples.

- -{ - // You may see comments in the examples below, - // But don't include comments in your JSON. - "propertyName": "propertyValue" -} - - - -
- - -Use double quotes. - - -

If a property requires quotes, double quotes must be used. All property names must be surrounded by double quotes. Property values of type string must be surrounded by double quotes. Other value types (like boolean or number) should not be surrounded by double quotes.

- -
- - -Data should not be arbitrarily grouped for convenience. - - -

Data elements should be "flattened" in the JSON representation. Data should not be arbitrarily grouped for convenience.

In some cases, such as a collection of properties that represents a single structure, it may make sense to keep the structured hierarchy. These cases should be carefully considered, and only used if it makes semantic sense. For example, an address could be represented two ways, but the structured way probably makes more sense for developers:

-

Flattened Address:

- -{ - "company": "Google", - "website": "http://www.google.com/", - "addressLine1": "111 8th Ave", - "addressLine2": "4th Floor", - "state": "NY", - "city": "New York", - "zip": "10011" -} - -

Structured Address:

- -{ - "company": "Google", - "website": "http://www.google.com/", - "address": { - "line1": "111 8th Ave", - "line2": "4th Floor", - "state": "NY", - "city": "New York", - "zip": "10011" - } -} - - -
-
- - - -Choose meaningful property names. - - -

Property names must conform to the following guidelines:

  • Property names should be meaningful names with defined semantics.
  • Property names must be camel-cased, ascii strings.
  • The first character must be a letter, an underscore (_) or a dollar sign ($).
  • Subsequent characters can be a letter, a digit, an underscore, or a dollar sign.
  • Reserved JavaScript keywords should be avoided (A list of reserved JavaScript keywords can be found below).

These guidelines mirror the guidelines for naming JavaScript identifiers. This allows JavaScript clients to access properties using dot notation. (for example, result.thisIsAnInstanceVariable). Here's an example of an object with one property:

- -{ - "thisPropertyIsAnIdentifier": "identifier value" -} - - - -
- - -JSON maps can use any Unicode character in key names. - - -

The property name naming rules do not apply when a JSON object is used as a map. A map (also referred to as an associative array) is a data type with arbitrary key/value pairs that use the keys to access the corresponding values. JSON objects and JSON maps look the same at runtime; this distinction is relevant to the design of the API. The API documentation should indicate when JSON objects are used as maps.

The keys of a map do not have to obey the naming guidelines for property names. Map keys may contain any Unicode characters. Clients can access these properties using the square bracket notation familiar for maps (for example, result.thumbnails["72"]).

- -{ - // The "address" property is a sub-object - // holding the parts of an address. - "address": { - "addressLine1": "123 Anystreet", - "city": "Anytown", - "state": "XX", - "zip": "00000" - }, - // The "thumbnails" property is a map that maps - // a pixel size to the thumbnail url of that size. - "thumbnails": { - "72": "http://url.to.72px.thumbnail", - "144": "http://url.to.144px.thumbnail" - } -} - - - -
- - -Certain property names are reserved for consistent use across services. - - -

Details about reserved property names, along with the full list, can be found later on in this guide. Services should avoid using these property names for anything other than their defined semantics.

- -
- - -Array types should have plural property names. All other property names should be singular. - - -

Arrays usually contain multiple items, and a plural property name reflects this. An example of this can be seen in the reserved names below. The items property name is plural because it represents an array of item objects. Most of the other fields are singular.

There may be exceptions to this, especially when referring to numeric property values. For example, in the reserved names, totalItems makes more sense than totalItem. However, technically, this is not violating the style guide, since totalItems can be viewed as totalOfItems, where total is singular (as per the style guide), and OfItems serves to qualify the total. The field name could also be changed to itemCount to look singular.

- -{ - // Singular - "author": "lisa", - // An array of siblings, plural - "siblings": [ "bart", "maggie"], - // "totalItem" doesn't sound right - "totalItems": 10, - // But maybe "itemCount" is better - "itemCount": 10, -} - - - -
- - -Avoid naming conflicts by choosing a new property name or versioning the API. - - -

New properties may be added to the reserved list in the future. There is no concept of JSON namespacing. If there is a naming conflict, these can usually be resolved by choosing a new property name or by versioning. For example, suppose we start with the following JSON object:

- -{ - "apiVersion": "1.0", - "data": { - "recipeName": "pizza", - "ingredients": ["tomatoes", "cheese", "sausage"] - } -} - - -

If in the future we wish to make ingredients a reserved word, we can do one of two things:

1) Choose a different name:

- -{ - "apiVersion": "1.0", - "data": { - "recipeName": "pizza", - "ingredientsData": "Some new property", - "ingredients": ["tomatoes", "cheese", "sausage"] - } -} - - -

2) Rename the property on a major version boundary:

- -{ - "apiVersion": "2.0", - "data": { - "recipeName": "pizza", - "ingredients": "Some new property", - "recipeIngredients": ["tomatos", "cheese", "sausage"] - } -} - - - -
-
- - - -Property values must be Unicode booleans, numbers, strings, objects, arrays, or null. - - -

The spec at JSON.org specifies exactly what type of data is allowed in a property value. This includes Unicode booleans, numbers, strings, objects, arrays, and null. JavaScript expressions are not allowed. APIs should support that spec for all values, and should choose the data type most appropriate for a particular property (numbers to represent numbers, etc.).

Good:

- -{ - "canPigsFly": null, // null - "areWeThereYet": false, // boolean - "answerToLife": 42, // number - "name": "Bart", // string - "moreData": {}, // object - "things": [] // array -} - - -

Bad:

- -{ - "aVariableName": aVariableName, // Bad - JavaScript identifier - "functionFoo": function() { return 1; } // Bad - JavaScript function -} - - - -
- - -Consider removing empty or null values. - - -

If a property is optional or has an empty or null value, consider dropping the property from the JSON, unless there's a strong semantic reason for its existence.

- -{ - "volume": 10, - - // Even though the "balance" property's value is zero, it should be left in, - // since "0" signifies "even balance" (the value could be "-1" for left - // balance and "+1" for right balance. - "balance": 0, - - // The "currentlyPlaying" property can be left out since it is null. - // "currentlyPlaying": null -} - - - -
- - -Enum values should be represented as strings. - - -

As APIs grow, enum values may be added, removed or changed. Using strings as enum values ensures that downstream clients can gracefully handle changes to enum values.

Java code:

- -public enum Color { - WHITE, - BLACK, - RED, - YELLOW, - BLUE -} - - -

JSON object:

- -{ - "color": "WHITE" -} - - - -
-
- -

As mentioned above, property value types must be booleans, numbers, strings, objects, arrays, or null. However, it is useful define a set of standard data types when dealing with certain values. These data types will always be strings, but they will be formatted in a specific manner so that they can be easily parsed.

- - -Dates should be formatted as recommended by RFC 3339. - - -

Dates should be strings formatted as recommended by RFC 3339

- -{ - "lastUpdate": "2007-11-06T16:34:41.000Z" -} - - - -
- - -Time durations should be formatted as recommended by ISO 8601. - - -

Time duration values should be strings formatted as recommended by ISO 8601.

- -{ - // three years, six months, four days, twelve hours, - // thirty minutes, and five seconds - "duration": "P3Y6M4DT12H30M5S" -} - - - -
- - -Latitudes/Longitudes should be formatted as recommended by ISO 6709. - - -

Latitude/Longitude should be strings formatted as recommended by ISO 6709. Furthermore, they should favor the ±DD.DDDD±DDD.DDDD degrees format.

- -{ - // The latitude/longitude location of the statue of liberty. - "statueOfLiberty": "+40.6894-074.0447" -} - - - -
-
- -

In order to maintain a consistent interface across APIs, JSON objects should follow the structure outlined below. This structure applies to both requests and responses made with JSON. Within this structure, there are certain property names that are reserved for specific uses. These properties are NOT required; in other words, each reserved property may appear zero or one times. But if a service needs these properties, this naming convention is recommend. Here is a schema of the JSON structure, represented in Orderly format (which in turn can be compiled into a JSONSchema). You can few examples of the JSON structure at the end of this guide.

- -object { - string apiVersion?; - string context?; - string id?; - string method?; - object { - string id? - }* params?; - object { - string kind?; - string fields?; - string etag?; - string id?; - string lang?; - string updated?; # date formatted RFC 3339 - boolean deleted?; - integer currentItemCount?; - integer itemsPerPage?; - integer startIndex?; - integer totalItems?; - integer pageIndex?; - integer totalPages?; - string pageLinkTemplate /^https?:/ ?; - object {}* next?; - string nextLink?; - object {}* previous?; - string previousLink?; - object {}* self?; - string selfLink?; - object {}* edit?; - string editLink?; - array [ - object {}*; - ] items?; - }* data?; - object { - integer code?; - string message?; - array [ - object { - string domain?; - string reason?; - string message?; - string location?; - string locationType?; - string extendedHelp?; - string sendReport?; - }*; - ] errors?; - }* error?; -}*; - - -

The JSON object has a few top-level properties, followed by either a data object or an error object, but not both. An explanation of each of these properties can be found below.

-
- -

The top-level of the JSON object may contain the following properties.

- - -Property Value Type: string
Parent: - -
- -

Represents the desired version of the service API in a request, and the version of the service API that's served in the response. apiVersion should always be present. This is not related to the version of the data. Versioning of data should be handled through some other mechanism such as etags.

Example:

- -{ "apiVersion": "2.1" } - - - -
- - -Property Value Type: string
Parent: - -
- -

Client sets this value and server echos data in the response. This is useful in JSON-P and batch situations , where the user can use the context to correlate responses with requests. This property is a top-level property because the context should present regardless of whether the response was successful or an error. context differs from id in that context is specified by the user while id is assigned by the service.

Example:

Request #1:

- -http://www.google.com/myapi?context=bart - - -

Request #2:

- -http://www.google.com/myapi?context=lisa - - -

Response #1:

- -{ - "context": "bart", - "data": { - "items": [] - } -} - - -

Response #2:

- -{ - "context": "lisa", - "data": { - "items": [] - } -} - - -

Common JavaScript handler code to process both responses:

- -function handleResponse(response) { - if (response.result.context == "bart") { - // Update the "Bart" section of the page. - } else if (response.result.context == "lisa") { - // Update the "Lisa" section of the page. - } -} - - - -
- - -Property Value Type: string
Parent: - -
- -

A server supplied identifier for the response (regardless of whether the response is a success or an error). This is useful for correlating server logs with individual responses received at a client.

Example:

- -{ "id": "1" } - - - -
- - -Property Value Type: string
Parent: - -
- -

Represents the operation to perform, or that was performed, on the data. In the case of a JSON request, the method property can be used to indicate which operation to perform on the data. In the case of a JSON response, the method property can indicate the operation performed on the data.

One example of this is in JSON-RPC requests, where method indicates the operation to perform on the params property:

- -{ - "method": "people.get", - "params": { - "userId": "@me", - "groupId": "@self" - } -} - - - -
- - -Property Value Type: object
Parent: - -
- -

This object serves as a map of input parameters to send to an RPC request. It can be used in conjunction with the method property to execute an RPC function. If an RPC function does not need parameters, this property can be omitted.

Example:

- -{ - "method": "people.get", - "params": { - "userId": "@me", - "groupId": "@self" - } -} - - - -
- - -Property Value Type: object
Parent: - -
- -

Container for all the data from a response. This property itself has many reserved property names, which are described below. Services are free to add their own data to this object. A JSON response should contain either a data object or an error object, but not both. If both data and error are present, the error object takes precedence.

- -
- - -Property Value Type: object
Parent: - -
- -

Indicates that an error has occurred, with details about the error. The error format supports either one or more errors returned from the service. A JSON response should contain either a data object or an error object, but not both. If both data and error are present, the error object takes precedence.

Example:

- -{ - "apiVersion": "2.0", - "error": { - "code": 404, - "message": "File Not Found", - "errors": [{ - "domain": "Calendar", - "reason": "ResourceNotFoundException", - "message": "File Not Found - }] - } -} - - - -
-
- -

The data property of the JSON object may contain the following properties.

- - -Property Value Type: string
Parent: data -
- -

The kind property serves as a guide to what type of information this particular object stores. It can be present at the data level, or at the items level, or in any object where its helpful to distinguish between various types of objects. If the kind object is present, it should be the first property in the object (See the "Property Ordering" section below for more details).

Example:

- -// "Kind" indicates an "album" in the Picasa API. -{"data": {"kind": "album"}} - - - -
- - -Property Value Type: string
Parent: data -
- -

Represents the fields present in the response when doing a partial GET, or the fields present in a request when doing a partial PATCH. This property should only exist during a partial GET/PATCH, and should not be empty.

Example:

- -{ - "data": { - "kind": "user", - "fields": "author,id", - "id": "bart", - "author": "Bart" - } -} - - - -
- - -Property Value Type: string
Parent: data -
- -

Represents the etag for the response. Details about ETags in the GData APIs can be found here: http://code.google.com/apis/gdata/docs/2.0/reference.html#ResourceVersioning

Example:

- -{"data": {"etag": "W/"C0QBRXcycSp7ImA9WxRVFUk.""}} - - - -
- - -Property Value Type: string
Parent: data -
- -

A globally unique string used to reference the object. The specific details of the id property are left up to the service.

Example:

- -{"data": {"id": "12345"}} - - - -
- - -Property Value Type: string (formatted as specified in BCP 47)
Parent: data (or any child element) -
- -

Indicates the language of the rest of the properties in this object. This property mimics HTML's lang property and XML's xml:lang properties. The value should be a language value as defined in BCP 47. If a single JSON object contains data in multiple languages, the service is responsible for developing and documenting an appropriate location for the lang property.

Example:

- -{"data": { - "items": [ - { "lang": "en", - "title": "Hello world!" }, - { "lang": "fr", - "title": "Bonjour monde!" } - ]} -} - - -
- - -Property Value Type: string (formatted as specified in RFC 3339)
Parent: data -
- -

Indicates the last date/time (RFC 3339) the item was updated, as defined by the service.

Example:

- -{"data": {"updated": "2007-11-06T16:34:41.000Z"}} - - - -
- - -Property Value Type: boolean
Parent: data (or any child element) -
- -

A marker element, that, when present, indicates the containing entry is deleted. If deleted is present, its value must be true; a value of false can cause confusion and should be avoided.

Example:

- -{"data": { - "items": [ - { "title": "A deleted entry", - "deleted": true - } - ]} -} - - - -
- - -Property Value Type: array
Parent: data -
- -

The property name items is reserved to represent an array of items (for example, photos in Picasa, videos in YouTube). This construct is intended to provide a standard location for collections related to the current result. For example, the JSON output could be plugged into a generic pagination system that knows to page on the items array. If items exists, it should be the last property in the data object (See the "Property Ordering" section below for more details).

Example:

- -{ - "data": { - "items": [ - { /* Object #1 */ }, - { /* Object #2 */ }, - ... - ] - } -} - - - -
-
- -

The following properties are located in the data object, and help page through a list of items. Some of the language and concepts are borrowed from the OpenSearch specification.

The paging properties below allow for various styles of paging, including:

An example of how to use these properties to implement paging can be found at the end of this guide.

- - -Property Value Type: integer
Parent: data -
- -

The number of items in this result set. Should be equivalent to items.length, and is provided as a convenience property. For example, suppose a developer requests a set of search items, and asks for 10 items per page. The total set of that search has 14 total items. The first page of items will have 10 items in it, so both itemsPerPage and currentItemCount will equal "10". The next page of items will have the remaining 4 items; itemsPerPage will still be "10", but currentItemCount will be "4".

Example:

- -{ - "data": { - // "itemsPerPage" does not necessarily match "currentItemCount" - "itemsPerPage": 10, - "currentItemCount": 4 - } -} - - - -
- - -Property Value Type: integer
Parent: data -
- -

The number of items in the result. This is not necessarily the size of the data.items array; if we are viewing the last page of items, the size of data.items may be less than itemsPerPage. However the size of data.items should not exceed itemsPerPage.

Example:

- -{ - "data": { - "itemsPerPage": 10 - } -} - - - -
- - -Property Value Type: integer
Parent: data -
- -

The index of the first item in data.items. For consistency, startIndex should be 1-based. For example, the first item in the first set of items should have a startIndex of 1. If the user requests the next set of data, the startIndex may be 10.

Example:

- -{ - "data": { - "startIndex": 1 - } -} - - - -
- - -Property Value Type: integer
Parent: data -
- -

The total number of items available in this set. For example, if a user has 100 blog posts, the response may only contain 10 items, but the totalItems would be 100.

Example:

- -{ - "data": { - "totalItems": 100 - } -} - - - -
- - -Property Value Type: string
Parent: data -
- -

A URI template indicating how users can calculate subsequent paging links. The URI template also has some reserved variable names: {index} representing the item number to load, and {pageIndex}, representing the page number to load.

Example:

- -{ - "data": { - "pagingLinkTemplate": "http://www.google.com/search/hl=en&q=chicago+style+pizza&start={index}&sa=N" - } -} - - - -
- - -Property Value Type: integer
Parent: data -
- -

The index of the current page of items. For consistency, pageIndex should be 1-based. For example, the first page of items has a pageIndex of 1. pageIndex can also be calculated from the item-based paging properties: pageIndex = floor(startIndex / itemsPerPage) + 1.

Example:

- -{ - "data": { - "pageIndex": 1 - } -} - - - -
- - -Property Value Type: integer
Parent: data -
- -

The total number of pages in the result set. totalPages can also be calculated from the item-based paging properties above: totalPages = ceiling(totalItems / itemsPerPage).

Example:

- -{ - "data": { - "totalPages": 50 - } -} - - - -
-
- -

The following properties are located in the data object, and represent references to other resources. There are two forms of link properties: 1) objects, which can contain any sort of reference (such as a JSON-RPC object), and 2) URI strings, which represent URIs to resources (and will always be suffixed with "Link").

- - -Property Value Type: object / string
Parent: data -
- -

The self link can be used to retrieve the item's data. For example, in a list of a user's Picasa album, each album object in the items array could contain a selfLink that can be used to retrieve data related to that particular album.

Example:

- -{ - "data": { - "self": { }, - "selfLink": "http://www.google.com/feeds/album/1234" - } -} - - - -
- - -Property Value Type: object / string
Parent: data -
- -

The edit link indicates where a user can send update or delete requests. This is useful for REST-based APIs. This link need only be present if the user can update/delete this item.

Example:

- -{ - "data": { - "edit": { }, - "editLink": "http://www.google.com/feeds/album/1234/edit" - } -} - - - -
- - -Property Value Type: object / string
Parent: data -
- -

The next link indicates how more data can be retrieved. It points to the location to load the next set of data. It can be used in conjunction with the itemsPerPage, startIndex and totalItems properties in order to page through data.

Example:

- -{ - "data": { - "next": { }, - "nextLink": "http://www.google.com/feeds/album/1234/next" - } -} - - - -
- - -Property Value Type: object / string
Parent: data -
- -

The previous link indicates how more data can be retrieved. It points to the location to load the previous set of data. It can be used in conjunction with the itemsPerPage, startIndex and totalItems properties in order to page through data.

Example:

- -{ - "data": { - "previous": { }, - "previousLink": "http://www.google.com/feeds/album/1234/next" - } -} - - - -
-
- -

The error property of the JSON object may contain the following properties.

- - -Property Value Type: integer
Parent: error -
- -

Represents the code for this error. This property value will usually represent the HTTP response code. If there are multiple errors, code will be the error code for the first error.

Example:

- -{ - "error":{ - "code": 404 - } -} - - - -
- - -Property Value Type: string
Parent: error -
- -

A human readable message providing more details about the error. If there are multiple errors, message will be the message for the first error.

Example:

- -{ - "error":{ - "message": "File Not Found" - } -} - - - -
- - -Property Value Type: array
Parent: error -
- -

Container for any additional information regarding the error. If the service returns multiple errors, each element in the errors array represents a different error.

Example:

- -{ "error": { "errors": [] } } - - - -
- - -Property Value Type: string
Parent: error.errors -
- -

Unique identifier for the service raising this error. This helps distinguish service-specific errors (i.e. error inserting an event in a calendar) from general protocol errors (i.e. file not found).

Example:

- -{ - "error":{ - "errors": [{"domain": "Calendar"}] - } -} - - - -
- - -Property Value Type: string
Parent: error.errors -
- -

Unique identifier for this error. Different from the error.code property in that this is not an http response code.

Example:

- -{ - "error":{ - "errors": [{"reason": "ResourceNotFoundException"}] - } -} - - - -
- - -Property Value Type: string
Parent: error.errors -
- -

A human readable message providing more details about the error. If there is only one error, this field will match error.message.

Example:

- -{ - "error":{ - "code": 404 - "message": "File Not Found", - "errors": [{"message": "File Not Found"}] - } -} - - - -
- - -Property Value Type: string
Parent: error.errors -
- -

The location of the error (the interpretation of its value depends on locationType).

Example:

- -{ - "error":{ - "errors": [{"location": ""}] - } -} - - - -
- - -Property Value Type: string
Parent: error.errors -
- -

Indicates how the location property should be interpreted.

Example:

- -{ - "error":{ - "errors": [{"locationType": ""}] - } -} - - - -
- - -Property Value Type: string
Parent: error.errors -
- -

A URI for a help text that might shed some more light on the error.

Example:

- -{ - "error":{ - "errors": [{"extendedHelper": "http://url.to.more.details.example.com/"}] - } -} - - - -
- - -Property Value Type: string
Parent: error.errors -
- -

A URI for a report form used by the service to collect data about the error condition. This URI should be preloaded with parameters describing the request.

Example:

- -{ - "error":{ - "errors": [{"sendReport": "http://report.example.com/"}] - } -} - - - -
-
- -

Properties can be in any order within the JSON object. However, in some cases the ordering of properties can help parsers quickly interpret data and lead to better performance. One example is a pull parser in a mobile environment, where performance and memory are critical, and unnecessary parsing should be avoided.

- - -kind should be the first property - - -

Suppose a parser is responsible for parsing a raw JSON stream into a specific object. The kind property guides the parser to instantiate the appropriate object. Therefore it should be the first property in the JSON object. This only applies when objects have a kind property (usually found in the data and items properties).

- -
- - -items should be the last property in the data object - - -

This allows all of the collection's properties to be read before reading each individual item. In cases where there are a lot of items, this avoids unnecessarily parsing those items when the developer only needs fields from the data.

- -
- - - -// The "kind" property distinguishes between an "album" and a "photo". -// "Kind" is always the first property in its parent object. -// The "items" property is the last property in the "data" object. -{ - "data": { - "kind": "album", - "title": "My Photo Album", - "description": "An album in the user's account", - "items": [ - { - "kind": "photo", - "title": "My First Photo" - } - ] - } -} - - - - -
- - - -Here's an example of the YouTube JSON API's response object. You can learn more about YouTube's JSON API here: http://code.google.com/apis/youtube/2.0/developers_guide_jsonc.html. - - - -{ - "apiVersion": "2.0", - "data": { - "updated": "2010-02-04T19:29:54.001Z", - "totalItems": 6741, - "startIndex": 1, - "itemsPerPage": 1, - "items": [ - { - "id": "BGODurRfVv4", - "uploaded": "2009-11-17T20:10:06.000Z", - "updated": "2010-02-04T06:25:57.000Z", - "uploader": "docchat", - "category": "Animals", - "title": "From service dog to SURFice dog", - "description": "Surf dog Ricochets inspirational video ...", - "tags": [ - "Surf dog", - "dog surfing", - "dog", - "golden retriever", - ], - "thumbnail": { - "default": "http://i.ytimg.com/vi/BGODurRfVv4/default.jpg", - "hqDefault": "http://i.ytimg.com/vi/BGODurRfVv4/hqdefault.jpg" - }, - "player": { - "default": "http://www.youtube.com/watch?v=BGODurRfVv4&feature=youtube_gdata", - "mobile": "http://m.youtube.com/details?v=BGODurRfVv4" - }, - "content": { - "1": "rtsp://v5.cache6.c.youtube.com/CiILENy73wIaGQn-Vl-0uoNjBBMYDSANFEgGUgZ2aWRlb3MM/0/0/0/video.3gp", - "5": "http://www.youtube.com/v/BGODurRfVv4?f=videos&app=youtube_gdata", - "6": "rtsp://v7.cache7.c.youtube.com/CiILENy73wIaGQn-Vl-0uoNjBBMYESARFEgGUgZ2aWRlb3MM/0/0/0/video.3gp" - }, - "duration": 315, - "rating": 4.96, - "ratingCount": 2043, - "viewCount": 1781691, - "favoriteCount": 3363, - "commentCount": 1007, - "commentsAllowed": true - } - ] - } -} - - - - - - -This example demonstrates how the Google search items could be represented as a JSON object, with special attention to the paging variables. - - -

This sample is for illustrative purposes only. The API below does not actually exist.

Here's a sample Google search results page:

Here's a sample JSON representation of this page:

- -{ - "apiVersion": "2.1", - "id": "1", - "data": { - "query": "chicago style pizza", - "time": "0.1", - "currentItemCount": 10, - "itemsPerPage": 10, - "startIndex": 11, - "totalItems": 2700000, - "nextLink": "http://www.google.com/search?hl=en&q=chicago+style+pizza&start=20&sa=N" - "previousLink": "http://www.google.com/search?hl=en&q=chicago+style+pizza&start=0&sa=N", - "pagingLinkTemplate": "http://www.google.com/search/hl=en&q=chicago+style+pizza&start={index}&sa=N", - "items": [ - { - "title": "Pizz'a Chicago Home Page" - // More fields for the search results - } - // More search results - ] - } -} - - -

Here's how each of the colored boxes from the screenshot would be represented (the background colors correspond to the colors in the images above):

  • Results 11 - 20 of about 2,700,000 = startIndex
  • Results 11 - 20 of about 2,700,000 = startIndex + currentItemCount - 1
  • Results 11 - 20 of about 2,700,000 = totalItems
  • Search results = items (formatted appropriately)
  • Previous/Next = previousLink / nextLink
  • Numbered links in "Gooooooooooogle" = Derived from "pageLinkTemplate". The developer is responsible for calculating the values for {index} and substituting those values into the "pageLinkTemplate". The pageLinkTemplate's {index} variable is calculated as follows:
    • Index #1 = 0 * itemsPerPage = 0
    • Index #2 = 2 * itemsPerPage = 10
    • Index #3 = 3 * itemsPerPage = 20
    • Index #N = N * itemsPerPage
- -
-
- - - -A list of reserved JavaScript words that should be avoided in property names. - - -

The words below are reserved by the JavaScript language and cannot be referred to using dot notation. The list represents best knowledge of keywords at this time; the list may change or vary based on your specific execution environment.

From the ECMAScript Language Specification 5th Edition

- -abstract -boolean break byte -case catch char class const continue -debugger default delete do double -else enum export extends -false final finally float for function -goto -if implements import in instanceof int interface -let long -native new null -package private protected public -return -short static super switch synchronized -this throw throws transient true try typeof -var volatile void -while with -yield - - -
-
-
- -

-Except as otherwise noted, the content of this page is licensed under the Creative Commons Attribution 3.0 License, and code samples are licensed under the Apache 2.0 License. -

-

-Revision 0.9 -

- -
-
- -
diff --git a/jsoncstyleguide_example_01.png b/jsoncstyleguide_example_01.png deleted file mode 100644 index d7a86ee..0000000 Binary files a/jsoncstyleguide_example_01.png and /dev/null differ diff --git a/jsoncstyleguide_example_02.png b/jsoncstyleguide_example_02.png deleted file mode 100644 index d3e8243..0000000 Binary files a/jsoncstyleguide_example_02.png and /dev/null differ diff --git a/lispguide.xml b/lispguide.xml deleted file mode 100644 index e5b6dc3..0000000 --- a/lispguide.xml +++ /dev/null @@ -1,3887 +0,0 @@ - - - - - -

- -Revision 1.28 -

- - -
-Robert Brown -
-
- François-René Rideau -
- -
- In memoriam Dan Weinreb -
- -

-Patterns mean "I have run out of language." — Rich Hickey -

- - - - - - - This style guide contains many details - that are initially hidden from view. - They are marked by the triangle icon, which you see here on your left. - Click it now. You should see "Hooray" appear below. - - -

- Hooray! Now you know you can expand points to get more details. - Alternatively, there's an "expand all" at the top of this document. -

- -
-
- -

- Common Lisp is a powerful multiparadigm programming language. - With great power comes great responsibility. -

-

- This guide recommends formatting and stylistic choices - designed to make your code easier for other people to understand. - For those internal applications and free software libraries that - we develop at Google, - you should keep within these guidelines when making changes. - Note however that each project has its own rules and customs - that complement or override these general guidelines; - the speed-oriented QPX low fare search engine notably - has a very different style and feel from the QRes reservation system. -

-

- If you're writing Common Lisp code outside Google, - we invite you to consider these guidelines. - You may find some of them useful - where they don't conflict with other priorities you have. - We welcome remarks and constructive feedback - on how to improve our guide, and - on what alternate styles work for you and why. -

- -

- This guide is not a Common Lisp tutorial. - For basic information about the language, please consult - Practical Common Lisp. - For a language reference, please consult the - Common Lisp HyperSpec. - For more detailed style guidance, take (with a pinch of salt) - a look at Peter Norvig and Kent Pitman's - style guide. -

-
-
- - - - Each guideline's level of importance is indicated - by use of the following keywords and phrases, adapted from - RFC 2119. - - - - - - - - - - - - - - - - - - - - - - - -
MUST -

- This word, or the terms "REQUIRED" or "SHALL", - means that the guideline is an absolute requirement. - You must ask permission to violate a MUST. -

-
MUST NOT -

- This phrase, or the phrase "SHALL NOT", - means that the guideline is an absolute prohibition. - You must ask permission to violate a MUST NOT. -

-
SHOULD -

- This word, or the adjective "RECOMMENDED", means that - there may exist valid reasons in particular circumstances - to ignore the demands of the guideline, but - the full implications must be understood and carefully weighed - before choosing a different course. - You must ask forgiveness for violating a SHOULD. -

-
SHOULD NOT -

- This phrase, or the phrase "NOT RECOMMENDED", means that - there may exist valid reasons in particular circumstances - to ignore the prohibitions of this guideline, but - the full implications should be understood and carefully weighed - before choosing a different course. - You must ask forgiveness for violating a SHOULD NOT. -

-
MAY -

- This word, or the adjective "OPTIONAL", - means that an item is truly optional. -

-
-

- Unlike RFCs, we don't capitalize every instance of one of the above - keywords when it is used. -

- -
- - - There are cases where transgression of some of these rules - is useful or even necessary. - In some cases, you must seek permission or obtain forgiveness - from the proper people. - - -

- Permission comes from the owners of your project. -

- -

- Forgiveness is requested in a comment - near the point of guideline violation, - and is granted by your code reviewer. - The original comment should be signed by you, and - the reviewer should add a signed approval to the comment at review time. -

- - -
- - - You MUST follow conventions. They are not optional. - - -

- Some of these guidelines are motivated by universal principles of good programming. - Some guidelines are motivated by technical peculiarities of Common Lisp. - Some guidelines were once motivated by a technical reason, - but the guideline remained after the reason subsided. - Some guidelines, such those about as comments and indentation, - are based purely on convention, rather than on clear technical merit. - Whatever the case may be, you must still follow these guidelines, - as well as other conventional guidelines - that have not been formalized in this document. -

-

- You MUST follow conventions. - They are important for readability. - When conventions are followed by default, - violations of the convention are a signal - that something notable is happening and deserves attention. - When conventions are systematically violated, - violations of the convention are a distracting noise - that needs to be ignored. -

-

- Conventional guidelines are indoctrination. - Their purpose is to make you follow the mores of the community, - - so you can more effectively cooperate with existing members. - It is still useful to distinguish the parts that are technically motivated - from the parts that are mere conventions, - so you know when best to defy conventions for good effect, - and when not to fall into the pitfalls that the conventions are there to help avoid. -

- -
- - - Fix old code as you go. - - -

- A lot of our code was written before these guidelines existed. - You should fix violations as you encounter them - in the course of your normal coding. -

-

- You must not fix violations en masse - without warning other developers and coordinating with them, - so as not to make the merging of large branches - more difficult than it already is. -

- -
- - - There are many topics for additional standardization - not covered by current version of this document, - but deferred to future versions. - - -
    -
  • - File and directory structure -
  • -
  • - Packages and modularity -
  • -
  • - Threads and locking -
  • -
  • - How to add configurable components -
  • -
  • - CLOS style: initforms, slot and accessor names, etc. -
  • -
  • - Recommendations on max number of slots per class. -
  • -
  • - More concrete examples of good code: -
      -
    • - exceptions -
    • -
    • - transactions, with retry -
    • -
    • - XML -
    • -
    • - typing -
    • -
    • - encapsulation / abstraction -
    • -
    • - class and slot names -
    • -
    • - etc. -
    • -
    -
  • -
  • - When (not) to use conditional compilation: -
      -
    • - modifying the product -
    • -
    • - conditional debugging/console output/etc. -
    • -
    • - "temporarily" commenting-out blocks of code -
    • -
    • - etc. -
    • -
    -
  • -
- -
-
- - - - There are some basic principles for team software development - that every developer must keep in mind. - Whenever the detailed guidelines are inadequate, confusing or contradictory, - refer back to these principles for guidance: -
    -
  • - Every developer's code must be easy for another developer - to read, understand, and modify - — even if the first developer isn't around to explain it. - (This is the "hit by a truck" principle.) -
  • -
  • - Everybody's code should look the same. - Ideally, there should be no way to look at lines of code - and recognize it as "Fred's code" by its style. -
  • -
  • - Be precise. -
  • -
  • - Be concise. -
  • -
  • - KISS — Keep It Simple, Stupid. -
  • -
  • - Use the smallest hammer for the job. -
  • -
  • - Use common sense. -
  • -
  • - Keep related code together. - Minimize the amount of jumping around - someone has to do to understand an area of code. -
  • -
-
- - -
- - -

- When making decisions about how to write a given piece of - code, aim for the following -ilities in this priority order: -

-
    -
  • - Usability by the customer -
  • -
  • - Debuggability/Testability -
  • -
  • - Readability/Comprehensibility -
  • -
  • - Extensibility/Modifiability -
  • -
  • - Efficiency (of the Lisp code at runtime) -
  • -
-
- -

- Most of these are obvious. -

-

- Usability by the customer means that the system has to do what the - customer requires; it has to handle the customer's transaction - volumes, uptime requirements; etc. -

-

- For the Lisp efficiency point, - given two options of equivalent complexity, - pick the one that performs better. - (This is often the same as the one that conses less, - i.e. allocates less storage from the heap.) -

-

- Given two options where one is more complex than the other, - pick the simpler option and revisit the decision only if - profiling shows it to be a performance bottleneck. -

-

- However, avoid premature optimization. - Don't add complexity to speed up something that runs rarely, - since in the long run, it matters less whether such code is fast. -

- -
- - - To build code that is robust and maintainable, - it matters a lot how the code is divided into components, - how these components communicate, - how changes propagate as they evolve, - and more importantly - how the programmers who develop these components communicate - as these components evolve. - - -

- If your work affects other groups, might be reusable across groups, - adds new components, has an impact on other groups - (including QA or Ops), or otherwise isn't purely local, - you must write it up using at least a couple of paragraphs, - and get a design approval from the other parties involved - before starting to write code — or be ready to scratch what you have - when they object. -

-

- If you don't know or don't care about these issues, - ask someone who does. -

- -
- - - Often, the smallest hammer is to use an existing library. - Or one that doesn't exist yet. - In such cases, you are encouraged to use or develop such a library, - but you must take appropriate precautions. - - -
    -
  • - You MUST NOT start a new library - unless you established that none is already available - that can be fixed or completed into becoming what you need. - That's a rule against the NIH syndrome ("Not Invented Here"), - which is particularly strong amongst Lisp hackers. -
  • -
  • - Whichever library, old or new, you pick, you MUST get permission - to incorporate third-party code into the code base. - You must discuss the use of such library - in the appropriate mailing-list, - and have your code reviewed by people knowledgeable in the domain - and/or the Lisp library ecosystem (if any). - Please be ready to argue why this particular solution makes sense - as compared to other available libraries. -
  • -
  • - Some libraries are distributed under licenses not compatible - with the software you're writing, and - must not be considered available for use. - Be aware of these issues, or consult with people who are. -
  • -
- - -
- - -

- If you write a general-purpose library, - or modify an existing open-source library, - you are encouraged to publish the result - separate from your main project and then - have your project import it like any other open-source library. -

- -
- -

- Use your judgment to distinguish - general-purpose versus business-specific code, - and open-source the general-purpose parts, - while keeping the business-specific parts a trade secret. -

- -

- Open-Sourcing code has many advantages, - including being able to leverage third parties for development, - letting the development of features be user-directed, - and keeping you honest with respect to code quality. - Whatever code you write, you will have to maintain anyway, - and make sure its quality is high enough to sustain use in production. - There should therefore be no additional burden to Open-Sourcing, - even of code that (at least initially) - is not directly usable by third parties. -

- - -
- - - Development process is outside the scope of this document. - However, developers should remember at least these bits: - get reviewed, write tests, eliminate warnings, run tests, avoid mass-changes. - - -

-

-
    -
  • - All code changes must be reviewed. - You should expect that your code will be reviewed by other hackers, - and that you will be assigned other hackers' code to review. - Part of the review criteria will be that code obeys - the coding standards in this document. -
  • -
  • - You must write and check-in tests for new code that you write and old bugs you fix. - There must be a unit test for every API function, - and any previously failing case. - Your work is not truly done until this activity is complete. - Estimating tasks must include the time it takes to produce such tests. -
  • -
  • - Your code must compile - without any compilation error or warning messages whatsoever. - If the compiler issues warnings that should be ignored, - muffle those warnings using the - UIOP:WITH-MUFFLED-COMPILER-CONDITIONS and - UIOP:*UNINTERESTING-COMPILER-CONDITIONS* - framework (part of UIOP, part of ASDF 3), - either around the entire project, or around individual files - (using ASDF's :around-compile hooks). -
  • -
  • - All code should be checked in an appropriate source control system, - in a way that allows for complete reproducibility of - build, test and execution of - the code that is, has been or may be deployed. -
  • -
  • - You must run the "precheckin" tests, and each component must pass - its unit tests successfully before you commit any code. -
  • -
  • - You should incorporate code coverage into your testing process. - Tests are not sufficient - if they do not cover all new and updated code; - code that for whatever reason cannot be included in coverage results - should be clearly marked as such including the reason. -
  • -
  • - Many people develop on branches. - You must get permission to undertake mass-changes - (e.g. mass reindentations) - so that we can coordinate in advance, - and give branch residents time to get back on the mainline -
  • -
- -
-
- - - -

- You must use correct spelling in your comments, - and most importantly in your identifiers. -

-

- When several correct spellings exist (including American vs English), - and there isn't a consensus amongst developers as which to use, - you should choose the shorter spelling. -

-

- You must use only common and domain-specific abbreviations, and - must be consistent with these abbreviations. You may abbreviate - lexical variables of limited scope in order to avoid overly-long - symbol names. -

-
- -

- If you're not sure, consult a dictionary, - Google for alternative spellings, - or ask a local expert. -

-

- Here are examples of choosing the correct spelling: -

-
    -
  • - Use "complimentary" in the sense of a meal or beverage - that is not paid for by the recipient, not "complementary". -
  • -
  • - Use "existent" and "nonexistent", not "existant". - Use "existence", not "existance". -
  • -
  • - Use "hierarchy" not "heirarchy". -
  • -
  • - Use "precede" not "preceed". -
  • -
  • - Use "weird", not "wierd". -
  • -
-

- Here are examples of choosing the shorter spelling: -

-
    -
  • - Use "canceled", not "cancelled" -
  • -
  • - Use "queuing", not "queueing". -
  • -
  • - Use "signaled", not "signalled"; -
  • -
  • - Use "traveled", not "travelled". -
  • -
  • - Use "aluminum", not "aluminium" -
  • -
  • - Use "oriented", not "orientated" -
  • -
  • - Use "color", not "colour" -
  • -
  • - Use "behavior", not "behaviour" -
  • -
-

- Make appropriate exceptions for industry standard nomenclature/jargon, - including plain misspellings. - For instance: -

-
    -
  • - Use "referer", not "referrer", in the context of the HTTP protocol. -
  • -
- - -
- - - You should format source code so that no line is longer than 100 characters. - - -

- Some line length restriction is better than none at all. - While old text terminals used to make 80 columns the standard, - these days, allowing 100 columns seems better, - since good style encourages the use of - descriptive variables and function names. -

- - -
- - -

- Indent your code the way a properly configured GNU Emacs does. -

-

- Maintain a consistent indentation style throughout a project. -

-

- Indent carefully to make the code easier to understand. -

-
- -

- Common Lisp indentation in Emacs is provided by the cl-indent library. - The latest version of cl-indent is packaged with - SLIME - (under contrib/slime-cl-indent.el). After installing SLIME, set up Emacs - to load SLIME automatically using - these instructions, adding slime-indentation to the list of - contrib libraries to be loaded in the call to slime-setup. -

-

- Ideally, use the default indentation settings provided by - slime-indentation. If necessary, customize indentation parameters to - maintain a consistent indentation style throughout an existing project. - Parameters can be customized using the :variables setting in - define-common-lisp-style. Indentation of specific forms can be - customized using the :indentation setting of define-common-lisp-style. - This is particularly useful when creating forms that behave like macros - or special operators that are indented differently than standard - function calls (e.g. defun, labels, or let). Add a - hook to 'lisp-mode-hook that calls common-lisp-set-style to set - the appropriate style automatically. -

- - -

- Use indentation to make complex function applications easier to read. - When an application does not fit on one line - or the function takes many arguments, - consider inserting newlines between the arguments - so that each one is on a separate line. - However, do not insert newlines in a way that makes it hard to tell - how many arguments the function takes - or where an argument form starts and ends. -

- - ;; Bad - (do-something first-argument second-argument (lambda (x) - (frob x)) fourth-argument last-argument) - - - ;; Better - (do-something first-argument - second-argument - #'(lambda (x) (frob x)) - fourth-argument - last-argument) - - -
- - -

- You should include a description at the top of each source file. -

-

- You should include neither authorship nor copyright information in a source file. -

-
- -

- Every source file should begin with a brief description - of the contents of that file. -

-

- After that description, every file should start the code itself with an - (in-package :package-name) form. -

-

- After that in-package form, - every file should follow with any file-specific - (declaim (optimize ...)) declaration - that is not covered by an ASDF :around-compile hook. -

- - ;;;; Variable length encoding for integers and floating point numbers. - - (in-package #:varint) - (declaim #.*optimize-default*) - -

- You should not include authorship information at the top of a file: - better information is available from version control, - and such a mention will only cause confusion and grief. - Indeed, whoever was the main author at the time such a mention was included - might not be who eventually made the most significant contributions to the file, - and even less who is responsible for the file at the moment. - -

-

- You should not include copyright information in individual source code files. - An exception is made for files meant to be disseminated as standalone. -

- - - -
- - - Vertical white space: one blank line between top-level forms. - - -

- You should include one blank line between top-level forms, - such as function definitions. - Exceptionally, blank lines can be omitted - between simple, closely related defining forms of the same kind, - such as a group of related type declarations or constant definitions. -

- - (defconstant +mix32+ #x12b9b0a1 "pi, an arbitrary number") - (defconstant +mix64+ #x2b992ddfa23249d6 "more digits of pi") - - (defconstant +golden-ratio32+ #x9e3779b9 "the golden ratio") - (defconstant +golden-ratio64+ #xe08c1d668b756f82 "more digits of the golden ratio") - - (defmacro incf32 (x y) - "Like INCF, but for integers modulo 2**32" - `(setf ,x (logand (+ ,x ,y) #xffffffff))) - (defmacro incf64 (x y) - "Like INCF, but for integers modulo 2**64" - `(setf ,x (logand (+ ,x ,y) #xffffffffffffffff))) - -

- Blank lines can be used to separate parts of a complicated function. - Generally, however, you should break a large function into smaller ones - instead of trying to make it more readable by adding vertical space. - If you can't, you should document with a ;; comment - what each of the separated parts of the function does. -

-

- You should strive to keep top-level forms, - including comments but excluding the documentation string, of - appropriate length; preferrably short. Forms extending beyond a - single page should be rare and their use should be justfied. - This applies to each of the forms in an eval-when, - rather than to the eval-when itself. - Additionally, defpackage forms may be longer, - since they may include long lists of symbols. -

- -
- - - Horizontal white space: none around parentheses. No tabs. - - -

- You must not include extra horizontal whitespace - before or after parentheses or around symbols. -

-

- You must not place right parentheses by themselves on a line. - A set of consecutive trailing parentheses must appear on the same line. -

- - ;; Very Bad - ( defun factorial ( limit ) - ( let (( product 1 )) - ( loop for i from 1 upto limit - do (setf product ( * product i ) ) ) - product - ) - ) - - - ;; Better - (defun factorial (limit) - (let ((product 1)) - (loop for i from 1 upto limit - do (setf product (* product i))) - product)) - -

- You should use only one space between forms. -

-

- You should not use spaces to vertically align forms - in the middle of consecutive lines. - An exception is made when the code possesses - an important yet otherwise not visible symmetry - that you want to emphasize. -

- - ;; Bad - (let* ((low 1) - (high 2) - (sum (+ (* low low) (* high high)))) - ...) - - - ;; Better - (let* ((low 1) - (high 2) - (sum (+ (* low low) (* high high)))) - ...)) - -

- You must align nested forms if they occur across more than one line. -

- - ;; Bad - (defun munge (a b c) - (* (+ a b) - c)) - - - ;; Better - (defun munge (a b c) - (* (+ a b) - c)) - -

- The convention is that the body of a binding form - is indented two spaces after the form. - Any binding data before the body is usually indented four spaces. - Arguments to a function call are aligned with the first argument; - if the first argument is on its own line, - it is aligned with the function name. -

- - (multiple-value-bind (a b c d) - (function-returning-four-values x y) - (declare (ignore c)) - (something-using a) - (also-using b d)) - -

- An exception to the rule against lonely parentheses - is made for an eval-when form around several definitions; - in this case, include a comment ; eval-when - after the closing parenthesis. -

-

- You must set your editor to - avoid inserting tab characters in the files you edit. - Tabs cause confusion when editors disagree - on how many spaces they represent. - In Emacs, do (setq-default indent-tabs-mode nil). -

- -
-
- - - - - You should use document strings on all visible functions - to explain how to use your code. - - -

- Unless some bit of code is painfully self-explanatory, - document it with a documentation string (also known as docstring). -

-

- Documentation strings are destined to be read - by the programmers who use your code. - They can be extracted from functions, types, classes, variables and macros, - and displayed by programming tools, such as IDEs, - or by REPL queries such as (describe 'foo); - web-based documentation or other reference works - can be created based on them. - Documentation strings are thus the perfect locus to document your API. - They should describe how to use the code - (including what pitfalls to avoid), - as opposed to how the code works (and where more work is needed), - which is what you'll put in comments. -

-

- Supply a documentation string when defining - top-level functions, types, classes, variables and macros. - Generally, add a documentation string wherever the language allows. -

-

- For functions, the docstring should describe the function's contract: - what the function does, - what the arguments mean, - what values are returned, - what conditions the function can signal. - It should be expressed at the appropriate level of abstraction, - explaining the intended meaning rather than, say, just the syntax. - In documentation strings, capitalize the names of Lisp symbols, - such as function arguments. - For example, "The value of LENGTH should be an integer." -

- - (defun small-prime-number-p (n) - "Return T if N, an integer, is a prime number. Otherwise, return NIL." - (cond ((or (< n 2)) - nil) - ((= n 2) - t) - ((divisorp 2 n) - nil) - (t - (loop for i from 3 upto (sqrt n) by 2 - never (divisorp i n))))) - - - (defgeneric table-clear (table) - (:documentation - "Like clrhash, empties the TABLE of all - associations, and returns the table itself.")) - -

- A long docstring may usefully - begin with a short, single-sentence summary, - followed by the larger body of the docstring. -

-

- When the name of a type is used, - the symbol may be quoted by surrounding it with - a back quote at the beginning and a single quote at the end. - Emacs will highlight the type, and the highlighting serves - as a cue to the reader that M-. - will lead to the symbol's definition. -

- - (defun bag-tag-expected-itinerary (bag-tag) - "Return a list of `legacy-pnr-pax-segment' objects representing - the expected itinerary of the `bag-tag' object, BAG-TAG." - ...) - -

- Every method of a generic function should be independently documented - when the specialization affects what the method does, - beyond what is described in its generic function's docstring. -

-

- When you fix a bug, - consider whether what the fixed code does is obviously correct or not; - if not, you must add a comment explaining - the reason for the code in terms of fixing the bug. - Adding the bug number, if any, is also recommended. -

- -
- - - You must use the appropriate number of semicolons to introduce comments. - - -

- Comments are explanations to the future maintainers of the code. - Even if you're the only person who will ever see and touch the code, - even if you're either immortal and never going to quit, - or unconcerned with what happens after you leave - (and have your code self-destruct in such an eventuality), - you may find it useful to comment your code. - Indeed, by the time you revisit your code, - weeks, months or years later, - you will find yourself a different person from the one who wrote it, - and you will be grateful to that previous self - for making the code readable. -

-

- You must comment anything complicated - so that the next developer can understand what's going on. - (Again, the "hit by a truck" principle.) -

-

- Also use comments as a way to guide those who read the code, - so they know what to find where. -

-
    -
  • - File headers and important comments - that apply to large sections of code in a source file - should begin with four semicolons. -
  • -
  • - You should use three semicolons - to begin comments that apply to just - one top-level form or small group of top-level forms. -
  • -
  • - Inside a top-level form, you should use two semicolons - to begin a comment if it appears between lines. -
  • -
  • - You should use one semicolon if it is a parenthetical remark - and occurs at the end of a line. - You should use spaces to separate the comment - from the code it refers to so the comment stands out. - You should try to vertically align - consecutive related end-of-line comments. -
  • -
- - ;;;; project-euler.lisp - ;;;; File-level comments or comments for large sections of code. - - ;;; Problems are described in more detail here: http://projecteuler.net/ - - ;;; Divisibility - ;;; Comments that describe a group of definitions. - - (defun divisorp (d n) - (zerop (mod n d))) - - (defun proper-divisors (n) - ...) - - (defun divisors (n) - (cons n (proper-divisors n))) - - ;;; Prime numbers - - (defun small-prime-number-p (n) - (cond ((or (< n 2)) - nil) - ((= n 2) ; parenthetical remark here - t) ; continuation of the remark - ((divisorp 2 n) - nil) ; different remark - ;; Comment that applies to a section of code. - (t - (loop for i from 3 upto (sqrt n) by 2 - never (divisorp i n))))) - -

- You should include a space between the semicolon and the text of the comment. -

- -
- - - You should punctuate documentation correctly. - - -

- When a comment is a full sentence, - you should capitalize the initial letter of the first word - and end the comment with a period. - In general, you should use correct punctuation. -

- -
- - - You must follow the convention of using TODO comments - for code requiring special attention. - For code using unobvious forms, you must include a comment. - - -

- For comments requiring special attention, such as - incomplete code, todo items, questions, breakage, and danger, - include a TODO comment indicating the type of problem, - its nature, and any notes on how it may be addressed. -

-

- The comments begin with TODO in all capital letters, - followed by the - - name, e-mail address, or other identifier - of the person - with the best context about the problem referenced by the TODO. - The main purpose is to have a consistent TODO that - can be searched to find out how to get more details upon - request. A TODO is not a commitment that the - person referenced will fix the problem. Thus when you create - a TODO, - it is almost always your - name - that is given. -

-

- When signing comments, - you should use your username (for code within the company) - or full email address (for code visible outside the company), - not just initials. - -

- - ;;--- TODO(george@gmail.com): Refactor to provide a better API. - -

- Be specific when indicating times or software releases - in a TODO comment and use - YYYY-MM-DD - format for dates to make automated processing of such dates easier, - e.g., 2038-01-20 for the end of the 32-bit signed time_t. -

- - ;;--- TODO(brown): Remove this code after release 1.7 or before 2012-11-30. - -

- For code that uses unobvious forms to accomplish a task, you must include a comment - stating the purpose of the form and the task it accomplishes. -

- -
- - - You should document DSLs and - any terse program in a DSL. - - -

- You should design your Domain Specific Language - to be easy to read and understand by people familiar with the domain. -

-

- You must properly document all your Domain Specific Language. -

-

- Sometimes, your DSL is designed for terseness. - In that case, it is important to document what each program does, - if it's not painfully obvious from the context. -

-

- Notably, when you use regular expressions - (e.g. with the CL-PPCRE package), - you MUST ALWAYS put in a comment - (usually a two-semicolon comment on the previous line) - explaining, at least basically, what the regular expression does, - or what the purpose of using it is. - The comment need not spell out every bit of the syntax, but - it should be possible for someone to follow the logic of the code - without actually parsing the regular expression. -

- -
- -
- - - - - You should use lower case. - You should follow the rules for Spelling and Abbreviations - You should follow punctuation conventions. - - -

- Use lower case for all symbols. - Consistently using lower case makes searching for symbol names easier - and is more readable. -

-

- Note that Common Lisp is case-converting, - and that the symbol-name of your symbols - will be upper case. - Because of this case-converting, - attempts to distinguish symbols by case are defeated, - and only result in confusion. - While it is possible to escape characters in symbols - to force lower case, - you should not use this capability - unless this is somehow necessary - to interoperate with third-party software. -

-

- Place hyphens between all the words in a symbol. - If you can't easily say an identifier out loud, - it is probably badly named. -

-

- You must not use "/" or "." - instead of "-" - unless you have a well-documented overarching reason to, - and permission from other hackers who review your proposal. -

-

- See the section on Spelling and Abbreviations - for guidelines on using abbreviations. -

- - ;; Bad - (defvar *default-username* "Ann") - (defvar *max-widget-cnt* 200) - - - ;; Better - (defvar *default-user-name* "Ann") - (defvar *maximum-widget-count* 200) - -

- There are conventions in Common Lisp - for the use of punctuation in symbols. - You should not use punctuation in symbols outside these conventions. -

-

- Unless the scope of a variable is very small, - do not use overly short names like - i and zq. -

- -
- - - Name your variables according to their intent, - not their content. - - -

- You should name a variable according - to the high-level concept that it represents, - not according to the low-level implementation details - of how the concept is represented. -

-

- Thus, you should avoid embedding - data structure or aggregate type names, - such as list, array, or - hash-table inside variable names, - unless you're writing a generic algorithm that applies to - arbitrary lists, arrays, hash-tables, etc. - In that case it's perfectly OK to name a variable - list or array. -

-

- Indeed, you should be introducing new abstract data types - with DEFCLASS or DEFTYPE, - whenever a new kind of intent appears for objects in your protocols. - Functions that manipulate such objects generically may then - use variables the name of which reflect that abstract type. -

-

- For example, if a variable's value is always a row - (or is either a row or NIL), - it's good to call it row or first-row - or something like that. - It is alright is row has been - DEFTYPE'd to STRING — - precisely because you have abstracted the detail away, - and the remaining salient point is that it is a row. - You should not name the variable STRING in this context, - except possibly in low-level functions that specifically manipulate - the innards of rows to provide the suitable abstraction. -

-

- Be consistent. - If a variable is named row in one function, - and its value is being passed to a second function, - then call it row rather than, say, value - (this was a real case). -

- -
- - - Name globals according to convention. - - -

- The names of global constants should start and end - with plus characters. -

-

- Global variable names should start and end with asterisks - (also known in this context as earmuffs). -

-

- In some projects, parameters that are not meant - to be usually modified or bound under normal circumstances - (but may be during experimentation or exceptional situations) - should start (but do not end) with a dollar sign. - If such a convention exists within your project, - you should follow it consistently. - Otherwise, you should avoid naming variables like this. -

-

- Common Lisp does not have global lexical variables, - so a naming convention is used to ensure that globals, - which are dynamically bound, - never have names that overlap with local variables. - It is possible to fake global lexical variables - with a differently named global variable - and a DEFINE-SYMBOL-MACRO. - You should not use this trick, - unless you first publish a library that abstracts it away. -

- - (defconstant +hash-results+ #xbd49d10d10cbee50) - - (defvar *maximum-search-depth* 100) - - -
- - - Names of predicate functions and variables end with a "P". - - -

- You should name boolean-valued functions and variables with a - trailing "P" or "-P", - to indicate they are predicates. - Generally, you should use - "P" when the rest of the function name is one word - and "-P" when it is more than one word. -

-

- A rationale for this convention is given in - the CLtL2 chapter on predicates. -

-

- For uniformity, you should follow the convention above, - and not one of the alternatives below. -

-

- An alternative rule used in some existing packages - is to always use "-P". - Another alternative rule used in some existing packages - is to always use "?". - When you develop such a package, - you must be consistent with the rest of the package. - When you start a new package, - you should not use such an alternative rule - without a very good documented reason. -

- -
- - - You should not include a library or package name - as a prefix within the name of symbols. - - -

- When naming a symbol (external or internal) in a package, - you should not include the package name - as a prefix within the name of the symbol. - Naming a symbol this way makes it awkward to use - from a client package accessing the symbol - by qualifying it with a package prefix, - where the package name then appears twice - (once as a package prefix, - another time as a prefix within the symbol name). -

- - ;; Bad - (in-package #:varint) - (defun varint-length64 () ... ) - - (in-package #:client-code) - (defconst +padding+ (varint:varint-length64 +end-token+)) - - - ;; Better - (in-package #:varint) - (defun length64 () ... ) - - (in-package #:client-code) - (defconst +padding+ (varint:length64 +end-token+)) - -

- An exception to the above rule would be to include a prefix - for the names of variables that would otherwise be expected to clash - with variables in packages that use the current one. - For instance, ASDF exports a variable *ASDF-VERBOSE* - that controls the verbosity of ASDF only, - rather than of the entire Lisp program. -

- -
- - - Use packages appropriately. - - -

- Lisp packages are used to demarcate namespaces. - Usually, each system has its own namespace. - A package has a set of external symbols, - which are intended to be used from outside the package, - in order to allow other modules to use this module's facilities. -

-

- The internal symbols of a package - should never be referred to from other packages. - That is, you should never have to use - the double-colon :: construct. - (e.g. QUAKE::HIDDEN-FUNCTION). - If you need to use double-colons to write real production code, - something is wrong and needs to be fixed. -

-

- As an exception, - unit tests may use the internals of the package being tested. - So when you refactor, watch out for - internals used by the package's unit tests. -

-

- The :: construct is also useful for very temporary hacks, - and at the REPL. - But if the symbol really is part of - the externally-visible definition of the package, - export it. -

-

- You may find that some internal symbols represent concepts - you usually want to abstract away and hide under the hood, - yet at times are necessary to expose for various extensions. - For the former reason, you do not want to export them, - yet for the latter reason, you have to export them. - The solution is to have two different packages, - one for your normal users to use, and - another for the implementation and its extenders to use. -

-

- Each package is one of two types: -

-
    -
  • - Intended to be included - in the :use specification of other packages. - If package A "uses" package B, - then the external symbols of package B - can be referenced from within package A - without a package prefix. - We mainly use this for low-level modules - that provide widely-used facilities. -
  • -
  • - Not intended to be "used". - To reference a facility provided by package B, - code in package A must use an explicit package prefix, - e.g. B:DO-THIS. -
  • -
-

- If you add a new package, it should always be of the second type, - unless you have a special reason and get permission. - Usually a package is designed to be one or the other, - by virtue of the names of the functions. - For example, if you have an abstraction called FIFO, - and it were in a package of the first type - you'd have functions named things like - FIFO-ADD-TO and FIFO-CLEAR-ALL. - If you used a package of the second type, - you'd have names like ADD-TO and CLEAR-ALL, - because the callers would be saying - FIFO:ADD-TO and FIFO:CLEAR-ALL. - (FIFO:FIFO-CLEAR-ALL is redundant and ugly.) -

-

- Another good thing about packages is that - your symbol names won't "collide" with the names of other packages, - except the ones your packages "uses". - So you have to stay away from symbols - that are part of the Lisp implementation (since you always "use" that) - and that are part of any other packages you "use", - but otherwise you are free to make up your own names, - even short ones, and not worry about some else - having used the same name. - You're isolated from each other. -

-

- Your package must not shadow (and thus effectively redefine) - symbols that are part of the Common Lisp language. - There are certain exceptions, - but they should be very well-justified and extremely rare: -

-
    -
  • - If you are explicitly replacing a Common Lisp symbol - by a safer or more featureful version. -
  • -
  • - If you are defining a package not meant to be "used", - and have a good reason to export a symbol - that clashes with Common Lisp, - such as log:error and log:warn - and so on. -
  • -
- -
-
- - - - - You should avoid side-effects when they are not necessary. - - -

- Lisp is best used as a "mostly functional" language. -

-

- Avoid modifying local variables, try rebinding instead. -

-

- Avoid creating objects and the SETFing their slots. - It's better to set the slots during initialization. -

-

- Make classes as immutable as possible, that is, avoid giving slots - setter functions if at all possible. -

-

- Using a mostly functional style makes it much easier - to write concurrent code that is thread-safe. - It also makes it easier to test the code. -

- -
- - - You should favor iteration over recursion. - - -

- Common Lisp systems are not required to implement - function calls from tail positions without leaking stack space - — which is known as proper tail calls (PTC), - tail call elimination (TCE), - or tail call optimization (TCO). - This means that indefinite recursion through tail calls - may quickly blow out the stack, - which hampers functional programming. - Still, most serious implementations (including SBCL and CCL) - do implement proper tail calls, but with restrictions: -

-
    -
  • - The (DECLARE (OPTIMIZE ...)) settings - must favor SPEED enough and - not favor DEBUG too much, - for some compiler-dependent meanings of "enough" and "too much". - (For instance, in SBCL, you should avoid (SPEED 0) - and (DEBUG 3) to achieve proper tail calls.) -
  • -
  • - There should not be dynamic bindings around the call - (even though some Scheme compilers are able to properly treat - such dynamic bindings, called parameters in Scheme parlance). -
  • -
-

- For compatibility with all compilers and optimization settings, - and to avoid stack overflow when debugging, - you should prefer iteration or the built in mapping functions - to relying on proper tail calls. -

-

- If you do rely on proper tail calls, - you must prominently document the fact, - and take appropriate measures to ensure an appropriate compiler is used - with appropriate optimization settings. - For fully portable code, you may have to use trampolines instead. -

- -
- - - Use special variables sparingly. - - -

- Using Lisp "special" (dynamically bound) variables - as implicit arguments to functions should be used sparingly, - and only in cases where it won't surprise the person reading the code, - and where it offers significant benefits. -

-

- Indeed, each special variable constitutes state. - Developers have to mentally track the state of all relevant variables - when trying to understand what the code does and how it does it; - tests have to be written and run with all relevant combinations; - to isolate some activity, care has to be taken to locally bind - all relevant variables, including those of indirectly used modules. - They can hide precious information from being printed in a backtrace. - Not only is there overhead associated to each new variable, - but interactions between variables - can make the code exponentially more complex - as the number of such variables increases. - The benefits have to match the costs. -

-

- Note though that a Lisp special variable is not a global variable - in the sense of a global variable in, say, BASIC or C. - As special variables can be dynamically bound to a local value, - they are much more powerful than - global value cells where all users necessarily interfere with each other. -

-

- Good candidates for such special variables - are items for which "the current" can be naturally used as prefix, - such as "the current database connection" or - "the current business data source". - They are singletons as far as the rest of the code is concerned, - and often passing them as an explicit argument - does not add anything to the readability or maintainability - of the source code in question. -

-

- They can make it easier to write code that can be refactored. - If you have a request processing chain, - with a number of layers that all operate upon a "current" request, - passing the request object explicitly to every function - requires that every function in the chain have a request argument. - Factoring out code into new functions often requires - that these functions also have this argument, - which clutters the code with boilerplate. -

-

- You should treat special variables - as though they are per-thread variables. - By default, you should leave a special variable - with no top-level binding at all, - and each thread of control - that needs the variable should bind it explicitly. - This will mean that any incorrect use of the variable - will result in an "unbound variable" error, and - each thread will see its own value for the variable. - Variables with a default global value should usually be - locally bound at thread creation time. - You should use suitable infrastructure - to automate the appropriate declaration of such variables. -

- - -
- - - Be consistent in assignment forms. - - -

- There are several styles for dealing with assignment and side-effects; - whichever a given package is using, - keep using the same consistently when hacking said package. - Pick a style that makes sense when starting a new package. -

-

- Regarding multiple assignment in a same form, there are two schools: - the first style groups as many assignments as possible into a single - SETF or PSETF form - thus minimizing the number of forms with side-effects; - the second style splits assignments into as many individual - SETF (or SETQ, see below) forms as possible, - to maximize the chances of locating forms that modify a kind of place - by grepping for (setf (foo .... - A grep pattern must actually contain as many place-modifying forms - as you may use in your programs, which may make this rationale either - convincing or moot depending on the rest of the style of your code. - You should follow the convention used in the package you are hacking. - We recommend the first convention for new packages. -

-

- Regarding SETF and SETQ, - there are two schools: - this first regards SETQ - as an archaic implementation detail, - and avoids it entirely in favor of SETF; - the second regards SETF - as an additional layer of complexity, - and avoids it in favor of SETQ whenever possible - (i.e. whenever the assigned place is a variable or symbol-macro). - You should follow the convention used in the package you are hacking. - We recommend the first convention for new packages. -

-

- In the spirit of a mostly pure functional style, - which makes testing and maintenance easier, - we invite you to consider how to do things with the fewest assignments required. -

- -
- - - You must make proper usage of assertions and conditions. - - -
    -
  • - ASSERT should be used ONLY to detect internal bugs. - Code should ASSERT invariants whose failure indicates - that the software is itself broken. - Incorrect input should be handled properly at runtime, - and must not cause an assertion violation. - The audience for an ASSERT failure is a developer. - Do not use the data-form and argument-form in ASSERT - to specify a condition to signal. - It's fine to use them to print out a message for debugging purposes - (and since it's only for debugging, there's no issue of - internationalization). -
  • -
  • - CHECK-TYPE, - ETYPECASE are also forms of assertion. - When one of these fails, that's a detected bug. - You should prefer to use CHECK-TYPE - over (DECLARE (TYPE ...)) - for the inputs of functions. -
  • -
  • - Your code should use assertions and type checks liberally. - The sooner a bug is discovered, the better! - Only code in the critical path for performance - and internal helpers should eschew - explicit assertions and type checks. -
  • -
  • - Invalid input, such as files that are read - but do not conform to the expected format, - should not be treated as assertion violations. - Always check to make sure that input is valid, - and take appropriate action if it is not, - such as signalling a real error. -
  • -
  • - ERROR should be used - to detect problems with user data, requests, permissions, etc., - or to report "unusual outcomes" to the caller. -
  • -
  • - ERROR should always be called - with an explicit condition type; - it should never simply be called with a string. - This enables internationalization. -
  • -
  • - Functions that report unusual outcomes - by signaling a condition should say so explicitly in their contracts - (their textual descriptions, in documentation and docstrings etc.). - When a function signals a condition - that is not specified by its contract, that's a bug. - The contract should specify the condition class(es) clearly. - The function may then signal any condition - that is a type-of any of those conditions. - That is, signaling instances of subclasses - of the documented condition classes is fine. -
  • -
  • - Complex bug-checks may need to use ERROR - instead of ASSERT. - -
  • -
  • - When writing a server, you must not call WARN. - Instead, you should use the appropriate logging framework. - -
  • -
  • - Code must not call SIGNAL. - Instead, use ERROR or ASSERT. -
  • -
  • - Code should not use THROW and CATCH; - instead use the restart facility. -
  • -
  • - Code should not generically handle all conditions, - e.g. type T, or use IGNORE-ERRORS. - Instead, let unknown conditions propagate to - the standard ultimate handler for processing. - -
  • -
  • - There are a few places where handling all conditions is appropriate, - but they are rare. - The problem is that handling all conditions can mask program bugs. - If you do need to handle "all conditions", - you MUST handle only ERROR, not T - and not SERIOUS-CONDITION. - (This is notably because CCL's process shutdown - depends on being able to signal process-reset - and have it handled by CCL's handler, - so we must not interpose our own handler.) -
  • -
  • - (error (make-condition 'foo-error ...)) - is equivalent to (error 'foo-error ...) — - code must use the shorter form. -
  • -
  • - Code should not signal conditions from inside the cleanup form of - UNWIND-PROTECT - (unless they are always handled inside the cleanup form), - or otherwise do non-local exits from cleanup handlers - outside of the handler e.g. INVOKE-RESTART. -
  • -
  • - Do not clean up by resignaling. - If you do that, and the condition is not handled, - the stack trace will halt at the point of the resignal, - hiding the rest. - And the rest is the part we really care about! - - ;; Bad - (handler-case - (catch 'ticket-at - (etd-process-blocks)) - (error (c) - (reset-parser-values) - (error c))) - - - ;; Better - (unwind-protect - (catch 'ticket-at - (etd-process-blocks)) - (reset-parser-values)) - -
  • -
- -
- - - If you know the type of something, you should make it explicit - in order to enable compile-time and run-time sanity-checking. - - - -

- If your function is using a special variable as an implicit argument, - it's good to put in a CHECK-TYPE for the special variable, - for two reasons: - to clue in the person reading the code - that this variable is being used implicitly as an argument, - and also to help detect bugs. -

- -

- Using (declare (type ...)) - is the least-desirable mechanism to use - because, as Scott McKay puts it: -

-
-

- The fact is, (declare (type ...)) does different things - depending on the compiler settings of speed, safety, etc. - In some compilers, when speed is greater than safety, - (declare (type ...)) will tell the compiler - "please assume that these variables have these types" - without generating any type-checks. - That is, if some variable has the value 1432 in it, - and you declare it to be of type string, - the compiler might just go ahead and use it as though it's a string. -

-

- Moral: don't use (declare (type ...)) - to declare the contract of any API functions, - it's not the right thing. - Sure, use it for "helper" functions, but not API functions. -

-
-

- You should, of course, use appropriate declarations - in internal low-level functions - where these declarations are used for optimization. - When you do, however, see our recommendations for - Unsafe Operations. -

- -
- - - Use CLOS appropriately. - - -

- When a generic function is intended to be called from other - modules (other parts of the code), there should be an - explicit DEFGENERIC form, - with a :DOCUMENTATION string - explaining the generic contract of the function - (as opposed to its behavior for some specific class). - It's generally good to do explicit DEFGENERIC forms, - but for module entry points it is mandatory. -

-

- When the argument list of a generic function includes - &KEY, - the DEFGENERIC should always explicitly list - all of the keyword arguments that are acceptable, - and explain what they mean. - (Common Lisp does not require this, but it is good form, - and it may avoid spurious warnings on SBCL.) -

-

- You should avoid SLOT-VALUE and WITH-SLOTS, - unless you absolutely intend to circumvent - any sort of method combination that might be in effect for the slot. - Rare exceptions include INITIALIZE-INSTANCE - and PRINT-OBJECT methods and - accessing normally hidden slots in the low-level implementation of - methods that provide user-visible abstractions. - Otherwise, you should use accessors, - WITH-ACCESSORS -

- -

- Accessor names generally follow a convention of - <protocol-name>-<slot-name>, - where a "protocol" in this case loosely indicates - a set of functions with well-defined behavior. -

-

- No implication of a formal "protocol" concept is necessarily intended, - much less first-class "protocol" objects. - However, there may indeed be an abstract CLOS class - or an - Interface-Passing Style interface - that embodies the protocol. - Further (sub)classes or (sub)interfaces may then implement - all or part of a protocol by defining - some methods for (generic) functions in the protocol, - including readers and writers. -

-

- For example, if there were a notional protocol called - is pnr with accessors pnr-segments - and pnr-passengers, then - the classes air-pnr, hotel-pnr and - car-pnr could each reasonably implement - methods for pnr-segments and pnr-passengers - as accessors. -

-

- By default, an abstract base class name is used - as the notional protocol name, so accessor names default - to <class-name>-<slot-name>; - while such names are thus quite prevalent, - this form is neither required nor even preferred. - In general, it contributes to "symbol bloat", - and in many cases has led to a proliferation of "trampoline" methods. -

-

- Accessors named <slot-name>-of should not be used. -

-

- Explicit DEFGENERIC forms should be used when there are - (or it is anticipated that there will be) - more than one DEFMETHOD for that generic function. - The reason is that the documentation for the generic function - explains the abstract contract for the function, - as opposed to explaining what an individual method does for - some specific class(es). -

-

- You must not use generic functions where there is no notional protocol. - To put it more concretely, - if you have more than one generic function that specializes its Nth argument, - the specializing classes should all be descendants of a single class. - Generic functions must not be used for "overloading", - i.e. simply to use the same name for two entirely unrelated types. -

-

- More precisely, it's not really - whether they descend from a common superclass, - but whether they obey the same "protocol". - That is, the two classes should handle the same set of generic functions, - as if there were an explicit DEFGENERIC for each method. -

-

- Here's another way to put it. - Suppose you have two classes, A and B, and a generic function F. - There are two methods for F, - which dispatch on an argument being of types A and B. - Is it plausible that there might be a function call somewhere - in the program that calls F, - in which the argument might sometimes, at runtime, - be of class A and other times be of class B? - If not, you probably are overloading and - should not be using a single generic function. -

-

- We allow one exception to this rule: - it's OK to do overloading - if the corresponding argument "means" the same thing. - Typically one overloading allows an X object, - and the other allows the name of an X object, - which might be a symbol or something. -

-

- You must not use MOP "intercessory" operations at runtime. - You should not use MOP "intercessory" operations at compile-time. - At runtime, they are at worst a danger, at best a performance issue. - At compile-time, it is usually cleaner that - macros should set things up the right way in one pass - than have to require a second pass of fixups through intercession; - but sometimes, fixups are necessary to resolve forward references, - and intercession is allowed then. - MOP intercession is a great tool for interactive development, - and you may enjoy it while developping and debugging; - but you should not use it in normal applications. -

-

- If a class definition creates a method - as a :READER, :WRITER, - or :ACCESSOR, - do not redefine that method. - It's OK to add :BEFORE, :AFTER, - and :AROUND methods, - but don't override the primary method. -

-

- In methods with keyword arguments, - you must always use &KEY, - even if the method does not care about the values of any keys, - and you should never use &ALLOW-OTHER-KEYS. - As long as a keyword is accepted by any method of a generic function, - it's OK to use it in the generic function, - even if the other methods of the same generic function - don't mention it explicitly. - This is particularly important - for INITIALIZE-INSTANCE methods, - since if you did use &ALLOW-OTHER-KEYS, - it would disable error checking for misspelled or wrong keywords - in MAKE-INSTANCE calls! -

- -

- A typical PRINT-OBJECT method might look like this: -

- - (defmethod print-object ((p person) stream) - (print-unprintable-object (p stream :type t :identity t) - (with-slots (first-name last-name) p - (safe-format stream "~a ~a" first-name last-name)))) - - -
-
- - - - - Use macros when appropriate, which is often. - Define macros when appropriate, which is seldom. - - -

- Macros bring syntactic abstraction, which is a wonderful thing. - It helps make your code clearer, by describing your intent - without getting bogged in implementation details - (indeed abstracting those details away). - It helps make your code more concise and more readable, - by eliminating both redundancy and irrelevant details. - But it comes at a cost to the reader, - which is learning a new syntactic concept for each macro. - And so it should not be abused. -

-

- The general conclusion is that there shouldn't be - any recognizable design pattern - in a good Common Lisp program. - The one and only pattern is: use the language, - which includes defining and using syntactic abstractions. -

-

- Existing macros must be used - whenever they make code clearer - by conveying intent in a more concise way, - which is often. - When a macro is available in your project - that expresses the concept you're using, - you must not write the expansion rather than use the macro. -

-

- New macros should be defined as appropriate, - which should be seldom, - for common macros have already been provided - by the language and its various libraries, - and your program typically only needs few new ones - relative to its size. -

-

- You should follow the OAOOM rule of thumb - for deciding when to create a new abstraction, - whether syntactic or not: - if a particular pattern is used more than twice, - it should probably be abstracted away. - A more refined rule to decide when to use abstraction - should take into account - the benefit in term of number of uses and gain at each use, - to the costs in term of having to get used to reading the code. - For syntactic abstractions, costs and benefits to the reader - is usually more important than costs and benefits to the writer, - because good code is usually written once - and read many times by many people - (including the same programmer - who has to maintain the program after having forgotten it). - Yet the cost to the writer of the macro - should also be taken into account; - however, in doing so it should rather be compared - to the cost of the programmer writing other code instead - that may have higher benefits. -

-

- Using Lisp macros properly requires taste. - Avoid writing complicated macros - unless the benefit clearly outweighs the cost. - It takes more effort for your fellow developers to learn your macro, - so you should only use a macro if the gain in expressiveness - is big enough to justify that cost. - As usual, feel free to consult your colleagues if you're not sure, - since without a lot of Lisp experience, - it can be hard to make this judgment. -

-

- You must never use a macro where a function will do. - That is, if the semantics of what you are writing - conforms to the semantics of a function, - then you must write it as a function rather than a macro. -

-

- You must not transform a function into a macro for performance reasons. - If profiling shows that you have a performance problem - with a specific function FOO, - document the need and profiling-results appropriately, - and - (declaim (inline foo)). -

- -

- You can also use a compiler-macro - as a way to speed up function execution - by specifying a source-to-source transformation. - Beware that it interferes with tracing the optimized function. -

-

- When you write a macro-defining macro - (a macro that generates macros), - document and comment it particularly clearly, - since these are harder to understand. -

-

- You must not install new reader macros - without a consensus among the developers of your system. - Reader macros must not leak out of the system that uses them - to clients of that system or other systems used in the same project. - You must use software such as - cl-syntax or named-readtables - to control how reader macros are used. - This clients who desire it may use the same reader macros as you do. - In any case, your system must be usable - even to clients who do not use these reader macros. -

-

- If your macro has a parameter that is a Lisp form - that will be evaluated when the expanded code is run, - you should name the parameter with the suffix -form. - This convention helps make it clearer to the macro's user - which parameters are Lisp forms to be evaluated, and which are not. - The common names body and end are - exceptions to this rule. -

-

- You should follow the so-called CALL-WITH style when it applies. - This style is explained at length in - http://random-state.net/log/3390120648.html. - The general principle is that the macro is strictly limited to processing the syntax, - and as much of the semantics as possible is kept in normal functions. - Therefore, a macro WITH-FOO is often limited to - generating a call to an auxiliary function - CALL-WITH-FOO - with arguments deduced from the macro arguments. - Macro &body arguments are typically - wrapped into a lambda expression of which they become the body, - which is passed as one of the arguments of the auxiliary function. -

-

- The separation of syntactic and semantic concerns - is a general principle of style that applies - beyond the case of WITH- macros. - Its advantages are many. - By keeping semantics outside the macro, - the macro is made simpler, easier to get right, and less subject to change, - which makes it easier to develop and maintain. - The semantics is written in a simpler language — one without staging — - which also makes it easier to develop and maintain. - It becomes possible to debug and update the semantic function - without having to recompile all clients of the macro. - The semantic function appears in the stack trace - which also helps debug client functions. - The macro expansion is made shorter and - each expansion shares more code with other expansions, - which reduces memory pressure which in turn usually makes things faster. - It also makes sense to write the semantic functions first, - and write the macros last as syntactic sugar on top. - You should use this style unless the macro is used - in tight loops where performance matters; - and even then, see our rules regarding optimization. -

-

- Any functions (closures) created by the macro should be named, - which can be done using FLET. - - This also allows you to declare the function to be of dynamic extent - (if it is — and often it is; yet see below regarding - DYNAMIC-EXTENT). -

-

- If a macro call contains a form, - and the macro expansion includes more than one copy of that form, - the form can be evaluated more than once, - and code it contains macro-expanded and compiled more than once. - If someone uses the macro and calls it - with a form that has side effects or that takes a long time to compute, - the behavior will be undesirable - (unless you're intentionally writing - a control structure such as a loop). - A convenient way to avoid this problem - is to evaluate the form only once, - and bind a (generated) variable to the result. - There is a very useful macro called ALEXANDRIA:ONCE-ONLY - that generates code to do this. - See also ALEXANDRIA:WITH-GENSYMS, - to make some temporary variables in the generated code. - Note that if you follow our CALL-WITH style, - you typically expand the code only once, as either - an argument to the auxiliary function, or - the body of a lambda passed as argument to it; - you therefore avoid the above complexity. -

-

- When you write a macro with a body, - such as a WITH-xxx macro, - even if there aren't any parameters, - you should leave space for them anyway. - For example, if you invent WITH-LIGHTS-ON, - do not make the call to it look like - (defmacro with-lights-on (&body b) ...). - Instead, do (defmacro with-lights-on (() &body b) ...). - That way, if parameters are needed in the future, - you can add them without necessarily having to change - all the uses of the macro. -

- -
- - - When using EVAL-WHEN, you should almost always use all of - (:compile-toplevel :load-toplevel :execute). - - -

- Lisp evaluation happens at several times, - some of them interleaved. - Be aware of them when writing macros. - EVAL-WHEN considered harmful to your mental health. -

-

- In summary of the article linked above, - unless you're doing truly advanced macrology, - the only valid combination in an EVAL-WHEN - is to include all of - (eval-when (:compile-toplevel :load-toplevel :execute) ...) -

-

- You must use - (eval-when (:compile-toplevel :load-toplevel :execute) ...) - whenever you define functions, types, classes, constants, variables, etc., - that are going to be used in macros. -

-

- It is usually an error to omit the :execute, - because it prevents LOADing the source rather than the fasl. - It is usually an error to omit the :load-toplevel - (except to modify e.g. readtables and compile-time settings), - because it prevents LOADing future files - or interactively compiling code - that depends on the effects that happen at compile-time, - unless the current file was COMPILE-FILEd - within the same Lisp session. -

-

- Regarding variables, note that because macros may or may not - be expanded in the same process that runs the expanded code, - you must not depend on compile-time and runtime effects - being either visible or invisible at the other time. - There are still valid uses of variables in macros: -

-
    -
  • - Some variables may hold dictionaries - for some new kind of definition and other meta-data. - If such meta-data is to be visible at runtime and/or in other files, - you must make sure that the macro expands into code that - will register the definitions to those meta-data structures - at load-time, - in addition to effecting the registration at compile-time. - Typically, your top-level definitions expand - to code that does the registration. - if your code doesn't expand at the top-level, - you can sometimes use LOAD-TIME-VALUE for good effect. - In extreme cases, you may have to use - ASDF-FINALIZERS:EVAL-AT-TOPLEVEL. -
  • -
  • - Some variables may hold temporary data - that is only used at compile-time in the same file, - and can be cleaned up at the end of the file's compilation. - Predefined such variables would include *readtable* - or compiler-internal variables holding - the current optimization settings. - You can often manage existing and new such variables using - the :AROUND-COMPILE hooks of ASDF. -
  • -
- -
- - - You should use #. sparingly, - and you must avoid read-time side-effects. - - -

- The #. standard read-macro - will read one object, evaluate the object, and - have the reader return the resulting value. -

-

- You must not use it where other idioms will do, such as - using EVAL-WHEN to evaluate side-effects at compile-time, - using a regular macro to return an expression computed at compile-time, - using LOAD-TIME-VALUE to compute it at load-time. -

-

- Read-time evaluation is often used as a quick way - to get something evaluated at compile time - (actually "read time" but it amounts to the same thing). - If you use this, the evaluation MUST NOT have any side effects - and MUST NOT depend on any variable global state. - The #. should be treated as a way - to force "constant-folding" - that a sufficiently-clever compiler - could have figure out all by itself, - when the compiler isn't sufficiently-clever - and the difference matters. -

-

- Another use of #. is to expand the equivalent of macros - in places that are neither expressions nor (quasi)quotations, - such as lambda-lists. However, if you find yourself using it a lot, - it might be time to instead define macros to replace your consumers - of lambda-lists with something that recognizes an extension. -

-

- Whenever you are going to use #., - you should consider using DEFCONSTANT and its variants, - possibly in an EVAL-WHEN, - to give the value a name explaining what it means. -

- -
- - - You must not use EVAL at runtime. - - -

- Places where it is actually appropriate to use EVAL - are so few and far between that you must consult with your reviewers; - it's easily misused. -

-

- If your code manipulates symbols at runtime - and needs to get the value of a symbol, - use SYMBOL-VALUE, not EVAL. -

-

- Often, what you really need is to write a macro, - not to use EVAL. -

-

- You may be tempted to use EVAL as a shortcut - to evaluating expressions in a safe subset of the language. - But it often requires more scrutiny to properly check and sanitize - all possible inputs to such use of EVAL - than to build a special-purpose evaluator. - You must not use EVAL in this way at runtime. -

-

- Places where it is OK to use EVAL are: -

-
    -
  • - The implementation of an interactive development tool. -
  • -
  • - The build infrastructure. -
  • -
  • - Backdoors that are part of testing frameworks. - (You MUST NOT have such backdoors in production code.) -
  • -
  • - Macros that fold constants at compile-time. -
  • -
  • - Macros that register definitions to meta-data structures; - the registration form is sometimes evaluated at compile-time - as well as included in the macro-expansion, - so it is immediately available to other macros. -
  • -
-

- Note that in the latter case, - if the macro isn't going to be used at the top-level, - it might not be possible to make these definitions available - as part of the expansion. - The same phenomenon may happen in a DEFTYPE expansion, - or in helper functions used by macros. - In these cases, you may actually have to use - ASDF-FINALIZERS:EVAL-AT-TOPLEVEL in your macro. - It will not only EVAL your definitions - at macro-expansion time for immediate availability, - it will also save the form aside, for inclusion in a - (ASDF-FINALIZERS:FINAL-FORMS) - that you need to include at the end of the file being compiled - (or before the form is needed). - This way, the side-effects are present when loading the fasl - without having compiled it as well as while compiling it; - in either case, the form is made available at load-time. - ASDF-FINALIZERS ensures that the form is present, - by throwing an error if you omit it. -

- -
- - - You must not use INTERN or UNINTERN at runtime. - - -

- You must not use INTERN at runtime. - Not only does it cons, - it either creates a permanent symbol that won't be collected - or gives access to internal symbols. - This creates opportunities for memory leaks, denial of service attacks, - unauthorized access to internals, clashes with other symbols. -

-

- You must not INTERN a string - just to compare it to a keyword; - use STRING= or STRING-EQUAL. -

- - (member (intern str :keyword) $keys) ; Bad - - - (member str $keys :test #'string-equal) ; Better - -

- You must not use UNINTERN at runtime. - It can break code that relies on dynamic binding. - It makes things harder to debug. - You must not dynamically intern any new symbol, - and therefore you need not dynamically unintern anything. -

-

- You may of course use INTERN at compile-time, - in the implementation of some macros. - Even so, it is usually more appropriate - to use abstractions on top of it, such as - ALEXANDRIA:SYMBOLICATE or - ALEXANDRIA:FORMAT-SYMBOL - to create the symbols you need. -

- - -
-
- - - - - Appropriately use or avoid using NIL. - - -

- NIL can have several different interpretations: -

-
    -
  • - "False." - In this case, use NIL. - You should test for false NIL - using the operator NOT or - using the predicate function NULL. -
  • -
  • - "Empty-list." - In this case, use '(). - (Be careful about quoting the empty-list when calling macros.) - You should use ENDP to test for the empty list - when the argument is known to be a proper list, - or with NULL otherwise. -
  • -
  • - A statement about some value being unspecified. - In this case, you may use NIL - if there is no risk of ambiguity anywhere in your code; - otherwise you should use an explicit, descriptive symbol. -
  • -
  • - A statement about some value being known not to exist. - In this case, you should use an explicit, descriptive symbol - instead of NIL. -
  • -
-

- You must not introduce ambiguity in your data representations - that will cause headaches for whoever has to debug code. - If there is any risk of ambiguity, - you should use an explicit, descriptive symbol or keyword - for each case, - instead of using NIL for either. - If you do use NIL, - you must make sure that the distinction is well documented. -

-

- In many contexts, - instead of representing "I don't know" as a particular value, - you should instead use multiple values, - one for the value that is known if any, - and one to denote whether the value was known or found. -

- -

- When working with database classes, keep in mind that - NIL need not always map to 'NULL' - (and vice-versa)! - The needs of the database may differ from the needs of the Lisp. -

- -
- - - You must select proper data representation. - You must not abuse the LIST data structure. - - -

- Even though back in 1958, LISP was short for "LISt Processing", - its successor Common Lisp has been a modern programming language - with modern data structures since the 1980s. - You must use the proper data structures in your programs. -

-

- You must not abuse the builtin (single-linked) LIST - data structure where it is not appropriate, - even though Common Lisp makes it especially easy to use it. -

-

- You must only use lists - when their performance characteristics - is appropriate for the algorithm at hand: - sequential iteration over the entire contents of the list. -

-

- An exception where it is appropriate to use lists - is when it is known in advance - that the size of the list will remain very short - (say, less than 16 elements). -

-

- List data structures are often (but not always) - appropriate for macros and functions used by macros at compile-time: - indeed, not only is source code passed as lists in Common Lisp, - but the macro-expansion and compilation processes - will typically walk over the entire source code, sequentially, once. - (Note that advanced macro systems don't directly use lists, but instead - use abstract syntax objects that track source code location and scope; - however there is no such advanced macro system - in Common Lisp at this time.) -

-

- Another exception where it is appropriate to use lists is - for introducing literal constants - that will be transformed into more appropriate data structures - at compile-time or load-time. - It is a good to have a function with a relatively short name - to build your program's data structures from such literals. -

-

- In the many cases when lists are not the appropriate data structure, - various libraries such as - cl-containers or - lisp-interface-library - provide plenty of different data structures - that should fulfill all the basic needs of your programs. - If the existing libraries are not satisfactory, see above about - Using Libraries and - Open-Sourcing Code. -

- -
- - - You should use the appropriate representation for product types. - - -

- You should avoid using a list as anything - besides a container of elements of like type. - You must not use a list as method of passing - multiple separate values of different types - in and out of function calls. - Sometimes it is convenient to use a list - as a little ad hoc structure, - i.e. "the first element of the list is a FOO, and the second is a BAR", - but this should be used minimally - since it gets harder to remember the little convention. - You must only use a list that way - when destructuring the list of arguments from a function, - or creating a list of arguments - to which to APPLY a function. -

-

- The proper way to pass around an object - comprising several values of heterogeneous types - is to use a structure as defined by DEFSTRUCT - or DEFCLASS. -

-

- You should use multiple values only - when function returns a small number of values - that are meant to be destructured immediately by the caller, - rather than passed together as arguments to further functions. -

-

- You should not return a condition object - as one of a set of multiple values. - Instead, you should signal the condition to denote an unusual outcome. -

-

- You should signal a condition to denote an unusual outcome, - rather than relying on a special return type. -

- -
- - - Use the appropriate functions when manipulating lists. - - -

- Use FIRST to access the first element of a list, - SECOND to access the second element, etc. - Use REST to access the tail of a list. - Use ENDP to test for the end of the list. -

-

- Use CAR and CDR - when the cons cell is not being used to implement a proper list - and is instead being treated as a pair of more general objects. - Use NULL to test for NIL in this context. -

-

- The latter case should be rare outside of alists, - since you should be using structures and classes where they apply, - and data structure libraries when you want trees. -

-

- Exceptionally, you may use CDADR and other variants - on lists when manually destructuring them, - instead of using a combination of several list accessor functions. - In this context, using CAR and CDR - instead of FIRST and REST also makes sense. - However, keep in mind that it might be more appropriate in such cases - to use higher-level constructs such as - DESTRUCTURING-BIND or OPTIMA:MATCH. -

- -
- - - You should use arrays rather than lists where random access matters. - - -

- ELT has O(n) behavior when used on lists. - If you are to use random element access on an object, - use arrays and AREF instead. -

-

- The exception is for code outside the critical path - where the list is known to be small anyway. -

- -
- - - You should only use lists as sets for very small lists. - - -

- Using lists as representations of sets is a bad idea - unless you know the lists will be small, - for accessors are O(n) instead of O(log n). - For arbitrary big sets, use balanced binary trees, - for instance using lisp-interface-library. -

-

- If you still use lists as sets, - you should not UNION lists just to search them. -

- - (member foo (union list-1 list-2)) ; Bad - - - (or (member foo list-1) (member foo list-2)) ; Better - -

- Indeed, UNION not only conses unnecessarily, - but it can be O(n^2) on some implementations, - and is rather slow even when it's O(n). -

- -
-
- - -

- You must follow the proper usage regarding - well-known functions, macros and special forms. -

- - - You must use proper defining forms for constant values. - - -

- The Lisp system we primarily use, SBCL, is very picky and - signals a condition whenever a constant is redefined to a value not - EQL to its previous setting. - You must not use DEFCONSTANT - when defining variables that are not - numbers, characters, or symbols (including booleans and keywords). - Instead, consistently use whichever alternative - is recommended for your project. -

- - ;; Bad - (defconstant +google-url+ "http://www.google.com/") - (defconstant +valid-colors+ '(red green blue)) - - - - - -

- Open-Source libraries may use - ALEXANDRIA:DEFINE-CONSTANT - for constants other than numbers, characters and symbols - (including booleans and keywords). - You may use the :TEST keyword argument - to specify an equality predicate. -

- - ;; Better, for Open-Source code: - (define-constant +google-url+ "http://www.google.com/" :test #'string=) - (define-constant +valid-colors+ '(red green blue)) - -

- Note that with optimizing implementations, such as SBCL or CMUCL, - defining constants this way precludes any later redefinition - short of UNINTERNing the symbol - and recompiling all its clients. - This may make it "interesting" to debug things at the REPL - or to deploy live code upgrades. - If there is a chance that your "constants" are not going to be constant - over the lifetime of your server processes - after taking into consideration scheduled and unscheduled code patches, - you should consider using - DEFPARAMETER or DEFVAR instead, - or possibly a variant of DEFINE-CONSTANT - that builds upon some future library implementing global lexicals - rather than DEFCONSTANT. - You may keep the +plus+ convention in these cases - to document the intent of the parameter as a constant. -

-

- Also note that LOAD-TIME-VALUE may help you - avoid the need for defined constants. -

- -
- - - You should make proper use of - &OPTIONAL and - &KEY arguments. - You should not use &AUX arguments. - - -

- You should avoid using &ALLOW-OTHER-KEYS, - since it blurs the contract of a function. - Almost any real function (generic or not) allows a certain - fixed set of keywords, as far as its caller is concerned, - and those are part of its contract. - If you are implementing a method of a generic function, - and it does not need to know - the values of some of the keyword arguments, - you should explicitly (DECLARE (IGNORE ...)) - all the arguments that you are not using. - You must not use &ALLOW-OTHER-KEYS - unless you explicitly want to disable checking of allowed keys - for all methods when invoking the generic function on arguments - that match this particular method. - Note that the contract of a generic function belongs in - the DEFGENERIC, not in the DEFMETHOD - which is basically an "implementation detail" of the generic function - as far as the caller of the generic is concerned. -

-

- A case where &ALLOW-OTHER-KEYS is appropriate - is when you write a wrapper function to other some other functions - that may vary (within the computation or during development), - and pass around a plist as a &REST argument. -

-

- You should avoid using &AUX arguments. -

-

- You should avoid having both &OPTIONAL - and &KEY arguments, - unless it never makes sense to specify keyword arguments - when the optional arguments are not all specified. - You must not have non-NIL defaults - to your &OPTIONAL arguments - when your function has both &OPTIONAL - and &KEY arguments. -

-

- For maximum portability of a library, it is good form - that DEFMETHOD definitions should - (DECLARE (IGNORABLE ...)) - all the required arguments that they are not using. - Indeed, some implementations will issue a warning - if you (DECLARE (IGNORE ...)) those arguments, - whereas other implementations will issue a warning - if you fail to (DECLARE (IGNORE ...)) them. - (DECLARE (IGNORABLE ...)) works on all implementations. -

-

- You should avoid excessive nesting of binding forms inside a function. - If your function ends up with massive nesting, - you should probably break it up into several functions or macros. - If it is really a single conceptual unit, - consider using a macro such as FARE-UTILS:NEST - to at least reduce the amount of indentation required. - It is bad form to use NEST in typical short functions - with 4 or fewer levels of nesting, - but also bad form not to use it in the exceptional long functions - with 10 or more levels of nesting. - Use your judgment and consult your reviewers. -

- - -
- - - Use the appropriate conditional form. - - -

- Use WHEN and UNLESS - when there is only one alternative. - Use IF when there are two alternatives - and COND when there are several. -

-

- However, don't use PROGN for an IF clause - — use COND, WHEN, or UNLESS. -

-

- Note that in Common Lisp, - WHEN and UNLESS return NIL - when the condition is not met. - You may take advantage of it. - Nevertheless, you may use an IF - to explicitly return NIL - if you have a specific reason to insist on the return value. - You may similarly include a fall-through clause (t nil) - as the last in your COND, - or (otherwise nil) as the last in your CASE, - to insist on the fact that the value returned by the conditional matters - and that such a case is going to be used. - You should omit the fall-through clause - when the conditional is used for side-effects. -

-

- You should prefer AND and OR - when it leads to more concise code than using - IF, COND, - WHEN or UNLESS, - and there are no side-effects involved. - You may also use an ERROR - as a side-effect in the final clause of an OR. -

-

- You should only use CASE and ECASE - to compare numbers, characters or symbols - (including booleans and keywords). - Indeed, CASE uses EQL for comparisons, - so strings, pathnames and structures may not compare the way you expect, - and 1 will differ from 1.0. -

-

- You should use ECASE and ETYPECASE - in preference to CASE and TYPECASE. - It is better to catch erroneous values early. -

-

- You should not use CCASE or CTYPECASE at all. - At least, you should not use them in server processes, - unless you have quite robust error handling infrastructure - and make sure not to leak sensitive data this way. - These are meant for interactive use, - and can cause interesting damage - if they cause data or control to leak to attackers. -

-

- You must not use gratuitous single quotes in CASE forms. - This is a common error: -

- - (case x ; Bad: silently returns NIL on mismatch - ('bar :bar) ; Bad: catches QUOTE - ('baz :baz)) ; Bad: also would catch QUOTE - - - (ecase x ; Better: will error on mismatch - ((bar) :bar) ; Better: won't match QUOTE - ((baz) :baz)) ; Better: same reason - -

- 'BAR there is (QUOTE BAR), - meaning this leg of the case will be executed - if X is QUOTE... - and ditto for the second leg - (though QUOTE will be caught by the first clause). - This is unlikely to be what you really want. -

-

- In CASE forms, - you must use otherwise instead of t - when you mean "execute this clause if the others fail". - You must use ((t) ...) - when you mean "match the symbol T" rather than "match anything". - You must also use ((nil) ...) - when you mean "match the symbol NIL" rather than "match nothing". -

-

- Therefore, if you want to map booleans NIL and T - to respective symbols :BAR and :QUUX, - you should avoid the former way and do it the latter way: -

- - (ecase x ; Bad: has no actual error case! - (nil :bar)) ; Bad: matches nothing - (t :quux)) ; Bad: matches anything - - - (ecase x ; Better: will actually catch non-booleans - ((nil) :bar)) ; Better: matches NIL - ((t) :quux)) ; Better: matches T - - -
- - - You should the appropriate predicates when comparing objects. - - -

- Lisp provides four general equality predicates: - EQ, EQL, EQUAL, - and EQUALP, - which subtly vary in semantics. - Additionally, Lisp provides the type-specific predicates - =, CHAR=, CHAR-EQUAL, - STRING=, and STRING-EQUAL. - Know the distinction! -

-

- You should use EQL to compare objects and symbols - for identity. -

-

- You must not use EQ to compare numbers or characters. - Two numbers or characters that are EQL - are not required by Common Lisp to be EQ. -

-

- When choosing between EQ and EQL, - you should use EQL unless you are writing - performance-critical low-level code. - EQL reduces the opportunity - for a class of embarrassing errors - (i.e. if numbers or characters are ever compared). - There may a tiny performance cost relative to EQ, - although under SBCL, it often compiles away entirely. - EQ is equivalent to EQL and type declarations, - and use of it for optimization should be treated just like - any such unsafe operations. -

-

- You should use CHAR= - for case-dependent character comparisons, - and CHAR-EQUAL for case-ignoring character comparisons. -

-

- You should use STRING= - for case-dependent string comparisons, - and STRING-EQUAL for case-ignoring string comparisons. -

-

- A common mistake when using SEARCH on strings - is to provide STRING= or STRING-EQUAL - as the :TEST function. - The :TEST function - is given two sequence elements to compare. - If the sequences are strings, - the :TEST function is called on two characters, - so the correct tests are CHAR= or CHAR-EQUAL. - If you use STRING= or STRING-EQUAL, - the result is what you expect, - but in some Lisp implementations it's much slower. - CCL (at least as of 8/2008) - creates a one-character string upon each comparison, for example, - which is very expensive. -

-

- Also, you should use :START and :END arguments - to STRING= or STRING-EQUAL - instead of using SUBSEQ; - e.g. (string-equal (subseq s1 2 6) s2) should instead be - (string-equal s1 s2 :start1 2 :end1 6) - This is preferable because it does not cons. -

-

- You should use ZEROP, - PLUSP, or MINUSP, - instead of comparing a value to 0 or 0.0. -

-

- You must not use exact comparison on floating point numbers, - since the vague nature of floating point arithmetic - can produce little "errors" in numeric value. - You should compare absolute values to a threshhold. -

-

- You must use = to compare numbers, - unless you really mean for 0, - 0.0 and -0.0 to compare unequal, - in which case you should use EQL. - Then again, you must not usually use exact comparison - on floating point numbers. -

-

- Monetary amounts should be using decimal (rational) numbers - to avoid the complexities and rounding errors - of floating-point arithmetic. - Libraries such as - wu-decimal - may help you; - once again, if this library is not satisfactory, see above about - Using Libraries and - Open-Sourcing Code. -

- - -
- - - Use the appropriate form for iteration. - - -

- You should simpler forms such as - DOLIST or DOTIMES - instead of LOOP - in simple cases when you're not going to use any - of the LOOP facilities such as - bindings, collection or block return. -

-

- Use the WITH clause of LOOP - when it will avoid a level of nesting with LET. - You may use LET if it makes it clearer - to return one of bound variables after the LOOP, - rather than use a clumsy FINALLY (RETURN ...) form. -

-

- In the body of a DOTIMES, - do not set the iteration variable. - (CCL will issue a compiler warning if you do.) -

-

- Most systems use unadorned symbols in the current package - as LOOP keywords. - Other systems use actual :keywords - from the KEYWORD package - as LOOP keywords. - You must be consistent with the convention used in your system. -

- -
- - - Use the appropriate I/O functions. - - -

- When writing a server, - code must not send output to the standard streams such as - *STANDARD-OUTPUT* or *ERROR-OUTPUT*. - Instead, code must use the proper logging framework - to output messages for debugging. - We are running as a server, so there is no console! -

-

- Code must not use PRINT-OBJECT - to communicate with a user — - PRINT-OBJECT is for debugging purposes only. - Modifying any PRINT-OBJECT method - must not break any public interfaces. -

-

- You should not use a sequence of WRITE-XXX - where a single FORMAT string could be used. - Using format allows you - to parameterize the format control string in the future - if the need arises. -

-

- You should use WRITE-CHAR to emit a character - rather than WRITE-STRING - to emit a single-character string. -

-

- You should not use (format nil "~A" value); - you should use PRINC-TO-STRING instead. -

-

- You should use ~<Newline> - or ~@<Newline> in format strings - to keep them from wrapping in 100-column editor windows, - or to indent sections or clauses to make them more readable. -

-

- You should not use STRING-UPCASE - or STRING-DOWNCASE - on format control parameters; - instead, it should use "~:@(~A~)" or "~(~A~)". -

-

- Be careful when using the FORMAT conditional directive. - The parameters are easy to forget. -

-
-
No parameters, e.g. "~[Siamese~;Manx~;Persian~] Cat"
-
- Take one format argument, which should be an integer. - Use it to choose a clause. Clause numbers are zero-based. - If the number is out of range, just print nothing. - You can provide a default value - by putting a ":" in front of the last ";". - E.g. in "~[Siamese~;Manx~;Persian~:;Alley~] Cat", - an out-of-range arg prints "Alley". -
-
: parameter, e.g. "~:[Siamese~;Manx~]"
-
- Take one format argument. If it's NIL, - use the first clause, otherwise use the second clause. -
-
@ parameter, e.g. "~@[Siamese ~a~]"
-
- If the next format argument is true, - use the choice, but do NOT take the argument. - If it's false, take one format argument and print nothing. - (Normally the clause uses the format argument.) -
-
# parameter, e.g. "~#[ none~; ~s~; ~s and ~s~]"
-
- Use the number of arguments to format - as the number to choose a clause. - The same as no parameters in all other ways. - Here's the full hairy example: - "Items:~#[ none~; ~S~; ~S and ~S~:;~@{~#[~; and~] ~S~^ ,~}~]." -
-
- -
-
- - - - - You should avoid unnecessary allocation of memory. - - -

- In a language with automatic storage management (such as Lisp or Java), - the colloquial phrase "memory leak" refers to situation - where storage that is not actually needed - nevertheless does not get deallocated, - because it is still reachable. -

-

- You should be careful that when you create objects, - you don't leave them reachable after they are no longer needed! -

-

- Here's a particular trap-for-the-unwary in Common Lisp. - If you make an array with a fill pointer, and put objects in it, - and then set the fill pointer back to zero, - those objects are still reachable as far as Lisp goes - (the Common Lisp spec says that it's still OK - to refer to the array entries past the end of the fill pointer). -

-

- Don't cons (i.e., allocate) unnecessarily. - Garbage collection is not magic. - Excessive allocation is usually a performance problem. -

- -
- - - You must only use faster unsafe operations - when there is a clear performance need - and you can document why it's correct. - - -

- Common Lisp implementations often provide backdoors - to compute some operations faster in an unsafe way. - For instance, some libraries provide arithmetic operations - that are designed to be used with fixnums only, - and yield the correct result faster if provided proper arguments. - The downside is that the result of such operations - is incorrect in case of overflow, and can - have undefined behavior when called with anything but fixnums. -

- -

- More generally, unsafe operations - will yield the correct result faster - than would the equivalent safe operation - if the arguments satisfy some invariant such as - being of the correct type and small enough; - however if the arguments fail to satisfy the required invariants, - then the operation may have undefined behavior, - such as crashing the software, or, - which is sometimes worse, silently giving wrong answers. - Depending on whether the software is piloting an aircraft - or other life-critical device, - or whether it is accounting for large amounts money, - such undefined behavior can kill or bankrupt people. - Yet proper speed can sometimes make the difference between - software that's unusably slow and software that does its job, - or between software that is a net loss - and software that can yield a profit. -

-

- You must not define or use unsafe operations without both - profiling results indicating the need for this optimization, - and careful documentation explaining why it is safe to use them. - Unsafe operations should be restricted to internal functions; - you should carefully documented how unsafe it is - to use these functions with the wrong arguments. - You should only use unsafe operations - inside functions internal to a package and - you should document the use of the declarations, - since calling the functions with arguments of the wrong type - can lead to undefined behavior. - Use check-type in functions exported from a package - to sanitize input arguments, - so that internal functions are never passed illegal values. -

-

- On some compilers, - new unsafe operations - can usually be defined by combining - type declarations with an OPTIMIZE declaration - that has sufficiently high SPEED and low SAFETY. - In addition to providing more speed for production code, - such declarations may more helpful - than check-type assertions - for finding bugs at compile-time, - on compilers that have type inference. - These compilers may interpret those declarations as assertions - if you switch to safer and slower optimize settings; - this is good to locate a dynamic error in your code during development, - but is not to be used for production code since - it defeats the purpose of declarations as a performance trick. -

- - -
- - - You should only use DYNAMIC-EXTENT - where it matters for performance, - and you can document why it is correct. - - -

- DYNAMIC-EXTENT declarations are - a particular case of - unsafe operations. -

-

- The purpose of a DYNAMIC-EXTENT declaration - is to improve performance by reducing garbage collection - in cases where it appears to be obvious that an object's lifetime - is within the "dynamic extent" of a function. - That means the object is created at some point - after the function is called, and - the object is always inaccessible after the function exits by any means. -

-

- By declaring a variable or a local function DYNAMIC-EXTENT, - the programmer asserts to Lisp - that any object that is ever a value of that variable - or the closure that is the definition of the function - has a lifetime within the dynamic extent of the (innermost) function - that declares the variable. -

-

- The Lisp implementation is then free to use that information - to make the program faster. - Typically, Lisp implementations can take advantage of this knowledge - to stack-allocate: -

-
    -
  • - The lists created to store &REST parameters. -
  • -
  • - Lists, vectors and structures allocated within a function. -
  • -
  • - Closures. -
  • -
-

- If the assertion is wrong, i.e. if the programmer's claim is not true, - the results can be catastrophic: - Lisp can terminate any time after the function returns, - or it can hang forever, or — worst of all — - it can produce incorrect results without any runtime error! -

-

- Even if the assertion is correct, - future changes to the function might introduce - a violation of the assertion. - This increases the danger. -

-

- In most cases, such objects are ephemeral. - Modern Lisp implementations use generational garbage collectors, - which are quite efficient under these circumstances. -

-

- Therefore, DYNAMIC-EXTENT declarations - should be used sparingly. You must only use them if: -

-
    -
  1. - There is some good reason to think that the overall effect - on performance is noticeable, and -
  2. -
  3. - It is absolutely clear that the assertion is true. -
  4. -
  5. - It is quite unlikely that the code will be changed - in ways that cause the declaration to become false. -
  6. -
-

- Point (1) is a special case of - the principle of avoiding premature optimization. - An optimization like this only matters if such objects - are allocated at a very high rate, e.g. "inside an inner loop". -

-

- Note that is relatively easy to ascertain that - a function will not escape the dynamic extent of the current call frame - by analyzing where the function is called and - what other functions it is passed to; - therefore, you should somewhat wary of declaring a function - DYNAMIC-EXTENT, but this is not a high-stress declaration. - On the other hand, it is much harder to ascertain that - none of the objects ever bound or assigned to that variable - and none of their sub-objects - will escape the dynamic extent of the current call frame, - and that they still won't in any future modification of a function. - Therefore, you should be extremely wary - of declaring a variable DYNAMIC-EXTENT. -

-

- It's usually hard to predict the effect of such optimization on performance. - When writing a function or macro - that is part of a library of reusable code, - there's no a priori way to know how often the code will run. - Ideally, tools would be available to discover - the availability and suitability of using such an optimization - based on running simulations and test cases, but - in practice this isn't as easy as it ought to be. - It's a tradeoff. - If you're very, very sure that the assertion is true - (that any object bound to the variable and any of its sub-objects - are only used within the dynamic extent of the specified scope), - and it's not obvious how much time will be saved - and it's not easy to measure, - then it may be better to put in the declaration than to leave it out. - (Ideally it would be easier to make such measurements - than it actually is.) -

- -
- - - You should use REDUCE - instead of APPLY where appropriate. - - -

- You should use REDUCE - instead of APPLY and a consed-up list, - where the semantics of the first operator argument - otherwise guarantees the same semantics. - Of course, you must use APPLY - if it does what you want and REDUCE doesn't. - For instance: -

- - ;; Bad - (apply #'+ (mapcar #'acc frobs)) - - - ;; Better - (reduce #'+ frobs :key #'acc :initial-value 0) - -

- This is preferable because it does not do extra consing, - and does not risk going beyond CALL-ARGUMENTS-LIMIT - on implementations where that limit is small, - which could blow away the stack on long lists - (we want to avoid gratuitous non-portability in our code). -

-

- However, you must be careful not to use REDUCE - in ways that needlessly increase - the complexity class of the computation. - For instance, (REDUCE 'STRCAT ...) is O(n^2) - when an appropriate implementation is only O(n). - Moreover, (REDUCE 'APPEND ...) - is also O(n^2) unless you specify :FROM-END T. - In such cases, you MUST NOT use REDUCE, - and you MUST NOT use (APPLY 'STRCAT ...) - or (APPLY 'APPEND ...) either. - Instead you MUST use proper abstractions - from a suitable library (that you may have to contribute to) - that properly handles those cases - without burdening users with implementation details. - See for instance UIOP:REDUCE/STRCAT. -

- - -
- - - You should not use NCONC; - you should use APPEND instead, - or better, better data structures. - - -

- You should almost never use NCONC. - You should use APPEND - when you don't depend on any side-effect. - You should use ALEXANDRIA:APPENDF - when you need to update a variable. - You should probably not depend on games - being played with the CDR - of the current CONS cell - (which some might argue is suggested but not guaranteed by the specification); - if you do, you must include a prominent - comment explaining the use of NCONC; - and you should probably reconsider your data representation strategy. -

-

- By extension, you should avoid MAPCAN - or the NCONC feature of LOOP. - You should instead respectively use - ALEXANDRIA:MAPPEND - and the APPEND feature of LOOP. -

-

- NCONC is very seldom a good idea, - since its time complexity class is no better than APPEND, - its space complexity class also is no better than APPEND - in the common case where no one else is sharing the side-effected list, - and its bug complexity class is way higher than APPEND. -

-

- If the small performance hit due - to APPEND vs. NCONC - is a limiting factor in your program, - you have a big problem and are probably using the wrong data structure: - you should be using sequences with constant-time append - (see Okasaki's book, and add them to lisp-interface-library), - or more simply you should be accumulating data in a tree - that will get flattened once in linear time - after the accumulation phase is complete. -

-

- You may only use NCONC, MAPCAN - or the NCONC feature of LOOP - in low-level functions where performance matters, - where the use of lists as a data structure has been vetted - because these lists are known to be short, - and when the function or expression the result of which are accumulated - explicitly promises in its contract that it only returns fresh lists - (in particular, it can't be a constant quote or backquote expression). - Even then, the use of such primitives must be rare, - and accompanied by justifying documentation. -

- -
-
- - - - - You should usually refer to a function as #'FUN rather than 'FUN. - - -

- The former, which reads as (FUNCTION FUN), - refers to the function object, and is lexically scoped. - The latter, which reads as (QUOTE FUN), - refers to the symbol, which when called - uses the global FDEFINITION of the symbol. -

-

- When using functions that take a functional argument - (e.g., MAPCAR, APPLY, - :TEST and :KEY arguments), - you should use the #' to refer to the function, - not just single quote. -

-

- An exception is when you explicitly want dynamic linking, - because you anticipate that - the global function binding will be updated. -

-

- Another exception is when you explicitly want to access - a global function binding, - and avoid a possible shadowing lexical binding. - This shouldn't happen often, as it is usually a bad idea - to shadow a function when you will want to use the shadowed function; - just use a different name for the lexical function. -

-

- You must consistently use either #'(lambda ...) - or (lambda ...) without #' everywhere. - Unlike the case of #'symbol vs 'symbol, - it is only a syntactic difference with no semantic impact, - except that the former works on Genera and the latter doesn't. - - You must use the former style if your code is intended as a library - with maximal compatibility to all Common Lisp implementations; - otherwise, it is optional which style you use. - #' may be seen as a hint - that you're introducing a function in expression context; - but the lambda itself is usually sufficient hint, - and concision is good. - Choose wisely, but above all, - consistently with yourself and other developers, - within a same file, package, system, project, etc. -

-

- Note that if you start writing a new system - in a heavily functional style, - you may consider using - lambda-reader, - a system that lets you use the unicode character λ - instead of LAMBDA. - But you must not start using such a syntactic extension - in an existing system without getting permission from other developers. -

- -
- - - Common Lisp pathnames are tricky. Be aware of pitfalls. Use UIOP. - - -

- It is surprisingly hard to properly deal with pathnames in Common Lisp. -

-

- ASDF 3 comes with a portability library UIOP - that makes it much easier to deal with pathnames - portably — and correctly — in Common Lisp. - You should use it when appropriate. -

-

- First, be aware of the discrepancies between - the syntax of Common Lisp pathnames, - which depends on which implementation and operating system - you are using, - and the native syntax of pathnames on your operating system. - The Lisp syntax may involves quoting of special characters - such as #\. and #\*, etc., - in addition to the quoting of - #\\ and #\" within strings. - By contrast, your operating system's other - system programming languages - (shell, C, scripting languages) - may only have one layer of quoting, into strings. -

-

- Second, when using MERGE-PATHNAMES, - be wary of the treatment of the HOST component, - which matters a lot on non-Unix platforms - (and even on some Unix implementations). - You probably should be using - UIOP:MERGE-PATHNAMES* or UIOP:SUBPATHNAME - instead of MERGE-PATHNAMES, - especially if your expectations for relative pathnames - are informed by the way they work in Unix or Windows; - otherwise you might hit weird bugs whereby on some implementations, - merging a relative pathnames with an absolute pathname - results in overriding the absolute pathname's host - and replace it with the host from the value of - *DEFAULT-PATHNAME-DEFAULTS* - at the time the relative pathname was created. -

-

- Third, be aware that DIRECTORY - is not portable across implementations - in how it handles wildcards, sub-directories, symlinks, etc. - There again, UIOP provides several - common abstractions to deal with pathnames, - but only does so good a job. - For a complete portable solution, use IOLib — - though its Windows support lags behind. -

-

- LOGICAL-PATHNAMEs are not a portable abstraction, - and should not be used in portable code. - Many implementations have bugs in them, when they are supported at all. - SBCL implements them very well, - but strictly enforces the limitations on characters - allowed by the standard, which restricts their applicability. - Other implementations allow arbitrary characters in such pathnames, - but in doing so are not being conformant, - and are still incompatible with each other in many ways. - You should use other pathname abstractions, - such as ASDF:SYSTEM-RELATIVE-PATHNAME or - the underlying UIOP:SUBPATHNAME and - UIOP:PARSE-UNIX-NAMESTRING. -

- -

- Finally, be aware that paths may change between - the time you build the Lisp image for your application, - and the time you run the application from its image. - You should be careful to reset your image - to forget irrelevant build-time paths and - reinitialize any search path from current environment variables. - ASDF for instance requires you to reset its paths - with UIOP:CLEAR-CONFIGURATION. - UIOP provides hooks - to call functions before an image is dumped, - from which to reset or makunbound relevant variables. -

- - -
- - - You must be careful when using a SATISFIES clause in a type specifier. - - -

- Most Common Lisp implementations can't optimize - based on a SATISFIES type, - but many of them offer simple optimizations - based on a type of the form - (AND FOO (SATISFIES BAR-P)) - where the first term of the AND clause - describes the structure of the object - without any SATISFIES - and the second term is the SATISFIES. -

- - (deftype prime-number () (satisfies prime-number-p)) ; Bad - - - (deftype prime-number () (and integer (satisfies prime-number-p)) ; Better - -

- However, AND in the DEFTYPE language - isn't a left-to-right short-circuit operator - as in the expression language; - it is a symmetrical connector that allows for reordering subterms - and doesn't guarantee short-circuiting. - Therefore, in the above example, - you cannot rely on the test for INTEGERness - to protect the function PRIME-NUMBER-P - from being supplied non-integer arguments - to test for being of instances of the type. - Implementations may, and some will, - invoke SATISFIES-specified function - at compile-time to test various relevant objects. -

-

- That is why any function specified in a SATISFIES clause - MUST accept objects of any type as argument to the function, - and MUST be defined within an EVAL-WHEN - (as well as any variable it uses or function it calls): -

- - (defun prime-number-p (n) ; Doubly bad! - (let ((m (abs n))) - (if (<= m *prime-number-cutoff*) - (small-prime-number-p m) - (big-prime-number-p m)))) - - - (eval-when (:compile-toplevel :load-toplevel :execute) ; Better - (defun prime-number-p (n) - (when (integerp n) ; Better - (let ((m (abs n))) - (if (<= m *prime-number-cutoff*) - (small-prime-number-p m) - (big-prime-number-p m)))))) - -

- In particular, the above means that the - example - used in the Common Lisp Standard is erroneous: - (and integer (satisfies evenp)) - is not a safe, conformant type specifier to use, - because EVENP will throw an error - rather than return NIL - when passed a non-integer as an argument. -

-

- Finally, there is a catch when your DEFTYPE code expands - to a SATISFIES with a dynamically generated function: -

-
    -
  • - You cannot control when implementations will or will not - expand a DEFTYPE. -
  • -
  • - The expansion itself cannot contain a function definition - or any code in the expression language. -
  • -
  • - You cannot control when the expansion is used, - it may happen in a different process - that didn't expand the definition. -
  • -
-

- Therefore, you cannot merely create the function - as a side-effect of expansion - using EVAL at type-expansion time. - The solution is to use - ASDF-FINALIZERS:EVAL-AT-TOPLEVEL instead. - See the very last point - in the discussion about EVAL. -

-

- Common Lisp is hard to satisfy. -

- -
-
- -
- -Credits: - Adam Worrall, Dan Pierson, Matt Marjanovic, Matt Reklaitis, - Paul Weiss, Scott McKay, Sundar Narasimhan, - and several other people contributed. - Special thanks to Steve Hain, - and to the previous editors, - in reverse chronological order Dan Weinreb and Jeremy Brown. - - -

-Revision 1.28 -

- - -
-Robert Brown -
- -
- François-René Rideau -
- - - -
diff --git a/objcguide.xml b/objcguide.xml deleted file mode 100644 index 68b6209..0000000 --- a/objcguide.xml +++ /dev/null @@ -1,1884 +0,0 @@ - - - - -

- -Revision 2.59 -

- - - -
-
- Mike Pinkerton
- Greg Miller
- Dave MacLachlan -
-
- - - - - - - This style guide contains many details that are initially - hidden from view. They are marked by the triangle icon, which you - see here on your left. Click it now. - You should see "Hooray" appear below. - - -

- Hooray! Now you know you can expand points to get more - details. Alternatively, there's an "expand all" at the - top of this document. -

- -
-
- - - -

- Objective-C is a very dynamic, object-oriented extension of C. It's - designed to be easy to use and read, while enabling sophisticated - object-oriented design. It is the primary development language for new - applications on Mac OS X and the iPhone. -

- -

- Cocoa is one of the main application frameworks on Mac OS X. It is a - collection of Objective-C classes that provide for rapid development of - full-featured Mac OS X applications. -

- -

- Apple has already written a very good, and widely accepted, coding guide - for Objective-C. Google has also written a similar guide for C++. This - Objective-C guide aims to be a very natural combination of Apple's and - Google's general recommendations. So, before reading this guide, please make - sure you've read: -

-

- - - -

- Note that all things that are banned in Google's C++ guide are also - banned in Objective-C++, unless explicitly noted in this document. -

- -

- The purpose of this document is to describe the Objective-C (and - Objective-C++) coding guidelines and practices that should be used for all - Mac OS X code. Many of these guidelines have evolved and been proven over - time on other projects and teams. - - Open-source projects developed by Google - conform to the requirements in this guide. -

- -

- Google has already released open-source code that conforms to these - guidelines as part of the - - Google Toolbox for Mac project - - (abbreviated GTM throughout this document). - Code meant to be shared across different projects is a good candidate to - be included in this repository. -

- - - -

- Note that this guide is not an Objective-C tutorial. We assume that the - reader is familiar with the language. If you are new to Objective-C or - need a refresher, please read - - Programming with Objective-C - . -

-
-
- - - -

- They say an example is worth a thousand words so let's start off with an - example that should give you a feel for the style, spacing, naming, etc. -

- -

- An example header file, demonstrating the correct commenting and spacing - for an @interface declaration -

- - - #import <Foundation/Foundation.h> - - // A sample class demonstrating good Objective-C style. All interfaces, - // categories, and protocols (read: all non-trivial top-level declarations - // in a header) MUST be commented. Comments must also be adjacent to the - // object they're documenting. - // - // (no blank line between this comment and the interface) - @interface Foo : NSObject - - // Returns an autoreleased instance of Foo. See -initWithBar: for details - // about |bar|. - + (instancetype)fooWithBar:(NSString *)bar; - - // Designated initializer. |bar| is a thing that represents a thing that - // does a thing. - - (instancetype)initWithBar:(NSString *)bar; - - // Gets and sets |_bar|. - - (NSString *)bar; - - (void)setBar:(NSString *)bar; - - // Does some work with |blah| and returns YES if the work was completed - // successfully, and NO otherwise. - - (BOOL)doWorkWithBlah:(NSString *)blah; - - @end - - -

- An example source file, demonstrating the correct commenting and spacing - for the @implementation of an interface. It also includes the - reference implementations for important methods like getters and setters, - init, and dealloc. -

- - - #import "Foo.h" - - - @implementation Foo { - NSString *_bar; - NSString *_foo; - } - - + (instancetype)fooWithBar:(NSString *)bar { - return [[[self alloc] initWithBar:bar] autorelease]; - } - - // Must always override super's designated initializer. - - (instancetype)init { - return [self initWithBar:nil]; - } - - - (instancetype)initWithBar:(NSString *)bar { - if ((self = [super init])) { - _bar = [bar copy]; - _bam = [[NSString alloc] initWithFormat:@"hi %d", 3]; - } - return self; - } - - - (void)dealloc { - [_bar release]; - [_bam release]; - [super dealloc]; - } - - - (NSString *)bar { - return _bar; - } - - - (void)setBar:(NSString *)bar { - [_bar autorelease]; - _bar = [bar copy]; - } - - - (BOOL)doWorkWithBlah:(NSString *)blah { - // ... - return NO; - } - - @end - - -

- Blank lines before and after @interface, - @implementation, and @end are optional. If your - @interface declares instance variables, a blank - line should come after the closing brace (}). -

-

- Unless an interface or implementation is very short, such as when declaring - a handful of private methods or a bridge class, adding blank lines usually - helps readability. -

- -
- - - - - - Use only spaces, and indent 2 spaces at a time. - - -

- We use spaces for indentation. Do not use tabs in your code. - You should set your editor to emit spaces when you hit the tab - key. -

- -
- - - - The maximum line length for Objective-C and Objective-C++ files is 100 - columns. Projects may opt to use an 80 column limit for consistency with - the C++ style guide. - - -

- You can make violations easier to spot by enabling Preferences > - Text Editing > Page guide at column: 100 in Xcode. -

- -
- - - - One space should be used between the - or + - and the return type, and no spacing in the parameter list except between - parameters. - - -

- Methods should look like this: -

- - - (void)doSomethingWithString:(NSString *)theString { - ... - } - -

- The spacing before the asterisk is optional. When adding new code, - be consistent with the surrounding file's style. -

-

- If you have too many parameters to fit on one line, giving each its - own line is preferred. If multiple lines are used, align each using - the colon before the parameter. -

- - - (void)doSomethingWith:(GTMFoo *)theFoo - rect:(NSRect)theRect - interval:(float)theInterval { - ... - } - -

- When the first keyword is shorter than the others, indent the later - lines by at least four spaces, maintaining colon alignment: -

- - - (void)short:(GTMFoo *)theFoo - longKeyword:(NSRect)theRect - evenLongerKeyword:(float)theInterval - error:(NSError **)theError { - ... - } - - -
- - - - Method invocations should be formatted much like method declarations. - When there's a choice of formatting styles, follow the convention - already used in a given source file. - - -

- Invocations should have all arguments on one line: -

- - [myObject doFooWith:arg1 name:arg2 error:arg3]; - -

- or have one argument per line, with colons aligned: -

- - [myObject doFooWith:arg1 - name:arg2 - error:arg3]; - -

- Don't use any of these styles: -

- - [myObject doFooWith:arg1 name:arg2 // some lines with >1 arg - error:arg3]; - - [myObject doFooWith:arg1 - name:arg2 error:arg3]; - - [myObject doFooWith:arg1 - name:arg2 // aligning keywords instead of colons - error:arg3]; - - -

- As with declarations and definitions, when the first keyword is shorter - than the others, indent the later lines by at least four spaces, - maintaining colon alignment: -

- - [myObj short:arg1 - longKeyword:arg2 - evenLongerKeyword:arg3 - error:arg4]; - -

- Invocations containing inlined blocks may have - their segments left-aligned at a four space indent. -

- -
- - - - The @public and @private access modifiers - should be indented by 1 space. - - -

- This is similar to public, private, and - protected in C++. -

- - @interface MyClass : NSObject { - @public - ... - @private - ... - } - @end - - -
- - - - Format exceptions with each @ label on its own line and a - space between the @ label and the opening brace - ({), as well as between the @catch and the - caught object declaration. - - -

- If you must use Obj-C exceptions, format them as follows. However, see - Avoid Throwing Exceptions for - reasons why you should not be using exceptions. -

- - @try { - foo(); - } - @catch (NSException *ex) { - bar(ex); - } - @finally { - baz(); - } - - -
- - - - There should not be a space between the type identifier and the name - of the protocol encased in angle brackets. - - -

- This applies to class declarations, instance variables, and method - declarations. For example: -

- - @interface MyProtocoledClass : NSObject<NSWindowDelegate> { - @private - id<MyFancyDelegate> _delegate; - } - - (void)setDelegate:(id<MyFancyDelegate>)aDelegate; - @end - - -
- - - - Code inside blocks should be indented four spaces. - - -

- There are several appropriate style rules, depending on how long the - block is: -

-
    -
  • If the block can fit on one line, no wrapping is necessary.
  • -
  • - If it has to wrap, the closing brace should line up with the first - character of the line on which the block is declared. -
  • -
  • Code within the block should be indented four spaces.
  • -
  • - If the block is large, e.g. more than 20 lines, it is recommended to - move it out-of-line into a local variable. -
  • -
  • - If the block takes no parameters, there are no spaces between the - characters ^{. If the block takes parameters, there is no - space between the ^( characters, but there is one space - between the ) { characters. -
  • -
  • - Invocations containing inlined blocks may have their segments - left-aligned at a four-space indent. This helps when invocations - contain multiple inlined blocks. -
  • -
  • - Two space indents inside blocks are also allowed, but should only - be used when it's consistent with the rest of the project's code. -
  • -
- - // The entire block fits on one line. - [operation setCompletionBlock:^{ [self onOperationDone]; }]; - - // The block can be put on a new line, indented four spaces, with the - // closing brace aligned with the first character of the line on which - // block was declared. - [operation setCompletionBlock:^{ - [self.delegate newDataAvailable]; - }]; - - // Using a block with a C API follows the same alignment and spacing - // rules as with Objective-C. - dispatch_async(_fileIOQueue, ^{ - NSString* path = [self sessionFilePath]; - if (path) { - // ... - } - }); - - // An example where the parameter wraps and the block declaration fits - // on the same line. Note the spacing of |^(SessionWindow *window) {| - // compared to |^{| above. - [[SessionService sharedService] - loadWindowWithCompletionBlock:^(SessionWindow *window) { - if (window) { - [self windowDidLoad:window]; - } else { - [self errorLoadingWindow]; - } - }]; - - // An example where the parameter wraps and the block declaration does - // not fit on the same line as the name. - [[SessionService sharedService] - loadWindowWithCompletionBlock: - ^(SessionWindow *window) { - if (window) { - [self windowDidLoad:window]; - } else { - [self errorLoadingWindow]; - } - }]; - - // Large blocks can be declared out-of-line. - void (^largeBlock)(void) = ^{ - // ... - }; - [_operationQueue addOperationWithBlock:largeBlock]; - - // An example with multiple inlined blocks in one invocation. - [myObject doSomethingWith:arg1 - firstBlock:^(Foo *a) { - // ... - } - secondBlock:^(Bar *b) { - // ... - }]; - - -
- - - - For projects using Xcode 4.4 or later and clang, the use of container - (array and dictionary) literals is encouraged. If split across multiple - lines, the contents should be indented two spaces. - - -

- If the collection fits on one line, put a single space after the opening - and before the closing brackets. -

- - NSArray* array = @[ [foo description], @"Another String", [bar description] ]; - - NSDictionary* dict = @{ NSForegroundColorAttributeName : [NSColor redColor] }; - -

- Not: -

- - NSArray* array = @[[foo description], [bar description]]; - - NSDictionary* dict = @{NSForegroundColorAttributeName: [NSColor redColor]}; - - -

- If the collection spans more than a single line, place the opening - bracket on the same line as the declaration, indent the body by two - spaces, and place the closing bracket on a new line that is indented to - the same level as the opening bracket. -

- - NSArray* array = @[ - @"This", - @"is", - @"an", - @"array" - ]; - - NSDictionary* dictionary = @{ - NSFontAttributeName : [NSFont fontWithName:@"Helvetica-Bold" size:12], - NSForegroundColorAttributeName : fontColor - }; - - -

- For dictionary literals, there should be one space before the colon and - at least one space after it (to optionally align the values). -

- - NSDictionary* option1 = @{ - NSFontAttributeName : [NSFont fontWithName:@"Helvetica-Bold" size:12], - NSForegroundColorAttributeName : fontColor - }; - - NSDictionary* option2 = @{ - NSFontAttributeName : [NSFont fontWithName:@"Arial" size:12], - NSForegroundColorAttributeName : fontColor - }; - -

- The following are all incorrect: -

- - // There should be a space before the colon. - NSDictionary* wrong = @{ - AKey: @"b", - BLongerKey: @"c", - }; - - // The items should each be on a new line, or the entire expression - // should fit on one line. - NSDictionary* alsoWrong= @{ AKey : @"a", - BLongerKey : @"b" }; - - // There should be no variable space before the colon, only after. - NSDictionary* stillWrong = @{ - AKey : @"b", - BLongerKey : @"c", - }; - - -
-
- - - -

- Naming rules are very important in maintainable code. Objective-C method - names tend to be very long, but this has the benefit that a block of code - can almost read like prose, thus rendering many comments unnecessary.

-

When writing pure Objective-C code, we mostly follow standard Objective-C - naming rules. These naming guidelines may differ - significantly from those outlined in the C++ style guide. For example, - Google's C++ style guide recommends the use of underscores between words - in variable names, whereas this guide recommends the use of intercaps, - which is standard in the Objective-C community. -

-

- Any class, category, method, or variable name may use all capitals for - initialisms - within the name. This follows Apple's standard of using all capitals - within a name for initialisms such as URL, TIFF, and EXIF. -

-

- When writing Objective-C++, however, things are not so cut and dry. Many - projects need to implement cross-platform C++ APIs with some Objective-C - or Cocoa, or bridge between a C++ back-end and a native Cocoa front-end. - This leads to situations where the two guides are directly at odds. -

-

- Our solution is that the style follows that of the method/function being - implemented. If you're in an @implementation block, use the - Objective-C naming rules. If you're implementing a method for a C++ - class, use the C++ naming rules. This avoids the situation - where instance variable and local variable naming rules are mixed within a - single function, which would be a serious detriment to readability. -

- - - - File names should reflect the name of the class implementation that - they contain—including case. Follow the convention that your - - project - uses. - - -

- File extensions should be as follows: -

- - - - - - - - - - - - - - - - - - - - - -
.hC/C++/Objective-C header file
.mObjective-C implementation file
.mmObjective-C++ implementation file
.ccPure C++ implementation file
.cC implementation file
-

- File names for categories should include the name of the class being - extended, e.g. GTMNSString+Utils.h or - GTMNSTextView+Autocomplete.h -

- -
- - - - Within a source file, Objective-C++ follows the style of the - function/method you're implementing. - - -

- In order to minimize clashes between the differing naming styles when - mixing Cocoa/Objective-C and C++, follow the style of the method being - implemented. If you're in an @implementation block, use - the Objective-C naming rules. If you're implementing a method for a - C++ class, use the C++ naming rules. -

- - // file: cross_platform_header.h - - class CrossPlatformAPI { - public: - ... - int DoSomethingPlatformSpecific(); // impl on each platform - private: - int an_instance_var_; - }; - - // file: mac_implementation.mm - #include "cross_platform_header.h" - - // A typical Objective-C class, using Objective-C naming. - @interface MyDelegate : NSObject { - @private - int _instanceVar; - CrossPlatformAPI* _backEndObject; - } - - (void)respondToSomething:(id)something; - @end - @implementation MyDelegate - - (void)respondToSomething:(id)something { - // bridge from Cocoa through our C++ backend - _instanceVar = _backEndObject->DoSomethingPlatformSpecific(); - NSString* tempString = [NSString stringWithFormat:@"%d", _instanceVar]; - NSLog(@"%@", tempString); - } - @end - - // The platform-specific implementation of the C++ class, using - // C++ naming. - int CrossPlatformAPI::DoSomethingPlatformSpecific() { - NSString* temp_string = [NSString stringWithFormat:@"%d", an_instance_var_]; - NSLog(@"%@", temp_string); - return [temp_string intValue]; - } - - -
- - - - Class names (along with category and protocol names) should start as - uppercase and use mixed case to delimit words. - - -

- When designing code to be shared across multiple applications, - prefixes are acceptable and recommended (e.g. GTMSendMessage). - Prefixes are also recommended for classes of large applications that - depend on external libraries. -

- - -
- - - - Category names should start with a 2 or 3 character prefix - identifying the category as part of a project or open for general - use. The category name should incorporate the name of the class it's - extending. - - -

- For example, if we want to create a category on NSString - for parsing, we would put the category in a file named - GTMNSString+Parsing.h, and the category itself would be - named GTMStringParsingAdditions (yes, we know the file - name and the category name do not match, but this file could have many - separate categories related to parsing). Methods in that category - should share the prefix (gtm_myCategoryMethodOnAString:) - in order to prevent collisions in Objective-C which only has a single - namespace. If the code isn't meant to be shared and/or doesn't run in - a different address-space, the method naming isn't quite as - important. -

-

- There should be a single space between the class name and the opening - parenthesis of the category. -

- - // Extending a framework class: - @interface NSString (GTMStringParsingAdditions) - - (NSString *)gtm_foobarString; - @end - - // Making your methods and properties private: - @interface FoobarViewController () - @property(nonatomic, retain) NSView *dongleView; - - (void)performLayout; - @end - - -
- - - - Method names should start as lowercase and then use mixed case. - Each named parameter should also start as lowercase. - - -

- The method name should read like a sentence if possible, meaning you - should choose parameter names that flow with the method name. (e.g. - convertPoint:fromRect: or - replaceCharactersInRange:withString:). See Apple's - Guide to Naming Methods for more details. -

-

- Accessor methods should be named the same as the variable they're - "getting", but they should not be prefixed with the word - "get". For example: - - - (id)getDelegate; // AVOID - - - - (id)delegate; // GOOD - -

-

- This is for Objective-C methods only. C++ method names and functions - continue to follow the rules set in the C++ style guide. -

- -
- - - - Variables names start with a lowercase and use mixed case to delimit - words. Instance variables have leading underscores. For example: - myLocalVariable, _myInstanceVariable. - - - -

- Do not use Hungarian notation for syntactic attributes, - such as the static type of a variable (int or pointer). Give as - descriptive a name as possible, within reason. Don't worry about - saving horizontal space as it is far more important to make your - code immediately understandable by a new reader. For example: -

- - int w; - int nerr; - int nCompConns; - tix = [[NSMutableArray alloc] init]; - obj = [someObject object]; - p = [network port]; - - - int numErrors; - int numCompletedConnections; - tickets = [[NSMutableArray alloc] init]; - userInfo = [someObject object]; - port = [network port]; - -
- - -

- Instance variables are mixed case and should be prefixed with an - underscore e.g. _usernameTextField. Note that historically - the convention was to put the underscore at the end of the name, and - projects may opt to continue using trailing underscores in new code - in order to maintain consistency within their codebase (see the - Historical Notes section). It is recommended you leave old - code as-is, unless doing so would create inconsistency within a class. -

-
- - -

- Constant names (#defines, enums, const local variables, etc.) should - start with a lowercase k and then use mixed case to - delimit words. For example: -

- - const int kNumberOfFiles = 12; - NSString *const kUserKey = @"kUserKey"; - enum DisplayTinge { - kDisplayTingeGreen = 1, - kDisplayTingeBlue = 2 - }; - -

- Because Objective-C does not provide namespacing, constants with global - scope should have an appropriate prefix to minimize the chance of name - collision, typically like kClassNameFoo. -

-
- -
- -
- - - -

- Though a pain to write, they are absolutely vital to keeping our code - readable. The following rules describe what you should comment and where. - But remember: while comments are very important, the best code is - self-documenting. Giving sensible names to types and variables is much - better than using obscure names and then trying to explain them through - comments. -

-

- When writing your comments, write for your audience: the next - - contributor - who will need to understand your code. Be generous—the next - one may be you! -

-

- Remember that all of the rules and conventions listed in the C++ Style - Guide are in effect here, with a few additional points, below. -

- - - - A file may optionally start with a description of its contents. - - - -

- Every file should contain the following items, in order: -

    -
  • license boilerplate if neccessary. Choose the appropriate - boilerplate for the license used by the project (e.g. - Apache 2.0, BSD, LGPL, GPL).
  • -
  • a basic description of the contents of the file if necessary.
  • -
-

-

- If you make significant changes to a file with an author line, - consider deleting the author line since revision history already - provides a more detailed and accurate record of authorship. -

- -
- - - - Every interface, category, and protocol declaration should have an - accompanying comment describing its purpose and how it fits into the - larger picture. - - - - // A delegate for NSApplication to handle notifications about app - // launch and shutdown. Owned by the main app controller. - @interface MyAppDelegate : NSObject { - ... - } - @end - -

- If you have already described an interface in detail in the - comments at the top of your file feel free to simply state - "See comment at top of file for a complete description", but - be sure to have some sort of comment. -

-

- Additionally, each method in the public interface should have a - comment explaining its function, arguments, return value, and any - side effects. -

-

- Document the synchronization assumptions the class makes, if - any. If an instance of the class can be accessed by multiple - threads, take extra care to document the rules and invariants - surrounding multithreaded use. -

- -
- - - - Use vertical bars to quote variable names and symbols in comments rather - than quotes or naming the symbol inline. - - -

- This helps eliminate ambiguity, especially when the symbol is a common - word that might make the sentence read like it was poorly constructed. - E.g. for a symbol "count": -

- - // Sometimes we need |count| to be less than zero. - -

- or when quoting something which already contains quotes -

- - // Remember to call |StringWithoutSpaces("foo bar baz")| - - -
- - - - Make the pointer ownership model as explicit as possible when it falls - outside the most common Objective-C usage idioms. - - - -

- Instance variables which are pointers to objects derived from NSObject - are presumed to be retained, and should be either commented as weak or - declared with the __weak lifetime qualifier when applicable. - Similarly, declared properties must specify an assign property - attribute if they are not retained by the class. An exception is - instance variables labeled as IBOutlets in desktop Mac software, - which are presumed to not be retained. -

-

- Where instance variables are pointers to Core Foundation, C++, and - other non-Objective-C objects, they should always be declared with - strong and weak comments to indicate which - pointers are and are not retained. Core Foundation and other - non-Objective-C object pointers require explicit memory management, - even when building for automatic reference counting or garbage - collection. -

-

- Examples of strong and weak declarations: - - @interface MyDelegate : NSObject { - @private - IBOutlet NSButton *_okButton; // Normal NSControl; implicitly weak on Mac only - - AnObjcObject* _doohickey; // My doohickey - __weak MyObjcParent *_parent; // So we can send msgs back (owns me) - - // non-NSObject pointers... - CWackyCPPClass *_wacky; // Strong, some cross-platform object - CFDictionaryRef *_dict; // Strong - } - @property(strong, nonatomic) NSString *doohickey; - @property(weak, nonatomic) NSString *parent; - @end - -

-
- -

- Object ownership and lifetime are explicit when using ARC, so no - additional comments are required. -

-
- -
- -
- - - - - - Instance variables should typically be declared in implementation files - or auto-synthesized by properties. When ivars are declared in a header - file, they should be marked @private. - - - - @interface MyClass : NSObject { - @private - id _myInstanceVariable; - } - @end - - - - - - - Comment and clearly identify your designated initializer. - - -

- It is important for those who might be subclassing your class that the - designated initializer be clearly identified. That way, they only need - to subclass a single initializer (of potentially several) to guarantee - their subclass' initializer is called. It also helps those debugging - your class in the future understand the flow of initialization code if - they need to step through it. -

- -
- - - - When writing a subclass that requires an init... method, - make sure you override the superclass' designated initializer. - - -

- If you fail to override the superclass' designated initializer, your - initializer may not be called in all cases, leading to subtle and - very difficult to find bugs. -

- -
- - - - It is strongly recommended and typical practice to place overridden - methods of NSObject at the top of an - @implementation. - - -

- This commonly applies (but is not limited) to the init..., - copyWithZone:, and dealloc methods. - init... methods should be grouped together, followed by - other NSObject methods. -

-

- Convenience class methods for creating instances may precede the - NSObject methods. -

- -
- - - - Don't initialize variables to 0 or nil in the - init method; it's redundant. - - -

- All memory for a newly allocated object is initialized to 0 (except - for isa), so don't clutter up the init method - by re-initializing variables to 0 or nil. -

- -
- - - - Do not invoke the NSObject class method new, - nor override it in a subclass. Instead, use alloc and - init methods to instantiate retained objects. - - -

- Modern Objective-C code explicitly calls alloc and an - init method to create and retain an object. As the - new class method is rarely used, it makes reviewing code - for correct memory management more difficult. -

- -
- - - - Keep your class simple; avoid "kitchen-sink" APIs. If a method doesn't - need to be public, don't make it so. Use a private category to prevent - cluttering the public header. - - -

- Unlike C++, Objective-C doesn't have a way to differentiate between - public and private methods—everything is public. As a result, - avoid placing methods in the public API unless they are actually - expected to be used by a consumer of the class. This helps reduce the - likelihood they'll be called when you're not expecting it. This includes - methods that are being overridden from the parent class. For internal - implementation methods, use a category defined in the implementation - file as opposed to adding them to the public header. -

- - #import "GTMFoo.h" - - @interface GTMFoo (PrivateDelegateHandling) - - (NSString *)doSomethingWithDelegate; // Declare private method - @end - - @implementation GTMFoo (PrivateDelegateHandling) - ... - - (NSString *)doSomethingWithDelegate { - // Implement this method - } - ... - @end - -

- If you are using Objective-C 2.0, you should instead declare your - private category using a class - extension, for example: -

- - @interface GMFoo () { ... } - -

- which will guarantee that the declared methods are implemented in the - @implementation section by issuing a compiler warning if - they are not. -

-

- Again, "private" methods are not really private. You could - accidentally override a superclass's "private" method, thus making a - very difficult bug to squash. In general, private methods should have - a fairly unique name that will prevent subclasses from unintentionally - overriding them. -

-

- Finally, Objective-C categories are a great way to segment a large - @implementation section into more understandable chunks - and to add new, application-specific functionality to the most - appropriate class. For example, instead of adding "middle truncation" - code to a random object in your app, make a new category on - NSString). -

- -
- - - - #import Objective-C/Objective-C++ headers, and - #include C/C++ headers. - - -

- Choose between #import and #include based - on the language of the header that you are including. -

-
    -
  • When including a header that uses Objective-C or Objective-C++, - use #import.
  • -
  • When including a standard C or C++ header, use - #include. The header should provide its own #define - guard.
  • -
-

- Some Objective-C headers lack #define guards, and expect - to be included only by #import. As Objective-C headers - may only be included in Objective-C source files and other Objective-C - headers, using #import across the board is appropriate. -

-

- Standard C and C++ headers without any Objective-C in them can expect - to be included by ordinary C and C++ files. Since there is no - #import in standard C or C++, such files will be - included by #include in those cases. Using - #include for them in Objective-C source files as well - means that these headers will always be included with the same - semantics. -

-

- This rule helps avoid inadvertent errors in cross-platform - projects. A Mac developer introducing a new C or C++ header might - forget to add #define guards, which would not cause - problems on the Mac if the new header were included with - #import, but would break builds on other platforms - where #include is used. Being consistent by using - #include on all platforms means that compilation is - more likely to succeed everywhere or fail everywhere, and avoids - the frustration of files working only on some platforms. -

- - #import <Cocoa/Cocoa.h> - #include <CoreFoundation/CoreFoundation.h> - #import "GTMFoo.h" - #include "base/basictypes.h" - - -
- - - - Include root frameworks over individual files. - - -

- While it may seem tempting to include individual system headers from a - framework such as Cocoa or Foundation, in fact it's less work on the - compiler if you include the top-level root framework. The root - framework is generally pre-compiled and can be loaded much more - quickly. In addition, remember to use #import rather than - #include for Objective-C frameworks. -

- - #import <Foundation/Foundation.h> // good - - - #import <Foundation/NSArray.h> // avoid - #import <Foundation/NSString.h> - ... - - -
- - - - When creating new temporary objects, autorelease them on - the same line as you create them rather than a separate - release later in the same method. - - -

- While ever so slightly slower, this prevents someone from accidentally - removing the release or inserting a return - before it and introducing a memory leak. E.g.: -

- - // AVOID (unless you have a compelling performance reason) - MyController* controller = [[MyController alloc] init]; - // ... code here that might return ... - [controller release]; - - - // BETTER - MyController* controller = [[[MyController alloc] init] autorelease]; - - -
- - - - Assignment of objects follows the autorelease then - retain pattern. - - -

- When assigning a new object to a variable, one must first release the - old object to avoid a memory leak. There are several "correct" ways to - handle this. We've chosen the "autorelease then retain" approach - because it's less prone to error. Be aware in tight loops it can fill - up the autorelease pool, and may be slightly less efficient, but we - feel the tradeoffs are acceptable. -

- - - (void)setFoo:(GMFoo *)aFoo { - [_foo autorelease]; // Won't dealloc if |_foo| == |aFoo| - _foo = [aFoo retain]; - } - - -
- - - - Instance subclasses may be in an inconsistent state during - init and dealloc method execution, so code in - those methods should avoid invoking accessors. - - -

- Subclasses have not yet been initialized or have already deallocated - when init and dealloc methods execute, making - accessor methods potentially unreliable. Whenever practical, directly - assign to and release ivars in those methods rather than rely on - accessors. -

- - - (instancetype)init { - self = [super init]; - if (self) { - _bar = [[NSMutableString alloc] init]; // good - } - return self; - } - - - (void)dealloc { - [_bar release]; // good - [super dealloc]; - } - - - - (instancetype)init { - self = [super init]; - if (self) { - self.bar = [NSMutableString string]; // avoid - } - return self; - } - - - (void)dealloc { - self.bar = nil; // avoid - [super dealloc]; - } - - -
- - - - dealloc should process instance variables in the same order - the @interface declares them, so it is easier for a reviewer - to verify. - - -

- A code reviewer checking a new or revised dealloc - implementation needs to make sure that every retained instance - variable gets released. -

-

- To simplify reviewing dealloc, order the code so that - the retained instance variables get released in the same order that - they are declared in the @interface. If - dealloc invokes other methods that release instance - variables, add comments describing what instance variables those - methods handle. -

- -
- - - - Setters taking an NSString, should always copy - the string it accepts. - - -

- Never just retain the string. This avoids the caller - changing it under you without your knowledge. Don't assume that - because you're accepting an NSString that it's not - actually an NSMutableString. -

- - - (void)setFoo:(NSString *)aFoo { - [_foo autorelease]; - _foo = [aFoo copy]; - } - - -
- - - - Don't @throw Objective-C exceptions, but you should be - prepared to catch them from third-party or OS calls. - - -

- We do compile with -fobjc-exceptions (mainly so we get - @synchronized), but we don't @throw. Use of - @try, @catch, and @finally are - allowed when required to properly use 3rd party code or libraries. If - you do use them please document exactly which methods you expect to - throw. -

- -
- - - - - Use nil checks for logic flow only. - - -

- Use nil pointer checks for logic flow of the application, - not for preventing crashes when sending messages. With current compilers - ( - as of LLVM 3.0/Xcode 4.2), sending a message to nil - reliably returns nil as a pointer, zero as an integer or floating-point - value, structs initialized to 0, and _Complex values equal - to {0, 0}. -

-

- Note that this applies to nil as a message target, not as - a parameter value. Individual methods may or may not safely handle - nil parameter values. -

-

- Note too that this is distinct from checking C/C++ pointers and block - pointers against NULL, which the runtime does not handle - and will cause your application to crash. You still need to make sure - you do not dereference a NULL pointer. -

- -
- - - - Be careful when converting general integral values to BOOL. - Avoid comparing directly with YES. - - -

- BOOL is defined as a signed char in Objective-C which means - that it can have values other than YES (1) and - NO (0). Do not cast or convert general integral values - directly to BOOL. Common mistakes include casting or - converting an array's size, a pointer value, or the result of a bitwise - logic operation to a BOOL which, depending on the value of - the last byte of the integral result, could still result in a - NO value. When converting a general integral value to a - BOOL use ternery operators to return a YES or - NO value. -

-

- You can safely interchange and convert BOOL, - _Bool and bool (see C++ Std 4.7.4, 4.12 and - C99 Std 6.3.1.2). You cannot safely interchange BOOL and - Boolean so treat Booleans as a general - integral value as discussed above. Only use BOOL in - Objective C method signatures. -

-

- Using logical operators (&&, || and - !) with BOOL is also valid and will return - values that can be safely converted to BOOL without the - need for a ternery operator. -

- - - (BOOL)isBold { - return [self fontTraits] & NSFontBoldTrait; - } - - (BOOL)isValid { - return [self stringValue]; - } - - - - (BOOL)isBold { - return ([self fontTraits] & NSFontBoldTrait) ? YES : NO; - } - - (BOOL)isValid { - return [self stringValue] != nil; - } - - (BOOL)isEnabled { - return [self isValid] && [self isBold]; - } - -

- Also, don't directly compare BOOL variables directly - with YES. Not only is it harder to read for those - well-versed in C, the first point above demonstrates that return - values may not always be what you expect. -

- - BOOL great = [foo isGreat]; - if (great == YES) - // ...be great! - - - BOOL great = [foo isGreat]; - if (great) - // ...be great! - - - -
- - - - Use of the @property directive is preferred, with the following caveat: - properties are an Objective-C 2.0 feature which will limit your code to - running on the iPhone and Mac OS X 10.5 (Leopard) and higher. Dot notation - is allowed only for access to a declared @property. - - - -

- A property's associated instance variable's name must conform to the - leading _ requirement. The property's name should be the same as its - associated instance variable without the leading _. The optional space - between the @property and the opening parenthesis - should be omitted, as seen in the examples. -

- - - @interface MyClass : NSObject - @property(copy, nonatomic) NSString *name; - @end - - @implementation MyClass - // No code required for auto-synthesis, else use: - // @synthesize name = _name; - @end - -
- -

- A property's declaration must come immediately after the instance - variable block of a class interface. A property's definition (if - not using automatic synthesis) must come immediately after the - @implementation block in a class definition. They are - indented at the same level as the @interface or - @implementation statements that they are enclosed in. -

- - @interface MyClass : NSObject { - @private - NSString *_name; - } - @property(copy, nonatomic) NSString *name; - @end - - @implementation MyClass - @synthesize name = _name; - - - (instancetype)init { - ... - } - @end - -
- -

- NSString properties should always be declared with the - copy attribute. -

-

- This logically follows from the requirement that setters for - NSStrings always must use copy instead of - retain. -

-
- -

- Be aware of the overhead of properties. By default, all synthesized - setters and getters are atomic. This gives each set and get calls a - substantial amount of synchronization overhead. Declare your - properties nonatomic unless you require atomicity. -

-
- -

- Dot notation is idiomatic style for Objective-C 2.0. It may be used - when doing simple operations to get and set a @property - of an object, but should not be used to invoke other object behavior. -

- - NSString *oldName = myObject.name; - myObject.name = @"Alice"; - - - NSArray *array = [[NSArray arrayWithObject:@"hello"] retain]; - - NSUInteger numberOfItems = array.count; // not a property - array.release; // not a property - -
- -
- - - - Omit the empty set of braces on interfaces that do not declare any - instance variables. - - - - @interface MyClass : NSObject - // Does a lot of stuff - - (void)fooBarBam; - @end - - - @interface MyClass : NSObject { - } - // Does a lot of stuff - - (void)fooBarBam; - @end - - - - - - -

- Use of automatically synthesized instance variables is preferred. Code - that must support earlier versions of the compiler toolchain (Xcode 4.3 - or earlier or when compiling with GCC) or is using properties inherited - from a protocol should prefer the @synthesize directive. -

-
- - - // Header file - @protocol Thingy - @property(nonatomic, copy) NSString *widgetName; - @end - - @interface Foo : NSObject<Thingy> - // A guy walks into a bar. - @property(nonatomic, copy) NSString *bar; - @end - - // Implementation file - @interface Foo () - @property(nonatomic, retain) NSArray *baz; - @end - - @implementation Foo - @synthesize widgetName = _widgetName; - @end - - -

- Automatically synthesized instance variables take the form of the - property's name prefixed with an underscore and so typically conform to - the required variable naming style. If your property name is unusual, - or you are otherwise unable to use automatically synthesized instance - variables, use of the @synthesize directive is preferred, with the - instance variable name specified explicitly (as @synthesize does not add - a leading underscore by default). -

- -
- - - -

- For projects that use Xcode 4.2 or later and will run only on 64-bit - Mac OS X 10.7 and iOS 5.0 and later, ARC is preferred. Use manual - reference counting when supporting earlier environments where zeroing - weak pointers are not available. -

-

- Classes that require ARC should include a preprocessor directive to - prevent compilation using manual reference counting. -

-

- Ownership qualifiers like __unsafe_unretained and - __weak should precede variable names. Specifying - __strong for variables is not required since it is - the default. Properties, on the other hand, should always specify the - strong keyword rather than relying on the compiler default. -

-

- Files that are compiled using ARC need to have preprocessor directives - to prevent compilation without ARC. See the code snippet below for - details. -

-
- -

- Example of an implementation file enforcing ARC style. Note that - declaring instance variables in the @implementation is permitted when - using ARC. - - #if !defined(__has_feature) || !__has_feature(objc_arc) - #error "This file requires ARC support." - #endif - - #import "Foo.h" - - @implementation Foo { - Bar* __weak _bar; - Baz* __unsafe_unretained _baz; - } - // ... - @end - -

- -
- - - -

- For projects that use Xcode 4.4 or later with clang, the use of - NSNumber literals - is allowed. Note however that this will limit the portability of your - code to other toolchains. -

-
- -

- NSNumber literals are used just like Objective C string literals. - Boxing is used when necessary. Code using NSNumber literals can be - deployed on any iOS/MacOS system. - - NSNumber *fortyTwo = @42; - NSNumber *piOverTwo = @(M_PI / 2); - enum { - kMyEnum = 2; - }; - NSNumber *myEnum = @(kMyEnum); - -

- -
-
- - - - - - - Delegate objects should not be retained when doing so would create - a retain cycle. - - -

- A class that implements the delegate pattern should typically: -

    -
  1. - Have an instance variable named _delegate to reference - the delegate. -
  2. -
  3. - Thus, the accessor methods should be named delegate - and setDelegate:. -
  4. -
  5. - The _delegate object should be weak if the class - is typically retained by its delegate, such that a strong delegate - would create a retain cycle. -
  6. -
-

- -
- - - - Separate the model from the view. Separate the controller from the - view and the model. Use @protocols for callback APIs. - - -

-

    -
  • - Separate model from view: don't build assumptions about the - presentation into the model or data source. Keep the interface - between the data source and the presentation abstract. Don't give - the model knowledge of its view. (A good rule of thumb is to ask - yourself if it's possible to have multiple presentations, with - different states, on a single instance of your data source.) -
  • -
  • - Separate controller from view and model: don't put all of the - "business logic" into view-related classes; this makes the code - very unusable. Make controller classes to host this code, but - ensure that the controller classes don't make too many assumptions - about the presentation. -
  • -
  • - Define callback APIs with @protocol, using - @optional if not all the methods are required. -
  • -
-

- -
- -
- - - - - - Trailing underscores were once preferred for instance variable names. - - -

- Our style guide used to have a rule saying that instance variables - should be named with a trailing underscore, similar to the naming of - member variables in C++. This was changed to leading underscores to - be consistent with the broader Objective-C community, to better follow - Apple's official guidelines, and to allow for use of new compiler - features like automatic instance variable synthesis. New projects are - strongly encouraged to use leading underscores. Existing projects may - continue to use trailing underscores in new code to maintain - consistency with the rest of their codebase. -

- -
- -
- -
- -

-Revision 2.59 -

- - - -
-Mike Pinkerton
-Greg Miller
-Dave MacLachlan
-
-
diff --git a/pyguide.html b/pyguide.html deleted file mode 100644 index 632c9c6..0000000 --- a/pyguide.html +++ /dev/null @@ -1,2311 +0,0 @@ - - -Google Python Style Guide - - - - - - -

Google Python Style Guide

-

- - Revision 2.59 -

- -
- Amit Patel
- Antoine Picard
- Eugene Jhong
- Jeremy Hylton
- Matt Smart
- Mike Shields
-
-
-

- Each style point has a summary for which additional information is available - by toggling the accompanying arrow button that looks this way: - . - You may toggle all summaries with the big arrow button: -

-
- - Toggle all summaries -
-
-
-
Table of Contents
- - - - - - - - - -
-
-
-

Important Note

-
-

Displaying Hidden Details in this Guide

- - link - -
- This style guide contains many details that are initially - hidden from view. They are marked by the triangle icon, which you - see here on your left. Click it now. - You should see "Hooray" appear below. -
-
-
-
-
-

Background

-

- Python is the main scripting language used at Google. This - style guide is a list of dos and don'ts for Python - programs. -

- -

- To help you format code correctly, we've created a settings - file for Vim. For Emacs, the default settings should be fine. -

- - -
- -
-

Python Language Rules

-
-

Lint

- - link - -
- Run pylint over your code. -
-
-
-
-

Imports

- - link - -
- Use imports for packages and modules only. -
-
-
-
-

Packages

- - link - -
- Import each module using the full pathname location of the module. -
-
-
-
-

Exceptions

- - link - -
- Exceptions are allowed but must be used carefully. -
-
-
-
-

Global variables

- - link - -
- Avoid global variables. -
-
-
-
-

Nested/Local/Inner Classes and Functions

- - link - -
- Nested/local/inner classes and functions are fine. -
-
-
-
-

List Comprehensions

- - link - -
- Okay to use for simple cases. -
-
-
-
-

Default Iterators and Operators

- - link - -
- Use default iterators and operators for types that support them, - like lists, dictionaries, and files. -
-
-
-
-

Generators

- - link - -
- Use generators as needed. -
-
-
-
-

Lambda Functions

- - link - -
- Okay for one-liners. -
-
-
-
-

Conditional Expressions

- - link - -
- Okay for one-liners. -
-
-
-
-

Default Argument Values

- - link - -
- Okay in most cases. -
-
-
-
-

Properties

- - link - -
- Use properties for accessing or setting data where you would - normally have used simple, lightweight accessor or setter methods. -
-
-
-
-

True/False evaluations

- - link - -
- Use the "implicit" false if at all possible. -
-
-
-
-

Deprecated Language Features

- - link - -
- Use string methods instead of the string module - where possible. Use function call syntax instead - of apply. Use list comprehensions - and for loops instead of filter and - map when the function argument would have been an - inlined lambda anyway. Use for loops instead of - reduce. -
-
-
-
-

Lexical Scoping

- - link - -
- Okay to use. -
-
-
-
-

Function and Method Decorators

- - link - -
- Use decorators judiciously when there is a clear advantage. -
-
-
-
-

Threading

- - link - -
- Do not rely on the atomicity of built-in types. -
-
-
-
-

Power Features

- - link - -
- Avoid these features. -
-
-
-
-
-

Python Style Rules

-
-

Semicolons

- - link - -
- Do not terminate your lines with semi-colons and do not use - semi-colons to put two commands on the same line. -
-
-
-
-

Line length

- - link - -
- Maximum line length is 80 characters. -
-
-
-
-

Parentheses

- - link - -
- Use parentheses sparingly. -
-
-
-
-

Indentation

- - link - -
- Indent your code blocks with 4 spaces. -
-
-
-
-

Blank Lines

- - link - -
- Two blank lines between top-level definitions, one blank line - between method definitions. -
-
-
-
-

Whitespace

- - link - -
- Follow standard typographic rules for the use of spaces around - punctuation. -
-
-
- - -
-

Shebang Line

- - link - -
- Most .py files do not need to start with a - #! line. Start the main file of a - program with - #!/usr/bin/python with an optional single digit - 2 or 3 suffix per - PEP-394. -
-
-
- -
-

Comments

- - link - -
- Be sure to use the right style for module, function, method and in-line - comments. -
-
-
-
-

Classes

- - link - -
- If a class inherits from no other base classes, explicitly inherit - from object. This also applies to nested classes. -
-
-
-
-

Strings

- - link - -
- Use the format method or the % operator for - formatting strings, even when the parameters are all strings. Use your - best judgement to decide between + and % - (or format) though. -
-
-
-
-

Files and Sockets

- - link - -
- Explicitly close files and sockets when done with them. -
-
-
-
-

TODO Comments

- - link - -
- Use TODO comments for code that is temporary, a - short-term solution, or good-enough but not perfect. -
-
-
-
-

Imports formatting

- - link - -
- Imports should be on separate lines. -
-
-
-
-

Statements

- - link - -
- Generally only one statement per line. -
-
-
-
-

Access Control

- - link - -
- If an accessor function would be trivial you should use public variables - instead of accessor functions to avoid the extra cost of function - calls in Python. When more functionality is added you can use - property to keep the syntax consistent. -
-
-
-
-

Naming

- - link - -
- module_name, package_name, ClassName, - method_name, ExceptionName, - function_name, GLOBAL_CONSTANT_NAME, - global_var_name, instance_var_name, function_parameter_name, - local_var_name. -
-
-
-
-

Main

- - link - -
- Even a file meant to be used as a script should be importable and a - mere import should not have the side effect of executing the script's - main functionality. The main functionality should be in a main() - function. -
-
-
-
- -

Parting Words

-

- BE CONSISTENT. -

- -

- If you're editing code, take a few minutes to look at the code - around you and determine its style. If they use spaces around - all their arithmetic operators, you should too. If their - comments have little boxes of hash marks around them, make your - comments have little boxes of hash marks around them too. -

- -

- The point of having style guidelines is to have a common vocabulary - of coding so people can concentrate on what you're saying rather - than on how you're saying it. We present global style rules here so - people know the vocabulary, but local style is also important. If - code you add to a file looks drastically different from the existing - code around it, it throws readers out of their rhythm when they go to - read it. Avoid this. -

- - - -

-Revision 2.59 -

- - -
- Amit Patel
- Antoine Picard
- Eugene Jhong
- Gregory P. Smith
- Jeremy Hylton
- Matt Smart
- Mike Shields
- Shane Liebling
-
- - diff --git a/shell.xml b/shell.xml deleted file mode 100644 index 2e75857..0000000 --- a/shell.xml +++ /dev/null @@ -1,1152 +0,0 @@ - - - - -

- -Revision 1.26 -

- - -
- Paul Armstrong
- Too many more to mention
-
- - - - - - - - - - Bash is the only shell scripting language permitted for - executables. - - -

- Executables must start with #!/bin/bash and a minimum - number of flags. Use set to set shell options so that - calling your script as bash <script_name> - does not break its functionality. -

-

- Restricting all executable shell scripts to bash - gives us a consistent shell language that's installed on all our - machines. -

-

- The only exception to this is where you're forced to by whatever - you're coding for. One example of this is Solaris SVR4 packages which - require plain Bourne shell for any scripts. -

- -
- - - - Shell should only be used for small utilities or simple wrapper - scripts. - - -

- While shell scripting isn't a development language, it is used for - writing various utility scripts throughout Google. This - style guide is more a recognition of its use rather than - a suggestion that it be used for widespread deployment. -

-

- Some guidelines: -

    -
  • - If you're mostly calling other utilities and are doing relatively - little data manipulation, shell is an acceptable choice for the - task. -
  • -
  • - If performance matters, use something other than shell. -
  • -
  • - If you find you need to use arrays for anything more than - assignment of ${PIPESTATUS}, you should use Python. -
  • -
  • - If you are writing a script that is more than 100 lines long, you - should probably be writing it in Python instead. Bear in mind - that scripts grow. Rewrite your script in another language - early to avoid a time-consuming rewrite at a later date. -
  • -
-

- -
-
- -
- - - - - - Executables should have no extension (strongly preferred) or a - .sh extension. - Libraries must have a .sh extension and should not be - executable. - - -

- It is not necessary to know what language a program is written in when - executing it and shell doesn't require an extension so we prefer not to - use one for executables. -

-

- However, for libraries it's important to know what language it is and - sometimes there's a need to have similar libraries in different - languages. This allows library files with identical purposes but - different languages to be identically named except for the - language-specific suffix. -

- -
- - - - SUID and SGID are forbidden on shell scripts. - - -

- There are too many security issues with shell that make it nearly - impossible to secure sufficiently to allow SUID/SGID. While bash does - make it difficult to run SUID, it's still possible on some platforms - which is why we're being explicit about banning it. -

-

- Use sudo to provide elevated access if you need it. -

- -
- -
- - - - - - All error messages should go to STDERR. - - -

- This makes it easier - to separate normal status from actual issues. -

-

- A function to print out error messages along with other status - information is recommended. - - err() { - echo "[$(date +'%Y-%m-%dT%H:%M:%S%z')]: $@" >&2 - } - - if ! do_something; then - err "Unable to do_something" - exit "${E_DID_NOTHING}" - fi - -

- -
- -
- - - - - - Start each file with a description of its contents. - - -

- Every file must have a top-level comment including a brief overview of - its contents. - A - copyright notice - and author information are optional. -

-

- Example: - - #!/bin/bash - # - # Perform hot backups of Oracle databases. - -

- - - -
- - - - Any function that is not both obvious and short must be commented. Any - function in a library must be commented regardless of length or - complexity. - - -

- It should be possible for someone else to learn how to use your - program or to use a function in your library by reading the comments - (and self-help, if provided) without reading the code. -

-

- All function comments should contain: -

    -
  • - Description of the function -
  • -
  • - Global variables used and modified -
  • -
  • - Arguments taken -
  • -
  • - Returned values other than the default exit status of the last - command run -
  • -
-

-

- Example: - - #!/bin/bash - # - # Perform hot backups of Oracle databases. - - export PATH='/usr/xpg4/bin:/usr/bin:/opt/csw/bin:/opt/goog/bin' - - ####################################### - # Cleanup files from the backup dir - # Globals: - # BACKUP_DIR - # ORACLE_SID - # Arguments: - # None - # Returns: - # None - ####################################### - cleanup() { - ... - } - -

- -
- - - - Comment tricky, non-obvious, interesting or important parts of your code. - - -

- This follows general Google coding comment practice. Don't comment - everything. If there's a complex algorithm or you're doing something - out of the ordinary, put a short comment in. -

- -
- - - - Use TODO comments for code that is temporary, a short-term solution, or - good-enough but not perfect. - - -

- This matches the convention in the C++ - Guide. -

-

- TODOs should include the string TODO in all caps, followed by your - username in parentheses. A colon is optional. It's preferable to put a - bug/ticket number next to the TODO item as well. -

-

- Examples: - - - # TODO(mrmonkey): Handle the unlikely edge cases (bug ####) - -

- -
- -
- - -

- While you should follow the style that's already there for files that - you're modifying, the following are required for any new code. -

- - - - Indent 2 spaces. No tabs. - - -

- Use blank lines between blocks to improve readability. Indentation is - two spaces. Whatever you do, don't use tabs. For existing files, stay - faithful to the existing indentation. -

- -
- - - - Maximum line length is 80 characters. - - -

- If you have to write strings that are longer than 80 characters, this - should be done with a here document or an embedded newline if possible. - Literal strings that have to be longer than 80 chars and can't sensibly - be split are ok, but it's strongly preferred to find a way to make it - shorter. -

-

- - # DO use 'here document's - cat <<END; - I am an exceptionally long - string. - END - - # Embedded newlines are ok too - long_string="I am an exceptionally - long string." - -

- -
- - - - Pipelines should be split one per line if they don't all fit on one line. - - -

- If a pipeline all fits on one line, it should be on one line. -

-

- If not, it should be split at one pipe segment per line with the pipe - on the newline and a 2 space indent for the next section of the pipe. - This applies to a chain of commands combined using '|' as well as to - logical compounds using '||' and '&&'. - - # All fits on one line - command1 | command2 - - # Long commands - command1 \ - | command2 \ - | command3 \ - | command4 - -

- -
- - - - Put ; do and ; then on the same line as the - while, for or if. - - -

- Loops in shell are a bit different, but we follow the same principles - as with braces when declaring functions. That is: ; then - and ; do should be on the same line as the if/for/while. - else should be on its own line and closing statements - should be on their own line vertically aligned with the opening - statement. -

-

- Example: - - for dir in ${dirs_to_cleanup}; do - if [[ -d "${dir}/${ORACLE_SID}" ]]; then - log_date "Cleaning up old files in ${dir}/${ORACLE_SID}" - rm "${dir}/${ORACLE_SID}/"* - if [[ "$?" -ne 0 ]]; then - error_message - fi - else - mkdir -p "${dir}/${ORACLE_SID}" - if [[ "$?" -ne 0 ]]; then - error_message - fi - fi - done - -

- -
- - - -
    -
  • - Indent alternatives by 2 spaces. -
  • -
  • - A one-line alternative needs a space after the close parenthesis of - the pattern and before the ;;. -
  • -
  • - Long or multi-command alternatives should be split over multiple - lines with the pattern, actions, and ;; on separate - lines. -
  • -
-
- -

- The matching expressions are indented one level from the 'case' and - 'esac'. Multiline actions are indented another level. In general, - there is no need to quote match expressions. Pattern expressions - should not be preceded by an open parenthesis. Avoid the - ;& and ;;& notations. -

- - case "${expression}" in - a) - variable="..." - some_command "${variable}" "${other_expr}" ... - ;; - absolute) - actions="relative" - another_command "${actions}" "${other_expr}" ... - ;; - *) - error "Unexpected expression '${expression}'" - ;; - esac - -

- Simple commands may be put on the same line as the pattern and - ;; as long as the expression remains readable. This is - often appropriate for single-letter option processing. When the - actions don't fit on a single line, put the pattern on a line on its - own, then the actions, then ;; also on a line of its own. - When on the same line as the actions, use a space after the close - parenthesis of the pattern and another before the ;;. -

- - verbose='false' - aflag='' - bflag='' - files='' - while getopts 'abf:v' flag; do - case "${flag}" in - a) aflag='true' ;; - b) bflag='true' ;; - f) files="${OPTARG}" ;; - v) verbose='true' ;; - *) error "Unexpected option ${flag}" ;; - esac - done - - -
- - - - In order of precedence: Stay consistent with what you find; - quote your variables; - prefer "${var}" over "$var", but see details. - - -

- These are meant to be guidelines, as the topic seems too controversial for - a mandatory regulation. -
- They are listed in order of precedence. -

-
    -
  1. - Stay consistent with what you find for existing code. -
  2. -
  3. - Quote variables, see Quoting section below. -
  4. -
  5. -

    - Don't brace-quote single character shell - specials / positional parameters, unless strictly necessary - or avoiding deep confusion. -
    - Prefer brace-quoting all other variables. - - # Section of recommended cases. - - # Preferred style for 'special' variables: - echo "Positional: $1" "$5" "$3" - echo "Specials: !=$!, -=$-, _=$_. ?=$?, #=$# *=$* @=$@ \$=$$ ..." - - # Braces necessary: - echo "many parameters: ${10}" - - # Braces avoiding confusion: - # Output is "a0b0c0" - set -- a b c - echo "${1}0${2}0${3}0" - - # Preferred style for other variables: - echo "PATH=${PATH}, PWD=${PWD}, mine=${some_var}" - while read f; do - echo "file=${f}" - done < <(ls -l /tmp) - - # Section of discouraged cases - - # Unquoted vars, unbraced vars, brace-quoted single letter - # shell specials. - echo a=$avar "b=$bvar" "PID=${$}" "${1}" - - # Confusing use: this is expanded as "${1}0${2}0${3}0", - # not "${10}${20}${30} - set -- a b c - echo "$10$20$30" - -

    -
  6. -
- -
- - - -
    -
  • - Always quote strings containing variables, command substitutions, - spaces or shell meta characters, unless careful unquoted expansion - is required. -
  • -
  • - Prefer quoting strings that are "words" - (as opposed to command options or path names). -
  • -
  • - Never quote literal integers. -
  • -
  • - Be aware of the quoting rules for - pattern matches in [[. -
  • -
  • - Use "$@" unless you have a specific reason to use $*. -
  • -
-
- -

- - # 'Single' quotes indicate that no substitution is desired. - # "Double" quotes indicate that substitution is required/tolerated. - - # Simple examples - # "quote command substitutions" - flag="$(some_command and its args "$@" 'quoted separately')" - - # "quote variables" - echo "${flag}" - - # "never quote literal integers" - value=32 - # "quote command substitutions", even when you expect integers - number="$(generate_number)" - - # "prefer quoting words", not compulsory - readonly USE_INTEGER='true' - - # "quote shell meta characters" - echo 'Hello stranger, and well met. Earn lots of $$$' - echo "Process $$: Done making \$\$\$." - - # "command options or path names" - # ($1 is assumed to contain a value here) - grep -li Hugo /dev/null "$1" - - # Less simple examples - # "quote variables, unless proven false": ccs might be empty - git send-email --to "${reviewers}" ${ccs:+"--cc" "${ccs}"} - - # Positional parameter precautions: $1 might be unset - # Single quotes leave regex as-is. - grep -cP '([Ss]pecial|\|?characters*)$' ${1:+"$1"} - - # For passing on arguments, - # "$@" is right almost everytime, and - # $* is wrong almost everytime: - # - # * $* and $@ will split on spaces, clobbering up arguments - # that contain spaces and dropping empty strings; - # * "$@" will retain arguments as-is, so no args - # provided will result in no args being passed on; - # This is in most cases what you want to use for passing - # on arguments. - # * "$*" expands to one argument, with all args joined - # by (usually) spaces, - # so no args provided will result in one empty string - # being passed on. - # (Consult 'man bash' for the nit-grits ;-) - - set -- 1 "2 two" "3 three tres"; echo $# ; set -- "$*"; echo "$#, $@") - set -- 1 "2 two" "3 three tres"; echo $# ; set -- "$@"; echo "$#, $@") - -

- -
- -
- - - - - - Use $(command) instead of backticks. - - -

- Nested backticks require escaping the inner ones with \. - The $(command) format doesn't change when nested and is - easier to read. -

-

- Example: - - # This is preferred: - var="$(command "$(command1)")" - - # This is not: - var="`command \`command1\``" - -

- -
- - - - [[ ... ]] is preferred over [, - test and /usr/bin/[. - - -

- [[ ... ]] reduces errors as no pathname expansion or word - splitting takes place between [[ and ]] and - [[ ... ]] allows for regular expression matching where - [ ... ] does not. - - # This ensures the string on the left is made up of characters in the - # alnum character class followed by the string name. - # Note that the RHS should not be quoted here. - # For the gory details, see - # E14 at http://tiswww.case.edu/php/chet/bash/FAQ - if [[ "filename" =~ ^[[:alnum:]]+name ]]; then - echo "Match" - fi - - # This matches the exact pattern "f*" (Does not match in this case) - if [[ "filename" == "f*" ]]; then - echo "Match" - fi - - # This gives a "too many arguments" error as f* is expanded to the - # contents of the current directory - if [ "filename" == f* ]; then - echo "Match" - fi - -

- -
- - - - Use quotes rather than filler characters where possible. - - -

- Bash is smart enough to deal with an empty string in a test. So, given - that the code is much easier to read, use tests for empty/non-empty - strings or empty strings rather than filler characters. - - # Do this: - if [[ "${my_var}" = "some_string" ]]; then - do_something - fi - - # -z (string length is zero) and -n (string length is not zero) are - # preferred over testing for an empty string - if [[ -z "${my_var}" ]]; then - do_something - fi - - # This is OK (ensure quotes on the empty side), but not preferred: - if [[ "${my_var}" = "" ]]; then - do_something - fi - - # Not this: - if [[ "${my_var}X" = "some_stringX" ]]; then - do_something - fi - -

-

- To avoid confusion about what you're testing for, explicitly use - -z or -n. - - # Use this - if [[ -n "${my_var}" ]]; then - do_something - fi - - # Instead of this as errors can occur if ${my_var} expands to a test - # flag - if [[ "${my_var}" ]]; then - do_something - fi - -

- -
- - - - Use an explicit path when doing wildcard expansion of filenames. - - -

- As filenames can begin with a -, it's a lot safer to - expand wildcards with ./* instead of *. - - # Here's the contents of the directory: - # -f -r somedir somefile - - # This deletes almost everything in the directory by force - psa@bilby$ rm -v * - removed directory: `somedir' - removed `somefile' - - # As opposed to: - psa@bilby$ rm -v ./* - removed `./-f' - removed `./-r' - rm: cannot remove `./somedir': Is a directory - removed `./somefile' - -

- -
- - - - eval should be avoided. - - -

- Eval munges the input when used for assignment to variables and can set - variables without making it possible to check what those variables - were. - - # What does this set? - # Did it succeed? In part or whole? - eval $(set_my_variables) - - # What happens if one of the returned values has a space in it? - variable="$(eval some_function)" - -

- -
- - - - Use process substitution or for loops in preference to piping to while. - Variables modified in a while loop do not propagate to the parent - because the loop's commands run in a subshell. - - -

- The implicit subshell in a pipe to while can make it difficult to track - down bugs. - - last_line='NULL' - your_command | while read line; do - last_line="${line}" - done - - # This will output 'NULL' - echo "${last_line}" - -

-

- Use a for loop if you are confident that the input will not contain - spaces or special characters (usually, this means not user input). - - total=0 - # Only do this if there are no spaces in return values. - for value in $(command); do - total+="${value}" - done - -

-

- Using process substitution allows redirecting output but puts the - commands in an explicit subshell rather than the implicit subshell that - bash creates for the while loop. - - total=0 - last_file= - while read count filename; do - total+="${count}" - last_file="${filename}" - done < <(your_command | uniq -c) - - # This will output the second field of the last line of output from - # the command. - echo "Total = ${total}" - echo "Last one = ${last_file}" - -

-

- Use while loops where it is not necessary to pass complex results - to the parent shell - this is typically where some more complex - "parsing" is required. Beware that simple examples are probably - more easily done with a tool such as awk. This may also be useful - where you specifically don't want to change the parent scope variables. - - # Trivial implementation of awk expression: - # awk '$3 == "nfs" { print $2 " maps to " $1 }' /proc/mounts - cat /proc/mounts | while read src dest type opts rest; do - if [[ ${type} == "nfs" ]]; then - echo "NFS ${dest} maps to ${src}" - fi - done - -

- -
- -
- - - - - - Lower-case, with underscores to separate words. Separate libraries - with ::. Parentheses are required after the function name. - The keyword function is optional, but must be used - consistently throughout a project. - - -

- If you're writing single functions, use lowercase and separate words - with underscore. If you're writing a package, separate package names - with ::. Braces must be on the same line as the function - name (as with other languages at Google) and no space between the - function name and the parenthesis. - - # Single function - my_func() { - ... - } - - # Part of a package - mypackage::my_func() { - ... - } - -

-

- The function keyword is extraneous when "()" is present - after the function name, but enhances quick identification of - functions. -

- -
- - - - As for function names. - - -

- Variables names for loops should be similarly named for any variable - you're looping through. - - for zone in ${zones}; do - something_with "${zone}" - done - -

- -
- - - - All caps, separated with underscores, declared at the top of the file. - - -

- Constants and anything exported to the environment should be - capitalized. - - # Constant - readonly PATH_TO_FILES='/some/path' - - # Both constant and environment - declare -xr ORACLE_SID='PROD' - -

-

- Some things become constant at their first setting (for example, via - getopts). Thus, it's OK to set a constant in getopts or based on a - condition, but it should be made readonly immediately afterwards. - Note that declare doesn't operate on global variables - within functions, so readonly or export is - recommended instead. -

- - VERBOSE='false' - while getopts 'v' flag; do - case "${flag}" in - v) VERBOSE='true' ;; - esac - done - readonly VERBOSE - - -
- - - - Lowercase, with underscores to separate words if desired. - - -

- This is for consistency with other code styles in Google: - maketemplate or make_template but not - make-template. -

- -
- - - - Use readonly or declare -r to ensure they're - read only. - - -

- As globals are widely used in shell, it's important to catch errors - when working with them. When you declare a variable that is - meant to be read-only, make this explicit. - - zip_version="$(dpkg --status zip | grep Version: | cut -d ' ' -f 2)" - if [[ -z "${zip_version}" ]]; then - error_message - else - readonly zip_version - fi - -

- -
- - - - Declare function-specific variables with local. Declaration - and assignment should be on different lines. - - -

- Ensure that local variables are only seen inside a function and its - children by using local when declaring them. This avoids - polluting the global name space and inadvertently setting variables - that may have significance outside the function. -

-

- Declaration and assignment must be separate statements when - the assignment value is provided by a command substitution; as - the 'local' builtin does not propagate the exit code from the - command substitution. - - my_func2() { - local name="$1" - - # Separate lines for declaration and assignment: - local my_var - my_var="$(my_func)" || return - - # DO NOT do this: $? contains the exit code of 'local', not my_func - local my_var="$(my_func)" - [[ $? -eq 0 ]] || return - - ... - } - -

- -
- - - - Put all functions together in the file just below constants. Don't hide - executable code between functions. - - -

- If you've got functions, put them all together near the top of the - file. Only includes, set statements and setting constants - may be done before declaring functions. -

-

- Don't hide executable code between functions. Doing so makes the code - difficult to follow and results in nasty surprises when debugging. -

- -
- - - - A function called main is required for scripts long enough - to contain at least one other function. - - -

- In order to easily find the start of the program, put the main - program in a function called main as the bottom most - function. This provides consistency with the rest of the code base as - well as allowing you to define more variables as local - (which can't be done if the main code is not a function). The last - non-comment line in the file should be a call to main: - - main "$@" - -

-

- Obviously, for short scripts where it's just a linear flow, - main is overkill and so is not required. -

- -
- -
- - - - - - Always check return values and give informative return values. - - -

- For unpiped commands, use $? or check directly via an - if statement to keep it simple. -

-

- Example: - - if ! mv "${file_list}" "${dest_dir}/" ; then - echo "Unable to move ${file_list} to ${dest_dir}" >&2 - exit "${E_BAD_MOVE}" - fi - - # Or - mv "${file_list}" "${dest_dir}/" - if [[ "$?" -ne 0 ]]; then - echo "Unable to move ${file_list} to ${dest_dir}" >&2 - exit "${E_BAD_MOVE}" - fi - - -

-

- Bash also has the PIPESTATUS variable that allows checking - of the return code from all parts of a pipe. If it's only necessary to - check success or failure of the whole pipe, then the following is - acceptable: - - tar -cf - ./* | ( cd "${dir}" && tar -xf - ) - if [[ "${PIPESTATUS[0]}" -ne 0 || "${PIPESTATUS[1]}" -ne 0 ]]; then - echo "Unable to tar files to ${dir}" >&2 - fi - -

-

- However, as PIPESTATUS will be overwritten as soon as you - do any other command, if you need to act differently on errors based on - where it happened in the pipe, you'll need to assign - PIPESTATUS to another variable immediately after running - the command (don't forget that [ is a command and will - wipe out PIPESTATUS). - - tar -cf - ./* | ( cd "${DIR}" && tar -xf - ) - return_codes=(${PIPESTATUS[*]}) - if [[ "${return_codes[0]}" -ne 0 ]]; then - do_something - fi - if [[ "${return_codes[1]}" -ne 0 ]]; then - do_something_else - fi - -

- -
- - - - Given the choice between invoking a shell builtin and invoking a separate - process, choose the builtin. - - -

- We prefer the use of builtins such as the Parameter Expansion - functions in bash(1) as it's more robust and portable - (especially when compared to things like sed). -

-

- Example: - - # Prefer this: - addition=$((${X} + ${Y})) - substitution="${string/#foo/bar}" - - # Instead of this: - addition="$(expr ${X} + ${Y})" - substitution="$(echo "${string}" | sed -e 's/^foo/bar/')" - -

- -
- -
- - -

- Use common sense and BE CONSISTENT. -

-

- Please take a few minutes to read the Parting Words section at the bottom - of the C++ Guide. -

-
- -

-Revision 1.26 -

- -
diff --git a/cpplint/README b/src/README similarity index 100% rename from cpplint/README rename to src/README diff --git a/cpplint/cpplint.py b/src/cpplint.py similarity index 100% rename from cpplint/cpplint.py rename to src/cpplint.py diff --git a/cpplint/cpplint_test_header.h b/src/cpplint_test_header.h similarity index 100% rename from cpplint/cpplint_test_header.h rename to src/cpplint_test_header.h diff --git a/cpplint/cpplint_unittest.py b/src/cpplint_unittest.py similarity index 100% rename from cpplint/cpplint_unittest.py rename to src/cpplint_unittest.py diff --git a/styleguide.css b/styleguide.css deleted file mode 100644 index adba8f3..0000000 --- a/styleguide.css +++ /dev/null @@ -1,147 +0,0 @@ -body { - background-color: #fff; - color: #333; - font-family: sans-serif; - font-size: 10pt; - margin-right: 100px; - margin-left: 100px; -} - -h1, h2, h3, h4, h5, h6, .toc_title { - color: #06c; - margin-top: 2em; - margin-bottom: 1em; -} - -h1 { - text-align: center; - font-size: 18pt; -} - -h2, .toc_title { - font-weight: bold; - font-size: 12pt; - margin-left: -40px; -} - -h3, h4, h5, h6 { - font-size: 10pt; - margin-left: -20px; -} - -.toc_category, .toc_stylepoint { - font-size: 10pt; - padding-top: .3em; - padding-bottom: .3em; -} - -table { - border-collapse: collapse; -} - -td, th { - border: 1px solid #ccc; - padding: 2px 12px; - font-size: 10pt; -} - -.toc td, .toc th { - border-width: 1px 5px; -} - -code, samp, var { - color: #060; -} - -pre { - font-size: 10pt; - display: block; - color: #060; - background-color: #f8fff8; - border-color: #f0fff0; - border-style: solid; - border-top-width: 1px; - border-bottom-width: 1px; - border-right-width: 1px; - border-left-width: 5px; - padding-left: 12px; - padding-right: 12px; - padding-top: 4px; - padding-bottom: 4px; -} - -pre.badcode { - color: #c00; - background-color: #fff8f8; - border-color: #fff0f0; -} - -.showhide_button { - float: left; - cursor: pointer; - border-width: 1px; - border-style: solid; - border-color: #ddd #aaa #aaa #ddd; - padding: 0 3px 1px; - margin: 0 4px 8px 0; - border-radius: 3px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; -} - -.link_button { - float: left; - display: none; - background-color: #f8f8ff; - border-color: #f0f0ff; - border-style: solid; - border-width: 1px; - font-size: 75%; - margin-top: 0; - margin-left: -50px; - padding: 4px; - border-radius: 3px; - -webkit-border-radius: 3px; - -moz-border-radius: 3px; -} - -address { - text-align: right; -} - -hr { - margin-top: 3.5em; - border-width: 1px; - color: #fff; -} - -.stylepoint_section { - display: block; - margin-bottom: 1em; - color: #5588ff; - font-family: sans-serif; - font-size: 90%; - font-weight: bold; - margin-left: -2%; -} - -.stylepoint_subsection { - color: #667799; - font-family: sans-serif; - font-size: 90%; - font-weight: bold; - margin-left: -1%; -} - -.stylepoint_subsubsection { - color: #667799; - font-family: sans-serif; - font-size: 80%; - font-weight: bold; - margin-left: 0; -} - -.revision { - text-align: right; -} - diff --git a/styleguide.xsl b/styleguide.xsl deleted file mode 100644 index 09a9b95..0000000 --- a/styleguide.xsl +++ /dev/null @@ -1,924 +0,0 @@ - - - - - - - - - - - - - - - - - - <xsl:value-of select="@title"/> - - - - - - - -

- - - -
- - - - - - - - - - - - -
-

- Each style point has a summary for which additional information is available - by toggling the accompanying arrow button that looks this way: - - . - You may toggle all summaries with the big arrow button: -

-
- - - - - - - Toggle all summaries -
-
- - - - -
- - -

Parting Words

- -
- - -
- -

- - - - - - - - -

- -
-
- - -
- - - - - - - - - - - - - - - - -

- - - - - -

- - - - - javascript:ShowHideByName(' - - ') - - - - ?showone=# - link - - - - - - - - - - - -
-
- - - -
- - -
-
- - - -
- -
- - - - - display: inline - display: none - - - -
-
-
- - -

- - Definition: - -

-
- - -

- - Pros: - -

-
- - -

- - Cons: - -

-
- - -

- - Decision: - -

-
- - -

- -

TODO: - -
-

-
- - -

- - - -

-
- - -

- - - -

-
- - -
- -

-           
-           
-           
-           
-             
-               
-               
-             
-           
-         
-
-
- - -
- -

-           
-           
-           
-           
-             
-               
-               
-             
-           
-         
-
-
- - -
- -

-             
-           
-
-
- - -
- -

-                             
-                           
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - -
-
Table of Contents
- - - - - - - -
- - -
- - - - - - # - - - - - - - - - -
-
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - _ - - - - - - - - - - - - - - -
- diff --git a/vimscriptfull.xml b/vimscriptfull.xml deleted file mode 100644 index 8d233f1..0000000 --- a/vimscriptfull.xml +++ /dev/null @@ -1,1534 +0,0 @@ - - - -

- - Revision 1.1 -

- - -
- Nate Soares
- Joshua Hoak
- David Barnett
-
- - - -

- This is the in-depth vimscript guide. If you're just a casual user - looking to write a plugin, the - abbreviated style guide is for you. -

-

- This rather rotund guide dives into justifications and clarifications. - It provides an idealized set of rules that are rather too draconian to - push on casual scripters. -

- -

- It's for users who want to know why certain decisions were made in the - abbreviated guide and who want to learn a thing or two about using - vimscript safely. -

-

- Fair warning: Vimscript is a maddening abyss. When you gaze into it, it - gazes also into you. Proceed with caution. -

-
-
- - -

- Vim is highly configurable. Users can change many of the default - settings, including the case sensitivity, the regular expression rules, - the substitution rules, and more. In order for your vimscript to work - for all users, follow these guidelines: -

- -

- In general, guard all commands and functions against user settings. -

- -
- - -

- All other language features are fair game. -

-
- - - - - - Separate library-providing plugins from command-providing plugins. - - -

- Many plugins provide either user functionality (commands, - autocommands, etc) or an API (of autoloaded functions) but not both. - This separation is encouraged, as it allows other plugins to pull in a - library without also pulling in commands, setting changes, and other - plugin functionality that affects the end user. -

- -
- - - - Don't clobber user settings. Provide as much configurability as - possible: that's what Vim's all about. - - -
    -
  • - Use maktaba flags for plugin configuration. Users can configure them - using the :Glaive command. - -
  • -
  • - Check if configuration variables exist before setting them. - - if !exists('g:myplugin_option') - let g:myplugin_option = 1 - endif - -
  • -
- -
-
- -

- Follow google-wide style conventions. Mimic google python style when - in doubt. -

- - - - - - Use vimdoc. - - -

- Provide help files generated by - vimdoc. Write - documentation in .vim files in conformance with the vimdoc standards - and include fields like "description" and "author" in the - addon-info.json file (see the - VAM documentation). -

- -
- - - - Follow google-wide conventions. - - -
    -
  • - Use two spaces for indents. -
  • -
  • - Do not use tabs. -
  • -
  • - Use spaces around operators except for arguments to commands. -
      -
    • - Using spaces around operators for commands is often invalid - syntax. This is inconsistently enforced by vimscript. To be - safe, always omit whitespace around arguments to commands. -
    • -
    • - - let s:variable = "concatenated " . "strings" - command -range=% MyCommand - - - let s:variable="concatenated "."strings" - command -range = % MyCommand - -
    • -
    -
  • -
  • - Do not introduce trailing whitespace. -
      -
    • - You need not go out of your way to remove it. -
    • -
    -
  • -
  • - Restrict lines to 80 columns wide. -
  • -
  • - Indent continued lines by two tabs (four spaces). -
  • -
  • - Do not waste whitespace aligning common segments of similar - commands. It is both difficult and expensive to maintain. -
      -
    • - - command -bang MyCommand call myplugin#foo() - command MyCommand2 call myplugin#bar() - - - command -bang MyCommand call myplugin#foo() - command MyCommand2 call myplugin#bar() - -
    • -
    -
  • -
- -
    -
  • - Prefer line continuations on semantic boundaries. -
      -
    • - - command SomeLongCommand - \ call some#function() - - - command SomeLongCommand call - \ some#function() - -
    • -
    • - Use your best judgement. -
    • -
    -
  • -
  • - Place one space after the backslash denoting a line continuation. -
      -
    • - When continuing a multi-line command a pipe can be substituted - for this space as necessary, as follows: - - autocommand BufEnter <buffer> - \ if !empty(s:var) - \| call some#function() - \|else - \| call some#function(s:var) - \|endif - -
    • -
    -
  • -
  • - Do not continue multi-line commands when you can avoid it. Prefer - function calls. -
  • -
-
- -
    -
  • - Place a space after the " before the comment text. -
      -
    • - - " I am a line comment. - call call(s:my_function) - -
    • -
    -
  • -
  • - Do not use inline comments. -
      -
    • - Some commands treat them as comments and others as unclosed - quotes. There are many edge cases. It's difficult to get - right and difficult to maintain. -
    • -
    • - Where you would use an inline comment, put a line comment on - the line above. -
    • -
    -
  • -
  • - When leaving blank lines in comments, include the quote in the - blank line. -
      -
    • - - " I am one continuous - " - " comment block - -
    • -
    -
  • -
-
- -
- - - -

- plugin-names-like-this, - FunctionNamesLikeThis, - CommandNamesLikeThis, - augroup_names_like_this, - variable_names_like_this. -

-

- Prefix all variables with their scope. -

-
- -
    -
  • - variable_names_like_this -
      -
    • - FuncRef variables count as functions and should be named like - functions. -
    • -
    • - This (pathological) convention is enforced by vim itself. -
    • -
    -
  • -
  • - Prefix global variables with g: -
      -
    • - Vimscript allows you to create global variables without - prefixing them. -
    • -
    • - It is very bad practice to introduce non-prefixed global - variables into scope. -
    • -
    • - Global variables should only be used for plugin configuration. -
    • -
    • - This does not apply to functions defined in - autoload directories. -
    • -
    -
  • -
  • - Prefix script-local variables with s: -
      -
    • - This prevents namespace collisions between plugins. -
    • -
    • - This also applies to script-local functions. -
    • -
    -
  • -
  • - Prefix function arguments with a: -
      -
    • - This is enforced by vim itself. -
    • -
    -
  • -
  • - Prefix function-local variables with l: -
      -
    • - This is not enforced by vimscript but is good practice. -
    • -
    • - It helps you remember that all other variables must be - prefixed with scope. -
    • -
    • - l: disambiguates between function-local and - vim-predefined variables. For example, count - refers to - v:count, not l:count. -
    • -
    • - It future proofs your scripts against the introduction of new - vim-predefined variables. -
    • -
    -
  • -
  • - Prefix pre-defined vim variables with v: -
      -
    • - This is not enforced by vimscript but is good practice. -
    • -
    • - It provides context as to where the (undeclared) variable is - coming from. -
    • -
    • - It reminds you that the variable can not be assigned to. -
    • -
    -
  • -
  • - Prefix buffer-local variables with b: -
      -
    • - This is useful for plugins that keep per-buffer state. -
    • -
    -
  • -
- -
- - - - Prefer single quotes. - - -

- Prefer single quoted strings. Specifically, in order of precedence: -

-
    -
  • - Always use single quotes for regular expressions. -
      -
    • - '\s*' is not the same as "\s*" -
    • -
    • - Single quotes will prevent the need for excessive backslashes. -
    • -
    • - Double single quotes escape to one single quote in single - quoted strings: 'example ('')' represents the - string - example (') -
    • -
    -
  • -
  • - If your string requires escape characters (\n, - \t, etc.) use double quotes. -
      -
    • - Escapes can not be expressed in single quoted strings. -
    • -
    • - Remember that '\n' in a regex does not represent a - newline, but rather "\n". You only need to use double quotes - when you want to embed the represented character itself (e.g. a - newline) in the string. -
    • -
    -
  • -
  • - If your string contains no escapes nor single quotes, use single - quoted strings. -
      -
    • - Most strings in vimscript are regexes, so this provides maximum - consistency. -
    • -
    -
  • -
  • - If your non-regex string contains single quotes but no double - quotes, use double quotes. -
      -
    • - Don't bother escaping strings if you don't have to. -
    • -
    • - This is similar to the python string rules. -
    • -
    -
  • -
  • - If your string contains both single and double quotes, use whichever - quoting style requires less escaping. -
      -
    • - Break ties in favor of single quotes. -
    • -
    -
  • -
- -
- - - - Prefer long names. Set settings locally. - - -
    -
  • - Prefer long names of built in settings (i.e. tabstop - over - ts). -
  • -
  • - Set local settings unless you explicitly want to set global - settings. -
      -
    • - Use setlocal and &l: instead of - set and &. -
    • -
    -
  • -
- -
-
- -

- Vim plugins should provide any or all of the following: - Commands, Autocommands, - Functions, Statusline Flags, and - Mappings. -

- - - -
    -
  • Define in plugin/commands.vim.
  • -
  • CommandNamesLikeThis.
  • -
  • Prefer semantic names to a unified prefix.
  • -
  • Do not use [!]
  • -
  • Extract logic into functions.
  • -
-
- -
    -
  • - CommandNamesLikeThis -
  • -
  • - Commands should be defined in one block with no whitespace between - them. -
      -
    • - Name commands semantically at the expense of a common prefix. -
    • -
    • - - command WhitespaceFixTrailing - command WhitespaceFixIndentation - - - command FixTrailingWhitespace - command FixIndentation - -
    • -
    -
  • -
  • - Use command without a bang. -
      -
    • - This notifies users to command name conflicts immediately at - startup. -
    • -
    • - Command name collisions are an error and should not fail - silently. -
    • -
    • - Plugins are guarded against re-entry, so a single vim session - should never attempt to re-define defined commands. -
    • -
    -
  • -
  • - Do not put logic in commands. -
      -
    • - Delegate to functions instead. -
    • -
    • - Pass non-argument command parameters (<bang>, - <register>, etc.) before argument parameters - (<f-args>, etc.). -
    • -
    • - Otherwise variable-length argument functions are difficult to - implement. -
    • -
    -
  • -
  • - Do not autoload commands. -
      -
    • - Autoloaded commands will not be available until after a function - in the same file is called. -
    • -
    • - Commands intended to be used in the .vimrc should be defined in - a instant/commands.vim file in plugins using - maktaba, or explicitly installed via an autoload function in - non-maktaba plugins. -
    • -
    -
  • -
- -
    -
  • - Pass <bang> to functions with - '<bang>' == '!'. -
      -
    • - The function should receive a boolean parameter, not a string. -
    • -
    -
  • -
-
- -
- - - -
    -
  • Define in plugin/autocmds.vim.
  • -
  • Use augroups.
  • -
  • augroup_names_like_this.
  • -
  • Clear the augroup first.
  • -
  • Extract logic into functions.
  • -
-
- -
    -
  • - All autocommands should be defined in the - plugin/autocmds.vim file. -
      -
    • - This allows users to disable your autocommands with - Glaive myplugin !plugin[autocmds]. -
    • -
    -
  • -
  • - Declare all autocommands in an augroup block. -
      -
    • - This allows your autocommands to be cleared with - autocmd!. -
    • -
    • - If your plugin only has one augroup, the - augroup name should be the same as your plugin - name, with underscores in place of any hyphens. -
    • -
    • - Otherwise augroup names should start with your - plugin name followed by an underscore. -
    • -
    -
  • -
  • - Do not put logic in autocommands. -
      -
    • - Delegate to functions instead. -
    • -
    -
  • -
  • - When creating a new augroup, clear it with - autocmd! -
      -
    • - This allows your plugins to be re-enterable. -
    • -
    -
  • -
- -
- - - -
    -
  • FunctionNamesLikeThis.
  • -
  • Autoload all functions.
  • -
  • Prefix script-local functions with s:
  • -
  • Use [!].
  • -
  • Use [abort].
  • -
-
- -
    -
  • - FunctionNamesLikeThis -
  • -
  • - Prefix all script-local functions with s: -
  • -
  • - Do not provide global functions. Use autoloaded functions instead. -
  • -
  • - Place two blank lines between top-level functions. -
  • -
  • - Declare all functions with abort. -
      -
    • - If you do not do this, the function's behavior depends upon - whether it is called within a try..endtry block - somewhere on the stack. -
    • -
    • - The abort keyword forces the function to act - consistently. -
    • -
    • - Without it, the function may (or may not) attempt to continue - execution after an error occurs. -
    • -
    -
  • -
  • - Use function! with a bang. -
      -
    • - This allows developers to re-source their scripts and have the - functions reloaded without complaint. -
    • -
    • - Function names should never collide because functions should - always be either script-local or defined in an - autoload directory. -
    • -
    • - Failing to use a bang in any function in an autoload file will - lead to cryptic errors if vim tries to re-source the file - (e.g., if you refer to an nonexistent autoload function). -
    • -
    -
  • -
  • - Use ... for optional arguments, not for lists of - arguments. -
      -
    • - Vimscript functions take at most 20 arguments. -
    • -
    • - Lists have no such length restriction. -
    • -
    • - Your function is likely to break when given too many arguments - if you use ... for a list of arguments. -
    • -
    -
  • -
  • - Throw exceptions rather than printing errors. -
      -
    • - Printed errors can not be caught. -
    • -
    • - Top-level functions expecting errors may catch them and print - error messages, but even those should throw their own errors - when they choke. -
    • -
    -
  • -
- -
- - - -
    -
  • - Provide opt-in key mappings in plugin/mappings.vim. -
  • -
  • - <Plug> mappings can be defined in - plugin/plugs.vim (unlike mappings.vim, plugs.vim is - opt-out). -
  • -
-
- -
    -
  • - Define key mappings in plugin/mappings.vim, using - maktaba#plugin#MapPrefix to get a prefix. -
      -
    • - Mappings defined in the special plugin/mappings.vim - file will be disabled by default (by the standard - maktaba#plugin#Enter() boilerplate). -
    • -
    • - Users can enable key mappings with - Glaive myplugin plugin[mappings]. -
    • -
    -
  • -
  • - Make all mappings with <unique>. -
      -
    • - This will inform the user when they have a mapping conflict - instead of silently clobbering their existing mappings. -
    • -
    -
  • -
  • - You may provide pseudo-mappings using <Plug> and - your plugin's name in plugin/plugs.vim (separate from - standard key mappings). -
      -
    • - <Plug> is a sequence which can not be typed. -
    • -
    • - You can do something like - noremap <Plug>namespace#MappingName - some_key_sequence - and then users can do - noremap <leader>x - <Plug>namespace#MappingName - to take advantage of your pseudo-mapping. -
    • -
    • - Pseudo-mappings should not be in - plugin/mappings.vim or they will be disabled by - default. -
    • -
    • - Such pseudo-mappings should be named <Plug> - followed by your plugin name, a pound sign, and a unique mapping - name (CamelCased like a function). -
    • -
    -
  • -
  • - Always use the noremap family of commands. Never use - the map family. -
      -
    • - map depends upon the user's existing mappings, and - could do anything. -
    • -
    -
  • -
  • - Only use noremap for commands that both make a motion - and take a range. -
      -
    • - noremap makes mappings in normal, visual, and - operator-pending modes. -
    • -
    • - If you don't want all these use nnoremap - onoremap or vnoremap explicitly. -
    • -
    -
  • -
  • - Always use <SID> in place of s: when - accessing script locals in mappings. -
      -
    • - Using s: will often fail as the mapping attempts to - type a literal s and colon. -
    • -
    -
  • -
- -
-
- - - - Declare dependencies in addon-info.json and use maktaba. - - -

- Declaring dependencies in addon-info.json allows conformant plugin - managers (like VAM) to ensure dependencies are installed. See the - VAM documentation for details. -

-

- Calling maktaba#library#Require from dependent code at - runtime ensures that dependencies have been installed and that they - don't include unsafe non-library files. -

- -
- - - - Use <plugin-name>#status#Status() or its - finer-grained variants to provide statusline flags. - - -

- Following is a convention for exposing statusline flags to the user. A - plugin should never modify the user's statusline except for when that - is the only purpose of the plugin (powerline, etc.). -

-
    -
  • - Provide the - Info, - Alert, - Warning, and - Error functions under the - <plugin-name>#status namespace. -
  • -
  • - Info should provide information about the - state of the buffer. -
      -
    • - Example: The current git branch. -
    • -
    -
  • -
  • - Alert should provide a quiet reminder - that the buffer is non-standard. -
      -
    • - Example: The readonly setting is on. -
    • -
    -
  • -
  • - Warning should provide a warning about - the current state of the buffer. -
      -
    • - Example: The file has been edited elsewhere. -
    • -
    -
  • -
  • - Error should bring to attention a loud - issue with the buffer. -
      -
    • - Example: The file does not pass the syntax checker. -
    • -
    -
  • -
  • - By following these conventions, users can easily build up their own - statusline customizing the verbosity and colors to their tastes. -
  • -
  • - All functions should take no arguments and should return either - empty strings or strings enclosed by square brackets, e.g. - [Google]. For example: -
      -
    • - A trailing whitespace plugin might return [$] if - the file contains trailing whitespace -
    • -
    • - A prose writing plugin might return [write] if vim - is in writing mode. -
    • -
    -
  • -
  • - Consider providing the - <plugin-name>#status#Status function. -
      -
    • - It should return the first non-empty of Error, - Warning, Alert, or Info. -
    • -
    • - This is useful for users who want only the most relevant flag - and do not have a colored statusline. -
    • -
    -
  • -
- -
-
- -

- These are commands which can only be used by a limited number of - plugins, and should not in general be used by yours. -

- -
- -

- Lay out plugin/ files in the following sections, if - applicable, separated by two blank lines: -

- -

- Lay out autoload/ files in the following sections, if - applicable, separated by two blank lines: -

- -

- This is recommended convention and is not enforced. -

- -
- - -

- Use the following shortcuts: -

- - -
- -

- This section plumbs some of the darker corners of vimscript, explaining - the language pathologies that you wish you didn't have to know. - -

- - - - If you don't support vi-compatibility mode, fail gracefully. - - -

- When compatible is set, many vim features are not - available. The vim feature which most commonly affects vimscript - authors is line continuations. -

-

- If you want your plugin to work in vim with vi compatibility on, you - will need to save the compatibility options at the beginning of each - plugin file, clear them, and restore them at the end of each plugin - file. See :help use-cpo-save for details. -

-

- Plugins that depend on maktaba generally don't need to worry about - compatible mode since maktaba currently just disables it, printing a - warning. -

- -
-
- -

- Revision 1.1 -

- - -
- Nate Soares
- Joshua Hoak
- David Barnett
-
-
diff --git a/vimscriptguide.xml b/vimscriptguide.xml deleted file mode 100644 index d16a3d7..0000000 --- a/vimscriptguide.xml +++ /dev/null @@ -1,412 +0,0 @@ - - - -

- - Revision 1.1 -

- - -
- Nate Soares
- Joshua Hoak
- David Barnett
-
- - - -

- This is a casual version of the vimscript style guide, because - vimscript is a casual language. When submitting vim plugin code, you - must adhere to these rules. For clarifications, justifications, and - explanations about the finer points of vimscript, please refer to the - heavy guide. -

-
-
- - -

- It's hard to get vimscript right. Many commands depend upon the user's - settings. By following these guidelines, you can hope to make your - scripts portable. -

- - Prefer single quoted strings - -

- Double quoted strings are semantically different in vimscript, and - you probably don't want them (they break regexes). -

-

- Use double quoted strings when you need an escape sequence (such as - "\n") or if you know it doesn't matter and you need to - embed single quotes. -

- -
- - - Use the =~# or =~? operator families over the - =~ family. - - -

- The matching behavior depends upon the user's ignorecase and smartcase - settings and on whether you compare them with the =~, - =~#, or =~? family of operators. Use the - =~# and =~? operator families explicitly - when comparing strings unless you explicitly need to honor the user's - case sensitivity settings. -

- -
- - Prefix all regexes with \m\C. - -

- In addition to the case sensitivity settings, regex behavior depends - upon the user's nomagic setting. To make regexes act like nomagic and - noignorecase are set, prepend all regexes with \m\C. -

-

- You are welcome to use other magic levels (\v) and case - sensitivities (\c) so long as they are intentional and - explicit. -

- -
- - Avoid commands with unintended side effects. - -

- Avoid using :s[ubstitute] as it moves the cursor and - prints error messages. Prefer functions (such as - search()) better suited to scripts. -

-

- For many vim commands, functions exist that do the same thing with - fewer side effects. See :help functions() for a list of - built-in functions. -

- -
- - Avoid commands that rely on user settings. - -

- Always use normal! instead of normal. The - latter depends upon the user's key mappings and could do anything. -

-

- Avoid :s[ubstitute], as its behavior depends upon a - number of local settings. -

-

- The same applies to other commands not listed here. -

- -
- - Match error codes, not error text. - -

Error text may be locale dependant.

- -
-
- - - - - - Message the user infrequently. - -

- Loud scripts are annoying. Message the user only when: -

    -
  • A long-running process has kicked off.
  • -
  • An error has occurred.
  • -
-

- -
- - Use strict and explicit checks where possible. - -

- Vimscript has unsafe, unintuitive behavior when dealing with some - types. For instance, 0 == 'foo' evaluates to true. -

-

- Use strict comparison operators where possible. When comparing against - a string literal, use the is# operator. Otherwise, prefer - maktaba#value#IsEqual or check type() - explicitly. -

-

- Check variable types explicitly before using them. Use functions from - maktaba#ensure, or check maktaba#value or - type() and throw your own errors. -

-

- Use :unlet for variables that may change types, - particularly those assigned inside loops. -

- -
- - Use sparingly. - -

- Use python only when it provides critical functionality, for example - when writing threaded code. -

- -
- - Use vimscript instead. - -

- Avoid using other scripting languages such as ruby and lua. We can - not guarantee that the end user's vim has been compiled with support - for non-vimscript languages. -

- -
- - - Use maktaba. - - -

- maktaba removes boilerplate, including: -

    -
  • Plugin creation
  • -
  • Error handling
  • -
  • Dependency checking
  • -
-

- -
- - Organize functionality into modular plugins - -

- Group your functionality as a plugin, unified in one directory (or - code repository) which shares your plugin's name (with a "vim-" prefix - or ".vim" suffix if desired). It should be split into plugin/, - autoload/, etc. subdirectories as necessary, and it should declare - metadata in the addon-info.json format (see the - VAM documentation for details). -

- -
- - - In the autoload/ directory, defined with [!] and - [abort]. - - -

- Autoloading allows functions to be loaded on demand, which makes - startuptime faster and enforces function namespacing. -

-

- Script-local functions are welcome, but should also live in autoload/ - and be called by autoloaded functions. -

-

- Non-library plugins should expose commands instead of functions. - Command logic should be extracted into functions and autoloaded. -

-

- [!] allows developers to reload their functions - without complaint. -

-

- [abort] forces the function to halt when it encounters - an error. -

- -
- - - In the plugin/commands.vim or under the ftplugin/ directory, defined - without [!]. - - -

- General commands go in plugin/commands.vim. - Filetype-specific commands go in ftplugin/. -

-

- Excluding [!] prevents your plugin from silently - clobbering existing commands. Command conflicts should be resolved by - the user. -

- -
- - - Place them in plugin/autocmds.vim, within augroups. - - -

- Place all autocommands in augroups. -

-

- The augroup name should be unique. It should either be, or be prefixed - with, the plugin name. -

-

- Clear the augroup with autocmd! before defining new - autocommands in the augroup. This makes your plugin re-entrable. -

- -
- - - Place them in plugin/mappings.vim, using - maktaba#plugin#MapPrefix to get a prefix. - - -

- All key mappings should be defined in - plugin/mappings.vim. -

-

- Partial mappings (see :help using-<Plug>.) should be defined in - plugin/plugs.vim. -

- -
- - Change settings locally - -

- Use :setlocal and &l: instead of - :set and & unless you have explicit - reason to do otherwise. -

- -
-
- - -

- Follow google style conventions. When in doubt, treat vimscript style - like python style. -

- - - - Similar to python. - -
-
-
- -
    -
  • Use two spaces for indents
  • -
  • Do not use tabs
  • -
  • Use spaces around operators -

    This does not apply to arguments to commands.

    - - let s:variable = "concatenated " . "strings" - command -range=% MyCommand - -
  • -
  • Do not introduce trailing whitespace -

    You need not go out of your way to remove it.

    -

    - Trailing whitespace is allowed in mappings which prep commands - for user input, such as - "noremap <leader>gf :grep -f ". -

    -
  • -
  • Restrict lines to 80 columns wide
  • -
  • Indent continued lines by four spaces
  • -
  • Do not align arguments of commands - - command -bang MyCommand call myplugin#foo() - command MyCommand2 call myplugin#bar() - - - command -bang MyCommand call myplugin#foo() - command MyCommand2 call myplugin#bar() - -
  • -
- -
- - - -

- In general, use - plugin-names-like-this, - FunctionNamesLikeThis, - CommandNamesLikeThis, - augroup_names_like_this, - variable_names_like_this. -

-

Always prefix variables with their scope.

-
- - -

Keep them short and sweet.

- -
- -

Prefix script-local functions with s:

-

Autoloaded functions may not have a scope prefix.

-

- Do not create global functions. Use autoloaded functions - instead. -

-
- -

Prefer succinct command names over common command prefixes.

-
- -

Augroup names count as variables for naming purposes.

-
- -
    -
  • Global variables with g:
  • -
  • Script-local variables with s:
  • -
  • Function arguments with a:
  • -
  • Function-local variables with l:
  • -
  • Vim-predefined variables with v:
  • -
  • Buffer-local variables with b:
  • -
-

- g:, s:, and a: must always - be used. -

-

- b: changes the variable semantics; use it when you - want buffer-local semantics. -

-

- l: and v: should be used for consistency, - future proofing, and to avoid subtle bugs. They are not strictly - required. Add them in new code but don’t go out of your way to add - them elsewhere. -

-
- -
-
- -

- Revision 1.1 -

- - -
- Nate Soares
- Joshua Hoak
- David Barnett
-
-
diff --git a/xmlstyle.html b/xmlstyle.html deleted file mode 100644 index ba4a376..0000000 --- a/xmlstyle.html +++ /dev/null @@ -1,681 +0,0 @@ - - - - - -
-
- -

-Google XML Document Format Style Guide

Version 1.0
Copyright Google 2008

Introduction

This document provides a set of guidelines for general use when designing new XML document formats (and to some extent XML documents as well; see Section 11).  Document formats usually include both formal parts (DTDs, schemas) and parts expressed in normative English prose.

These guidelines apply to new designs, and are not intended to force retroactive changes in existing designs.  When participating in the creation of public or private document format designs, the guidelines may be helpful but should not control the group consensus.

This guide is meant for the design of XML that is to be generated and consumed by machines rather than human beings.  Its rules are not applicable to formats such as XHTML (which should be formatted as much like HTML as possible) or ODF which are meant to express rich text.  A document that includes embedded content in XHTML or some other rich-text format, but also contains purely machine-interpretable portions, SHOULD follow this style guide for the machine-interpretable portions.  It also does not affect XML document formats that are created by translations from proto buffers or through some other type of format.

Brief rationales have been added to most of the guidelines.  They are maintained in the same document in hopes that they won't get out of date, but they are not considered normative.

The terms MUST, MUST NOT, SHOULD, SHOULD NOT, and MAY are used in this document in the sense of RFC 2119.
 

1. To design or not to design, that is the question

  1. Attempt to reuse existing XML formats whenever possible, especially those which allow extensions.  Creating an entirely new format should be done only with care and consideration; read Tim Bray's warnings first.  Try to get wide review of your format, from outside your organization as well, if possible.  [Rationale: New document formats have a cost: they must be reviewed, documented, and learned by users.]

  2. If you are reusing or extending an existing format, make sensible - -use of the prescribed elements and attributes, especially any that are -required.  Don't completely repurpose them, but do try to see how they -might be used in creative ways if the vanilla semantics aren't -suitable.  As a last resort when an element or attribute is required by the format but is not appropriate for your use case, use some -fixed string as its value.  [Rationale:  Markup reuse is good, markup abuse is bad.]

  3. When extending formats, use the implicit style of the existing format, even if it contradicts this guide.  [Rationale: Consistency.]

2. Schemas

  1. Document formats SHOULD be expressed using a schema language.  [Rationale: Clarity and machine-checkability.]

  2. The schema language SHOULD be RELAX NG compact syntax.  Embedded Schematron rules MAY be added to the schema for additional fine control.  [Rationale: - -RELAX NG is the most flexible schema language, with very few arbitrary -restrictions on designs.  The compact syntax is quite easy to read and -learn, and can be converted one-to-one to and from the XML syntax when -necessary.  Schematron handles arbitrary cross-element and -cross-attribute constraints nicely.]

  3. Schemas SHOULD use the "Salami Slice" style (one rule per element).  Schemas MAY use the "Russian Doll" style (schema resembles document) if they are short and simple.  The "Venetian Blind" style (one rule per element type) is unsuited to RELAX NG and SHOULD NOT be used.

  4. Regular expressions SHOULD be provided to assist in validating complex values.

  5. DTDs and/or W3C XML Schemas MAY be provided for compatibility with existing products, tools, or users.  [Rationale: We can't change the world all at once.]

3. Namespaces

  1. Element names MUST be in a namespace, except -when extending pre-existing document types that do not use namespaces.  - -A default namespace SHOULD be used.  [Rationale: Namespace-free -documents are obsolete; every set of names should be in some -namespace.  Using a default namespace improves readability.]

  2. Attribute -names SHOULD NOT be in a namespace unless they are drawn from a foreign -document type or are meant to be used in foreign document types.  [Rationale: Attribute names in a namespace must always have a prefix, which is annoying to type and hard to read.]

    -
  3. Namespace names are HTTP URIs.  Namespace names SHOULD take the form http://example.com/whatever/year, where whatever is a unique value based on the name of the document type, and year - -is the year the namespace was created.  There may be additional URI-path parts -before the year.  [Rationale: Existing convention.  Providing the year allows for the possible recycling of code names.]

  4. Namespaces MUST NOT be changed unless the semantics of particular elements or attributes has changed in drastically incompatible ways.  [Rationale: Changing the namespace requires changing all client code.]

  5. Namespace prefixes SHOULD be short (but not so short that they are likely to be conflict with another project).  Single-letter prefixes MUST NOT be used. Prefixes SHOULD contain only lower-case ASCII letters.  [Rationale: Ease of typing and absence of encoding compatibility problems.]

- -

4. Names and enumerated values

Note: "Names" refers to the names of elements, attributes, and enumerated values.

  1. All names MUST use lowerCamelCase. That is, they start with an initial lower-case letter, then each new word within the name starts with an initial capital letter. [Rationale: Adopting a single style provides consistency, which helps when referring to names since the capitalization is known and so does not have to be remembered.  It matches Java style, and other languages can be dealt with using automated name conversion.]

  2. Names MUST contain only ASCII letters and digits.  -[Rationale: Ease of typing and absence of encoding compatibility problems.]

  3. Names SHOULD NOT exceed 25 characters. Longer names SHOULD be -avoided by devising concise and informative names.  If a name can only remain within this limit by becoming obscure, the limit SHOULD be ignored.  [Rationale: Longer names are awkward to use and require additional bandwidth.]

  4. Published standard abbreviations, if sufficiently well-known, MAY be employed in constructing names. Ad hoc abbreviations MUST NOT be used.  Acronyms MUST be treated as words for camel-casing purposes: informationUri, not informationURI. [Rationale:  An abbreviation that is well known -to one community is often incomprehensible to others who need to use -the same document format (and who do understand the full name); treating an acronym as a word makes it easier to see where the word boundaries are.]


- -

-5. Elements

  1. All elements MUST contain either nothing, character content, or child elements.  Mixed content MUST NOT be used.  [Rationale: Many XML data models don't handle mixed content properly, and its use makes the element order-dependent.  As always, textual formats are not covered by this rule.]

  2. XML elements that merely wrap repeating child elements SHOULD NOT be used.  [Rationale: They are not used in Atom and add nothing.]
- -


6. Attributes

  1. Document formats MUST NOT depend on the order of attributes in a start-tag.  [Rationale: Few XML parsers report the order, and it is not part of the XML Infoset.]

  2. Elements SHOULD NOT be overloaded with too many attributes (no more -than 10 as a rule of thumb).  Instead, use child elements to -encapsulate closely related attributes.  [Rationale: This -approach maintains the built-in extensibility that XML provides with -elements, and is useful for providing forward compatibility as a -specification evolves.]

  3. Attributes MUST NOT be used to hold values in which line breaks are significant.  [Rationale: Such line breaks are converted to spaces by conformant XML parsers.]

  4. Document formats MUST allow either single or double quotation marks around attribute values.  [Rationale:  XML parsers don't report the difference.]
- -


-

-

-7. Values

  1. Numeric values SHOULD be 32-bit signed integers, 64-bit signed integers, or 64-bit IEEE doubles, all expressed in base 10.  These correspond to the XML Schema types xsd:int, xsd:long, and xsd:double respectively.  If required in particular cases, xsd:integer (unlimited-precision integer) values MAY also be used.  [Rationale: There are far too many numeric types in XML Schema: these provide a reasonable subset.] 

  2. - -Boolean values SHOULD NOT be used (use enumerations instead).  If they must be used, they MUST be expressed as true or false, corresponding to a subset of the XML Schema type xsd:boolean.  The alternative xsd:boolean values 1 and 0 MUST NOT be used.  [Rationale: Boolean arguments are not extensible.  The additional flexibility of allowing numeric values is not abstracted away by any parser.]

  3. Dates should be represented using RFC 3339 format, a subset of both -ISO 8601 format and XML Schema xsd:dateTime format.  UTC times SHOULD be used rather than local times.  - -[Rationale: There are far too many date formats and time zones, although it is recognized that sometimes local time preserves important information.]

  4. Embedded syntax in character content and attribute values SHOULD NOT be -used.  Syntax in values means XML tools are largely useless.  Syntaxes such as  dates, URIs, and -XPath expressions are exceptions.  [Rationale:  -Users should be able to process XML documents using only an XML parser -without requiring additional special-purpose parsers, which are easy to -get wrong.]

  5. Be careful with whitespace in values.  XML parsers don't strip whitespace in elements, but do convert newlines to spaces in attributes.  However, application frameworks may do more aggressive whitespace stripping.  Your document format SHOULD give rules for whitespace stripping.
- -


-

-

-

8. Key-value pairs

  1. -Simple key-value pairs SHOULD be represented with an empty element whose name represents the key, with the value attribute containing the value. Elements that have a value attribute MAY also have a unit attribute to specify the unit of a measured value.  For physical measurements, the SI system SHOULD be used.  [Rationale: - -Simplicity and design consistency.  Keeping the value in an attribute -hides it from the user, since displaying just the value without the key is not useful.]

  2. If the number of possible keys is very large or unbounded, key-value pairs MAY be represented by a single generic element with key, value, and optional unit and scheme -attributes (which serve to discriminate keys from different domains).  -In that case, also provide (not necessarily in the same document) a -list of keys with human-readable explanations.

9. Binary data

Note: There are no hard and fast rules about whether binary data should be included as part of an XML document or not.  If it's too large, it's probably better to link to it.


  1. Binary data MUST NOT be included directly as-is in XML documents, but MUST be encoded using Base64 encoding.  [Rationale: XML does not allow arbitrary binary bytes.]

  2. - -The line breaks required by Base64 MAY be omitted.  [Rationale: The line breaks are meant to keep plain text lines short, but XML is not really plain text.]

  3. An attribute named xsi:type with value xs:base64Binary MAY be attached to this element to signal that the Base64 format is in use.  [Rationale: Opaque blobs should have decoding instructions attached.]

-

10. Processing instructions

  1. New processing instructions MUST NOT be created except in order to specify purely local processing conventions, and SHOULD be avoided altogether.  Existing standardized processing instructions MAY be used.  [Rationale: Processing instructions fit awkwardly into XML data models and can always be replaced by elements; they exist primarily to avoid breaking backward compatibility.]

 

- -

-

 

11. Representation of XML document instances

Note:  These points are only guidelines, as the format of program-created instances will often be outside the programmer's control (for example, when an XML serialization library is being used).  In no case should XML parsers rely on these guidelines being followed.  Use standard XML parsers, not hand-rolled hacks.


  1. The character encoding used SHOULD be UTF-8.  Exceptions should require extremely compelling circumstances.  [Rationale: UTF-8 is universal and in common use.]

  2. Namespaces SHOULD be declared in the root element of a document wherever possible.  [Rationale: Clarity and consistency.]

  3. The mapping of namespace URIs to prefixes SHOULD remain constant throughout the document, and SHOULD also be used in documentation of the design.  [Rationale: Clarity and consistency.]

  4. Well-known prefixes such as html: (for XHTML), dc: (for Dublin Core metadata), and xs: (for XML Schema) should be used for standard namespaces.  [Rationale: Human readability.]

  5. Redundant whitespace in a tag SHOULD NOT be -used.  Use one space before each attribute in a start-tag; if the start -tag is too long, the space MAY be replaced by a newline.  [Rationale: Consistency and conciseness.]

  6. Empty elements MAY be expressed as empty tags or a start-tag -immediately followed by an end-tag. No distinction should be made -between these two formats by any application.  [Rationale: They are not distinguished by XML parsers.]

  7. Documents MAY be pretty-printed using 2-space indentation for child -elements.  Elements that contain character content SHOULD NOT be -wrapped.  Long start-tags MAY be broken using newlines (possibly with extra indentation) after any attribute value except the last.  [Rationale: General compatibility with our style.  Wrapping character content affects its value.]

  8. Attribute values MAY be surrounded with either quotation marks or apostrophes. -Specifications MUST NOT require or forbid the use of either form.  &apos; and &quot; may be freely used to escape each type of quote.  [Rationale: No XML parsers report the distinction.]

    - -
  9. Comments MUST NOT be used to carry real data.  Comments MAY be used to contain TODOs in hand-written XML.  Comments SHOULD NOT be used at all in publicly transmitted documents. [Rationale:  Comments are often discarded by parsers.]

  10. If comments are nevertheless used, they SHOULD appear only in the document prolog or in elements that -contain child elements.  If pretty-printing is required, pretty-print -comments like elements, but with line wrapping.  Comments SHOULD NOT -appear in elements that contain character content.  [Rationale:  Whitespace in and around comments improves readability, but embedding a -comment in character content can lead to confusion about what -whitespace is or is not in the content.]

  11. Comments SHOULD have whitespace following <!-- and preceding -->.  [Rationale: Readability.]

  12. CDATA sections MAY be used; they are equivalent to the use of &amp; and &lt;.  Specifications MUST NOT require or forbid the use of CDATA sections.  [Rationale: Few XML parsers report the distinction, and combinations of CDATA and text are often reported as single objects anyway.]

  13. Entity references other than the XML standard entity references &amp;, &lt;, &gt;, &quot;, and &apos; MUST NOT be used.  Character references MAY be used, but actual characters are preferred, unless the character encoding is not UTF-8.  As usual, textual formats are exempt from this rule.
- -

 

-

-

-



-12. Elements vs. Attributes -

-

-Note:  There are no hard and fast rules for deciding when to use attributes and when to use elements.  Here are some of the considerations that designers should take into account; no rationales are given. -

-

-12.1. General points:
-

- -
    -
  1. -

    -Attributes are more restrictive than elements, and all designs have some elements, so an all-element design is simplest -- which is not the same as best. -

    -

    -
    -

    -
  2. -
  3. -

    -In a tree-style data model, elements are typically represented internally as nodes, which use more memory than the strings used to represent attributes.  Sometimes the nodes are of different application-specific classes, which in many languages also takes up memory to represent the classes. -

    -

    -
    - -

    -
  4. -
  5. -

    -When streaming, elements are processed one at a time (possibly even piece by piece, depending on the XML parser you are using), whereas all the attributes of an element and their values are reported at once, which costs memory, particularly if some attribute values are very long. -

    -

    -
    -

    -
  6. -
  7. -

    -Both element content and attribute values need to be escaped appropriately, so escaping should not be a consideration in the design. -

    -

    -
    -

    - -
  8. -
  9. -

    -In some programming languages and libraries, processing elements is easier; in others, processing attributes is easier.  Beware of using ease of processing as a criterion.  In particular, XSLT can handle either with equal facility. -

    -

    -
    -

    -
  10. -
  11. -

    -If a piece of data should usually be shown to the user, consider using an element; if not, consider using an attribute.  (This rule is often violated for one reason or another.) - -

    -

    -
    -

    -
  12. -
  13. -

    -If you are extending an existing schema, do things by analogy to how things are done in that schema. -

    -

    -
    -

    -
  14. -
  15. -

    -Sensible schema languages, meaning RELAX NG and Schematron, treat elements and attributes symmetrically.  Older and cruder schema languages such as DTDs and XML Schema, tend to have better support for elements. - -

    -
  16. -
-

-

-

-12.2 Using elements
-

-
    -
  1. -

    -If something might appear more than once in a data model, use an element rather than introducing attributes with names like foo1, foo2, foo3 .... -

    - -

    -
    -

    -
  2. -
  3. -

    -Use elements to represent a piece of information that can be considered an independent object and when the information is related via a parent/child relationship to another piece of information. -

    -

    -
    -

    -
  4. -
  5. -

    -Use elements when data incorporates strict typing or relationship rules. -

    -

    - -
    -

    -
  6. -
  7. -

    -If order matters between two pieces of data, use elements for them: attributes are inherently unordered. -

    -

    -
    -

    -
  8. -
  9. -

    -If a piece of data has, or might have, its own substructure, use it in an element: getting substructure into an attribute is always messy.  Similarly, if the data is a constituent part of some larger piece of data, put it in an element. -

    - -

    -
    -

    -
  10. -
  11. -

    -An exception to the previous rule: multiple whitespace-separated tokens can safely be put in an attribute.  In principle, the separator can be anything, but schema-language validators are currently only able to handle whitespace, so it's best to stick with that. -

    -

    -
    -

    -
  12. -
  13. -

    -If a piece of data extends across multiple lines, use an element: XML parsers will change newlines in attribute values into spaces. - -

  14. If a piece of data is very large, use an element so that its content can be streamed.

  15. -
  16. -

    -If a piece of data is in a natural language, put it in an element so you can use the xml:lang attribute to label the language being used.  Some kinds of natural-language text, like Japanese, often make use annotations that are conventionally represented using child elements; right-to-left languages like Hebrew and Arabic may similarly require child elements to manage bidirectionality properly. -

    - -

    -

    -
  17. -
-

-12.3 Using attributes
-

-
    -
  1. -

    -If the data is a code from an enumeration, code list, or controlled vocabulary, put it in an attribute if possible.  For example, language tags, currency codes, medical diagnostic codes, etc. are best handled as attributes. -

    -

    -
    - -

    -
  2. -
  3. -

    -If a piece of data is really metadata on some other piece of data (for example, representing a class or role that the main data serves,  or specifying a method of processing it), put it in an attribute if possible. -

    -

    -
    -

    -
  4. -
  5. -

    -In particular, if a piece of data is an ID for some other piece of data, or a reference to such an ID, put the identifying piece in an attribute.  When it's an ID, use the name xml:id for the attribute. - -

    -

    -
    -

    -
  6. -
  7. -

    -Hypertext references are conventionally put in href attributes. -

    -

    -
    -

    -
  8. -
  9. - -

    -If a piece of data is applicable to an element and any descendant elements unless it is overridden in some of them, it is conventional to put it in an attribute.  Well-known examples are xml:lang, xml:space, xml:base, and namespace declarations. -

    -

    -
    -

    -
  10. -
  11. -

    - -If terseness is really the most important thing, use attributes, but consider gzip compression instead -- it works very well on documents with highly repetitive structures.

  12. -

-

13. Parting words -

-

-

-Use common sense and BE CONSISTENT.   Design for extensibility.  You are gonna need it.  [Rationale: Long and painful experience.]


- -

-When designing XML formats, take a few minutes to look at other formats and determine their style.  The point of having style guidelines is so that people can concentrate on what you are -saying, rather than on how you are saying it.

-
-Break ANY OR ALL of these rules (yes, even the ones that say MUST) rather than create a crude, arbitrary, disgusting mess of a design if that's what following them slavishly would give you.  In particular, random mixtures of attributes and child elements are hard to follow and hard to use, though it often makes good sense to use both when the data clearly fall into two different groups such as simple/complex or metadata/data. -

-

-
-Newbies always ask: -

- -

-    "Elements or attributes? -

-

-Which will serve me best?" -

-

-    Those who know roar like lions; -

-

-    Wise hackers smile like tigers. -

-

-                    --a tanka, or extended haiku - -

-
-

-
-

-
[TODO: if a registry of schemas is set up, add a link to it]




-
-