From fc53e737032cfc89b955316fbeef91b29e0898bf Mon Sep 17 00:00:00 2001 From: EliteMasterEric Date: Sun, 22 Jan 2023 22:23:05 -0500 Subject: [PATCH] Established new code style and auto-formatting rules. --- .editorconfig | 7 + .gitattributes | 1 + .prettierrc.js | 21 ++ .vscode/extensions.json | 9 +- .vscode/launch.json | 19 +- CODESTYLE.md | 32 ++ checkstyle.json | 661 ++++++++++++++++++++++++++++++++++++++++ hxformat.json | 46 +-- 8 files changed, 763 insertions(+), 33 deletions(-) create mode 100644 .editorconfig create mode 100644 .gitattributes create mode 100644 .prettierrc.js create mode 100644 CODESTYLE.md create mode 100644 checkstyle.json diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 000000000..118201cde --- /dev/null +++ b/.editorconfig @@ -0,0 +1,7 @@ +# top-most EditorConfig file +root = true + +# Unix-style newlines with a newline ending every file +[*] +end_of_line = lf +insert_final_newline = true \ No newline at end of file diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 000000000..94f480de9 --- /dev/null +++ b/.gitattributes @@ -0,0 +1 @@ +* text=auto eol=lf \ No newline at end of file diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 000000000..2939c1c74 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,21 @@ +/** + * Configuration for JSON file formatting. + */ +module.exports = { + // Line width before Prettier tries to add new lines. + printWidth: 80, + + // Indent with 2 spaces. + tabs: false, + useTabs: false, + tabWidth: 2, + + // Use double quotes. + singleQuote: false, + quoteProps: "preserve", + parser: "json", + + bracketSpacing: true, // Spacing between brackets in object literals. + trailingComma: "none", // No trailing commas. + semi: false, // No semicolons at ends of statements. +}; \ No newline at end of file diff --git a/.vscode/extensions.json b/.vscode/extensions.json index a8513ffd2..e48a1e1b8 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,8 +1,9 @@ { "recommendations": [ - "nadako.vshaxe", - "wiggin77.codedox", - "vshaxe.hxcpp-debugger", - "openfl.lime-vscode-extension" + "nadako.vshaxe", // Basic Haxe integration + "wiggin77.codedox", // Haxe documentation + "vshaxe.hxcpp-debugger", // CPP debugging + "openfl.lime-vscode-extension", // Lime integration + "esbenp.prettier-vscode", // JSON formatting ] } \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index ef76cb5cb..d16f1ca4f 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -2,18 +2,13 @@ "version": "0.2.0", "configurations": [ { - // Launch in native/CPP + // Launch in native/CPP on Windows/OSX/Linux "name": "Lime", "type": "lime", "request": "launch" }, { - // Evaluate macros with debugging enabled - "name": "Haxe Eval", - "type": "haxe-eval", - "request": "launch" - }, - { + // Launch in browser "name": "HTML5 Debug", "type": "chrome", "request": "launch", @@ -23,11 +18,11 @@ "preLaunchTask": "debug: html" }, { - "name": "Mac (Debug)", - "type": "hxcpp", - "request": "launch", - "program": "${workspaceRoot}/export/debug/macos/bin/Funkin.app/Contents/MacOS/Funkin", - "preLaunchTask": "debug: mac" + // Performs a build for debugging macros + // Debugging is attached on the compilation rather than the game itself + "name": "Haxe Eval", + "type": "haxe-eval", + "request": "launch" } ] } diff --git a/CODESTYLE.md b/CODESTYLE.md new file mode 100644 index 000000000..9fb08eef3 --- /dev/null +++ b/CODESTYLE.md @@ -0,0 +1,32 @@ +# Code Style Guide + +Code style is enforced using Visual Studio Code extensions. + +## .hx +Formatting is handled by the `nadako.vshaxe` extension, which includes Haxe Formatter. +Haxe Formatter automatically resolves issues such as intentation style and line breaks, and can be configured in `hxformat.json`. + +Code Quality is handled by the `vshaxe.haxe-checkstyle` extension, which includes Haxe Checkstyle. + +### Haxe Checkstyle Notes +* Checks can be escalated to display as different serverities in the Problems window. + * Checks can be disabled by setting the severity to `IGNORE`. +* `IndentationCharacter` checks what is used to indent, `Indentation` checks how deep the intentation is. +* `CommentedOutCode` check is in place because old code should be retrieved via Git history. +* TODO items: + - Reconfigure `MethodLength` + - Reconfigure `CyclomaticComplexity` + - Re-enable `MagicNumber` + - Re-configure `NestedControlFlow` + - Re-configure `NestedIfDepth` + - Figure out something for `Trace` + - Fix bug and enable `DocCommentStyle` + +## .json +Formatting is handled by the `esbenp.prettier-vscode` extension, which includes Prettier. +Prettier automatically handles formatting of JSON files, and can be configured in `.prettierrc.js`. + +### Prettier Notes +* Prettier will automatically attempt to place expressions on a single line if they fit, but will keep them multi-line if they are manually made multi-line. + * This means that long singleline objects are automatically expanded, and short multiline objects aren't automatically collapsed. + * You may want to use regex replacement to manually remove the first newline in short multi-line objects to convince Prettier to collapse them. diff --git a/checkstyle.json b/checkstyle.json new file mode 100644 index 000000000..69a86dbfe --- /dev/null +++ b/checkstyle.json @@ -0,0 +1,661 @@ +{ + "extendsConfigPath": "", + "defineCombinations": [], + "defaultSeverity": "INFO", + "baseDefines": [], + "version": 1, + "exclude": {}, + "checks": [ + { + "props": {}, + "type": "Anonymous" + }, + { + "props": { + "spaceBefore": false, + "spaceInside": false + }, + "type": "ArrayAccess" + }, + { + "props": {}, + "type": "ArrayLiteral" + }, + { + "props": { + "allowSingleArgParens": false, + "allowReturn": false, + "allowFunction": false, + "allowCurlyBody": false + }, + "type": "ArrowFunction" + }, + { + "props": { + "avoidIdentifiers": [] + }, + "type": "AvoidIdentifier" + }, + { + "props": {}, + "type": "AvoidStarImport" + }, + { + "props": {}, + "type": "AvoidTernaryOperator" + }, + { + "props": {}, + "type": "BlockBreakingConditional" + }, + { + "props": { + "format": "^(e|t|ex|[a-z][a-z][a-zA-Z]+)$" + }, + "type": "CatchParameterName" + }, + { + "props": { + "thresholdSimilar": 120, + "severityIdentical": "WARNING", + "thresholdIdentical": 60 + }, + "type": "CodeSimilarity" + }, + { + "props": {}, + "type": "CommentedOutCode" + }, + { + "props": { + "policy": "aligned", + "allowSingleline": true, + "severity": "INFO" + }, + "type": "ConditionalCompilation" + }, + { + "props": { + "ignoreExtern": true, + "format": "^[A-Z][A-Z0-9]*(_[A-Z0-9_]+)*$", + "tokens": [] + }, + "type": "ConstantName" + }, + { + "props": { + "thresholds": [ + { + "complexity": 20, + "severity": "WARNING" + }, + { + "complexity": 25, + "severity": "ERROR" + } + ], + "severity": "IGNORE" + }, + "type": "CyclomaticComplexity" + }, + { + "props": {}, + "type": "DefaultComesLast" + }, + { + "props": { + "lineStyle": "onestar", + "startStyle": "twostars", + "severity": "IGNORE" + }, + "type": "DocCommentStyle" + }, + { + "props": {}, + "type": "Dynamic" + }, + { + "props": {}, + "type": "ERegLiteral" + }, + { + "props": { + "tokens": [ + "CLASS_DEF", + "ENUM_DEF", + "ABSTRACT_DEF", + "TYPEDEF_DEF", + "INTERFACE_DEF", + "OBJECT_DECL", + "FUNCTION", + "FOR", + "IF", + "WHILE", + "SWITCH", + "TRY", + "CATCH" + ], + "option": "empty" + }, + "type": "EmptyBlock" + }, + { + "props": { + "requireEmptyLineAfterPackage": true, + "requireEmptyLineAfterInterface": true, + "requireEmptyLineAfterAbstract": true, + "allowEmptyLineAfterSingleLineComment": true, + "max": 1, + "requireEmptyLineAfterClass": true, + "allowEmptyLineAfterMultiLineComment": true + }, + "type": "EmptyLines" + }, + { + "props": { + "enforceEmptyPackage": true + }, + "type": "EmptyPackage" + }, + { + "props": { + "none": [], + "upto": [], + "defaultPolicy": "upto", + "exact": [], + "max": 1, + "ignore": [], + "atleast": [], + "skipSingleLineTypes": true + }, + "type": "ExtendedEmptyLines" + }, + { + "props": { + "requireParams": true, + "fieldType": "BOTH", + "requireReturn": true, + "ignoreOverride": true, + "tokens": [ + "ABSTRACT_DEF", + "CLASS_DEF", + "ENUM_DEF", + "INTERFACE_DEF", + "TYPEDEF_DEF" + ], + "modifier": "PUBLIC", + "excludeNames": ["new", "toString"] + }, + "type": "FieldDocComment" + }, + { + "props": { + "max": 1000, + "ignoreEmptyLines": true + }, + "type": "FileLength" + }, + { + "props": {}, + "type": "Final" + }, + { + "props": { + "option": "upperCase" + }, + "type": "HexadecimalLiteral" + }, + { + "props": { + "ignoreSetter": true, + "ignoreFormat": "^(main|run)$", + "ignoreConstructorParameter": true + }, + "type": "HiddenField" + }, + { + "props": { + "character": " " + }, + "type": "Indentation" + }, + { + "props": { + "character": "space", + "severity": "INFO", + "ignorePattern": "^$" + }, + "type": "IndentationCharacter" + }, + { + "props": { + "ignoreReturnAssignments": false + }, + "type": "InnerAssignment" + }, + { + "props": { + "allowProperties": false, + "allowMarkerInterfaces": true + }, + "type": "Interface" + }, + { + "props": { + "severity": "IGNORE" + }, + "type": "LeftCurly" + }, + { + "props": { + "max": 160, + "ignorePattern": "^$" + }, + "type": "LineLength" + }, + { + "props": { + "listeners": ["addEventListener", "addListener", "on", "once"], + "format": "^_?[a-z][a-zA-Z0-9]*$" + }, + "type": "ListenerName" + }, + { + "props": { + "ignoreExtern": true, + "format": "^[a-z][a-zA-Z0-9]*$", + "tokens": [] + }, + "type": "LocalVariableName" + }, + { + "props": { + "ignoreNumbers": [-1, 0, 1, 2], + "severity": "IGNORE" + }, + "type": "MagicNumber" + }, + { + "props": { + "ignoreExtern": true, + "format": "^[a-z][a-zA-Z0-9]*$", + "tokens": [] + }, + "type": "MemberName" + }, + { + "props": { + "maxPrivate": 100, + "maxPublic": 100, + "maxTotal": 100 + }, + "type": "MethodCount" + }, + { + "props": { + "max": 50, + "ignoreEmptyLines": true, + "severity": "IGNORE" + }, + "type": "MethodLength" + }, + { + "props": { + "ignoreExtern": true, + "format": "^[a-z][a-zA-Z0-9]*$", + "tokens": [] + }, + "type": "MethodName" + }, + { + "props": { + "modifiers": [ + "MACRO", + "OVERRIDE", + "PUBLIC_PRIVATE", + "STATIC", + "INLINE", + "DYNAMIC", + "FINAL" + ] + }, + "type": "ModifierOrder" + }, + { + "props": { + "minLength": 2, + "ignore": "^\\s+$", + "allowDuplicates": 5 + }, + "type": "MultipleStringLiterals" + }, + { + "props": {}, + "type": "MultipleVariableDeclarations" + }, + { + "props": { + "allowSingleLineStatement": true, + "tokens": ["FOR", "IF", "ELSE_IF", "WHILE", "DO_WHILE"] + }, + "type": "NeedBraces" + }, + { + "props": { + "max": 3 + }, + "type": "NestedControlFlow" + }, + { + "props": { + "max": 1 + }, + "type": "NestedForDepth" + }, + { + "props": { + "max": 1 + }, + "type": "NestedIfDepth" + }, + { + "props": { + "max": 1 + }, + "type": "NestedTryDepth" + }, + { + "props": { + "option": "questionMark" + }, + "type": "NullableParameter" + }, + { + "props": { + "newFunctionTypePolicy": "around", + "ternaryOpPolicy": "around", + "unaryOpPolicy": "none", + "oldFunctionTypePolicy": "around", + "boolOpPolicy": "around", + "intervalOpPolicy": "none", + "assignOpPolicy": "around", + "bitwiseOpPolicy": "around", + "arithmeticOpPolicy": "around", + "compareOpPolicy": "around", + "arrowPolicy": "around", + "arrowFunctionPolicy": "around" + }, + "type": "OperatorWhitespace" + }, + { + "props": { + "tokens": [ + "=", + "+", + "-", + "*", + "/", + "%", + ">", + "<", + ">=", + "<=", + "==", + "!=", + "&", + "|", + "^", + "&&", + "||", + "<<", + ">>", + ">>>", + "+=", + "-=", + "*=", + "/=", + "%=", + "<<=", + ">>=", + ">>>=", + "|=", + "&=", + "^=", + "...", + "=>", + "++", + "--" + ], + "option": "eol" + }, + "type": "OperatorWrap" + }, + { + "props": { + "ignoreExtern": true, + "format": "^(_|[a-z][a-zA-Z0-9]*$)", + "tokens": [] + }, + "type": "ParameterName" + }, + { + "props": { + "max": 7, + "ignoreOverriddenMethods": false + }, + "type": "ParameterNumber" + }, + { + "props": {}, + "type": "PublicAccessor" + }, + { + "props": { + "prohibitMeta": false + }, + "type": "RedundantAccessMeta" + }, + { + "props": { + "prohibitMeta": false + }, + "type": "RedundantAllowMeta" + }, + { + "props": { + "enforcePrivate": false, + "enforcePublic": true, + "enforcePublicPrivate": false + }, + "type": "RedundantModifier" + }, + { + "props": { + "enforceReturnTypeForAnonymous": false, + "allowEmptyReturn": true, + "enforceReturnType": true + }, + "type": "Return" + }, + { + "props": { + "ignoreFormat": "^$", + "max": 2 + }, + "type": "ReturnCount" + }, + { + "props": { + "severity": "IGNORE" + }, + "type": "RightCurly" + }, + { + "props": { + "commaPolicy": "after", + "semicolonPolicy": "after", + "allowTrailingComma": false, + "dotPolicy": "none" + }, + "type": "SeparatorWhitespace" + }, + { + "props": { + "tokens": [","], + "option": "eol" + }, + "type": "SeparatorWrap" + }, + { + "props": {}, + "type": "SimplifyBooleanExpression" + }, + { + "props": {}, + "type": "SimplifyBooleanReturn" + }, + { + "props": { + "spaceIfCondition": "should", + "spaceAroundBinop": true, + "spaceForLoop": "should", + "ignoreRangeOperator": true, + "spaceWhileLoop": "should", + "spaceCatch": "should", + "spaceSwitchCase": "should", + "noSpaceAroundUnop": true + }, + "type": "Spacing" + }, + { + "props": { + "policy": "onlySingle", + "allowException": true + }, + "type": "StringLiteral" + }, + { + "props": { + "format": "^\\s*(TODO|FIXME|HACK|XXX|BUG)" + }, + "type": "TODOComment" + }, + { + "props": { + "ignorePattern": "^$" + }, + "type": "TabForAligning" + }, + { + "props": { + "severity": "IGNORE" + }, + "type": "Trace" + }, + { + "props": {}, + "type": "TrailingWhitespace" + }, + { + "props": { + "ignoreEnumAbstractValues": true + }, + "type": "Type" + }, + { + "props": { + "tokens": [ + "ABSTRACT_DEF", + "CLASS_DEF", + "ENUM_DEF", + "INTERFACE_DEF", + "TYPEDEF_DEF" + ] + }, + "type": "TypeDocComment" + }, + { + "props": { + "ignoreExtern": true, + "format": "^[A-Z]+[a-zA-Z0-9]*$", + "tokens": [] + }, + "type": "TypeName" + }, + { + "props": {}, + "type": "UnnecessaryConstructor" + }, + { + "props": { + "moduleTypeMap": {}, + "ignoreModules": [] + }, + "type": "UnusedImport" + }, + { + "props": {}, + "type": "UnusedLocalVar" + }, + { + "props": { + "severity": "IGNORE" + }, + "type": "VariableInitialisation" + }, + { + "props": { + "typeHintPolicy": "enforce_all", + "ignoreEnumAbstractValues": true + }, + "type": "VarTypeHint" + }, + { + "props": { + "tokens": [",", ";"], + "allowTrailingComma": false + }, + "type": "WhitespaceAfter" + }, + { + "props": { + "tokens": [ + "=", + "+", + "-", + "*", + "/", + "%", + ">", + "<", + ">=", + "<=", + "==", + "!=", + "&", + "|", + "^", + "&&", + "||", + "<<", + ">>", + ">>>", + "+=", + "-=", + "*=", + "/=", + "%=", + "<<=", + ">>=", + ">>>=", + "|=", + "&=", + "^=", + "=>" + ] + }, + "type": "WhitespaceAround" + } + ], + "numberOfCheckerThreads": 5 +} diff --git a/hxformat.json b/hxformat.json index 2a7775dda..cacbbf810 100644 --- a/hxformat.json +++ b/hxformat.json @@ -1,19 +1,31 @@ { - "lineEnds": { - "leftCurly": "both", - "rightCurly": "both", - "emptyCurly": "noBreak", - "objectLiteralCurly": { - "leftCurly": "after" - } - }, - "indentation": { - "character": " " - }, - "sameLine": { - "ifElse": "next", - "doWhile": "next", - "tryBody": "next", - "tryCatch": "next" - } + "disableFormatting": false, + + "indentation": { + "character": " ", + "tabWidth": 2, + "indentCaseLabels": true + }, + + "lineEnds": { + "anonFunctionCurly": { + "emptyCurly": "break", + "leftCurly": "after", + "rightCurly": "both" + }, + "leftCurly": "both", + "rightCurly": "both" + }, + + "sameLine": { + "ifBody": "same", + "ifElse": "next", + "doWhile": "next", + "tryBody": "next", + "tryCatch": "next" + }, + + "whitespace": { + "switchPolicy": "around" + } }