Compare commits

..

No commits in common. "master" and "v0.6.0" have entirely different histories.

540 changed files with 703 additions and 7912 deletions

16
.gitattributes vendored
View File

@ -1,16 +0,0 @@
tests/issue0228.d text eol=lf
tests/allman/issue0228.d.ref text eol=crlf
tests/knr/issue0228.d.ref text eol=crlf
tests/otbs/issue0228.d.ref text eol=crlf
tests/issue0552_lf.d text eol=lf
tests/allman/issue0552_lf.d.ref text eol=lf
tests/knr/issue0552_lf.d.ref text eol=lf
tests/otbs/issue0552_lf.d.ref text eol=lf
tests/issue0552_cr.d text eol=cr
tests/allman/issue0552_cr.d.ref text eol=cr
tests/knr/issue0552_cr.d.ref text eol=cr
tests/otbs/issue0552_cr.d.ref text eol=cr
tests/issue0552_crlf.d text eol=crlf
tests/allman/issue0552_crlf.d.ref text eol=crlf
tests/knr/issue0552_crlf.d.ref text eol=crlf
tests/otbs/issue0552_crlf.d.ref text eol=crlf

View File

@ -1,34 +0,0 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
name: D
on:
push:
branches: [ "master" ]
pull_request:
branches: [ "master" ]
permissions:
contents: read
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: dlang-community/setup-dlang@4c99aa991ce7d19dd3064de0a4f2f6b2f152e2d7
- name: 'Build & Test'
run: |
# Build the project, with its main file included, without unittests
dub build --compiler=$DC
# Build and run tests, as defined by `unittest` configuration
# In this mode, `mainSourceFile` is excluded and `version (unittest)` are included
# See https://dub.pm/package-format-json.html#configurations
dub test --compiler=$DC
# Run tests
cd tests && rdmd test

9
.gitmodules vendored
View File

@ -1,9 +1,12 @@
[submodule "libdparse"]
path = libdparse
url = https://github.com/dlang-community/libdparse.git
[submodule "makd"]
path = makd
url = https://github.com/sociomantic-tsunami/makd
[submodule "beaver"]
path = beaver
url = https://github.com/sociomantic-tsunami/beaver.git
[submodule "stdx-allocator"]
path = stdx-allocator
url = https://github.com/dlang-community/stdx-allocator
[submodule "d-test-utils"]
path = d-test-utils
url = https://github.com/dlang-community/d-test-utils.git

18
.travis.sh Executable file
View File

@ -0,0 +1,18 @@
#!/bin/bash
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
else
git submodule update --init --recursive
make debug -j2
fi
cd tests && ./test.sh

45
.travis.yml Normal file
View File

