1# JerryScript Coding Standards 2 3This text is a brief overview of JerryScript Coding Standards. 4Each rule starts with a short description followed by several 5examples. We believe examples are better than long explanations. 6Please follow these guidelines when you submit a patch for 7review. 8 9## General rules 10 11* Indentation is two spaces. 12* Tab characters are not allowed. 13* Maximum line length is 120 characters (excluding newline). 14* No trailing white space is allowed. 15* Run `tools/run-tests.py --check-vera` to check several 16 of the coding conventions automatically. 17 18## Comments 19 20Only block comments (`/* */`) are allowed in JerryScript. 21Comments should be complete sentences (e.g. start with an 22upper case letter), except for return value, field and 23argument descriptions (see the exceptions below). The 24text part of a comment should focus on explaining *why* 25the code is doing something rather than *what* the code 26is doing. 27 28```diff 29+++ Good +++ 30``` 31 32```c 33 /* A perfect comment. */ 34 35 /* A perfect multiline 36 * comment. Each line should 37 * start with an asterisk. */ 38``` 39 40```diff 41--- Bad --- 42``` 43 44```c 45 // Double slash comments are not allowed. 46 47 /* not a complete sentence */ 48 49 /* A bad mulitiline 50 comment. */ 51``` 52 53All types, constants and functions require a description in 54JerryScript. These comments should start with `/**`. The starting 55`/**` and ending `*/` must be on separate lines. 56 57```diff 58+++ Good +++ 59``` 60 61```c 62/** 63 * A correct description. 64 */ 65``` 66 67```diff 68--- Bad --- 69``` 70 71```c 72/** An incorrect description. */ 73``` 74 75## Preprocessor defines 76 77The name of a preprocessor macro must be an uppercase string 78and these macros must be preceded by a description. 79Abbreviations are allowed but not preferred in new code. 80 81```diff 82+++ Good +++ 83``` 84 85```c 86/** 87 * Short description about the constant. 88 */ 89#define JERRY_VALUE_SEVEN 7 90 91/** 92 * Short description about the macro function. 93 */ 94#define JERRY_ADD_TWO_NUMBERS(arg1, arg2) \ 95 ((arg1) + (arg2)) 96 97/** 98 * Although this is correct, a reviewer might request 99 * to change NUMS to NUMBERS. Hence it is recommended 100 * to use NUMBERS in the first place. 101 */ 102#define JERRY_ADD_TWO_NUMS(arg1, arg2) \ 103 ((arg1) + (arg2)) 104``` 105 106```diff 107--- Bad --- 108``` 109 110```c 111#define JERRY_CONSTANT_WITHOUT_DESCRIPTION 5 112 113#define JeRrY_mIxEd_CaSe_NaMe "str" 114``` 115 116## Conditional preprocessor directives 117 118A comment is required after `#else` and `#endif` in JerryScript. 119The defined keyword should be omitted from these comments. 120 121```diff 122+++ Good +++ 123``` 124 125```c 126#ifdef JERRY_A 127 128#else /* !JERRY_A */ 129 130#endif /* JERRY_A */ 131 132#ifdef JERRY_A 133#if defined JERRY_B && defined JERRY_C && (JERRY_C > 6) 134 135#else /* !(JERRY_B && JERRY_C && (JERRY_C > 6)) */ 136 137#endif /* JERRY_B && JERRY_C && (JERRY_C > 6) */ 138#endif /* JERRY_A */ 139``` 140 141```diff 142--- Bad --- 143``` 144 145```c 146#ifdef JERRY_A 147 148#endif 149 150#ifdef JERRY_A 151 152#endif /* defined JERRY_A */ 153 154#ifdef JERRY_B 155 /* Missing comment after else. */ 156#else 157 158#endif /* JERRY_B */ 159``` 160 161## Code blocks 162 163Each code block must be enclosed in curly braces even 164if it is a single line statement. These braces must 165be on separate lines. There must be a single space 166before the opening parenthesis of the expression 167after if/while/switch keywords. 168 169```diff 170+++ Good +++ 171``` 172 173```c 174if (value > 6) 175{ 176 function_call (); 177} 178 179if (value > 1) 180{ 181 function_call_a (); 182} 183else 184{ 185 function_call_b (); 186} 187 188do 189{ 190 function_call (); 191 value++; 192} 193while (value < 6); 194 195switch (value) 196{ 197 case A: 198 { 199 /* FALLTHRU comment is allowed if a 200 * switch-case is not terminated by 201 * break/continue/return. */ 202 203 /* FALLTHRU */ 204 } 205 case B: 206 case C: 207 { 208 break; 209 } 210 case D: 211 { 212 /* We can use continue if we are in a loop. */ 213 continue; 214 } 215 default: 216 { 217 return; 218 } 219} 220``` 221 222```diff 223--- Bad --- 224``` 225 226```c 227if (value > 6) 228 function_call_a (); 229else 230 function_call_b (); 231 232if (value > 6) { 233 function_call_a (); 234} 235 236if (value > 6) function_call_a (); 237else { function_call_b (); } 238 239if 240(value > 6) 241{ 242} 243 244switch (value) { 245 case 0: break; 246 default: { 247 return 5; 248 } 249} 250 251switch (value) 252{ 253 case A: 254 { 255 if (value > 6) 256 { 257 CASE B: 258 { 259 /* This is allowed in C but 260 * not in JerryScript. */ 261 break; 262 } 263 } 264 } 265} 266 267do 268 value++; 269while (value < 5); 270 271do { 272 value++; 273} while (value < 5); 274 275do 276{ 277 value++; 278} while (value < 5); 279``` 280 281## Newlines 282 283A newline in JerryScript is a separator which separates different 284parts of the source code. Its primary purpose is to improve 285readability. Unlike other rules developers have some freedom 286to add newlines to their code. However there are some rules. 287 288* Only a single newline separator is allowed. 289* Source files must be terminated by a newline. 290* Global declarations must be separated by a newline. 291* Newlines are not allowed after an opening curly brace or before 292 a closing curly brace 293* No newlines are allowed between control statements (if-else, while, 294 for, switch, etc.) and their code blocks. 295* There should be a newline after the variable declarations 296 if they are the first statements of a block. 297 298```diff 299+++ Good +++ 300``` 301 302```c 303if (a > 5) 304{ 305 /* Newline must be present after the first 306 * variable declarations of a code block. */ 307 int j = a - 1; 308 int k = a * 2; 309 310 return j + k; 311} 312 313while (a < 5) 314{ 315 a++; 316 317 /* It is recommended to put a newline after 318 * intermediate variable declarations. */ 319 int i = a * 2; 320 321 b = i - 3; 322} 323 324/* It is a recommended to put newlines around asserts. */ 325a = b + 5; 326 327JERRY_ASSERT (a < 20); 328 329c = a + 7; 330 331/* It is a good practice to put a newline after a multiline 332 * function call (see Function calls later). */ 333f (a, 334 b, 335 c); 336 337a = 6; 338``` 339 340```diff 341--- Bad --- 342``` 343 344```c 345/* No newlines are allowed after an opening curly 346 * brace or before a closing curly brace */ 347 348while (a > 0) 349{ 350 351 a = 6; 352 353} 354 355if (a > 5) 356{ 357 while (b < 6) 358 { 359 360 b++; 361 } 362 363} 364 365 366/* Two or more newlines are not allowed. */ 367a = 6; 368 369 370b = 7; 371 372/* No newlines are allowed between control staments 373 * and their code blocks. */ 374 375if (a > 6) 376 377{ 378} 379 380else 381 382{ 383} 384 385do 386 387{ 388} 389 390while (a < 6); 391``` 392 393## Expressions 394 395Spaces are required around binary operators. No space is 396needed otherwise. 397 398```diff 399+++ Good +++ 400``` 401 402```c 403a = b + c; 404a = (b + c) << 3; 405a = b = c + ~d; 406a += ++c + d++; 407call_function (a * (b + !!c) - d + (e % f)); 408if (a) 409{ 410} 411``` 412 413```diff 414--- Bad --- 415``` 416 417```c 418a=b+c; 419a = b+c; 420a += c + ( d ); 421/* Introduce temporary variables or macros 422 * if the expression is too long. Occures rarely.. */ 423a = b 424 + c; 425if ( a + b > 0 ) 426{ 427} 428``` 429 430## Logical operators 431 432All expressions with && and || logical operators must be 433enclosed in parentheses. A single and multiline form is 434allowed for these expressions. In the latter case each 435line must start with the logical operator and each line 436must be aligned to the column right after the opening 437parenthesis. 438 439```diff 440+++ Good +++ 441``` 442 443```c 444/* Single line form. */ 445a = ((c && d) || (e && f)); 446 447a = (c 448 && d); 449 450a = (c 451 && (d || e) 452 && f); 453 454do 455{ 456} 457while (a 458 && b); 459 460/* This form is rarely used but it is ok. */ 461if (a 462 && (b 463 || c 464 || d) 465 && e) 466{ 467} 468``` 469 470```diff 471--- Bad --- 472``` 473 474```c 475if (a || b || 476 c) 477{ 478} 479 480/* Parentheses are missing. */ 481a = b || c; 482 483/* Misaligned &&. */ 484if (a 485 && b) 486{ 487} 488``` 489 490## Ternary conditional operators 491 492A special form of ternary conditional operators are allowed 493in JerryScript where the ? and : operators are on separate 494lines in the same column. 495 496```diff 497+++ Good +++ 498``` 499 500```c 501a = (b ? c 502 : d); 503 504/* Single line form is accepted as well. */ 505a = (b ? c : d); 506 507/* This form is rarely used but it is ok. */ 508if (a ? b 509 : (c ? d 510 : e)) 511{ 512} 513``` 514 515```diff 516--- Bad --- 517``` 518 519```c 520a = b ? 521 c : d; 522 523while (a ? b 524 : c) 525{ 526} 527 528if (a 529 ? b 530 : c) 531{ 532} 533``` 534 535## Function calls 536 537There must be a space after the function name. Each argument 538must be in the same or separated lines. In the former case 539there must be a space before the next argument and in the 540latter case all arguments must be aligned to the same column. 541 542```diff 543+++ Good +++ 544``` 545 546```c 547function_a (); 548function_b (a); 549function_c (a, b, c); 550 551function_c (a, 552 b, 553 c); 554 555function_c (a, 556 b, 557 function_c (a, 558 b, 559 c); 560``` 561 562```diff 563--- Bad --- 564``` 565 566```c 567/* No space before the opening parenthesis. */ 568function_f(); 569 570function_f ( 571); 572 573function_g(a); 574 575function_g 576 (a 577 ); 578 579/* Two arguments on the same line. */ 580function_h (a, b, 581 c); 582 583function_h (a, 584 b, c); 585 586/* Misaligned arguments. */ 587function_h (a, 588 b, 589 c); 590``` 591 592## Variable declarations 593 594JerryScript is a pure C99 codebase so variable 595declarations can be anywhere in the code including 596inside for-loops. It is recommended to declare a 597variable before the first use. 598 599```diff 600+++ Good +++ 601``` 602 603```c 604for (int i = 0; i < 10; i++) 605{ 606 int j = i + 1; 607 while (j < 10) 608 { 609 ++j; 610 } 611} 612 613/* Multiline form of for loops. */ 614for (int i = 0; 615 i < 10; 616 i++) 617{ 618} 619``` 620 621## Type casting 622 623There must be a space after the closing parenthesis 624of the type cast. Type casting has no multiline form 625in JerryScript. 626 627```diff 628+++ Good +++ 629``` 630 631```c 632int a = (int) double_variable; 633 634int a = (int) (long) (float) double_variable; 635``` 636 637```diff 638--- Bad --- 639``` 640 641```c 642/* Wrong spaces. */ 643int a = ( int )double_variable; 644 645/* No multiline form. */ 646int a = (int) 647 double_variable; 648``` 649 650## Pointers and asterisk character 651 652Each pointer in JerryScript must be a lowercase string 653which is ending with a `_p` suffix. Furthermore there 654must be a space before the asterisk character. 655 656```diff 657+++ Good +++ 658``` 659 660```c 661 int *int_p; 662 663 /* No need to add multiple _p-s for multiple indirections. 664 * It is recommended to avoid these constructs using typedef 665 * declarations. A reviewer might request such a change. */ 666 int ***int_p; 667 668 /* This rule applies for type casting as well. */ 669 char = *(char *) type_p; 670``` 671 672```diff 673--- Bad --- 674``` 675 676```c 677 /* No _p after the name. */ 678 int *ptr; 679 680 /* Wrong asterisk position. */ 681 int* ptr_p; 682 683 char_p = * (char*)type_p; 684``` 685 686## Types 687 688Each type in JerryScript must be a lowercase string 689which ends with a `_t` suffix. Furthermore each type 690declaration must be preceded by a short description 691of the type and each field must have a short description 692as well. 693 694```diff 695+++ Good +++ 696``` 697 698```c 699/** 700 * Short description of the following structure. 701 */ 702typedef struct 703{ 704 /* Field descriptions do not start with capital letters 705 * and there is no full stop at the end. */ 706 field1_t field1; /**< description of field 1 */ 707 field2_t field2; /**< description of field 2 */ 708 709 field_n_t field_n; /**< description of field n */ 710} structure_name_t; 711 712/** 713 * Another integer type. 714 */ 715typedef int jerry_int; 716``` 717 718```diff 719--- Bad --- 720``` 721 722```c 723typedef struct 724{ 725 field_t field_without_description; 726} structure_without_description_t; 727 728typedef struct { int a; } single_line_struct; 729 730typedef 731union { 732} 733wrong_newlines_t; 734 735/* 736 * Bad comment format. 737 */ 738typedef 739char wrong_newlines_again_t; 740``` 741 742## Function declarations 743 744Function declarations in JerryScript are verbose but this format 745reduces the maintenance cost and allows faster understanding of 746the code. 747 748```diff 749+++ Good +++ 750``` 751 752```c 753/** 754 * Short overview about the purpose of this function. 755 * 756 * A more detailed explanation if needed. 757 * 758 * Note: 759 * Extra notes if needed. 760 * 761 * @return short description about the value 762 * returned by the function 763 */ 764return_value_type_t 765function_name (argument1, /**< description of argument1 */ 766 argument2, /**< description of argument2 */ 767 ... 768 argument_n, /**< description of argument n */ 769{ 770 771 /* Function body. */ 772 773} /* function_name */ 774``` 775 776```diff 777--- Bad --- 778``` 779 780```c 781static int 782print (char *text) /**< description of text argument */ 783{ 784 /* Missing comment before the function. */ 785} /* print */ 786 787/** 788 * Prints the text received by the function. 789 * 790 * @return number of characters printed by the function 791 */ 792int print(char *text) 793{ 794 /* No description of text argument. */ 795 /* Missing comment at the end of the function. */ 796} 797``` 798