Skip to content

Style Guide

Stephen Zhao edited this page Sep 17, 2017 · 5 revisions

Directory and Package Structure

Directories

  • We are currently following the standard maven directory structure:
CaSCAS/
+-- config/          ;; For config files
|   '-- cascas.ini   ;; The default config file
+-- lib/             ;; For compiled libraries, currently unused
+-- log/             ;; log files are generated here when cascas is run from the dev environment
+-- src/             ;; Source code files
|   +-- main/
|   |   +-- java/    ;; Java source code (package-directory correspondence therein)
|   |   '-- scala/   ;; Dcala source code (package-directory correspondence therein)
|   '-- test/
|       +-- java/    ;; Java test code (package-directory correspondence therein)
|       '-- scala/   ;; Scala test code (package-directory correspondence therein)
+-- target/          ;; Built binaries and jars from source
'-- working/         ;; Any private working files (not committed)

Scala Packages

org.cascas_project.cascas.
+-- lang.                      ;; CaSCAS Language Internal Representation
|   '-- builtin.               ;; Built-In type and operator definitions
+-- parser.                    ;; The parser component
+-- shared.                    ;; Shared definitions
+-- tokens.                    ;; Where the tokens are located
+-- util.                      ;; Utility functions and definitions

Scala Code

A code style configuration for IntelliJ IDEA is in the making. Once it is complete, it will be committed to and provided with the project.

Source File Header

  • Use the following template to make a header at the beginning of every Scala code file in CaSCAS Project (org.cascas_project.cascas)
//==============================================================================
// from/cascas/package/path/to/file.scala : CaSCAS Project
//==============================================================================

package org.cascas_project.cascas.from.cascas.package.path.to

//==============================================================================
  • Imports directly follow this header

Sections and Spacing

  • Use the following to delimit sections in code
//==============================================================================
  • Use 4 empty lines between class / trait definitions
  • If methods within a class are short or do not feature empty lines / extra line breaks,
    • then use 1 empty line between methods
  • If methods within a class feature empty lines within themselves,
    • then use 2 empty lines between methods

Code Formatting

  • Recommended line length is 80 characters
  • Maximum allowed line length is 120 characters
  • Use 2 spaces per indentation level
  • Explicitly annotate types in all cases unless unreasonable
    • for val declarations / assigns
    • for var declarations / assigns
    • for defs (parameters and return type)
    • for class constructors
    • optional if a val/var/def is explicitly initialized to a literal
  • For declarations:
    • Do not put a space between the identifier and type annotation colon
    • Do put a space between the colon and the type annotation
    • Use spaces to separate the =
    • e.g. val name: String = "Overlord_Prime"
  • Keep declarations on one line if it fits within the recommended line length.
    • if a class or function declaration is too long to fit,
    • then separate each parameter with a line break and give +1 indent level,
    • and keep braces and parentheses on the lines preceding and following the parameters,
    • and keep extensions / mixins on the final line.
    • if extensions / mixins exceed the recommended line length,
    • then separate each extension / mixin by a line break and give +1 indent level,
    • and place the final curly brace on its own line after the last extension / mixin.
    • e.g.
      case class BuiltInExpr(
        args: Vector[FormalParameter],
        onApply: (Context) => Evaluation,
        ret: TypeIdentifier,
        onEval: (Context) => Evaluation = Evaluation(this, ContextMutationSet.empty)
      ) extends Expr {
      
  • When annotating function types, use the shorthand "lambda" instead of the full function type name
    • e.g.
    • DO: callback: (Event, EventArgs) => Boolean
    • DO NOT: callback: Function[(Event, EventArgs), Boolean]