@ -0,0 +1,45 @@
sudo: false
language: d
d:
- dmd-nightly
- dmd-beta
- dmd
- ldc-beta
- ldc
os:
- linux
# - osx # disabled until travis has more mac resources
env:
- BUILD=
- BUILD=dub
script: ./.travis.sh
jobs:
include:
- stage: Build & Upload Package
if: tag IS present
# Which package to deploy
env:
- DMD=2.076.*
- DIST=xenial
- PATH="$(git config -f .gitmodules submodule.beaver.path)/bin:$PATH"
language: generic
sudo: required
services:
- docker
git:
submodules: false
before_install: git submodule update --init
install: beaver dlang install
script:
- beaver dlang make pkg
deploy:
provider: script
script: beaver bintray upload -d dlang-community/apt/dfmt build/last/pkg/*.deb
skip_cleanup: true
on:
tags: true # must be a git tag
repo: dlang-community/dfmt # must be a tag on dlang-community

130
README.md
View File

@ -1,66 +1,53 @@
# dfmt [![Build Status](https://github.com/dlang-community/dfmt/actions/workflows/d.yml/badge.svg)](https://github.com/dlang-community/dfmt/actions?query=workflow%3A%22D%22)
# dfmt [![Build Status](https://travis-ci.org/dlang-community/dfmt.svg?branch=master)](https://travis-ci.org/dlang-community/dfmt)
**dfmt** is a formatter for D source code
## Status
**dfmt** is beta quality. Make backups of your files or use source control
when using the **--inplace** option.
## Installation
### Installing with DUB
```sh
> dub run dfmt -- -h
```
### Building from source using Make
## Building
### Using Make
* Clone the repository
* Run ```git submodule update --init --recursive``` in the dfmt directory
* To compile with DMD, run ```make``` in the dfmt directory. To compile with
LDC, run ```make ldc``` instead. The generated binary will be placed in ```dfmt/bin/```.
### Building from source using dub
* Clone the repository
* run `dub build --build=release`, optionally with `--compiler=ldc2`
### Installing with DUB
```sh
> dub fetch --version='~master' dfmt && dub run dfmt -- -h
```
## Using
By default, dfmt reads its input from **stdin** and writes to **stdout**.
If a file name is specified on the command line, input will be read from the
file instead, and output will be written to **stdout**.
**dfmt** uses [EditorConfig](http://editorconfig.org/) files for configuration. If you run **dfmt** on a
source file it will look for *.editorconfig* files that apply to that source file.
If no file is specified on the command line, **dfmt** will look for *.editorconfig*
**dfmt** uses EditorConfig files for configuration. If you run **dfmt** on a
source file it will look for .editorconfig files that apply to that source file.
If no file is specified on the command line, **dfmt** will look for .editorconfig
files that would apply to a D file in the current working directory. Command
line options can be used instead of *.editorconfig* files, or to override options
found there.
line options can be used instead of .editorconfig files, or to override options
found in .editorconfig files.
### Options
* `--help | -h`: Display command line options.
* `--inplace | -i`: A file name is required and the file will be edited in-place.
* `--align_switch_statements`: *see dfmt_align_switch_statements [below](#dfmt-specific-properties)*
* `--brace_style`: *see dfmt_brace_style [below](#dfmt-specific-properties)*
* `--compact_labeled_statements`: *see dfmt_compact_labeled_statements [below](#dfmt-specific-properties)*
* `--end_of_line`: *see end_of_line [below](#standard-editorconfig-properties)*
* `--indent_size`: *see indent_size [below](#standard-editorconfig-properties)*
* `--indent_style | -t`: *see indent_style [below](#standard-editorconfig-properties)*
* `--max_line_length`: *see max_line_length [below](#standard-editorconfig-properties)*
* `--outdent_attributes`: *see dfmt_outdent_attributes [below](#dfmt-specific-properties)*
* `--selective_import_space`: *see dfmt_selective_import_space [below](#dfmt-specific-properties)*
* `--single_template_constraint_indent`: *see dfmt_single_template_constraint_indent [below](#dfmt-specific-properties)*
* `--soft_max_line_length`: *see dfmt_soft_max_line_length [below](#dfmt-specific-properties)*
* `--space_after_cast`: *see dfmt_space_after_cast [below](#dfmt-specific-properties)*
* `--space_before_aa_colon`: *see dfmt_space_before_aa_colon [below](#dfmt-specific-properties)*
* `--space_before_named_arg_colon`: *see dfmt_space_before_named_arg_colon [below](#dfmt-specific-properties)*
* `--space_before_function_parameters`: *see dfmt_space_before_function_parameters [below](#dfmt-specific-properties)*
* `--split_operator_at_line_end`: *see dfmt_split_operator_at_line_end [below](#dfmt-specific-properties)*
* `--tab_width`: *see tab_width [below](#standard-editorconfig-properties)*
* `--template_constraint_style`: *see dfmt_template_constraint_style [below](#dfmt-specific-properties)*
* `--keep_line_breaks`: *see dfmt_keep_line_breaks [below](#dfmt-specific-properties)*
* `--single_indent`: *see dfmt_single_indent [below](#dfmt-specific-properties)*
* `--reflow_property_chains`: *see dfmt_property_chains [below](#dfmt-specific-properties)*
* `--space_after_keywords`: *see dfmt_space_after_keywords [below](#dfmt-specific-properties)*
* **--help | -h**: Display command line options
* **--inplace | -i**: A file name is required and the file will be edited in-place.
* **--align_switch_statements**: See **dfmt_align_switch_statements** below
* **--brace_style**: See **brace_style** below
* **--end_of_line**: See **end_of_line** below
* **--indent_size**: See **indent_size** below
* **--indent_style | -t**: See **indent_style** below
* **--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
* **--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
* **--tab_width**: See **tab_width** below
* **--selective_import_space**: See **dfmt_selective_import_space** below
* **--compact_labeled_statements**: See **dfmt_compact_labeled_statements** below
* **--template_constraint_style**: See **dfmt_template_constraint_style** below
### Example
```
@ -79,9 +66,9 @@ void main(string[] args)
// dfmt has no way of knowing that "getopt" is special, so it wraps the
// argument list normally
getopt(args, "optionOne", &optionOne, "optionTwo", &optionTwo, "optionThree", &optionThree);
getopt(args, "optionOne", &optionOne, "optionTwo", &optionTwo, "optionThree", &optionThree);
// dfmt off
// dfmt off
getopt(args,
"optionOne", &optionOne,
"optionTwo", &optionTwo,
@ -94,37 +81,30 @@ void main(string[] args)
**dfmt** uses [EditorConfig](http://editorconfig.org/) configuration files.
**dfmt**-specific properties are prefixed with *dfmt_*.
### Standard EditorConfig properties
Property Name | Allowed Values | Description
--------------|----------------|------------
end_of_line | `cr`, `crlf` and `lf` | [See EditorConfig documentation.](https://github.com/editorconfig/editorconfig/wiki/EditorConfig-Properties#end_of_line) When not set, `dfmt` adopts the first line ending in the input.
insert_final_newline | **`true`** | Not supported. `dfmt` always inserts a final newline.
charset | **`UTF-8`** | Not supported. `dfmt` only works correctly on UTF-8.
indent_style | `tab`, **`space`** | [See EditorConfig documentation.](https://github.com/editorconfig/editorconfig/wiki/EditorConfig-Properties#indent_style)
indent_size | positive integers (**`4`**) | [See EditorConfig documentation.](https://github.com/editorconfig/editorconfig/wiki/EditorConfig-Properties#indent_size)
tab_width | positive integers (**`4`**) | [See EditorConfig documentation.](https://github.com/editorconfig/editorconfig/wiki/EditorConfig-Properties#tab_width)
trim_trailing_whitespace | **`true`** | Not supported. `dfmt` does not emit trailing whitespace.
max_line_length | positive integers (**`120`**) | [See EditorConfig documentation.](https://github.com/editorconfig/editorconfig/wiki/EditorConfig-Properties#max_line_length)
Property Name | Allowed Values | Default Value | Description
--------------|----------------|---------------|------------
end_of_line | `cr`, `crlf` and `lf` | `lf` | [See EditorConfig documentation.](https://github.com/editorconfig/editorconfig/wiki/EditorConfig-Properties#end_of_line)
insert_final_newline | | `true` | Not supported. `dfmt` always inserts a final newline.
charset | | `UTF-8` | Not supported. `dfmt` only works correctly on UTF-8.
indent_style | `tab`, `space` | `space` | [See EditorConfig documentation.](https://github.com/editorconfig/editorconfig/wiki/EditorConfig-Properties#indent_style)
indent_size | positive integers | `4` | [See EditorConfig documentation.](https://github.com/editorconfig/editorconfig/wiki/EditorConfig-Properties#indent_size)
tab_width | positive integers | `4` | [See EditorConfig documentation.](https://github.com/editorconfig/editorconfig/wiki/EditorConfig-Properties#tab_width)
trim_trailing_whitespace | | `true` | Not supported. `dfmt` does not emit trailing whitespace.
max_line_length | positive integers | `120` | [See EditorConfig documentation.](https://github.com/editorconfig/editorconfig/wiki/EditorConfig-Properties#max_line_length)
### dfmt-specific properties
Property Name | Allowed Values | Description
--------------|----------------|------------
dfmt_brace_style | **`allman`**, `otbs`, `stroustrup` or `knr` | [See Wikipedia](https://en.wikipedia.org/wiki/Brace_style)
dfmt_soft_max_line_length | positive integers (**`80`**) | The formatting process will usually keep lines below this length, but they may be up to *max_line_length* columns long.
dfmt_align_switch_statements | **`true`**, `false` | Align labels, cases, and defaults with their enclosing switch.
dfmt_outdent_attributes (Not yet implemented) | **`true`**, `false`| Decrease the indentation level of attributes.
dfmt_split_operator_at_line_end | `true`, **`false`** | Place operators on the end of the previous line when splitting lines.
dfmt_space_after_cast | **`true`**, `false` | Insert space after the closing paren of a `cast` expression.
dfmt_space_after_keywords (Not yet implemented) | **`true`**, `false` | Insert space after `if`, `while`, `foreach`, etc, and before the `(`.
dfmt_space_before_function_parameters | `true`, **`false`** | Insert space before the opening paren of a function parameter list.
dfmt_selective_import_space | **`true`**, `false` | Insert space after the module name and before the `:` for selective imports.
dfmt_compact_labeled_statements | **`true`**, `false` | 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` | Control the formatting of template constraints.
dfmt_single_template_constraint_indent | `true`, **`false`** | Set if the constraints are indented by a single tab instead of two. Has only an effect if the style set to `always_newline_indent` or `conditional_newline_indent`.
dfmt_space_before_aa_colon | `true`, **`false`** | Adds a space after an associative array key before the `:` like in older dfmt versions.
dfmt_space_before_named_arg_colon | `true`, **`false`** | Adds a space after a named function argument or named struct constructor argument before the `:`.
dfmt_keep_line_breaks | `true`, **`false`** | Keep existing line breaks if these don't violate other formatting rules.
dfmt_single_indent | `true`, **`false`** | Set if the code in parens is indented by a single tab instead of two.
dfmt_reflow_property_chains | **`true`**, `false` | Recalculate the splitting of property chains into multiple lines.
dfmt_space_after_keywords | **`true`**, `false` | Insert space after keywords (if,while,foreach,for, etc.).
Property Name | Allowed Values | Default Value | Description
--------------|----------------|---------------|------------
dfmt_brace_style | `allman`, `otbs`, or `stroustrup` | `allman` | [See Wikipedia](https://en.wikipedia.org/wiki/Brace_style)
dfmt_soft_max_line_length | positive integers | `80` | The formatting process will usually keep lines below this length, but they may be up to max_line_length columns long.
dfmt_align_switch_statements (Not yet implemented) | `true`, `false` | `true` | Align labels, cases, and defaults with their enclosing switch.
dfmt_outdent_attributes (Not yet implemented) | `true`, `false` | `true` | Decrease the indentation level of attributes.
dfmt_split_operator_at_line_end | `true`, `false` | `false` | Place operators on the end of the previous line when splitting lines.
dfmt_space_after_cast | `true`, `false` | `true` | Insert space after the closing paren of a `cast` expression.
dfmt_space_after_keywords (Not yet implemented) | `true`, `false` | `true` | Insert space after `if`, `while`, `foreach`, etc, and before the `(`.
dfmt_space_before_function_parameters | `true`, `false` | `false` | Insert space before the opening paren of a function parameter list.
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.
## Terminology
* Braces - `{` and `}`

111
appveyor.yml Normal file
View File

@ -0,0 +1,111 @@
platform: x64
environment:
matrix:
- DC: dmd
DVersion: stable
arch: x64
- DC: dmd
DVersion: stable
arch: x86
# - DC: ldc
# DVersion: beta
# arch: x86
# - DC: ldc
# DVersion: beta
# arch: x64
# - DC: ldc
# DVersion: stable
# arch: x86
# - DC: ldc
# DVersion: stable
# arch: x64
skip_tags: false
branches:
only:
- master
install:
- ps: function ResolveLatestDMD
{
$version = $env:DVersion;
if($version -eq "stable") {
$latest = (Invoke-WebRequest "http://downloads.dlang.org/releases/LATEST").toString();
$url = "http://downloads.dlang.org/releases/2.x/$($latest)/dmd.$($latest).windows.7z";
}elseif($version -eq "beta") {
$latest = (Invoke-WebRequest "http://downloads.dlang.org/pre-releases/LATEST").toString();
$latestVersion = $latest.split("-")[0].split("~")[0];
$url = "http://downloads.dlang.org/pre-releases/2.x/$($latestVersion)/dmd.$($latest).windows.7z";
}elseif($version -eq "nightly") {
$url = "http://nightlies.dlang.org/dmd-master-2017-05-20/dmd.master.windows.7z"
}else {
$url = "http://downloads.dlang.org/releases/2.x/$($version)/dmd.$($version).windows.7z";
}
$env:PATH += ";C:\dmd2\windows\bin;";
return $url;
}
- ps: function ResolveLatestLDC
{
$version = $env:DVersion;
if($version -eq "stable") {
$latest = (Invoke-WebRequest "https://ldc-developers.github.io/LATEST").toString().replace("`n","").replace("`r","");
$url = "https://github.com/ldc-developers/ldc/releases/download/v$($latest)/ldc2-$($latest)-win64-msvc.zip";
}elseif($version -eq "beta") {
$latest = (Invoke-WebRequest "https://ldc-developers.github.io/LATEST_BETA").toString().replace("`n","").replace("`r","");
$url = "https://github.com/ldc-developers/ldc/releases/download/v$($latest)/ldc2-$($latest)-win64-msvc.zip";
} else {
$latest = $version;
$url = "https://github.com/ldc-developers/ldc/releases/download/v$($version)/ldc2-$($version)-win64-msvc.zip";
}
$env:PATH += ";C:\ldc2-$($latest)-win64-msvc\bin";
$env:DC = "ldc2";
return $url;
}
- ps: function SetUpDCompiler
{
$env:toolchain = "msvc";
if($env:DC -eq "dmd"){
echo "downloading ...";
$url = ResolveLatestDMD;
echo $url;
Invoke-WebRequest $url -OutFile "c:\dmd.7z";
echo "finished.";
pushd c:\\;
7z x dmd.7z > $null;
popd;
}
elseif($env:DC -eq "ldc"){
echo "downloading ...";
$url = ResolveLatestLDC;
echo $url;
Invoke-WebRequest $url -OutFile "c:\ldc.zip";
echo "finished.";
pushd c:\\;
7z x ldc.zip > $null;
popd;
}
}
- ps: SetUpDCompiler
build_script:
- ps: if($env:arch -eq "x86"){
$env:compilersetupargs = "x86";
$env:Darch = "x86";
$env:DConf = "m32";
}elseif($env:arch -eq "x64"){
$env:compilersetupargs = "amd64";
$env:Darch = "x86_64";
$env:DConf = "m64";
}
- ps: $env:compilersetup = "C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall";
- '"%compilersetup%" %compilersetupargs%'
test_script:
- echo %PLATFORM%
- echo %Darch%
- echo %DC%
- echo %PATH%
- '%DC% --version'
- dub test --arch=%Darch% --compiler=%DC%
- git submodule update --init --recursive
- build.bat

View File

@ -24,7 +24,7 @@ _dfmt()
eolOpts="lf cr crlf"
boolOpts="true false"
braceOpts="allman otbs stroustrup knr"
braceOpts="allman otbs stroustrup"
indentOpts="tab space"
constraintOpts="conditional_newline_indent conditional_newline always_newline always_newline_indent"

1
beaver Submodule

@ -0,0 +1 @@
Subproject commit 82f8c8f6bbd9f0fbd9753a134377bec134a5956c

6
beaver.Dockerfile Normal file
View File

@ -0,0 +1,6 @@
# Copyright sociomantic labs GmbH 2017.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.txt or copy at
# http://www.boost.org/LICENSE_1_0.txt)
FROM sociomantictsunami/dlang:v4

View File

@ -11,20 +11,6 @@ set STDXALLOCATOR=
set STDXALLOCATORBLOCKS=
set OBIN=bin\dfmt
:: git might not be installed, so we provide 0.0.0 as a fallback or use
:: the existing githash file if existent
if not exist "bin" mkdir bin
git describe --tags > bin\githash_.txt
for /f %%i in ("bin\githash_.txt") do set githashsize=%%~zi
if %githashsize% == 0 (
if not exist "bin\githash.txt" (
echo v0.0.0 > bin\githash.txt
)
) else (
move /y bin\githash_.txt bin\githash.txt
)
for %%x in (src\dfmt\*.d) do set CORE=!CORE! %%x
for %%x in (libdparse\src\std\experimental\*.d) do set STD=!STD! %%x
for %%x in (libdparse\src\dparse\*.d) do set STDD=!STDD! %%x
@ -32,6 +18,6 @@ for %%x in (stdx-allocator\source\stdx\allocator\*.d) do set STDXALLOCATOR=!STDX
for %%x in (stdx-allocator\source\stdx\allocator\building_blocks\*.d) do set STDXALLOCATORBLOCKS=!STDXALLOCATORBLOCKS! %%x
@echo on
%DC% %CORE% %STD% %STDD% %STDE% %STDXALLOCATOR% %STDXALLOCATORBLOCKS% -I"stdx-allocator\source" -I"libdparse\src" -Jbin %DFLAGS% -of%OBIN%.exe
%DC% %CORE% %STD% %STDD% %STDE% %STDXALLOCATOR% %STDXALLOCATORBLOCKS% -I"stdx-allocator\source" -I"libdparse\src" %DFLAGS% -of%OBIN%.exe
if exist %OBIN%.obj del %OBIN%.obj

@ -1 +0,0 @@
Subproject commit 206a2e6abd97b4462f3a320e4f2d23986fad3cff

View File

@ -4,17 +4,6 @@
"targetType": "autodetect",
"license": "BSL-1.0",
"dependencies": {
"libdparse": ">=0.19.2 <1.0.0"
},
"targetPath" : "bin/",
"targetName" : "dfmt",
"stringImportPaths" : [
"bin"
],
"versions" : [
"built_with_dub"
],
"preBuildCommands" : [
"$DC -run \"$PACKAGE_DIR/dubhash.d\""
]
"libdparse": "~>0.8.0-alpha.5"
}
}

View File

@ -1,23 +0,0 @@
import std.algorithm;
import std.ascii;
import std.conv;
import std.exception;
import std.file;
import std.path;
import std.process;
import std.range;
import std.string;
void main()
{
auto dir = environment.get("DUB_PACKAGE_DIR");
auto hashFile = dir.buildPath("bin", "dubhash.txt");
auto gitVer = executeShell("git -C " ~ dir ~ " describe --tags");
auto ver = (gitVer.status == 0 ? gitVer.output.strip
: "v" ~ dir.dirName.baseName.findSplitAfter(
environment.get("DUB_ROOT_PACKAGE") ~ "-")[1]).ifThrown("0.0.0")
.chain(newline).to!string.strip;
dir.buildPath("bin").mkdirRecurse;
if (!hashFile.exists || ver != hashFile.readText.strip)
hashFile.write(ver);
}

@ -1 +1 @@
Subproject commit fe6d1e38fb4fc04323170389cfec67ed7fd4e24a
Subproject commit ee0fa01ab74b6bf27bed3c7bdb9d6fb789963342

1
makd Submodule

@ -0,0 +1 @@
Subproject commit d735c1df67399693f699f8315418173a55de5313

View File

@ -1,63 +1,46 @@
PREFIX = /usr/local
SRC := $(shell find src -name "*.d") \
$(shell find libdparse/src -name "*.d")
IMPORTS := -Ilibdparse/src -Isrc -Jbin
$(shell find libdparse/src -name "*.d") \
$(shell find stdx-allocator/source -name "*.d")
INCLUDE_PATHS := -Ilibdparse/src -Istdx-allocator/source -Isrc
DMD_COMMON_FLAGS := -dip25 -w $(INCLUDE_PATHS) -Jviews
DMD_DEBUG_FLAGS := -debug -g $(DMD_COMMON_FLAGS)
DMD_FLAGS := -O -inline $(DMD_COMMON_FLAGS)
DMD_TEST_FLAGS := -unittest -g $(DMD_COMMON_FLAGS)
LDC_FLAGS := -g -w -oq $(INCLUDE_PATHS)
GDC_FLAGS := -g -w -oq $(INCLUDE_PATHS)
DC ?= dmd
LDC ?= ldc2
GDC ?= gdc
DMD_COMMON_FLAGS := -w $(IMPORTS)
DMD_DEBUG_FLAGS := -debug -g $(DMD_COMMON_FLAGS)
DMD_FLAGS := -O -inline $(DMD_COMMON_FLAGS)
DMD_TEST_FLAGS := -unittest -g $(DMD_COMMON_FLAGS)
LDC_FLAGS := -g -w -oq $(IMPORTS)
GDC_FLAGS := -g -w -oq $(IMPORTS)
override DMD_FLAGS += $(DFLAGS)
override LDC_FLAGS += $(DFLAGS)
override GDC_FLAGS += $(DFLAGS)
.PHONY: all clean install debug dmd ldc gdc pkg release test
all: bin/dfmt
bin/githash.txt:
mkdir -p bin
git describe --tags > bin/githash.txt
.PHONY: dmd ldc gdc test
dmd: bin/dfmt
ldc: bin/githash.txt
$(LDC) $(SRC) $(LDC_FLAGS) -ofbin/dfmt
views/VERSION : .git/refs/tags .git/HEAD
mkdir -p $(dir $@)
git describe --tags > $@
ldc: $(SRC)
$(LDC) $(LDC_FLAGS) $^ -ofbin/dfmt
-rm -f *.o
gdc: bin/githash.txt
$(GDC) $(SRC) $(GDC_FLAGS) -obin/dfmt
gdc: $(SRC)
$(GDC) $(GDC_FLAGS) $^ -obin/dfmt
test: debug
cd tests && ./test.d
cd tests && ./test.sh
bin/dfmt-test: bin/githash.txt $(SRC)
$(DC) $(DMD_TEST_FLAGS) $(filter %.d,$^) -of$@
bin/dfmt-test: $(SRC)
$(DC) $(DMD_TEST_FLAGS) $^ -of$@
bin/dfmt: bin/githash.txt $(SRC)
bin/dfmt: views/VERSION $(SRC)
$(DC) $(DMD_FLAGS) $(filter %.d,$^) -of$@
debug: bin/githash.txt $(SRC)
debug: views/VERSION $(SRC)
$(DC) $(DMD_DEBUG_FLAGS) $(filter %.d,$^) -ofbin/dfmt
pkg: dmd
$(MAKE) -f makd/Makd.mak pkg
clean:
$(RM) bin/dfmt bin/dfmt-test bin/githash.txt
install:
chmod +x bin/dfmt
mkdir -p $(DESTDIR)$(PREFIX)/bin
cp -f bin/dfmt $(DESTDIR)$(PREFIX)/bin/dfmt
release:
./release.sh
$(MAKE) bin/githash.txt
$(RM) bin/dfmt

31
pkg/dfmt.pkg Normal file
View File

@ -0,0 +1,31 @@
# dfmt packaging configuration
# ============================
dfmt_bindir='bin'
#-------------------------------------------------------------------------------
# Define the keyword arguments to pass to fpm (via the OPTS dict)
#-------------------------------------------------------------------------------
OPTS.update(
name = "dfmt",
url = 'https://github.com/dlang-community/dfmt',
maintainer = 'Stefan Koch <stefan.koch@sociomantic.com>',
vendor = 'Sociomantic Labs GmbH',
provides = "dfmt",
description = '''\
D source code formatter
''',
depends = FUN.autodeps('dfmt', path=dfmt_bindir),
)
#-------------------------------------------------------------------------------
# Define the positional arguments to pass to fpm (via the ARGS list)
#-------------------------------------------------------------------------------
ARGS.extend(FUN.mapfiles(dfmt_bindir, '/usr/bin', 'dfmt'))
ARGS.extend([
'bash-completion/completion/dfmt=/usr/share/bash-completion/completion/dfmt'
])
# vim: set ft=python tw=80 :

View File

@ -1,21 +0,0 @@
#!/usr/bin/env bash
# Build the Windows binaries under Linux
set -eux -o pipefail
BIN_NAME=dfmt
# Allow the script to be run from anywhere
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
cd $DIR
source setup-ldc-windows.sh
# Run LDC with cross-compilation
archiveName="$BIN_NAME-$VERSION-$OS-$ARCH_SUFFIX.zip"
echo "Building $archiveName"
mkdir -p bin
DC=ldmd2 make ldc
cd bin
mv "${BIN_NAME}" "${BIN_NAME}.exe"
zip "$archiveName" "${BIN_NAME}.exe"

View File

@ -1,23 +0,0 @@
#!/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[*]} -Jbin"
tar cvfz "bin/$archiveName" -C bin dfmt

View File

@ -0,0 +1,5 @@
### 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.

View File

@ -1,70 +0,0 @@
#!/usr/bin/env bash
# sets up LDC for cross-compilation. Source this script, s.t. the new LDC is in PATH
LDC_VERSION="1.13.0"
ARCH=${ARCH:-32}
VERSION=$(git describe --abbrev=0 --tags)
OS=windows
# Step 0: install ldc
if [ ! -f install.sh ] ; then
wget https://dlang.org/install.sh
fi
. $(bash ./install.sh -a "ldc-${LDC_VERSION}")
# for the install.sh script only
LDC_PATH="$(dirname $(dirname $(which ldc2)))"
# Step 1a: download the LDC x64 windows binaries
if [ "${ARCH}" == 64 ] && [ ! -d "ldc2-${LDC_VERSION}-windows-x64" ] ; then
wget "https://github.com/ldc-developers/ldc/releases/download/v1.13.0/ldc2-${LDC_VERSION}-windows-x64.7z"
7z x "ldc2-${LDC_VERSION}-windows-x64.7z" > /dev/null
# Step 2a: Add LDC windows binaries to LDC Linux
if [ ! -d "${LDC_PATH}/lib-win64" ] ; then
cp -r ldc2-1.13.0-windows-x64/lib "${LDC_PATH}/lib-win64"
cat >> "$LDC_PATH"/etc/ldc2.conf <<EOF
"x86_64-.*-windows-msvc":
{
switches = [
"-defaultlib=phobos2-ldc,druntime-ldc",
"-link-defaultlib-shared=false",
];
lib-dirs = [
"%%ldcbinarypath%%/../lib-win64",
];
};
EOF
fi
fi
# Step 1b: download the LDC x86 windows binaries
if [ "${ARCH}" == 32 ] && [ ! -d "ldc2-${LDC_VERSION}-windows-x86" ] ; then
wget "https://github.com/ldc-developers/ldc/releases/download/v1.13.0/ldc2-${LDC_VERSION}-windows-x86.7z"
7z x "ldc2-${LDC_VERSION}-windows-x86.7z" > /dev/null
# Step 2b: Add LDC windows binaries to LDC Linux
if [ ! -d "${LDC_PATH}/lib-win32" ] ; then
cp -r ldc2-1.13.0-windows-x86/lib "${LDC_PATH}/lib-win32"
cat >> "$LDC_PATH"/etc/ldc2.conf <<EOF
"i686-.*-windows-msvc":
{
switches = [
"-defaultlib=phobos2-ldc,druntime-ldc",
"-link-defaultlib-shared=false",
];
lib-dirs = [
"%%ldcbinarypath%%/../lib-win32",
];
};
EOF
fi
fi
# set suffices and compilation flags
if [ "$ARCH" == "64" ] ; then
ARCH_SUFFIX="x86_64"
export DFLAGS="-mtriple=x86_64-windows-msvc"
else
ARCH_SUFFIX="x86"
export DFLAGS="-mtriple=i686-windows-msvc"
fi

View File

@ -8,41 +8,18 @@ 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;
}
struct StructInitializerInfo
{
size_t startLocation;
size_t endLocation;
}
/// 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, uniq;
import std.array : array;
import std.algorithm : sort;
sort(doubleNewlineLocations);
sort(spaceAfterLocations);
sort(unaryLocations);
sort(attributeDeclarationLines);
sort(atAttributeStartLocations);
sort(caseEndLocations);
sort(structInitStartLocations);
sort(structInitEndLocations);
@ -51,20 +28,11 @@ struct ASTInformation
sort(conditionalWithElseLocations);
sort(conditionalStatementLocations);
sort(arrayStartLocations);
sort(assocArrayStartLocations);
sort(contractLocations);
sort(constraintLocations);
sort(constructorDestructorLocations);
sort(staticConstructorDestructorLocations);
sort(sharedStaticConstructorDestructorLocations);
sort!((a,b) => a.endLocation < b.endLocation)
(indentInfoSortedByEndLocation);
sort!((a,b) => a.endLocation < b.endLocation)
(structInfoSortedByEndLocation);
sort(ufcsHintLocations);
ufcsHintLocations = ufcsHintLocations.uniq().array();
sort(ternaryColonLocations);
sort(namedArgumentColonLocations);
}
/// Locations of end braces for struct bodies
@ -79,9 +47,6 @@ struct ASTInformation
/// Lines containing attribute declarations
size_t[] attributeDeclarationLines;
/// Lines containing attribute declarations that can be followed by a new line
size_t[] atAttributeStartLocations;
/// Case statement colon locations
size_t[] caseEndLocations;
@ -97,12 +62,6 @@ struct ASTInformation
/// Closing braces of function literals
size_t[] funLitEndLocations;
/// Locations of aggregate bodies (struct, class, union)
size_t[] aggregateBodyLocations;
/// Locations of function bodies
size_t[] funBodyLocations;
/// Conditional statements that have matching "else" statements
size_t[] conditionalWithElseLocations;
@ -112,9 +71,6 @@ struct ASTInformation
/// Locations of start locations of array initializers
size_t[] arrayStartLocations;
/// Locations of start locations of associative array initializers
size_t[] assocArrayStartLocations;
/// Locations of "in" and "out" tokens that begin contracts
size_t[] contractLocations;
@ -129,20 +85,6 @@ struct ASTInformation
/// Locations of constructor/destructor "this" tokens ?
size_t[] constructorDestructorLocations;
/// Locations of '.' characters that might be UFCS chains.
size_t[] ufcsHintLocations;
BraceIndentInfo[] indentInfoSortedByEndLocation;
/// Opening & closing braces of struct initializers
StructInitializerInfo[] structInfoSortedByEndLocation;
/// Locations ternary expression colons.
size_t[] ternaryColonLocations;
/// Locations of named arguments of function call or struct constructor.
size_t[] namedArgumentColonLocations;
}
/// Collects information from the AST that is useful for the formatter
@ -165,19 +107,6 @@ final class FormatVisitor : ASTVisitor
arrayInitializer.accept(this);
}
override void visit(const ArrayLiteral arrayLiteral)
{
astInformation.arrayStartLocations ~= arrayLiteral.tokens[0].index;
arrayLiteral.accept(this);
}
override void visit(const AssocArrayLiteral assocArrayLiteral)
{
astInformation.arrayStartLocations ~= assocArrayLiteral.tokens[0].index;
astInformation.assocArrayStartLocations ~= assocArrayLiteral.tokens[0].index;
assocArrayLiteral.accept(this);
}
override void visit (const SharedStaticConstructor sharedStaticConstructor)
{
astInformation.sharedStaticConstructorDestructorLocations ~= sharedStaticConstructor.location;
@ -214,18 +143,6 @@ final class FormatVisitor : ASTVisitor
destructor.accept(this);
}
override void visit (const FunctionBody functionBody)
{
if (auto bd = functionBody.specifiedFunctionBody)
{
if (bd.blockStatement)
{
astInformation.funBodyLocations ~= bd.blockStatement.startLocation;
}
}
functionBody.accept(this);
}
override void visit(const ConditionalDeclaration dec)
{
if (dec.hasElse)
@ -268,14 +185,10 @@ final class FormatVisitor : ASTVisitor
override void visit(const FunctionLiteralExpression funcLit)
{
if (funcLit.specifiedFunctionBody !is null)
if (funcLit.functionBody !is null)
{
const bs = funcLit.specifiedFunctionBody.blockStatement;
astInformation.funLitStartLocations ~= bs.startLocation;
astInformation.funLitEndLocations ~= bs.endLocation;
astInformation.indentInfoSortedByEndLocation ~=
BraceIndentInfo(bs.startLocation, bs.endLocation);
astInformation.funLitStartLocations ~= funcLit.functionBody.blockStatement.startLocation;
astInformation.funLitEndLocations ~= funcLit.functionBody.blockStatement.endLocation;
}
funcLit.accept(this);
}
@ -298,22 +211,21 @@ final class FormatVisitor : ASTVisitor
caseRangeStatement.accept(this);
}
override void visit(const SpecifiedFunctionBody specifiedFunctionBody)
override void visit(const FunctionBody functionBody)
{
if (specifiedFunctionBody.blockStatement !is null)
astInformation.doubleNewlineLocations ~= specifiedFunctionBody.blockStatement.endLocation;
specifiedFunctionBody.accept(this);
if (functionBody.blockStatement !is null)
astInformation.doubleNewlineLocations ~= functionBody.blockStatement.endLocation;
if (functionBody.bodyStatement !is null && functionBody.bodyStatement
.blockStatement !is null)
astInformation.doubleNewlineLocations
~= functionBody.bodyStatement.blockStatement.endLocation;
functionBody.accept(this);
}
override void visit(const StructInitializer structInitializer)
{
astInformation.structInitStartLocations ~= structInitializer.startLocation;
astInformation.structInitEndLocations ~= structInitializer.endLocation;
astInformation.structInfoSortedByEndLocation ~=
StructInitializerInfo(structInitializer.startLocation, structInitializer.endLocation);
astInformation.indentInfoSortedByEndLocation ~=
BraceIndentInfo(structInitializer.startLocation, structInitializer.endLocation);
structInitializer.accept(this);
}
@ -331,15 +243,12 @@ final class FormatVisitor : ASTVisitor
override void visit(const Invariant invariant_)
{
if (invariant_.blockStatement !is null)
astInformation.doubleNewlineLocations ~= invariant_.blockStatement.endLocation;
astInformation.doubleNewlineLocations ~= invariant_.blockStatement.endLocation;
invariant_.accept(this);
}
override void visit(const StructBody structBody)
{
astInformation.aggregateBodyLocations ~= structBody.startLocation;
astInformation.doubleNewlineLocations ~= structBody.endLocation;
structBody.accept(this);
}
@ -359,26 +268,6 @@ 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!"-")
@ -394,110 +283,18 @@ final class FormatVisitor : ASTVisitor
attributeDeclaration.accept(this);
}
override void visit(const FunctionAttribute functionAttribute)
{
if (functionAttribute.atAttribute !is null)
astInformation.atAttributeStartLocations ~= functionAttribute.atAttribute.startLocation;
functionAttribute.accept(this);
}
override void visit(const MemberFunctionAttribute memberFunctionAttribute)
{
if (memberFunctionAttribute.atAttribute !is null)
astInformation.atAttributeStartLocations ~= memberFunctionAttribute.atAttribute.startLocation;
memberFunctionAttribute.accept(this);
}
override void visit(const Attribute attribute)
{
if (attribute.atAttribute !is null)
astInformation.atAttributeStartLocations ~= attribute.atAttribute.startLocation;
attribute.accept(this);
}
override void visit(const StorageClass storageClass)
{
if (storageClass.atAttribute !is null)
astInformation.atAttributeStartLocations ~= storageClass.atAttribute.startLocation;
storageClass.accept(this);
}
override void visit(const InContractExpression inContractExpression)
{
astInformation.contractLocations ~= inContractExpression.inTokenLocation;
inContractExpression.accept(this);
}
override void visit(const InStatement inStatement)
{
astInformation.contractLocations ~= inStatement.inTokenLocation;
inStatement.accept(this);
}
override void visit(const OutContractExpression outContractExpression)
{
astInformation.contractLocations ~= outContractExpression.outTokenLocation;
outContractExpression.accept(this);
}
override void visit(const OutStatement outStatement)
{
astInformation.contractLocations ~= outStatement.outTokenLocation;
outStatement.accept(this);
}
override void visit(const TernaryExpression ternaryExpression)
{
astInformation.ternaryColonLocations ~= ternaryExpression.colon.index;
ternaryExpression.accept(this);
}
override void visit(const FunctionCallExpression functionCall)
{
visit(functionCall.arguments);
functionCall.accept(this);
}
override void visit(const NewExpression newCall)
{
visit(newCall.arguments);
newCall.accept(this);
}
override void visit(const NewAnonClassExpression newAnonClassCall)
{
visit(newAnonClassCall.constructorArguments);
newAnonClassCall.accept(this);
}
private void visit(const Arguments arguments)
{
// Check if call has any arguments.
if (!arguments || arguments.namedArgumentList is null)
{
return;
}
foreach (item; arguments.namedArgumentList.items)
{
// Do nothing if not a named argument.
if (item.name == tok!"")
{
continue;
}
// Find first colon if named argument.
foreach (t; item.tokens)
{
if (t.type == tok!":")
{
astInformation.namedArgumentColonLocations ~= t.index;
break;
}
}
}
}
private:
ASTInformation* astInformation;
}

View File

@ -10,20 +10,18 @@ import dfmt.editorconfig;
/// Brace styles
enum BraceStyle
{
_unspecified,
unspecified,
/// $(LINK https://en.wikipedia.org/wiki/Indent_style#Allman_style)
allman,
/// $(LINK https://en.wikipedia.org/wiki/Indent_style#Variant:_1TBS)
otbs,
/// $(LINK https://en.wikipedia.org/wiki/Indent_style#Variant:_Stroustrup)
stroustrup,
/// $(LINK https://en.wikipedia.org/wiki/Indentation_style#K&R_style)
knr,
stroustrup
}
enum TemplateConstraintStyle
{
_unspecified,
unspecified,
conditional_newline_indent,
conditional_newline,
always_newline,
@ -55,20 +53,6 @@ struct Config
OptionalBoolean dfmt_compact_labeled_statements;
///
TemplateConstraintStyle dfmt_template_constraint_style;
///
OptionalBoolean dfmt_single_template_constraint_indent;
///
OptionalBoolean dfmt_space_before_aa_colon;
///
OptionalBoolean dfmt_keep_line_breaks;
///
OptionalBoolean dfmt_single_indent;
///
OptionalBoolean dfmt_reflow_property_chains;
///
OptionalBoolean dfmt_space_after_statement_keyword;
///
OptionalBoolean dfmt_space_before_named_arg_colon;
mixin StandardEditorConfigFields;
@ -79,7 +63,7 @@ struct Config
void initializeWithDefaults()
{
pattern = "*.d";
end_of_line = EOL._default;
end_of_line = EOL.lf;
indent_style = IndentStyle.space;
indent_size = 4;
tab_width = 4;
@ -95,12 +79,6 @@ 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;
dfmt_space_before_aa_colon = OptionalBoolean.f;
dfmt_keep_line_breaks = OptionalBoolean.f;
dfmt_single_indent = OptionalBoolean.f;
dfmt_reflow_property_chains = OptionalBoolean.t;
dfmt_space_before_named_arg_colon = OptionalBoolean.f;
}
/**

View File

@ -26,22 +26,21 @@ private auto commentRe = ctRegex!(`^\s*[#;].*$`);
enum OptionalBoolean : ubyte
{
_unspecified = 3,
unspecified = 3,
t = 1,
f = 0
}
enum IndentStyle : ubyte
{
_unspecified,
unspecified,
tab,
space
}
enum EOL : ubyte
{
_unspecified,
_default,
unspecified,
lf,
cr,
crlf
@ -75,7 +74,7 @@ mixin template StandardEditorConfigFields()
static if (N == "pattern")
continue;
else static if (is(T == enum))
*thisN = otherN != T._unspecified ? otherN : *thisN;
*thisN = otherN != T.unspecified ? otherN : *thisN;
else static if (is(T == int))
*thisN = otherN != -1 ? otherN : *thisN;
else static if (is(T == string))

File diff suppressed because it is too large Load Diff

View File

@ -2,9 +2,8 @@ module dfmt.globmatch_editorconfig;
import std.path : CaseSensitive;
import std.range : isForwardRange, ElementEncodingType;
import std.traits : isSomeChar, isSomeString;
import std.range.primitives : empty, save, front, popFront;
import std.traits : Unqual;
import std.string : isSomeChar, isSomeString, empty, save, front, popFront;
import std.typecons : Unqual;
import std.conv : to;
import std.path : filenameCharCmp, isDirSeparator;
@ -12,7 +11,7 @@ import std.path : filenameCharCmp, isDirSeparator;
// * changes meaning to match all characters except '/'
// ** added to take over the old meaning of *
bool globMatchEditorConfig(CaseSensitive cs = CaseSensitive.osDefault, C, Range)(
Range path, const(C)[] pattern) @safe pure
Range path, const(C)[] pattern) @safe pure nothrow
if (isForwardRange!Range && isSomeChar!(ElementEncodingType!Range)
&& isSomeChar!C && is(Unqual!C == Unqual!(ElementEncodingType!Range)))
in
@ -23,7 +22,7 @@ in
assert(balancedParens(pattern, '[', ']', 0));
assert(balancedParens(pattern, '{', '}', 0));
}
do
body
{
alias RC = Unqual!(ElementEncodingType!Range);

View File

@ -5,12 +5,8 @@
module dfmt.indentation;
import dfmt.config;
import dfmt.editorconfig;
import dparse.lexer;
import std.bitmanip : bitfields;
/**
* Returns: true if the given token type is a wrap indent type
*/
@ -33,31 +29,6 @@ bool isTempIndent(IdType type) pure nothrow @nogc @safe
*/
struct IndentStack
{
/// Configuration
private const Config* config;
this(const Config* config)
{
this.config = config;
}
static struct Details
{
mixin(bitfields!(
// generally true for all operators except {, case, @, ], (, )
bool, "wrap", 1,
// temporary indentation which get's reverted when a block starts
// generally true for all tokens except ), {, case, @
bool, "temp", 1,
// emit minimal newlines
bool, "mini", 1,
// for associative arrays or arrays containing them, break after every item
bool, "breakEveryItem", 1,
// when an item inside an array would break mid-item, definitely break at the comma first
bool, "preferLongBreaking", 1,
uint, "", 27));
}
/**
* Get the indent size at the most recent occurrence of the given indent type
*/
@ -84,7 +55,7 @@ struct IndentStack
int tempIndentCount = 0;
for (size_t i = index; i > 0; i--)
{
if (!details[i - 1].wrap && arr[i - 1] != tok!"]")
if (!isWrapIndent(arr[i - 1]) && arr[i - 1] != tok!"]")
break;
tempIndentCount++;
}
@ -95,27 +66,9 @@ struct IndentStack
* Pushes the given indent type on to the stack.
*/
void push(IdType item) pure nothrow
{
Details detail;
detail.wrap = isWrapIndent(item);
detail.temp = isTempIndent(item);
push(item, detail);
}
/**
* Pushes the given indent type on to the stack.
*/
void push(IdType item, Details detail) pure nothrow
{
arr[index] = item;
details[index] = detail;
//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++;
}
index = index + 1 == arr.length ? index : index + 1;
}
/**
@ -123,8 +76,7 @@ struct IndentStack
*/
void pop() pure nothrow
{
if (index)
index--;
index = index == 0 ? index : index - 1;
}
/**
@ -132,7 +84,7 @@ struct IndentStack
*/
void popWrapIndents() pure nothrow @safe @nogc
{
while (index > 0 && details[index - 1].wrap)
while (index > 0 && isWrapIndent(arr[index - 1]))
index--;
}
@ -141,7 +93,7 @@ struct IndentStack
*/
void popTempIndents() pure nothrow @safe @nogc
{
while (index > 0 && details[index - 1].temp)
while (index > 0 && isTempIndent(arr[index - 1]))
index--;
}
@ -166,15 +118,7 @@ struct IndentStack
*/
bool topIsTemp()
{
return index > 0 && index <= arr.length && details[index - 1].temp;
}
/**
* Returns: `true` if the top of the indent stack is a temporary indent with the specified token
*/
bool topIsTemp(IdType item)
{
return index > 0 && index <= arr.length && arr[index - 1] == item && details[index - 1].temp;
return index > 0 && index <= arr.length && isTempIndent(arr[index - 1]);
}
/**
@ -182,15 +126,7 @@ struct IndentStack
*/
bool topIsWrap()
{
return index > 0 && index <= arr.length && details[index - 1].wrap;
}
/**
* Returns: `true` if the top of the indent stack is a temporary indent with the specified token
*/
bool topIsWrap(IdType item)
{
return index > 0 && index <= arr.length && arr[index - 1] == item && details[index - 1].wrap;
return index > 0 && index <= arr.length && isWrapIndent(arr[index - 1]);
}
/**
@ -213,11 +149,6 @@ struct IndentStack
return arr[index - 1];
}
Details topDetails() const pure nothrow @property @safe @nogc
{
return details[index - 1];
}
int indentLevel() const pure nothrow @property @safe @nogc
{
return indentSize();
@ -231,16 +162,13 @@ struct IndentStack
/**
* Dumps the current state of the indentation stack to `stderr`. Used for debugging.
*/
void dump(size_t pos = size_t.max, string file = __FILE__, uint line = __LINE__) const
void dump(string file = __FILE__, uint line = __LINE__)
{
import dparse.lexer : str;
import std.algorithm.iteration : map;
import std.stdio : stderr;
if (pos == size_t.max)
stderr.writefln("\033[31m%s:%d %(%s %)\033[0m", file, line, arr[0 .. index].map!(a => str(a)));
else
stderr.writefln("\033[31m%s:%d at %d %(%s %)\033[0m", file, line, pos, arr[0 .. index].map!(a => str(a)));
stderr.writefln("\033[31m%s:%d %(%s %)\033[0m", file, line, arr[0 .. index].map!(a => str(a)));
}
private:
@ -248,7 +176,6 @@ private:
size_t index;
IdType[256] arr;
Details[arr.length] details;
int indentSize(const size_t k = size_t.max) const pure nothrow @safe @nogc
{
@ -262,28 +189,17 @@ private:
{
immutable int pc = (arr[i] == tok!"!" || arr[i] == tok!"(" || arr[i] == tok!")") ? parenCount + 1
: parenCount;
if ((details[i].wrap || arr[i] == tok!"(") && parenCount > 1)
if ((isWrapIndent(arr[i]) || arr[i] == tok!"(") && parenCount > 1)
{
parenCount = pc;
continue;
}
if (i + 1 < index)
{
if (config.dfmt_single_indent == OptionalBoolean.t && skipDoubleIndent(i, parenCount))
{
parenCount = pc;
if (arr[i] == tok!"]")
continue;
}
immutable currentIsNonWrapTemp = !details[i].wrap
&& details[i].temp && arr[i] != tok!")" && arr[i] != tok!"!";
if (currentIsNonWrapTemp && arr[i + 1] == tok!"]")
{
parenCount = pc;
continue;
}
immutable currentIsNonWrapTemp = !isWrapIndent(arr[i])
&& isTempIndent(arr[i]) && arr[i] != tok!")" && arr[i] != tok!"!";
if (arr[i] == tok!"static"
&& arr[i + 1].among!(tok!"if", tok!"else", tok!"foreach", tok!"foreach_reverse")
&& (i + 2 >= index || arr[i + 2] != tok!"{"))
@ -298,23 +214,15 @@ private:
continue;
}
}
else if (parenCount == 0 && arr[i] == tok!"(" && config.dfmt_single_indent == OptionalBoolean.f)
else if (parenCount == 0 && arr[i] == tok!"(")
size++;
if (arr[i] == tok!"!")
size++;
parenCount = pc;
size++;
}
return size;
}
bool skipDoubleIndent(size_t i, int parenCount) const pure nothrow @safe @nogc
{
return (details[i + 1].wrap && arr[i] == tok!")")
|| (parenCount == 0 && arr[i + 1] == tok!"," && arr[i] == tok!"(");
}
}
unittest

