2006-04-27 Jonathan Chambers <jonathan.chambers@ansys.com>
[mcs.git] / CodingStyle
blob9ca84959917b39c875168e8a4dce2d382cc3bbc0
1 * Coding Style for the Mono C# source code.
3 * Class Libraries and Assembly Layout
5         The class libraries are grouped together in the assemblies
6         they belong.
7         
8         Each directory here represents an assembly, and inside each
9         directory we divide the code based on the namespace they
10         implement.
11         
12         In addition, each assembly directory contains a Test directory
13         that holds the NUnit tests for that assembly.
14         
15         We use a new build system which is described by various README
16         files in mcs/build
17         
18         The build process typically builds an assembly, but in some
19         cases it also builds special versions of the assemblies
20         intended to be used for testing.
22 * Missing implementation bits
24         If you implement a class and you are missing implementation bits,
25         please use the attribute [MonoTODO].  This attribute can be used
26         to programatically generate our status web pages:
28         [MonoTODO]
29         int MyFunction ()
30         {
31                 throw new NotImplementedException ();
32         }
34 * Supporting .NET 1.2, .NET 1.1 and .NET 1.0 builds
36         The defines NET_1_1 and NET_2_0 are used to include
37         features.   When NET_2_0 is defined, it also implies that the
38         NET_1_1 is defined.
40         To have code which is only available in an old version, use ONLY_1_0,
41         ONLY_1_1
43 * Tagging buggy code
45         If there is a bug in your implementation tag the problem by using
46         the word "FIXME" in the code, together with a description of the 
47         problem.
49         Do not use XXX or obscure descriptions, because otherwise people
50         will not be able to understand what you mean.
52 * Tagging Problematic specs.
54         If the documentation and the Microsoft implementation do
55         differ (you wrote a test case to prove this), I suggest that you edit
56         the file `mcs/class/doc/API-notes' so we can keep track of these problems
57         and submit our comments to ECMA or Microsoft and seek clarification.
59         Sometimes the documentation might be buggy, and sometimes the implementation
60         might be buggy.  Lets try to identify and pinpoint which one
61         is the correct one.
63         Sometimes the specification will be lame (consider Version.ToString (fieldCount)
64         where there is no way of knowing how many fields are available, making the API
65         not only stupid, but leading to unreliable code).
67         In those cases, use the keyword "LAMESPEC".
68         
70 * Coding considerations and style.
72         In order to keep the code consistent, please use the following
73         conventions.  From here on `good' and `bad' are used to attribute
74         things that would make the coding style match, or not match.  It is not
75         a judgement call on your coding abilities, but more of a style and 
76         look call.  Please try to follow these guidelines to ensure prettiness.
78         Use 8 space tabs for writing your code (hopefully we can keep
79         this consistent).  If you are modifying someone else's code, try
80         to keep the coding style similar.
82         Since we are using 8-space tabs, you might want to consider the Linus
83         Torvals trick to reduce code nesting.  Many times in a loop, you will
84         find yourself doing a test, and if the test is true, you will nest.
85         Many times this can be changed.  Example:
88                 for (i = 0; i < 10; i++) {
89                         if (something (i)) {
90                                 do_more ();
91                         }
92                 }
94         This take precious space, instead write it like this:
96                 for (i = 0; i < 10; i++) {
97                         if (!something (i))
98                                 continue;
99                         do_more ();
100                 }
102 * Performance and readability
104         It is more important to be correct than to be fast.
106         It is more important to be maintainable than to be fast.
108         Fast code that is difficult to maintain is likely going to
109         be looked down upon.
111 * Style Guidelines
113                 * Use a space before an opening parenthesis when calling
114                   functions, or indexing, like this:
116                         method (a);
117                         b [10];
119                 * Do not put a space after the opening parenthesis and the 
120                   closing one, ie:
122                         good: method (a);       array [10];
124                         bad:  method ( a );     array[ 10 ];
126                 * Inside a code block, put the opening brace on the same line
127                   as the statement:
129                         good:
130                                 if (a) {
131                                         code ();
132                                         code ();
133                                 }
135                         bad:
136                                 if (a) 
137                                 {
138                                         code ();
139                                         code ();
140                                 }
142                 * Avoid using unecessary open/close braces, vertical space
143                   is usually limited:
145                         good:
146                                 if (a)
147                                         code ();
149                         bad:
150                                 if (a) {
151                                         code ();
152                                 }
154                 * When defining a method, use the C style for brace placement, 
155                   that means, use a new line for the brace, like this:
157                         good:
158                                 void Method ()
159                                 {
160                                 }
162                         bad:
163                                 void Method () {
164                                 }
166                 * Properties and indexers are an exception, keep the
167                   brace on the same line as the property declaration.
168                   Rationale: this makes it visually
169                   simple to distinguish them.
171                         good:
172                                 int Property {
173                                         get {
174                                                 return value;
175                                         }
176                                 }
178                         bad:
179                                 int Property 
180                                 {
181                                         get {
182                                                 return value;
183                                         }
184                                 }
186                   Notice how the accessor "get" also keeps its brace on the same
187                   line.
189                   For very small properties, you can compress things:
191                         ok:
192                                 int Property {
193                                         get { return value; }
194                                         set { x = value; }
195                                 }
197                 * Use white space in expressions liberally, except in the presence
198                   of parenthesis:
200                         good:
202                                 if (a + 5 > method (blah () + 4))
204                         bad:
205                                 if (a+5>method(blah()+4))
207                 * For any new files, please use a descriptive introduction, like
208                   this:
210                         //
211                         // System.Comment.cs: Handles comments in System files.
212                         //
213                         // Author:
214                         //   Juan Perez (juan@address.com)
215                         //
216                         // (C) 2002 Address, Inc (http://www.address.com)
217                         //
219                 * If you are modyfing someone else's code, and your contribution
220                   is significant, please add yourself to the Authors list.
222                 * Switch statements have the case at the same indentation as the
223                   switch:
225                         switch (x) {
226                         case 'a':
227                                 ...
228                         case 'b':
229                                 ...
230                         }
232                 * Argument names should use the camel casing for
233                   identifiers, like this:
235                         good:
236                                 void Method (string myArgument)
238                         bad:
239                                 void Method (string lpstrArgument)
240                                 void Method (string my_string)
242                 * Empty methods: They should have the body of code using two    
243                   lines, in consistency with the rest:
245                         good:
246                                 void EmptyMethod ()
247                                 {
248                                 }
250                         bad:
251                                 void EmptyMethod () {}
253                                 void EmptyMethod () 
254                                 {}
255                 
256                 * Line length: The line length for C# source code is 134 columns.
259                   If your function declaration arguments go beyond
260                   this point, please align your arguments to match the
261                   opening brace, like this:
263                         void Function (int arg, string argb,
264                                        int argc)
265                         {
266                         }
267          
268                   When invoking functions, the rule is different, the
269                   arguments are not aligned with the previous
270                   argument, instead they begin at the tabbed position,
271                   like this:
272           
273                         void M ()
274                         {
275                                 MethodCall ("Very long string that will force",
276                                         "Next argument on the 8-tab pos",
277                                         "Just like this one")
278                 
279                         }
281                 * Variable declaration indentation.
283                   Sometimes it is convenient to indent the variables to make the code
284                   look pretier, but do not add gratuitous space, try to use the minimally
285                   necessary space, for example:
287                   Good:
289                         void Method ()
290                         {
291                                 string b;
292                                 int    a;
293                                 byte   c;
294                         }
296                   Bad:
298                         void Method ()
299                         {
300                                 string          b;
301                                 int             a;
302                                 byte            c;
303                         }
305                 * Braces and the `else' clause
307                   If there are braces closing or opening next to the else clause,
308                   they go on the same line as the word `else', for example:
310                   Good:
312                         if (..) {
314                         } else {
315                 
316                         }
317         
318                   Bad:
320                         if (..) {
322                         } 
323                         else {
324                 
325                         }
327                   Bad:
329                         if (..) {
331                         } else 
332                         {               
333                         }
335                   Bad:
337                         if (..) {
339                         } 
340                         else 
341                         {
342                 
343                         }
345 * RCS and CVS tags
347         Some users like to use the special RCS/CVS tags in their
348         source code: $id$, $log$ and so on.  
350         The use of these is not permitted on the Mono source code
351         repository.   This metadata belongs on a ChangeLog or in the
352         SVN metadata. 
354 * File formats
356         Historically our repository has used a mix of line-endings,
357         this is a mistake that we are trying hard to fix.
359         For existing files, please make sure that you do not convert 
360         the file, as that causes us to loose precious history (the
361         full file is commited).
363         For new files that you create, please make sure that you use
364         Subversion's support for mapping the line endings
365         automatically, after adding your file:
367                 $ svn add file.cs
369         Execute this command:
371                 $ svn propset svn:eol-style native file.cs
373         Which will make the file automatically receive the proper
374         treatment from that point on.
376         Please verify before commiting that your changes wont loose
377         history, you can do this by running:
379                 $ svn diff
381         And examining the output.
383 * ChangeLogs
385         ChangeLogs are the files that we use to track the project
386         history.  ChangeLogs are found one per directory, or in small
387         projects, one per project.
389         The format looks like this:
391         2004-11-19  Raja R Harinath  <rharinath@novell.com>
393                 * Makefile (%-profiles): Go through an intermediate
394                 set of rules.  Move body to ...
395                 (profiles-do--%): ... this.
396                 (profiles-do--run-test): Customized rule that usefully
397                 runs with 'make -j' and 'make -k'.
398                 (profiles-do--all, profile-do--%--all): Orchestrate
399                 the bootstrap process.
401                 * file.cs (MainForm): Updated version.
403         The date, author, email address in the first line.
405         From that point on a list of changes in a file-by-file basis,
406         describing what changes were done.
407                 
408 * Warnings
410         Avoid commiting code with warnings to the repository, the use
411         of #pragmas to disable warnings is strongly discouraged, but
412         can be used on unique cases.  Please justify the use of the
413         warning ignore clause on a comment.
415         Do not commit changes to the Makefiles that removes warnings,
416         if anything warnings should be eliminated one at a time, and
417         if not possible, they must be flagged.
420 * Examples:
422 class X : Y {
424         bool Method (int argument_1, int argument_2)
425         {
426                 if (argument_1 == argument_2)
427                         throw new Exception (Locale.GetText ("They are equal!");
429                 if (argument_1 < argument_2) {
430                         if (argument_1 * 3 > 4)
431                                 return true;
432                         else
433                                 return false;
434                 }
436                 //
437                 // This sample helps keep your sanity while using 8-spaces for tabs
438                 // 
439                 VeryLongIdentifierWhichTakesManyArguments (
440                         Argument1, Argument2, Argument3,
441                         NestedCallHere (
442                                 MoreNested));
443         }
445         bool MyProperty {
446                 get {
447                         return x;
448                 }
450                 set {
451                         x = value;
452                 }
453         }
455         void AnotherMethod () 
456         {
457                 if ((a + 5) != 4) {
458                 }
460                 while (blah) {
461                         if (a)
462                                 continue;
463                         b++;
464                 }
465         }
467