From 80b831addaece9f0c4f65b27eb501767db1f7fb1 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Fri, 16 Jun 2017 07:22:14 +0200 Subject: [PATCH 1/6] Workaround 17506 by excluding treemap.d (#459) * Workaround 17506 by excluding treemap.d * Add Bugzilla and GitHub references for workaround 17506 --- makefile | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/makefile b/makefile index bf0a71c..edd6b62 100644 --- a/makefile +++ b/makefile @@ -5,8 +5,10 @@ DMD := $(DC) GDC := gdc LDC := ldc2 OBJ_DIR := obj +# Exclusion of treemap is due to https://issues.dlang.org/show_bug.cgi?id=17506 +# More details: https://github.com/dlang-community/D-Scanner/issues/461 SRC := \ - $(shell find containers/src -name "*.d")\ + $(shell find containers/src -name "*.d" -not -name 'treemap.d')\ $(shell find dsymbol/src -name "*.d")\ $(shell find inifiled/source/ -name "*.d")\ $(shell find libdparse/src/std/experimental/ -name "*.d")\ From d8ee9a3e4bdd01f382916e5808073275e830f3f1 Mon Sep 17 00:00:00 2001 From: Basile Burg Date: Sat, 17 Jun 2017 13:57:22 +0200 Subject: [PATCH 2/6] set more def bucket count to get better perfs on huge modules (#462) --- src/main.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.d b/src/main.d index 6b0a9b0..1d9d205 100644 --- a/src/main.d +++ b/src/main.d @@ -169,7 +169,7 @@ else immutable usingStdin = args.length == 1; - StringCache cache = StringCache(StringCache.defaultBucketCount); + StringCache cache = StringCache(0xFFFF); if (defaultConfig) { string s = getConfigurationLocation(); From db4659587084daa456b04725e208d690c085686e Mon Sep 17 00:00:00 2001 From: Basile Burg Date: Sun, 18 Jun 2017 03:08:22 +0200 Subject: [PATCH 3/6] Revert "set more def bucket count to get better perfs on huge modules (#462)" This reverts commit d8ee9a3e4bdd01f382916e5808073275e830f3f1. --- src/main.d | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.d b/src/main.d index 1d9d205..6b0a9b0 100644 --- a/src/main.d +++ b/src/main.d @@ -169,7 +169,7 @@ else immutable usingStdin = args.length == 1; - StringCache cache = StringCache(0xFFFF); + StringCache cache = StringCache(StringCache.defaultBucketCount); if (defaultConfig) { string s = getConfigurationLocation(); From 778411c12bbdc9ed1a1bc8f318669cc50deda644 Mon Sep 17 00:00:00 2001 From: ZombineDev Date: Sun, 18 Jun 2017 22:25:32 +0300 Subject: [PATCH 4/6] Revert "Workaround 17506 by excluding treemap.d (#459)" This reverts commit 80b831addaece9f0c4f65b27eb501767db1f7fb1. The workaround is no longer necessary as the problematic feature has been reverted from dmd-nightly. --- makefile | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/makefile b/makefile index edd6b62..bf0a71c 100644 --- a/makefile +++ b/makefile @@ -5,10 +5,8 @@ DMD := $(DC) GDC := gdc LDC := ldc2 OBJ_DIR := obj -# Exclusion of treemap is due to https://issues.dlang.org/show_bug.cgi?id=17506 -# More details: https://github.com/dlang-community/D-Scanner/issues/461 SRC := \ - $(shell find containers/src -name "*.d" -not -name 'treemap.d')\ + $(shell find containers/src -name "*.d")\ $(shell find dsymbol/src -name "*.d")\ $(shell find inifiled/source/ -name "*.d")\ $(shell find libdparse/src/std/experimental/ -name "*.d")\ From 6df62b7b4d5996fad06c6c4daec52676b8632a44 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Mon, 19 Jun 2017 14:21:18 +0200 Subject: [PATCH 5/6] Fix line_length checker for multiLine literals (#465) --- src/analysis/line_length.d | 148 +++++++++++++++++++++++++++++++------ 1 file changed, 125 insertions(+), 23 deletions(-) diff --git a/src/analysis/line_length.d b/src/analysis/line_length.d index 61fcb3d..2cf86ce 100644 --- a/src/analysis/line_length.d +++ b/src/analysis/line_length.d @@ -26,25 +26,24 @@ class LineLengthCheck : BaseAnalyzer override void visit(const Module) { - ulong lastErrorLine = ulong.max; size_t endColumn = 0; + lastErrorLine = ulong.max; foreach (i, token; tokens) { immutable info = tokenLength(token, i > 0 ? tokens[i - 1].line : 0); - if (info[1]) - endColumn = info[0] + token.column - 1; + if (info.multiLine) + endColumn = checkMultiLineToken(token, endColumn); + else if (info.newLine) + endColumn = info.length + token.column - 1; else { immutable wsChange = i > 0 ? token.column - (tokens[i - 1].column + tokenByteLength(tokens[i - 1])) : 0; - endColumn += wsChange + info[0]; - } - if (endColumn > MAX_LINE_LENGTH && token.line != lastErrorLine) - { - addErrorMessage(token.line, token.column, KEY, MESSAGE); - lastErrorLine = token.line; + endColumn += wsChange + info.length; } + if (endColumn > MAX_LINE_LENGTH) + triggerError(token); } } @@ -52,27 +51,106 @@ class LineLengthCheck : BaseAnalyzer private: - static size_t tokenByteLength(ref const Token tok) + ulong lastErrorLine = ulong.max; + + void triggerError(ref const Token tok) + { + if (tok.line != lastErrorLine) + { + addErrorMessage(tok.line, tok.column, KEY, MESSAGE); + lastErrorLine = tok.line; + } + } + + static bool isLineSeparator(dchar c) + { + import std.uni : lineSep, paraSep; + return c == lineSep || c == '\n' || c == '\v' || c == '\r' || c == paraSep; + } + + size_t checkMultiLineToken()(auto ref const Token tok, size_t startColumn = 0) + { + import std.utf : byDchar; + + auto col = startColumn; + foreach (c; tok.text.byDchar) + { + if (isLineSeparator(c)) + { + if (col > MAX_LINE_LENGTH) + triggerError(tok); + col = 1; + } + else + col += getEditorLength(c); + } + return col; + } + + unittest + { + import std.stdio; + assert(new LineLengthCheck(null, null).checkMultiLineToken(Token(tok!"stringLiteral", " ", 0, 0, 0)) == 8); + assert(new LineLengthCheck(null, null).checkMultiLineToken(Token(tok!"stringLiteral", " \na", 0, 0, 0)) == 2); + assert(new LineLengthCheck(null, null).checkMultiLineToken(Token(tok!"stringLiteral", " \n ", 0, 0, 0)) == 5); + } + + static size_t tokenByteLength()(auto ref const Token tok) { return tok.text is null ? str(tok.type).length : tok.text.length; } - static Tuple!(size_t, bool) tokenLength(ref const Token tok, size_t prevLine) + unittest { - import std.uni : lineSep, paraSep; + assert(tokenByteLength(Token(tok!"stringLiteral", "aaa", 0, 0, 0)) == 3); + assert(tokenByteLength(Token(tok!"stringLiteral", "Дистан", 0, 0, 0)) == 12); + // tabs and whitespace + assert(tokenByteLength(Token(tok!"stringLiteral", " ", 0, 0, 0)) == 1); + assert(tokenByteLength(Token(tok!"stringLiteral", " ", 0, 0, 0)) == 4); + } - size_t endColumn = 0; - if (tok.text is null) - endColumn += str(tok.type).length; + // D Style defines tabs to have a width of four spaces + static size_t getEditorLength(C)(C c) + { + if (c == '\t') + return 4; else - foreach (dchar c; tok.text) + return 1; + } + + alias TokenLength = Tuple!(size_t, "length", bool, "newLine", bool, "multiLine"); + static TokenLength tokenLength()(auto ref const Token tok, size_t prevLine) + { + import std.utf : byDchar; + + size_t length = 0; + bool newLine = tok.line > prevLine; + bool multiLine; + + if (tok.text is null) + length += str(tok.type).length; + else + foreach (c; tok.text.byDchar) { - if (c == lineSep || c == '\n' || c == '\v' || c == '\r' || c == paraSep) - endColumn = 0; + if (isLineSeparator(c)) + { + length = 1; + multiLine = true; + } else - endColumn++; + length += getEditorLength(c); } - return tuple(endColumn, tok.line > prevLine); + + return TokenLength(length, newLine, multiLine); + } + + unittest + { + assert(tokenLength(Token(tok!"stringLiteral", "aaa", 0, 0, 0), 0).length == 3); + assert(tokenLength(Token(tok!"stringLiteral", "Дистан", 0, 0, 0), 0).length == 6); + // tabs and whitespace + assert(tokenLength(Token(tok!"stringLiteral", " ", 0, 0, 0), 0).length == 4); + assert(tokenLength(Token(tok!"stringLiteral", " ", 0, 0, 0), 0).length == 4); } import std.conv : to; @@ -91,13 +169,37 @@ private: StaticAnalysisConfig sac = disabledConfig(); sac.long_line_check = Check.enabled; + assertAnalyzerWarnings(q{ -Window window = Platform.instance.createWindow("Дистанционное управление сварочным оборудованием", null); +Window window = Platform.instance.createWindow("Дистанционное управление сварочным оборудованием ", null); +Window window = Platform.instance.createWindow("Дистанционное управление сварочным оборудованием ", null); // [warn]: Line is longer than 120 characters unittest { - assert("foo" == "fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"); - assert("foo" == "foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo"); // [warn]: Line is longer than 120 characters +// with tabs +assert("foo" == "foooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo1"); +assert("foo" == "fooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo2"); // [warn]: Line is longer than 120 characters +// with whitespace (don't overwrite) + assert("foo" == "boooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo3"); + assert("foo" == "booooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo4"); // [warn]: Line is longer than 120 characters } }c, sac); +// TODO: libdparse counts columns bytewise + //assert("foo" == "boooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo5"); + //assert("foo" == "booooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooooo6"); // [warn]: Line is longer than 120 characters + + // reduced from std/regex/internal/thompson.d + assertAnalyzerWarnings(q{ + // whitespace on purpose, do not remove! + mixin(`case IR.`~e~`: + opCacheTrue[pc] = &Ops!(true).op!(IR.`~e~`); + opCacheBackTrue[pc] = &BackOps!(true).op!(IR.`~e~`); + `); + mixin(`case IR.`~e~`: + opCacheTrue[pc] = &Ops!(true).op!(IR.`~e~`); + opCacheTrue[pc] = &Ops!(true).op!(IR.`~e~`); + opCacheBackTrue[pc] = &BackOps!(true).op!(IR.`~e~`); // [warn]: Line is longer than 120 characters + `); + }c, sac); + stderr.writeln("Unittest for LineLengthCheck passed."); } From 7de68bf5f9144401874194cb087aab43ba6f0b44 Mon Sep 17 00:00:00 2001 From: Sebastian Wilzbach Date: Tue, 20 Jun 2017 09:40:57 +0200 Subject: [PATCH 6/6] Make Dscanner usable as a library (#469) --- dub.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dub.json b/dub.json index 852447e..3d790fb 100644 --- a/dub.json +++ b/dub.json @@ -4,7 +4,7 @@ "copyright": "© Brian Schott", "authors": ["Brian Schott"], "license" : "Boost Software License - Version 1.0", - "targetType": "executable", + "targetType": "autodetect", "versions": [ "built_with_dub", "StdLoggerDisableWarning"