View File

@ -4,9 +4,6 @@
// http://www.boost.org/LICENSE_1_0.txt)
module dfmt.main;
import std.string : strip;
static immutable VERSION = () {
debug
{
@ -17,19 +14,49 @@ static immutable VERSION = () {
enum DEBUG_SUFFIX = "";
}
version (built_with_dub)
static if (is(typeof(import("VERSION"))))
{
enum DFMT_VERSION = import("dubhash.txt").strip;
// 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
enum gitDescribeOutput = import("VERSION");
string result;
if (gitDescribeOutput[0] == 'v')
result = gitDescribeOutput[1 .. $];
else
result = null;
uint minusCount;
foreach (i, c; result)
{
if (c == '\n' || c == '\r')
{
result = result[0 .. i];
break;
}
if (c == '-')
{
++minusCount;
}
}
if (minusCount > 1)
result = null;
return result ? result ~ DEBUG_SUFFIX
: gitDescribeOutput ~ DEBUG_SUFFIX;
}
else
{
/**
* Current build's Git commit hash
*/
enum DFMT_VERSION = import("githash.txt").strip;
return "unknown" ~ DEBUG_SUFFIX ~ "-version";
}
return DFMT_VERSION ~ DEBUG_SUFFIX;
} ();
@ -38,13 +65,13 @@ version (NoMain)
}
else
{
import std.array : front, popFront;
import std.stdio : stdout, stdin, stderr, writeln, File;
import dfmt.config : Config;
import dfmt.editorconfig : getConfigFor;
import dfmt.formatter : format;
import std.array : appender, front, popFront;
import std.getopt : getopt, GetOptException;
import std.path : buildPath, dirName, expandTilde;
import std.stdio : File, stderr, stdin, stdout, writeln;
import dfmt.editorconfig : getConfigFor;
import std.getopt : getopt, GetOptException;
int main(string[] args)
{
@ -58,9 +85,9 @@ else
void handleBooleans(string option, string value)
{
import dfmt.editorconfig : OptionalBoolean;
import std.exception : enforce;
import std.exception : enforceEx;
enforce!GetOptException(value == "true" || value == "false", "Invalid argument");
enforceEx!GetOptException(value == "true" || value == "false", "Invalid argument");
immutable OptionalBoolean optVal = value == "true" ? OptionalBoolean.t
: OptionalBoolean.f;
switch (option)
@ -76,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;
@ -86,27 +113,6 @@ 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;
case "space_before_aa_colon":
optConfig.dfmt_space_before_aa_colon = optVal;
break;
case "space_before_named_arg_colon":
optConfig.dfmt_space_before_named_arg_colon = optVal;
break;
case "keep_line_breaks":
optConfig.dfmt_keep_line_breaks = optVal;
break;
case "single_indent":
optConfig.dfmt_single_indent = optVal;
break;
case "reflow_property_chains":
optConfig.dfmt_reflow_property_chains = optVal;
break;
case "space_after_keywords":
optConfig.dfmt_space_after_keywords = optVal;
break;
default:
assert(false, "Invalid command-line switch");
}
@ -129,19 +135,12 @@ else
"soft_max_line_length", &optConfig.dfmt_soft_max_line_length,
"outdent_attributes", &handleBooleans,
"space_after_cast", &handleBooleans,
"space_after_keywords", &handleBooleans,
"selective_import_space", &handleBooleans,
"space_before_function_parameters", &handleBooleans,
"split_operator_at_line_end", &handleBooleans,
"compact_labeled_statements", &handleBooleans,
"single_template_constraint_indent", &handleBooleans,
"space_before_aa_colon", &handleBooleans,
"space_before_named_arg_colon", &handleBooleans,
"tab_width", &optConfig.tab_width,
"template_constraint_style", &optConfig.dfmt_template_constraint_style,
"keep_line_breaks", &handleBooleans,
"single_indent", &handleBooleans,
"reflow_property_chains", &handleBooleans);
"template_constraint_style", &optConfig.dfmt_template_constraint_style);
// dfmt on
}
catch (GetOptException e)
@ -165,13 +164,14 @@ else
args.popFront();
immutable bool readFromStdin = args.length == 0;
File output = stdout;
version (Windows)
{
// On Windows, set stdout to binary mode (needed for correct EOL writing)
// See Phobos' stdio.File.rawWrite
{
import std.stdio : _O_BINARY;
immutable fd = stdout.fileno;
immutable fd = output.fileno;
_setmode(fd, _O_BINARY);
version (CRuntime_DigitalMars)
{
@ -188,11 +188,11 @@ else
Config explicitConfig;
if (explicitConfigDir)
{
import std.file : exists, isDir;
import std.path : exists, isDir;
if (!exists(explicitConfigDir) || !isDir(explicitConfigDir))
{
stderr.writeln("--config|c must specify existing directory path");
stderr.writeln("--config_dir|c must specify existing directory path");
return 1;
}
explicitConfig = getConfigFor!Config(explicitConfigDir);
@ -230,9 +230,7 @@ else
else
break;
}
immutable bool formatSuccess = format("stdin", buffer,
stdout.lockingTextWriter(), &config);
return formatSuccess ? 0 : 1;
format("stdin", buffer, output.lockingTextWriter(), &config);
}
else
{
@ -240,7 +238,6 @@ else
if (args.length >= 2)
inplace = true;
int retVal;
while (args.length > 0)
{
const path = args.front;
@ -268,26 +265,14 @@ else
if (!config.isValid())
return 1;
File f = File(path);
// ignore empty files
if (f.size)
{
buffer = new ubyte[](cast(size_t) f.size);
f.rawRead(buffer);
auto output = appender!string;
immutable bool formatSuccess = format(path, buffer, output, &config);
if (formatSuccess)
{
if (inplace)
File(path, "wb").rawWrite(output.data);
else
stdout.rawWrite(output.data);
}
else
retVal = 1;
}
buffer = new ubyte[](cast(size_t) f.size);
f.rawRead(buffer);
if (inplace)
output = File(path, "wb");
format(path, buffer, output.lockingTextWriter(), &config);
}
return retVal;
}
return 0;
}
}
@ -304,60 +289,52 @@ private version (Windows)
}
}
template optionsToString(E) if (is(E == enum))
private string optionsToString(E)() if (is(E == enum))
{
import std.algorithm.searching : startsWith;
import std.traits : EnumMembers;
import std.conv : to;
enum optionsToString = () {
string result = "(";
foreach (s; [__traits(allMembers, E)])
{
if (!s.startsWith("_"))
result ~= s ~ "|";
}
result = result[0 .. $ - 1] ~ ")";
return result;
} ();
string result = "(";
foreach (i, option; EnumMembers!E)
{
immutable s = to!string(option);
if (s != "unspecified")
result ~= s ~ "|";
}
result = result[0 .. $ - 1] ~ ")";
return result;
}
private void printHelp()
{
writeln(`dfmt `, VERSION, `
https://github.com/dlang-community/dfmt
https://github.com/Hackerpilot/dfmt
Options:
--help, -h Print this help message
--inplace, -i Edit files in place
--config, -c Path to directory to load .editorconfig file from.
--config_dir, -c Path to directory to load .editorconfig file from.
--version Print the version number and then exit
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)), `
--keep_line_breaks
optionsToString!(typeof(Config.indent_style))(), `
--soft_max_line_length
--max_line_length
--outdent_attributes
--space_after_cast
--space_before_function_parameters
--space_after_keywords
--selective_import_space
--single_template_constraint_indent
--split_operator_at_line_end
--compact_labeled_statements
--template_constraint_style
--space_before_aa_colon
--space_before_named_arg_colon
--single_indent
--reflow_property_chains
`,
optionsToString!(typeof(Config.dfmt_template_constraint_style)));
optionsToString!(typeof(Config.dfmt_template_constraint_style))());
}
private string createFilePath(bool readFromStdin, string fileName)

