From 8fcd8065be865ae8db20da5977df9117747ec448 Mon Sep 17 00:00:00 2001 From: "Jason Shirk (POWERSHELL)" Date: Thu, 21 Jul 2016 23:12:46 -0700 Subject: [PATCH] Coding guidelines first cut --- docs/dev-process/coding-guidelines.md | 88 ++++++++++++++++++++++++--- 1 file changed, 80 insertions(+), 8 deletions(-) diff --git a/docs/dev-process/coding-guidelines.md b/docs/dev-process/coding-guidelines.md index 110d38457d..da26e8012e 100644 --- a/docs/dev-process/coding-guidelines.md +++ b/docs/dev-process/coding-guidelines.md @@ -1,9 +1,81 @@ -author: Jason -> file encodings! -> performance standards -> platform support -> how to write portable code, tests, UI across platforms -> #ifdef -> note about internal APIs? -> avoid take dependency on code via reflection +# C# Coding Style + +## Coding Conventions + +As a general rule, our coding convention is to follow the style of the surrounding code. +Avoid reformatting any code when submitting a PR as it obscures the functional changes of your change. +We run the [.NET code formatter tool](https://github.com/dotnet/codeformatter) regularly help keep consistent formatting. + +A basic rule of formatting is to use "Visual Studio defaults". +Here are some general guidelines + +* No tabs, indent 4 spaces. +* Braces usually go on their own line, + with the exception of single line statements that are properly indented. +* Use `_camelCase` for instance fields, + use `readonly` where possible. +* Use of `this` is neither encouraged nor discouraged. +* Avoid more than one blank empty line. +* Public members should use [doc comments](https://msdn.microsoft.com/en-us/library/b2s063f7.aspx), + internal members may use doc comments but it is not enouraged. +* Public members in a namespace that ends with `Internal`, + for example `System.Management.Automation.Internal` are not considered a supported public API. + Such members are necessarily public as implementation details in code shared between C# and PowerShell script, + or must be available publically by generated code. +* File encoding should be ASCII (preferred) + or UTF8 (with BOM) if absolutely necessary. + +## Preprocessor defines + +There are 3 primary preprocessor macros we define during builds: + +* DEBUG - guard code that should not be included in release builds +* CORECLR - guard code that differs between Full CLR and CoreCLR +* UNIX - guard code that is specific to Unix (Linux and Mac OS X) + +Any other preprocessor defines found in the source are used for one-off custom builds, +typically to help debug specific scenarios. + +### Runtimes + +The PowerShell repo is used to build PowerShell targeting CoreCLR as well as CLR 4.5. + +Code under !CORECLR must build against CLR 4.5. +We will not accept changes that require a later version of the full CLR. +In extremely rare cases, we may use reflection to use an API in a later version of the CLR, +but the feature must robustly handle running with CLR 4.5. + +We may reject code under !CORECLR without explanation because +we do not support installation or testing of such code in this repo. +All new features should support CoreCLR. + +## Performance considerations + +PowerShell has a lot of performance sensitive code as well as a lot of inefficient code. +We have some guidelines that we typically apply widely even in less important code +because code and patterns are copied we want certain inefficient code to stay out of the performance critical code. + +Some general guidelines: + +* Avoid LINQ - it can create lots of avoidable garbage +* Prefer `for` and `foreach`, + with a slight preference towards `for` when you're uncertain if `foreach` allocates an iterator. +* Avoid `params` arrays, prefer adding overloads with 1, 2, 3, and maybe more parameters. +* Be aware of APIs such as `String.Split(params char[])` that do not provide overloads to avoid array allocation. + When calling such APIs, reuse a static array when possible. +* Avoid unnecessary memory allocation in a loop. + Move the memory allocation outside the loop if possible. + +## Portable code + +The PowerShell code base started on Windows and depends on many Win32 APIs through P/Invoke. +Going forward, we try to depend on CoreCLR to handle platform differences, +so avoid adding new P/Invoke calls where a suitable alternative exists in .NET. + +Try to minimize the use of `#if UNIX` and `#if CORECLR`. +When absolutely necessary, avoid duplicating more code than necessary, +and instead prefer introducing helper functions to minimize the platform differences. + +When adding platform dependent code, prefer preprocessor directives +over runtime checks. \ No newline at end of file