diff --git a/.travis.sh b/.travis.sh index 3812c45..fa34497 100755 --- a/.travis.sh +++ b/.travis.sh @@ -4,9 +4,6 @@ set -e if [[ $BUILD == dub ]]; then dub build --build=release - - mkdir bin - mv dfmt ./bin elif [[ $DC == ldc2 ]]; then git submodule update --init --recursive make ldc -j2 diff --git a/.travis.yml b/.travis.yml index 9f09a5e..462998e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -43,3 +43,55 @@ jobs: on: tags: true # must be a git tag repo: dlang-community/dfmt # must be a tag on dlang-community + - stage: GitHub Release + #if: tag IS present + d: ldc-1.8.0 + os: linux + script: echo "Deploying to GitHub releases ..." && ./release.sh + deploy: + provider: releases + api_key: $GH_REPO_TOKEN + file_glob: true + file: bin/dfmt-*.tar.gz + skip_cleanup: true + on: + repo: dlang-community/dfmt + tags: true + - stage: GitHub Release + #if: tag IS present + d: ldc-1.8.0 + os: osx + script: echo "Deploying to GitHub releases ..." && ./release.sh + deploy: + provider: releases + api_key: $GH_REPO_TOKEN + file_glob: true + file: bin/dfmt-*.tar.gz + skip_cleanup: true + on: + repo: dlang-community/dfmt + tags: true + - stage: GitHub Release + #if: tag IS present + d: dmd + os: linux + language: generic + sudo: yes + script: echo "Deploying to GitHub releases ..." && ./release-windows.sh + addons: + apt: + packages: + - p7zip-full + - wine + deploy: + provider: releases + api_key: $GH_REPO_TOKEN + file_glob: true + file: bin/dfmt-*.zip + skip_cleanup: true + on: + repo: dlang-community/dfmt + tags: true +stages: + - name: test + if: type = pull_request or (type = push and branch = master) diff --git a/README.md b/README.md index 7aff4cf..b97e46f 100644 --- a/README.md +++ b/README.md @@ -41,6 +41,7 @@ found in .editorconfig files. * **--max_line_length**: See **max_line_length** below * **--soft_max_line_length**: See **dfmt_soft_max_line_length** below * **--outdent_attributes**: See **dfmt_outdent_attributes** below +* **--single_template_constraint_indent**: See **dfmt_template_constraint_style** below * **--space_after_cast**: See **dfmt_space_after_cast** below * **--space_before_function_parameters**: See **dfmt_space_before_function_parameters** below * **--split_operator_at_line_end**: See **dfmt_split_operator_at_line_end** below @@ -68,7 +69,7 @@ void main(string[] args) // argument list normally getopt(args, "optionOne", &optionOne, "optionTwo", &optionTwo, "optionThree", &optionThree); - // dfmt off + // dfmt off getopt(args, "optionOne", &optionOne, "optionTwo", &optionTwo, @@ -105,6 +106,7 @@ dfmt_space_before_function_parameters | `true`, `false` | `false` | Insert space dfmt_selective_import_space | `true`, `false` | `true` | Insert space after the module name and before the `:` for selective imports. dfmt_compact_labeled_statements | `true`, `false` | `true` | Place labels on the same line as the labeled `switch`, `for`, `foreach`, or `while` statement. dfmt_template_constraint_style | `conditional_newline_indent` `conditional_newline` `always_newline` `always_newline_indent` | `conditional_newline_indent` | Control the formatting of template constraints. +dfmt_single_template_constraint_indent | `true`, `false` | `false` | Set if the constraints are indented by a single tab instead of two. Has only an effect for if indentation style if set to `always_newline_indent` or `conditional_newline_indent`. ## Terminology * Braces - `{` and `}` diff --git a/dub.json b/dub.json index 40015f9..39ee2c0 100644 --- a/dub.json +++ b/dub.json @@ -4,6 +4,8 @@ "targetType": "autodetect", "license": "BSL-1.0", "dependencies": { - "libdparse": "~>0.8.0-alpha.5" - } + "libdparse": "~>0.8.6" + }, + "targetPath" : "bin/", + "targetName" : "dfmt", } diff --git a/libdparse b/libdparse index ee0fa01..086cf06 160000 --- a/libdparse +++ b/libdparse @@ -1 +1 @@ -Subproject commit ee0fa01ab74b6bf27bed3c7bdb9d6fb789963342 +Subproject commit 086cf06051bb1f33c94891ba6c39a57f164ee296 diff --git a/makefile b/makefile index 47536f8..e67be44 100644 --- a/makefile +++ b/makefile @@ -44,3 +44,6 @@ pkg: dmd clean: $(RM) bin/dfmt + +release: + ./release.sh diff --git a/release-windows.sh b/release-windows.sh new file mode 100755 index 0000000..c482d42 --- /dev/null +++ b/release-windows.sh @@ -0,0 +1,25 @@ +#!/usr/bin/env bash +# Build the Windows binaries under Linux (requires wine) +set -eux -o pipefail +VERSION=$(git describe --abbrev=0 --tags) +OS=windows +ARCH_SUFFIX="x86" + +# Allow the script to be run from anywhere +DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" +cd $DIR + +# Step 1: download the DMD binaries +if [ ! -d dmd2 ] ; then + wget http://downloads.dlang.org/releases/2.x/2.079.0/dmd.2.079.0.windows.7z + 7z x dmd.2.079.0.windows.7z > /dev/null +fi + +# Step 2: Run DMD via wineconsole +archiveName="dfmt-$VERSION-$OS-$ARCH_SUFFIX.zip" +echo "Building $archiveName" +mkdir -p bin +DC="$DIR/dmd2/windows/bin/dmd.exe" wine cmd /C build.bat + +cd bin +zip "$archiveName" dfmt.exe diff --git a/release.sh b/release.sh new file mode 100755 index 0000000..1d345fc --- /dev/null +++ b/release.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash +set -eux -o pipefail +VERSION=$(git describe --abbrev=0 --tags) +ARCH="${ARCH:-64}" +LDC_FLAGS=() +unameOut="$(uname -s)" +case "$unameOut" in + Linux*) OS=linux; LDC_FLAGS=("-flto=full" "-linker=gold" "-static") ;; + Darwin*) OS=osx; LDC_FLAGS+=("-L-macosx_version_min" "-L10.7" "-L-lcrt1.o"); ;; + *) echo "Unknown OS: $unameOut"; exit 1 +esac + +case "$ARCH" in + 64) ARCH_SUFFIX="x86_64";; + 32) ARCH_SUFFIX="x86";; + *) echo "Unknown ARCH: $ARCH"; exit 1 +esac + +archiveName="dfmt-$VERSION-$OS-$ARCH_SUFFIX.tar.gz" + +echo "Building $archiveName" +${MAKE:-make} ldc LDC_FLAGS="${LDC_FLAGS[*]}" +tar cvfz "bin/$archiveName" -C bin dfmt diff --git a/relnotes/first_release.feature.md b/relnotes/first_release.feature.md deleted file mode 100644 index ed227ad..0000000 --- a/relnotes/first_release.feature.md +++ /dev/null @@ -1,5 +0,0 @@ -### First dfmt release with neptune! - -Well there we go, from now on with proper Changelog and all that. - -Since previous releases were done without using neptune guidelines, we are missing proper release notes / a changelog for this release, but for new releases you can expect much more comprehensive release notes. diff --git a/src/dfmt/ast_info.d b/src/dfmt/ast_info.d index db7fe22..afb1784 100644 --- a/src/dfmt/ast_info.d +++ b/src/dfmt/ast_info.d @@ -8,13 +8,29 @@ module dfmt.ast_info; import dparse.lexer; import dparse.ast; +enum BraceIndentInfoFlags +{ + tempIndent = 1 << 0, +} + +struct BraceIndentInfo +{ + size_t startLocation; + size_t endLocation; + + uint flags; + + uint beginIndentLevel; +} + /// AST information that is needed by the formatter. struct ASTInformation { /// Sorts the arrays so that binary search will work on them void cleanup() { - import std.algorithm : sort; + import std.algorithm : sort, uniq; + import std.array : array; sort(doubleNewlineLocations); sort(spaceAfterLocations); @@ -33,6 +49,10 @@ struct ASTInformation sort(constructorDestructorLocations); sort(staticConstructorDestructorLocations); sort(sharedStaticConstructorDestructorLocations); + sort!((a,b) => a.endLocation < b.endLocation) + (indentInfoSortedByEndLocation); + sort(ufcsHintLocations); + ufcsHintLocations = ufcsHintLocations.uniq().array(); } /// Locations of end braces for struct bodies @@ -85,6 +105,11 @@ struct ASTInformation /// Locations of constructor/destructor "this" tokens ? size_t[] constructorDestructorLocations; + + /// Locations of '.' characters that might be UFCS chains. + size_t[] ufcsHintLocations; + + BraceIndentInfo[] indentInfoSortedByEndLocation; } /// Collects information from the AST that is useful for the formatter @@ -187,8 +212,12 @@ final class FormatVisitor : ASTVisitor { if (funcLit.functionBody !is null) { - astInformation.funLitStartLocations ~= funcLit.functionBody.blockStatement.startLocation; - astInformation.funLitEndLocations ~= funcLit.functionBody.blockStatement.endLocation; + const bs = funcLit.functionBody.blockStatement; + + astInformation.funLitStartLocations ~= bs.startLocation; + astInformation.funLitEndLocations ~= bs.endLocation; + astInformation.indentInfoSortedByEndLocation ~= + BraceIndentInfo(bs.startLocation, bs.endLocation); } funcLit.accept(this); } @@ -226,6 +255,9 @@ final class FormatVisitor : ASTVisitor { astInformation.structInitStartLocations ~= structInitializer.startLocation; astInformation.structInitEndLocations ~= structInitializer.endLocation; + astInformation.indentInfoSortedByEndLocation ~= + BraceIndentInfo(structInitializer.startLocation, structInitializer.endLocation); + structInitializer.accept(this); } @@ -268,6 +300,26 @@ final class FormatVisitor : ASTVisitor override void visit(const UnaryExpression unary) { + import std.typecons : rebindable; + + int chainLength; + auto u = rebindable(unary); + while (u !is null) + { + if (u.identifierOrTemplateInstance !is null + && u.identifierOrTemplateInstance.templateInstance !is null) + chainLength++; + u = u.unaryExpression; + } + if (chainLength > 1) + { + u = unary; + while (u.unaryExpression !is null) + { + astInformation.ufcsHintLocations ~= u.dotLocation; + u = u.unaryExpression; + } + } if (unary.prefix.type == tok!"~" || unary.prefix.type == tok!"&" || unary.prefix.type == tok!"*" || unary.prefix.type == tok!"+" || unary.prefix.type == tok!"-") diff --git a/src/dfmt/config.d b/src/dfmt/config.d index 9dcc8fe..a9e59a3 100644 --- a/src/dfmt/config.d +++ b/src/dfmt/config.d @@ -53,6 +53,8 @@ struct Config OptionalBoolean dfmt_compact_labeled_statements; /// TemplateConstraintStyle dfmt_template_constraint_style; + /// + OptionalBoolean dfmt_single_template_constraint_indent; mixin StandardEditorConfigFields; @@ -79,6 +81,7 @@ struct Config dfmt_selective_import_space = OptionalBoolean.t; dfmt_compact_labeled_statements = OptionalBoolean.t; dfmt_template_constraint_style = TemplateConstraintStyle.conditional_newline_indent; + dfmt_single_template_constraint_indent = OptionalBoolean.f; } /** diff --git a/src/dfmt/formatter.d b/src/dfmt/formatter.d index 9112aa1..5456f7f 100644 --- a/src/dfmt/formatter.d +++ b/src/dfmt/formatter.d @@ -283,6 +283,10 @@ private: { formatKeyword(); } + else if (current.text == "body" && peekBackIsFunctionDeclarationEnding()) + { + formatKeyword(); + } else if (isBasicType(current.type)) { writeToken(); @@ -324,6 +328,7 @@ private: void formatConstraint() { + import dfmt.editorconfig : OB = OptionalBoolean; with (TemplateConstraintStyle) final switch (config.dfmt_template_constraint_style) { case unspecified: @@ -342,15 +347,19 @@ private: immutable l = currentLineLength + betweenParenLength(tokens[index + 1 .. $]); if (l > config.dfmt_soft_max_line_length) { - pushWrapIndent(tok!"!"); + config.dfmt_single_template_constraint_indent == OB.t ? + pushWrapIndent() : pushWrapIndent(tok!"!"); newline(); } else if (peekBackIs(tok!")")) write(" "); break; case always_newline_indent: - pushWrapIndent(tok!"!"); - newline(); + { + config.dfmt_single_template_constraint_indent == OB.t ? + pushWrapIndent() : pushWrapIndent(tok!"!"); + newline(); + } break; } // if @@ -370,7 +379,12 @@ private: if (commentText[0 .. 2] == "//") commentText = commentText[2 .. $]; else - commentText = commentText[2 .. $ - 2]; + { + if (commentText.length > 3) + commentText = commentText[2 .. $ - 2]; + else + commentText = commentText[2 .. $]; + } return commentText.strip(); } @@ -586,8 +600,10 @@ private: indents.pop(); if (parenDepth == 0 && (peekIs(tok!"is") || peekIs(tok!"in") - || peekIs(tok!"out") || peekIs(tok!"body"))) + || peekIs(tok!"out") || peekIs(tok!"do") || peekIsBody)) + { writeToken(); + } else if (peekIsLiteralOrIdent() || peekIsBasicType()) { writeToken(); @@ -732,7 +748,9 @@ private: { import std.algorithm : map, sum, canFind; - if (astInformation.structInitStartLocations.canFindIndex(tokens[index].index)) + auto tIndex = tokens[index].index; + + if (astInformation.structInitStartLocations.canFindIndex(tIndex)) { sBraceDepth++; auto e = expressionEndIndex(index); @@ -741,13 +759,21 @@ private: writeToken(); if (l > config.dfmt_soft_max_line_length) { + import std.algorithm.searching : find; + + auto indentInfo = astInformation.indentInfoSortedByEndLocation + .find!((a,b) => a.startLocation == b)(tIndex); + assert(indentInfo.length > 0); + cast()indentInfo[0].flags |= BraceIndentInfoFlags.tempIndent; + cast()indentInfo[0].beginIndentLevel = indents.indentLevel; + indents.push(tok!"{"); newline(); } else niBraceDepth++; } - else if (astInformation.funLitStartLocations.canFindIndex(tokens[index].index)) + else if (astInformation.funLitStartLocations.canFindIndex(tIndex)) { sBraceDepth++; if (peekBackIs(tok!")")) @@ -803,15 +829,34 @@ private: void formatRightBrace() { - if (astInformation.structInitEndLocations.canFindIndex(tokens[index].index)) + void popToBeginIndent(BraceIndentInfo indentInfo) + { + foreach(i; indentInfo.beginIndentLevel .. indents.indentLevel) + { + indents.pop(); + } + + indentLevel = indentInfo.beginIndentLevel; + } + + size_t pos; + if (astInformation.structInitEndLocations.canFindIndex(tokens[index].index, &pos)) { if (sBraceDepth > 0) sBraceDepth--; if (niBraceDepth > 0) niBraceDepth--; + + auto indentInfo = astInformation.indentInfoSortedByEndLocation[pos]; + if (indentInfo.flags & BraceIndentInfoFlags.tempIndent) + { + popToBeginIndent(indentInfo); + simpleNewline(); + indent(); + } writeToken(); } - else if (astInformation.funLitEndLocations.canFindIndex(tokens[index].index)) + else if (astInformation.funLitEndLocations.canFindIndex(tokens[index].index, &pos)) { if (niBraceDepth > 0) { @@ -913,9 +958,11 @@ private: if (!currentIs(tok!"{") && !currentIs(tok!";")) write(" "); } - else if (!currentIs(tok!"{") && !currentIs(tok!";") - && !currentIs(tok!"in") && !currentIs(tok!"out") && !currentIs(tok!"body")) + else if (!currentIs(tok!"{") && !currentIs(tok!";") && !currentIs(tok!"in") && + !currentIs(tok!"out") && !currentIs(tok!"do") && current.text != "body") + { newline(); + } else if (currentIs(tok!"{") && indents.topAre(tok!"static", tok!"if")) { // Hacks to format braced vs non-braced static if declarations. @@ -1004,7 +1051,12 @@ private: if (!currentIs(tok!"{")) newline(); break; - case tok!"body": + case tok!"identifier": + if (current.text == "body") + goto case tok!"do"; + else + goto default; + case tok!"do": if (!peekBackIs(tok!"}")) newline(); writeToken(); @@ -1190,11 +1242,14 @@ private: break; case tok!".": regenLineBreakHintsIfNecessary(index); - if (linebreakHints.canFind(index) || (linebreakHints.length == 0 + immutable bool ufcsWrap = astInformation.ufcsHintLocations.canFindIndex(current.index); + if (ufcsWrap || linebreakHints.canFind(index) || (linebreakHints.length == 0 && currentLineLength + nextTokenLength() > config.max_line_length)) { pushWrapIndent(); newline(); + if (ufcsWrap) + regenLineBreakHints(index); } writeToken(); break; @@ -1317,7 +1372,18 @@ private: void regenLineBreakHints(immutable size_t i) { - immutable size_t j = expressionEndIndex(i); + import std.range : assumeSorted; + import std.algorithm.comparison : min; + import std.algorithm.searching : countUntil; + + // The end of the tokens considered by the line break algorithm is + // either the expression end index or the next mandatory line break, + // whichever is first. + auto r = assumeSorted(astInformation.ufcsHintLocations).upperBound(tokens[i].index); + immutable ufcsBreakLocation = r.empty + ? size_t.max + : tokens[i .. $].countUntil!(t => t.index == r.front) + i; + immutable size_t j = min(expressionEndIndex(i), ufcsBreakLocation); // Use magical negative value for array literals and wrap indents immutable inLvl = (indents.topIsWrap() || indents.topIs(tok!"]")) ? -indentLevel : indentLevel; @@ -1659,10 +1725,7 @@ const pure @safe @nogc: const(Token) peekBack(uint distance = 1) nothrow { - if (index < distance) - { - assert(0, "Trying to peek before the first token"); - } + assert(index >= distance, "Trying to peek before the first token"); return tokens[index - distance]; } @@ -1793,6 +1856,18 @@ const pure @safe @nogc: return peekImplementation(tokenType, 1, ignoreComments); } + bool peekIsBody() nothrow + { + return index + 1 < tokens.length && tokens[index + 1].text == "body"; + } + + bool peekBackIsFunctionDeclarationEnding() nothrow + { + return peekBackIsOneOf(false, tok!")", tok!"const", tok!"immutable", + tok!"inout", tok!"shared", tok!"@", tok!"pure", tok!"nothrow", + tok!"return", tok!"scope"); + } + bool peekBackIsSlashSlash() nothrow { return index > 0 && tokens[index - 1].type == tok!"comment" @@ -1844,9 +1919,28 @@ const pure @safe @nogc: } } -bool canFindIndex(const size_t[] items, size_t index) pure @safe @nogc +bool canFindIndex(const size_t[] items, size_t index, size_t* pos = null) pure @safe @nogc { import std.range : assumeSorted; - - return !assumeSorted(items).equalRange(index).empty; + if (!pos) + { + return !assumeSorted(items).equalRange(index).empty; + } + else + { + auto trisection_result = assumeSorted(items).trisect(index); + if (trisection_result[1].length == 1) + { + *pos = trisection_result[0].length; + return true; + } + else if (trisection_result[1].length == 0) + { + return false; + } + else + { + assert(0, "the constraint of having unique locations has been violated"); + } + } } diff --git a/src/dfmt/indentation.d b/src/dfmt/indentation.d index e009d12..8eeacea 100644 --- a/src/dfmt/indentation.d +++ b/src/dfmt/indentation.d @@ -68,7 +68,13 @@ struct IndentStack void push(IdType item) pure nothrow { arr[index] = item; - index = index + 1 == arr.length ? index : index + 1; + //FIXME this is actually a bad thing to do, + //we should not just override when the stack is + //at it's limit + if (index < arr.length) + { + index++; + } } /** @@ -76,7 +82,8 @@ struct IndentStack */ void pop() pure nothrow { - index = index == 0 ? index : index - 1; + if (index) + index--; } /** diff --git a/src/dfmt/main.d b/src/dfmt/main.d index cde0956..c229ab9 100644 --- a/src/dfmt/main.d +++ b/src/dfmt/main.d @@ -18,18 +18,18 @@ static immutable VERSION = () { { // takes the `git describe --tags` output and removes the leading // 'v' as well as any kind of newline - // if the tag is considered malformed it gets used verbatim + // if the tag is considered malformed it gets used verbatim enum gitDescribeOutput = import("VERSION"); - string result; + string result; if (gitDescribeOutput[0] == 'v') result = gitDescribeOutput[1 .. $]; else result = null; - uint minusCount; + uint minusCount; foreach (i, c; result) { @@ -39,17 +39,17 @@ static immutable VERSION = () { break; } - if (c == '-') - { + if (c == '-') + { ++minusCount; } } if (minusCount > 1) - result = null; + result = null; return result ? result ~ DEBUG_SUFFIX - : gitDescribeOutput ~ DEBUG_SUFFIX; + : gitDescribeOutput ~ DEBUG_SUFFIX; } else @@ -85,9 +85,9 @@ else void handleBooleans(string option, string value) { import dfmt.editorconfig : OptionalBoolean; - import std.exception : enforceEx; + import std.exception : enforce; - enforceEx!GetOptException(value == "true" || value == "false", "Invalid argument"); + enforce!GetOptException(value == "true" || value == "false", "Invalid argument"); immutable OptionalBoolean optVal = value == "true" ? OptionalBoolean.t : OptionalBoolean.f; switch (option) @@ -103,7 +103,7 @@ else break; case "space_before_function_parameters": optConfig.dfmt_space_before_function_parameters = optVal; - break; + break; case "split_operator_at_line_end": optConfig.dfmt_split_operator_at_line_end = optVal; break; @@ -113,6 +113,9 @@ else case "compact_labeled_statements": optConfig.dfmt_compact_labeled_statements = optVal; break; + case "single_template_constraint_indent": + optConfig.dfmt_single_template_constraint_indent = optVal; + break; default: assert(false, "Invalid command-line switch"); } @@ -139,6 +142,7 @@ else "space_before_function_parameters", &handleBooleans, "split_operator_at_line_end", &handleBooleans, "compact_labeled_statements", &handleBooleans, + "single_template_constraint_indent", &handleBooleans, "tab_width", &optConfig.tab_width, "template_constraint_style", &optConfig.dfmt_template_constraint_style); // dfmt on @@ -293,26 +297,25 @@ private version (Windows) } } -private string optionsToString(E)() if (is(E == enum)) +template optionsToString(E) if (is(E == enum)) { - import std.traits : EnumMembers; - import std.conv : to; + enum optionsToString = () { - string result = "("; - foreach (i, option; EnumMembers!E) - { - immutable s = to!string(option); - if (s != "unspecified") - result ~= s ~ "|"; - } - result = result[0 .. $ - 1] ~ ")"; - return result; + string result = "("; + foreach (s; [__traits(allMembers, E)]) + { + if (s != "unspecified") + result ~= s ~ "|"; + } + result = result[0 .. $ - 1] ~ ")"; + return result; + } (); } private void printHelp() { writeln(`dfmt `, VERSION, ` -https://github.com/Hackerpilot/dfmt +https://github.com/dlang-community/dfmt Options: --help, -h Print this help message @@ -322,23 +325,24 @@ Options: Formatting Options: --align_switch_statements - --brace_style `, optionsToString!(typeof(Config.dfmt_brace_style))(), + --brace_style `, optionsToString!(typeof(Config.dfmt_brace_style)), ` - --end_of_line `, optionsToString!(typeof(Config.end_of_line))(), ` + --end_of_line `, optionsToString!(typeof(Config.end_of_line)), ` --indent_size --indent_style, -t `, - optionsToString!(typeof(Config.indent_style))(), ` + optionsToString!(typeof(Config.indent_style)), ` --soft_max_line_length --max_line_length --outdent_attributes --space_after_cast --space_before_function_parameters --selective_import_space + --single_template_constraint_indent --split_operator_at_line_end --compact_labeled_statements --template_constraint_style `, - optionsToString!(typeof(Config.dfmt_template_constraint_style))()); + optionsToString!(typeof(Config.dfmt_template_constraint_style))); } private string createFilePath(bool readFromStdin, string fileName) diff --git a/src/dfmt/tokens.d b/src/dfmt/tokens.d index 55b31c6..952cc31 100644 --- a/src/dfmt/tokens.d +++ b/src/dfmt/tokens.d @@ -217,7 +217,7 @@ private string generateFixedLengthCases() a => format(`case tok!"%s": return %d + 1;`, a, a.length)).join("\n\t"); string[] identifierTokens = [ - "abstract", "alias", "align", "asm", "assert", "auto", "body", "bool", + "abstract", "alias", "align", "asm", "assert", "auto", "bool", "break", "byte", "case", "cast", "catch", "cdouble", "cent", "cfloat", "char", "class", "const", "continue", "creal", "dchar", "debug", "default", "delegate", "delete", "deprecated", "do", "double", "else", "enum", "export", "extern", "false", "final", "finally", "float", diff --git a/stdx-allocator b/stdx-allocator index 7487970..b7778fd 160000 --- a/stdx-allocator +++ b/stdx-allocator @@ -1 +1 @@ -Subproject commit 7487970b58f4a2c0d495679329a8a2857111f3fd +Subproject commit b7778fd6bf5f9aaaa87dd27f989cefbf9b3b365f diff --git a/tests/allman/breakOnDots.d.ref b/tests/allman/breakOnDots.d.ref index 5190a9f..f5ab653 100644 --- a/tests/allman/breakOnDots.d.ref +++ b/tests/allman/breakOnDots.d.ref @@ -3,7 +3,8 @@ unittest { { foreach (abcde, def; abcdef.map!(battlecruiser => battlecruiser[123 .. 1231231]) - .filter!(bravo => charlie[10] > 90000).sum()) + .filter!(bravo => charlie[10] > 90000) + .sum()) { } diff --git a/tests/allman/constraint_singe_tab.d.ref b/tests/allman/constraint_singe_tab.d.ref new file mode 100644 index 0000000..176e0f4 --- /dev/null +++ b/tests/allman/constraint_singe_tab.d.ref @@ -0,0 +1,9 @@ +void foo()() + if (dogs && pigs && birds && ants && foxes && flies && cats && bugs && bees + && cows && sheeps && monkeys && whales) +{ +} + +void foo()() if (dogs && pigs && birds) +{ +} diff --git a/tests/allman/constraint_singe_tab2.d.ref b/tests/allman/constraint_singe_tab2.d.ref new file mode 100644 index 0000000..59c0cb1 --- /dev/null +++ b/tests/allman/constraint_singe_tab2.d.ref @@ -0,0 +1,10 @@ +void foo()() + if (dogs && pigs && birds && ants && foxes && flies && cats && bugs && bees + && cows && sheeps && monkeys && whales) +{ +} + +void foo()() + if (dogs && pigs && birds) +{ +} diff --git a/tests/allman/do_body.d.ref b/tests/allman/do_body.d.ref new file mode 100644 index 0000000..52fd2ea --- /dev/null +++ b/tests/allman/do_body.d.ref @@ -0,0 +1,19 @@ +import character.body; + +void body() @nogc +in +{ +} +body +{ + body = null; +} + +void body() +in +{ +} +do +{ + body = null; +} diff --git a/tests/allman/issue0237.d.ref b/tests/allman/issue0237.d.ref new file mode 100644 index 0000000..7d91255 --- /dev/null +++ b/tests/allman/issue0237.d.ref @@ -0,0 +1,40 @@ +void fn() +{ + { + { + { + auto file = { + "integrationtest/feed/etc/config.iniaasdfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "etc/config.ini" + }; + { + int x; + } + } + } + } +} + +struct A +{ + int x, y, z; +} + +int main() +{ + int fun() + { + import std.stdio : writeln; + import std.typecons : tuple; + + A a = { + tuple(Variant(1))[0].get!int, tuple(Variant(2))[0].get!int, + tuple(Variant(3))[0].get!int + }; + A b = { + tuple(Variant(1))[0].get!int, tuple(Variant(2))[0].get!int, + tuple(Variant(3))[0].get!int + }; + writeln(a); + } +} diff --git a/tests/allman/ufcschain.d.ref b/tests/allman/ufcschain.d.ref new file mode 100644 index 0000000..c36b1ae --- /dev/null +++ b/tests/allman/ufcschain.d.ref @@ -0,0 +1,6 @@ +void main() +{ + stuff[].map!(things => stuff.doThings) + .filter!(stuff) + .array(); +} diff --git a/tests/constraint_singe_tab.args b/tests/constraint_singe_tab.args new file mode 100644 index 0000000..2797662 --- /dev/null +++ b/tests/constraint_singe_tab.args @@ -0,0 +1,2 @@ +--template_constraint_style=conditional_newline_indent +--single_template_constraint_indent=true diff --git a/tests/constraint_singe_tab.d b/tests/constraint_singe_tab.d new file mode 100644 index 0000000..097b267 --- /dev/null +++ b/tests/constraint_singe_tab.d @@ -0,0 +1,4 @@ +void foo()() if (dogs && pigs && birds && ants && foxes && flies && cats && bugs && bees && cows && sheeps && monkeys && whales) +{} + +void foo()() if (dogs && pigs && birds) {} diff --git a/tests/constraint_singe_tab2.args b/tests/constraint_singe_tab2.args new file mode 100644 index 0000000..608415d --- /dev/null +++ b/tests/constraint_singe_tab2.args @@ -0,0 +1,2 @@ +--template_constraint_style=always_newline_indent +--single_template_constraint_indent=true diff --git a/tests/constraint_singe_tab2.d b/tests/constraint_singe_tab2.d new file mode 100644 index 0000000..097b267 --- /dev/null +++ b/tests/constraint_singe_tab2.d @@ -0,0 +1,4 @@ +void foo()() if (dogs && pigs && birds && ants && foxes && flies && cats && bugs && bees && cows && sheeps && monkeys && whales) +{} + +void foo()() if (dogs && pigs && birds) {} diff --git a/tests/do_body.d b/tests/do_body.d new file mode 100644 index 0000000..dc8f3aa --- /dev/null +++ b/tests/do_body.d @@ -0,0 +1,7 @@ +import character.body; + +void body() @nogc +in{} body{body = null;} + +void body() +in{} do{ body = null;} diff --git a/tests/issue0237.d b/tests/issue0237.d new file mode 100644 index 0000000..3de4fea --- /dev/null +++ b/tests/issue0237.d @@ -0,0 +1,22 @@ +void fn () {{{{ +auto file = +{ "integrationtest/feed/etc/config.iniaasdfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", +"etc/config.ini" }; +{ int x; } +}}}} +struct A +{ + int x, y, z; +} + +int main() +{ + int fun() + { + import std.stdio : writeln; + import std.typecons : tuple; + A a = { tuple(Variant(1))[0].get!int, tuple(Variant(2))[0].get!int, tuple(Variant(3))[0].get!int }; + A b = { tuple(Variant(1))[0].get!int, tuple(Variant(2))[0].get!int, tuple(Variant(3))[0].get!int }; + writeln(a); + } +} diff --git a/tests/otbs/breakOnDots.d.ref b/tests/otbs/breakOnDots.d.ref index 0327058..bdfb29b 100644 --- a/tests/otbs/breakOnDots.d.ref +++ b/tests/otbs/breakOnDots.d.ref @@ -2,7 +2,8 @@ unittest { { { foreach (abcde, def; abcdef.map!(battlecruiser => battlecruiser[123 .. 1231231]) - .filter!(bravo => charlie[10] > 90000).sum()) { + .filter!(bravo => charlie[10] > 90000) + .sum()) { } abcdeabcdeabcde(12341234).abcdeabcdeabcde(12341234).abcdeabcdeabcde(12341234) diff --git a/tests/otbs/constraint_singe_tab.d.ref b/tests/otbs/constraint_singe_tab.d.ref new file mode 100644 index 0000000..39fb8eb --- /dev/null +++ b/tests/otbs/constraint_singe_tab.d.ref @@ -0,0 +1,7 @@ +void foo()() + if (dogs && pigs && birds && ants && foxes && flies && cats && bugs && bees + && cows && sheeps && monkeys && whales) { +} + +void foo()() if (dogs && pigs && birds) { +} diff --git a/tests/otbs/constraint_singe_tab2.d.ref b/tests/otbs/constraint_singe_tab2.d.ref new file mode 100644 index 0000000..975bf28 --- /dev/null +++ b/tests/otbs/constraint_singe_tab2.d.ref @@ -0,0 +1,8 @@ +void foo()() + if (dogs && pigs && birds && ants && foxes && flies && cats && bugs && bees + && cows && sheeps && monkeys && whales) { +} + +void foo()() + if (dogs && pigs && birds) { +} diff --git a/tests/otbs/do_body.d.ref b/tests/otbs/do_body.d.ref new file mode 100644 index 0000000..89138ce --- /dev/null +++ b/tests/otbs/do_body.d.ref @@ -0,0 +1,15 @@ +import character.body; + +void body() @nogc +in { +} +body { + body = null; +} + +void body() +in { +} +do { + body = null; +} diff --git a/tests/otbs/issue0237.d.ref b/tests/otbs/issue0237.d.ref new file mode 100644 index 0000000..08848ae --- /dev/null +++ b/tests/otbs/issue0237.d.ref @@ -0,0 +1,36 @@ +void fn() { + { + { + { + auto file = { + "integrationtest/feed/etc/config.iniaasdfaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", + "etc/config.ini" + }; + { + int x; + } + } + } + } +} + +struct A { + int x, y, z; +} + +int main() { + int fun() { + import std.stdio : writeln; + import std.typecons : tuple; + + A a = { + tuple(Variant(1))[0].get!int, tuple(Variant(2))[0].get!int, + tuple(Variant(3))[0].get!int + }; + A b = { + tuple(Variant(1))[0].get!int, tuple(Variant(2))[0].get!int, + tuple(Variant(3))[0].get!int + }; + writeln(a); + } +} diff --git a/tests/otbs/ufcschain.d.ref b/tests/otbs/ufcschain.d.ref new file mode 100644 index 0000000..2a4dd2b --- /dev/null +++ b/tests/otbs/ufcschain.d.ref @@ -0,0 +1,5 @@ +void main() { + stuff[].map!(things => stuff.doThings) + .filter!(stuff) + .array(); +} diff --git a/tests/ufcschain.d b/tests/ufcschain.d new file mode 100644 index 0000000..dbdd7dc --- /dev/null +++ b/tests/ufcschain.d @@ -0,0 +1,4 @@ +void main() +{ + stuff[].map!(things => stuff.doThings).filter!(stuff).array(); +}