View File

@ -15,7 +15,7 @@ in
{
assert(tokens[0].type == tok!"(");
}
do
body
{
uint length = 0;
size_t i = 1;
@ -134,6 +134,7 @@ int breakCost(IdType p, IdType c) pure nothrow @safe @nogc
case tok!"||":
case tok!"&&":
case tok!",":
case tok!":":
case tok!"?":
return 0;
case tok!"(":
@ -183,10 +184,6 @@ int breakCost(IdType p, IdType c) pure nothrow @safe @nogc
case tok!"~":
case tok!"+=":
return 200;
case tok!":":
// colon could be after a label or an import, where it should normally wrap like before
// for everything else (associative arrays) try not breaking around colons
return p == tok!"identifier" ? 0 : 300;
case tok!".":
return p == tok!")" ? 0 : 300;
default:
@ -220,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", "bool",
"abstract", "alias", "align", "asm", "assert", "auto", "body", "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",
@ -230,7 +227,7 @@ private string generateFixedLengthCases()
"package", "pragma", "private", "protected", "public", "pure", "real", "ref", "return", "scope",
"shared", "short", "static", "struct", "super", "switch", "synchronized", "template", "this",
"throw", "true", "try", "typedef", "typeid", "typeof", "ubyte", "ucent", "uint", "ulong",
"union", "unittest", "ushort", "version", "void", "wchar",
"union", "unittest", "ushort", "version", "void", "volatile", "wchar",
"while", "with", "__DATE__", "__EOF__", "__FILE__",
"__FUNCTION__", "__gshared", "__LINE__", "__MODULE__", "__parameters",
"__PRETTY_FUNCTION__", "__TIME__", "__TIMESTAMP__",

View File

@ -172,6 +172,9 @@ size_t[] chooseLineBreakTokens(size_t index, const Token[] tokens,
void validMoves(OR)(auto ref OR output, const Token[] tokens, immutable short[] depths,
uint current, const Config* config, int currentLineLength, int indentLevel)
{
import std.algorithm : sort, canFind, min;
import std.array : insertInPlace;
foreach (i, token; tokens)
{
if (!isBreakToken(token.type) || (((1 << i) & current) != 0))

@ -1 +1 @@
Subproject commit ae237cabd1843774cc78aad0729c914a3dd579db
Subproject commit 7487970b58f4a2c0d495679329a8a2857111f3fd

View File

@ -1,17 +0,0 @@
unittest
{
targets = [[RectangleShape.create(tex, vec2(-8 * scale, -32 * scale),
vec2(16 * scale, 48 * scale), vec4(14 / 16.0, 0, 16 / 16.0, 3 / 16.0)),
RectangleShape.create(tex, vec2(-8 * scale, -32 * scale), vec2(16 * scale,
32 * scale), vec4(14 / 16.0, 3 / 16.0, 16 / 16.0, 5 / 16.0))],
[RectangleShape.create(tex, vec2(-8 * scale, -8 * scale), vec2(16 * scale,
16 * scale), vec4(14 / 16.0, 5 / 16.0, 15 / 16.0, 6 / 16.0)), RectangleShape.create(tex,
vec2(-8 * scale, -8 * scale), vec2(16 * scale, 16 * scale),
vec4(15 / 16.0, 5 / 16.0, 16 / 16.0, 6 / 16.0))]];
int[][] foo = [[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32], [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32]];
float[3][3] mat = [[234.3456,42435.8653,23.5],[3.245,235.3,234.664],[14324.6453,23434.645,9678.345]];
}
string[][] globalArray = [["123456789012345678901234567890", "123456789012345678901234567890"], ["123456789012345678901234567890", "123456789012345678901234567890"]];

View File

@ -1,38 +0,0 @@
unittest
{
targets = [
[
RectangleShape.create(tex, vec2(-8 * scale, -32 * scale),
vec2(16 * scale, 48 * scale), vec4(14 / 16.0, 0, 16 / 16.0, 3 / 16.0)),
RectangleShape.create(tex, vec2(-8 * scale, -32 * scale),
vec2(16 * scale, 32 * scale), vec4(14 / 16.0, 3 / 16.0, 16 / 16.0, 5 / 16.0))
],
[
RectangleShape.create(tex, vec2(-8 * scale, -8 * scale),
vec2(16 * scale, 16 * scale), vec4(14 / 16.0, 5 / 16.0, 15 / 16.0, 6 / 16.0)),
RectangleShape.create(tex, vec2(-8 * scale, -8 * scale),
vec2(16 * scale, 16 * scale), vec4(15 / 16.0, 5 / 16.0, 16 / 16.0, 6 / 16.0))
]
];
int[][] foo = [
[
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32
],
[
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19,
20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32
]
];
float[3][3] mat = [
[234.3456, 42435.8653, 23.5], [3.245, 235.3, 234.664],
[14324.6453, 23434.645, 9678.345]
];
}
string[][] globalArray = [
["123456789012345678901234567890", "123456789012345678901234567890"],
["123456789012345678901234567890", "123456789012345678901234567890"]
];

View File

@ -1,23 +0,0 @@
class C
{
void f()
{
if (true)
{
f(map.map.map.map.map.map.map.map.map.map.map.map.map.map.map.map
.map.map.map.map.map.map, __FILE__, __FILE__, __FILE__, __FILE__, __FILE__,
__FILE__, __FILE__, __FILE__, __FILE__, __FILE__, __FILE__,
__FILE__, __FILE__, __FILE__, __FILE__, __FILE__, __LINE__);
g(map && map && map && map && map && map && map && map && map && map && map
&& map, __FILE__, __FILE__, __FILE__, __FILE__, __FILE__,
__FILE__, __FILE__, __LINE__);
h(map || map || map || map || map || map || map || map || map || map || map
|| map, __FILE__, __FILE__, __FILE__, __FILE__, __FILE__,
__FILE__, __FILE__, __LINE__);
i(map + map + map + map + map + map + map + map + map + map + map + map + map
+ map + map + map + map + map, __FILE__, __FILE__, __FILE__,
__FILE__, __FILE__, __FILE__, __FILE__, __LINE__);
}
}
}

View File

@ -1,31 +0,0 @@
class C
{
void f()
{
if (true)
{
f(
array.map!(a => a.prop)
.array
.to!string,
__FILE__,
__LINE__);
g(
map &&
map,
__FILE__,
__LINE__);
h(
map ||
map,
__FILE__,
__LINE__);
i(
map
+ map,
__FILE__,
__LINE__);
}
}
}

View File

@ -1,7 +0,0 @@
unittest
{
foo([
target.value.region[1], target.value.region[1], target.value.region[1],
target.value.region[1], target.value.region[1]
]);
}

View File

@ -1,8 +0,0 @@
void main()
{
string key;
int[string] var = [
key: 5
];
}

View File

@ -1,26 +0,0 @@
unittest
{
Bson base = Bson([
"maps": Bson([
Bson(["id": Bson(4), "comment": Bson("hello")]),
Bson(["id": Bson(49), "comment": Bson(null)])
]),
"short": Bson(["a": "b", "c": "d"]),
"numbers": Bson([
1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2,
3, 4, 5, 6, 7, 8, 9, 0
]),
"shuffleOnReset": serializeToBson([
"all": false,
"selected": true,
"maybe": false
]),
"resetOnEmpty": Bson(false),
"applyMods": Bson(true),
"sendComments": Bson(true)
]);
int[] x = [
1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1, 2, 3,
4, 5, 6, 7, 8, 9, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0
];
}

View File

@ -1,25 +0,0 @@
auto find()
{
return Map.findRange([
"$and": [
["deleted": Bson(false)],
[
"$or": Bson([
serializeToBson(["forceUpdate": Bson(true)]),
serializeToBson([
"info.approved": ["$eq": Bson(1)],
"fetchDate": [
"$lte": Bson(BsonDate(currentTime - 60.days))
]
]),
serializeToBson([
"info.approved": ["$ne": Bson(1)],
"fetchDate": [
"$lte": Bson(BsonDate(currentTime - 14.days))
]
])
])
]
]
]);
}

View File

@ -3,8 +3,7 @@ unittest
{
{
foreach (abcde, def; abcdef.map!(battlecruiser => battlecruiser[123 .. 1231231])
.filter!(bravo => charlie[10] > 90000)
.sum())
.filter!(bravo => charlie[10] > 90000).sum())
{
}

View File

@ -2,6 +2,6 @@ int /*sneaky*/ foo( /*comments*/ ) /*everywhere*/
{
// comment on its own line
foo() // comment on same line
.bar(); // also on same line
.bar(); // also on same line
/* again */ // same line
}

View File

@ -1,9 +0,0 @@
void foo()()
if (dogs && pigs && birds && ants && foxes && flies && cats && bugs && bees
&& cows && sheeps && monkeys && whales)
{
}
void foo()() if (dogs && pigs && birds)
{
}

View File

@ -1,10 +0,0 @@
void foo()()
if (dogs && pigs && birds && ants && foxes && flies && cats && bugs && bees
&& cows && sheeps && monkeys && whales)
{
}
void foo()()
if (dogs && pigs && birds)
{
}

View File

@ -1,8 +0,0 @@
void main()
{
if (true)
debug
{
foo();
}
}

View File

@ -1,7 +0,0 @@
void main()
{
debug (0)
foo();
else
bar();
}

View File

@ -1,21 +0,0 @@
int foo(int arg)
in
{
assert(arg > 0);
}
out (result)
{
assert(result == 0);
}
do
{
return 0;
}
int bar(int arg)
in (arg > 0)
out (; true)
out /*Major*/ ( /*Tom*/ result /*To ground control*/ ; result == 0)
{
return 0;
}

View File

@ -1,19 +0,0 @@
import character.body;
void body() @nogc
in
{
}
body
{
body = null;
}
void body()
in
{
}
do
{
body = null;
}

View File

@ -1,6 +0,0 @@
enum Foo
{
deprecated member0,
@UDA(0) member1
}

View File

@ -1,54 +0,0 @@
static foreach (x; [
1,
2,
3,
])
{
}
static foreach_reverse (x; [
1,
2,
3,
])
{
}
void f()
{
foreach (x; [
1,
2,
3,
])
{
}
foreach_reverse (x; [
1,
2,
3,
])
{
}
if (!SymbolTool.instance.workspacesFilesUris.canFind!sameFile(uri))
{
send(TextDocument.publishDiagnostics, new PublishDiagnosticsParams(uri, [
]));
}
foreach (x; map([
1,
2,
3,
]))
{
}
foreach (x; foo!(map!([
1,
2,
3,
])))
{
}
}

View File

@ -1 +0,0 @@
void foo(@UDA(0) @UDA(1) Bar bar);

View File

@ -1 +0,0 @@
alias u8 = ubyte

View File

@ -1,4 +1,3 @@
immutable NameId[] namesA = [
{"Aacgr", 0x00386}, // GREEK CAPITAL LETTER ALPHA WITH TONOS
{"aacgr", 0x003AC}, // GREEK SMALL LETTER ALPHA WITH TONOS
immutable NameId[] namesA = [{"Aacgr", 0x00386}, // GREEK CAPITAL LETTER ALPHA WITH TONOS
{"aacgr", 0x003AC}, // GREEK SMALL LETTER ALPHA WITH TONOS
];

View File

@ -9,28 +9,25 @@ string generateFixedLengthCases()
string[] fixedLengthTokens = [
"abstract", "alias", "align", "asm", "assert", "auto", "body", "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", "for", "foreach",
"foreach_reverse", "function", "goto", "idouble", "if", "ifloat",
"immutable", "import", "in", "inout", "int", "interface", "invariant",
"ireal", "is", "lazy", "long", "macro", "mixin", "module", "new",
"nothrow", "null", "out", "override", "package", "pragma", "private",
"protected", "public", "pure", "real", "ref", "return", "scope", "shared",
"short", "static", "struct", "super", "switch", "synchronized", "template",
"this", "throw", "true", "try", "typedef", "typeid", "typeof", "ubyte",
"ucent", "uint", "ulong", "union", "unittest", "ushort", "version", "void",
"volatile", "wchar", "while", "with", "__DATE__", "__EOF__",
"__FILE__", "__FUNCTION__", "__gshared", "__LINE__",
"__MODULE__", "__parameters", "__PRETTY_FUNCTION__", "__TIME__",
"__TIMESTAMP__", "__traits", "__vector", "__VENDOR__", "__VERSION__",
",", ".", "..", "...", "/", "/=", "!", "!<", "!<=", "!<>", "!<>=",
"!=", "!>", "!>=", "$", "%", "%=", "&", "&&", "&=", "(", ")", "*",
"*=", "+", "++", "+=", "-", "--", "-=", ":", ";", "<", "<<", "<<=",
"<=", "<>", "<>=", "=", "==", "=>", ">", ">=", ">>", ">>=", ">>>",
">>>=", "?", "@", "[", "]", "^", "^=", "^^", "^^=", "{", "|", "|=", "||",
"}", "~", "~="
"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",
"for", "foreach", "foreach_reverse", "function", "goto", "idouble", "if", "ifloat", "immutable",
"import", "in", "inout", "int", "interface", "invariant", "ireal", "is",
"lazy", "long", "macro", "mixin", "module", "new", "nothrow", "null", "out", "override",
"package", "pragma", "private", "protected", "public", "pure", "real", "ref", "return", "scope",
"shared", "short", "static", "struct", "super", "switch", "synchronized", "template", "this",
"throw", "true", "try", "typedef", "typeid", "typeof", "ubyte", "ucent", "uint", "ulong",
"union", "unittest", "ushort", "version", "void", "volatile", "wchar",
"while", "with", "__DATE__", "__EOF__", "__FILE__",
"__FUNCTION__", "__gshared", "__LINE__", "__MODULE__", "__parameters",
"__PRETTY_FUNCTION__", "__TIME__", "__TIMESTAMP__",
"__traits", "__vector", "__VENDOR__", "__VERSION__", ",", ".", "..",
"...", "/", "/=", "!", "!<", "!<=", "!<>", "!<>=", "!=", "!>", "!>=",
"$", "%", "%=", "&", "&&", "&=", "(", ")", "*", "*=", "+", "++",
"+=", "-", "--", "-=", ":", ";", "<", "<<", "<<=", "<=", "<>", "<>=",
"=", "==", "=>", ">", ">=", ">>", ">>=", ">>>", ">>>=", "?", "@", "[",
"]", "^", "^=", "^^", "^^=", "{", "|", "|=", "||", "}", "~", "~="
];
}

View File

@ -1,15 +0,0 @@
unittest
{
testScene = new Scene(longArgument, longArgument, longArgument,
longArgument, longArgument, longArgument, delegate(Scene scene) {
import std.stdio;
if (!scene.alreadyEntered)
{
fwriteln(
"This is a test. This is a test. This is a test. This is a test. This is a test. Test12.");
auto p = cast(Portal) sceneManager.previousScene;
scene.destroyCurrentScript();
}
});
}

View File

@ -1,5 +1,5 @@
auto fun = function() {};
auto fun = () {};
auto fun = function() { };
auto fun = () { };
auto fun = {};
auto fun = { int i; };

View File

@ -1,15 +0,0 @@
void foo()
{
string command;
version (Posix)
command ~= " 2> /dev/null 1> /dev/null";
version (Posix)
command ~= " 2> /dev/null 1> /dev/null";
unittest
{
version (Posix)
command ~= " 2> /dev/null 1> /dev/null";
}
}

View File

@ -1,16 +0,0 @@
void main()
{
auto myTid = runTask({
auto conn = connectTCP("localhost", 4222);
auto l = Lexer(conn);
foreach (t; l)
{
}
conn.close();
});
// foo
runEventLoop();
}

View File

@ -1,8 +0,0 @@
/* This test relies on ../.gitattributes to contain these lines:
tests/issue0228.d text eol=lf
tests/allman/issue0228.d.ref text eol=crlf
tests/knr/issue0228.d.ref text eol=crlf
tests/otbs/issue0228.d.ref text eol=crlf
*/

View File

@ -1,40 +0,0 @@
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);
}
}

View File

@ -1,5 +0,0 @@
enum Status : bool
{
abort = true,
ignore = false
}

View File

@ -1,23 +0,0 @@
unittest
{
with (Object)
{
// do something
}
with (Object) with (Object)
{
// do something
}
with (Object) with (Object) with (Object)
{
// do something
}
with (Object)
{
with (Object)
{
// do something
}
}
}

View File

@ -1,11 +0,0 @@
void main()
{
S s1 = {a: 3};
S s2 = {a: 3, b: "test string"};
S s3 = {a: 3, b: "test string", c: {x: 3.14, y: 3 + 4}};
T t = {
someStructMember1: 2, someStructMember2: 42, someStructMember3: null, // foobar
someOtherMember1: objA, someOtherMember2: objB, someOtherMember3: 0,
somethingMore: null, someFlagInThisStruct: -1
};
}

View File

@ -1,19 +0,0 @@
void main()
{
debug foo();
else bar();
debug (0)
foo();
else
bar();
// inlineElse reset check
debug foo();
if (true)
foo();
else
bar();
}

View File

@ -1,16 +0,0 @@
void foo()
{
if (true)
enum vectorizeable = aLongExpressionThatCausesWrapping()
&& aLongExpressionThatCausesWrapping();
else
enum vectorizeable = false;
if (true)
{
enum vectorizeable = aLongExpressionThatCausesWrapping()
&& aLongExpressionThatCausesWrapping();
}
else
enum vectorizeable = false;
}

View File

@ -1,3 +0,0 @@
alias foo = typeof({ import std.math; });
alias bar = typeof({ write("aaa"); });
alias baz = typeof({});

View File

@ -1,4 +0,0 @@
void main()
{
() @trusted { stderr.writeln("\033[01;33m", url, "\033[0m"); }();
}

View File

@ -1,4 +0,0 @@
class Bar(A) : Foo
if (isFloating!A)
{
}

View File

@ -1,6 +0,0 @@
import super_long_import_module_name : withSuperLongSymbolNames, andAlsoLotsOfThem;
import super_long_import_module_name : withSuperLongSymbolNames,
andAlsoLotsOfThem, lotsAnsLots, andLots, andLotsOfThem, lineExceeds120;
private:
void foo();

View File

@ -1,15 +0,0 @@
void foo() /**/
in
{
}
body
{
}
void bar() /**/
out
{
}
body
{
}

View File

@ -1,22 +0,0 @@
void main(string[] args)
{
// Test with catch
if (args.length > 1)
try
doSomeStuff();
catch (Exception error)
ohNoSomeErrorHappened();
else
thatsNotHowYouUseThisProgram();
// Test with finally
if (args.length > 2)
try
doOtherStuff();
catch (Exception error)
ohNoSomeErrorHappened();
finally
doSomeCleanup();
else
dontDoOtherStuff();
}

View File

@ -1,30 +0,0 @@
import std.stdio : readln, /* comment1 */ writeln;
import std.stdio : readln, // comment2
writeln;
import std.stdio : readln,
// comment3
writeln;
import std.stdio : readln,
/* comment4 */
writeln;
import std.stdio : readln, readln, readln, readln, readln, readln, readln,
readln, readln, readln, readln,
// comment5
writeln;
import std.stdio : // comment6
readln, readln, readln, readln, readln, readln, // comment7
// comment8
writeln;
import std.stdio : /* comment9 */
readln, readln, readln, readln, readln, readln, /* comment10 */
// comment11
writeln;
import std.stdio : readln, // comment12
readln, readln, readln, readln, readln, readln, // comment13
// comment14
writeln;
import std.stdio : readln,
// comment15
readln, readln, readln, readln, readln, readln, // comment16
// comment17
writeln;

View File

@ -1,6 +0,0 @@
import std.stdio;
@safe extern (C) void main()
{
writeln("Hello World!");
}

View File

@ -1,6 +0,0 @@
void f(bool body)
{
if (body)
{
}
}

View File

@ -1,40 +0,0 @@
struct S1
{
ulong x;
ulong y;
ulong function(ulong) f;
}
struct S2
{
ulong x;
ulong y;
ulong z;
ulong w;
}
// -----------------------------------------------------------------------------
// Example 1
// Anonymous function in struct, long struct initializer
immutable S1 s1 = {
1111111111111111111, 1111111111111111111, (x) { return x + 1111; },
};
void f1()
{
}
// -----------------------------------------------------------------------------
// Example 2
// Anonymous function anywhere, long struct initializer
int function(int) f2 = (x) { return x + 1111; };
immutable S2 s = {
1111111111111111111, 1111111111111111111, 1111111111111111111, 1111111111111111111,
};
void f2()
{
}

View File

@ -1,7 +0,0 @@
int abs(int x)
{
if (x < 0) // x negative, must negate
return -x;
else // x already non-negative, just return it
return x;
}

View File

@ -1 +0,0 @@
extern (Objective-C) int a;

View File

@ -1,4 +0,0 @@
struct S
{
invariant (true);
}

View File

@ -1,40 +0,0 @@
class C
{
abstract void f1() //
in (true);
abstract void f2() /* */
in (true);
abstract bool f3() //
out (r; r);
abstract bool f4() /* */
out (r; r);
abstract void f5() //
do
{
}
abstract void f6() /* */
do
{
}
abstract bool f7() //
in (true) //
out (r; r) //
do //
{
return true;
}
abstract bool f8() /* */
in (true) /* */
out (r; r) /* */
do /* */
{
return true;
}
}

View File

@ -1,2 +0,0 @@
@nogc //
void foo();

View File

@ -1,10 +0,0 @@
void main()
{
format!"%s" //
("");
format!("%s") //
("");
format!("%s") //
("", argument1, argument2, argument3, argument4, argument5,
argument6, argument7, argument8, argument9, argument10);
}

View File

@ -1,8 +0,0 @@
bool asdf(const string owner, const string mail) @safe
{
requestHTTP(url, (scope HTTPClientRequest request) {
request.writeFormBody([owner: owner, mail: mail]);
}, (scope HTTPClientResponse response) {});
return true;
}

View File

@ -1,7 +0,0 @@
string BuildForwardCall()
{
return `static if (is(typeof(mocked___.` ~ methodString ~ argsPassed ~ `)))
{
return (mocked___.` ~ methodString ~ argsPassed ~ `);
}`;
}

View File

@ -1,15 +0,0 @@
module tests.issue0483;
void main()
{
switch (0)
{
case 1:
case 2:
label:
case 3:
break;
default:
break;
}
}

View File

@ -1,5 +0,0 @@
void main()
{
int a;
int[int] hashmap = [a : a, a : a, a : a];
}

View File

@ -1,5 +0,0 @@
void main()
{
auto someAutoVariableName = this.firstLink.secondLink
.filter!(shouldBeProbablySomeIdentifierOrNot);
}

View File

@ -1,29 +0,0 @@
void main()
{
const a1 = [
builder.rebuild!((x, y, z) => x + y + z)
.rebuild!(x => x)
.rebuild!(x => x),
];
const a2 = [
builder.rebuild!(x => x)
.rebuild!(x => x)
.rebuild!(x => x),
builder.rebuild!(x => x)
.rebuild!(x => x)
.rebuild!(x => x),
];
foo([
line1,
value_line2_bla_bla_bla.propertyCallBlaBlaBla(a, b, c)
.propertyCallBlaBlaBla(a, b, c, d).propertyCallBlaBlaBla(a, b, c)
.propertyCallBlaBlaBla(a, b, c).value,
]);
}
void foo()
{
afdsafds.asdf.flub;
}

View File

@ -1,74 +0,0 @@
private void selectMember(Args...)(Args args)
{
static if (true)
{
static if (args[0])
{
}
else
{
}
}
if (true)
{
if (args[0])
{
}
else
{
}
}
}
private void selectMember(Args...)(Args args)
{
static if (true)
{
static if ([
0,
1,
2,
3,
4,
])
{
}
else
{
}
}
if (true)
{
if (args[
0,
1,
2,
3,
4,
])
{
}
else
{
}
}
}
void f()
{
foreach (x; y)
if (foo)
{
}
else
{
}
if (a)
if (b)
{
}
else
{
}
}

View File

@ -1,34 +0,0 @@
void main()
{
const a1 = [
builder
.rebuild!((x, y, z) => x + y + z)
.rebuild!(x => x)
.rebuild!(x => x),
];
const a2 = [
builder
.rebuild!(x => x)
.rebuild!(x => x)
.rebuild!(x => x),
builder
.rebuild!(x => x)
.rebuild!(x => x)
.rebuild!(x => x),
];
foo([
line1,
value_line2_bla_bla_bla.propertyCallBlaBlaBla(a, b, c)
.propertyCallBlaBlaBla(a, b, c, d).propertyCallBlaBlaBla(a, b, c)
.propertyCallBlaBlaBla(a, b, c).value,
]);
}
void foo()
{
afdsafds
.asdf
.flub;
}

View File

@ -1,5 +0,0 @@
alias f1 = S function();
alias f2 = S!"foo" function();
alias f3 = S!5 function();
alias f4 = S!S function();
alias f5 = S!(S) function();

View File

@ -1,4 +0,0 @@
void main()
{
auto aa = ["aaa": 1, "bbb": 2];
}

View File

@ -1,15 +0,0 @@
string f()
{
return duration.total!"seconds".to!string;
}
string g()
{
return duration.total!"seconds"().to!string;
}
string h()
{
return duration.total!"seconds"().to!string.to!string.to!string.to!string.to!string.to!string
.to!string.to!string.to!string;
}

View File

@ -1,40 +0,0 @@
deprecated("foo")
void test()
{
}
package(foo)
void bar()
{
}
@uda()
void baz()
{
}
deprecated
deprecated_()
{
}
@uda
void uda_()
{
}
@property
void property()
{
}
deprecated("Reason") @uda
void propertyuda()
{
}
deprecated("Reason")
@uda
void udaproperty()
{
}

View File

@ -1,7 +0,0 @@
struct S
{
@safe invariant
{
assert(true);
}
}

View File

@ -1,34 +0,0 @@
void main()
{
string a = "foo"
~ "bar" // bar
~ "baz";
}
void foo()
{
afdsafds
.asdf // blah
.flub;
}
void main()
{
string a = "foo"
~ "bar" /* bar */
~ "baz";
}
void foo()
{
afdsafds
.asdf /* blah */
.flub;
}
void foo() // hello
{ // world
// ok
writeln("hi"); // hi!
} // done
//finish

View File

@ -1,7 +0,0 @@
struct S
{
ref S foo() return
{
return this;
}
}

View File

@ -1,17 +0,0 @@
public int f() return
in (true)
{
return 0;
}
public int g() return
out (; true)
{
return 0;
}
public int h() return
body
{
return 0;
}

View File

@ -1,4 +0,0 @@
void f() return
do
{
}

View File

@ -1 +0,0 @@
/// Testing CR line endings. void main() { }

Some files were not shown because too many files have changed in this diff Show More