From 768bb492631cf3ee65ecb11081c6b2616e9aa721 Mon Sep 17 00:00:00 2001 From: AlexHaxe Date: Sun, 28 Feb 2021 22:26:49 +0100 Subject: [PATCH] fixed local metadata linebreaks, fixes #630 (#636) * fixed local metadata linebreaks, fixes #630 * prepared version 1.12.0 --- CHANGELOG.md | 4 +- haxelib.json | 4 +- package-lock.json | 2 +- package.json | 2 +- src/formatter/marker/MarkLineEnds.hx | 24 ++- src/formatter/marker/MarkSameLine.hx | 33 ++-- .../lineends/issue_630_local_metadata.hxtest | 151 ++++++++++++++++++ 7 files changed, 204 insertions(+), 16 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 049b362b..5679e2a5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,12 @@ ## dev branch / next version (1.x.x) -- Added testcase for local metadata linebreak, fixes [#630](https://github.com/HaxeCheckstyle/haxe-formatter/issues/630) ([#631](https://github.com/HaxeCheckstyle/haxe-formatter/issues/631)) +## version 1.12.0 (2021-02-28) + - Added `lineEnds.lineEndCharacter` to set line end character used for output ([#633](https://github.com/HaxeCheckstyle/haxe-formatter/issues/633)) - Fixed support for overload access modifier, fixes [#626](https://github.com/HaxeCheckstyle/haxe-formatter/issues/626) ([#627](https://github.com/HaxeCheckstyle/haxe-formatter/issues/627)) - Fixed parens after curly block, fixes [#629](https://github.com/HaxeCheckstyle/haxe-formatter/issues/629) ([#631](https://github.com/HaxeCheckstyle/haxe-formatter/issues/631)) +- Fixed local metadata linebreak, fixes [#630](https://github.com/HaxeCheckstyle/haxe-formatter/issues/630) ([#631](https://github.com/HaxeCheckstyle/haxe-formatter/issues/631) + [#636](https://github.com/HaxeCheckstyle/haxe-formatter/issues/636)) - Fixed `is as` formatted as `isas`, fixes [#634](https://github.com/HaxeCheckstyle/haxe-formatter/issues/634) ([#635](https://github.com/HaxeCheckstyle/haxe-formatter/issues/635)) - Retired Haxe 3.4.7 compile support ([#627](https://github.com/HaxeCheckstyle/haxe-formatter/issues/627)) diff --git a/haxelib.json b/haxelib.json index 1311e667..e84f96f3 100644 --- a/haxelib.json +++ b/haxelib.json @@ -8,8 +8,8 @@ "style" ], "description": "A code formatter for Haxe", - "version": "1.11.2", - "releasenote": "fixed array type parameter - see CHANGELOG for details.", + "version": "1.12.0", + "releasenote": "added lineEnds.lineEndCharacter and bugfixes - see CHANGELOG for details.", "contributors": [ "AlexHaxe", "Gama11" diff --git a/package-lock.json b/package-lock.json index a03998eb..a4d4d909 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "@haxecheckstyle/haxe-formatter", - "version": "1.11.2", + "version": "1.12.0", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index b9e0876e..bb272f13 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@haxecheckstyle/haxe-formatter", - "version": "1.11.2", + "version": "1.12.0", "description": "A code formatter for Haxe", "repository": { "type": "git", diff --git a/src/formatter/marker/MarkLineEnds.hx b/src/formatter/marker/MarkLineEnds.hx index 79a28499..88053559 100644 --- a/src/formatter/marker/MarkLineEnds.hx +++ b/src/formatter/marker/MarkLineEnds.hx @@ -356,22 +356,42 @@ class MarkLineEnds extends MarkerBase { var atTokens:Array = parsedCode.root.filterCallback(function(token:TokenTree, index:Int):FilterResult { return switch (token.tok) { case At: - FoundGoDeeper; + FoundSkipSubtree; default: GoDeeper; } }); + function addLineEndBefore(atToken:TokenTree) { + var prev:TokenInfo = getPreviousToken(atToken); + if (prev == null) { + lineEndBefore(atToken); + return; + } + switch (prev.token.tok) { + case Kwd(KwdElse): + lineEndBefore(atToken); + case BrOpen: + lineEndBefore(atToken); + case Kwd(KwdFinal) | Kwd(KwdFunction) | Kwd(KwdVar): + noLineEndBefore(atToken); + default: + } + } for (token in atTokens) { var metadataPolicy:AtLineEndPolicy = determineMetadataPolicy(token); var lastChild:Null = TokenTreeCheckUtils.getLastToken(token); if (lastChild == null) { continue; } + var isNotFirst:Bool = (token.previousSibling != null) && (token.previousSibling.tok.match(At)); + if (!isNotFirst) { + addLineEndBefore(token); + } if (metadataPolicy == After) { lineEndAfter(lastChild); continue; } - if ((token.previousSibling != null) && (token.previousSibling.tok.match(At))) { + if (isNotFirst) { // only look at first metadata continue; } diff --git a/src/formatter/marker/MarkSameLine.hx b/src/formatter/marker/MarkSameLine.hx index c0ae7b65..12561326 100644 --- a/src/formatter/marker/MarkSameLine.hx +++ b/src/formatter/marker/MarkSameLine.hx @@ -586,17 +586,24 @@ class MarkSameLine extends MarkerBase { if (prev == null) { noLineEndBefore(token); } else { - switch (prev.token.tok) { - case POpen | Dot: - whitespace(token, NoneBefore); - case BrClose | Semicolon: - switch (token.tok) { - case At: - case _: + switch (token.tok) { + case At: + switch (prev.token.tok) { + case POpen | Dot: + whitespace(token, NoneBefore); + case BrOpen | BrClose | Semicolon | DblDot | Sharp(_) | Kwd(_): + case Binop(_): + lineEndBefore(token); + default: + noLineEndBefore(token); + } + case _: + switch (prev.token.tok) { + case POpen | Dot: + whitespace(token, NoneBefore); + default: noLineEndBefore(token); } - default: - noLineEndBefore(token); } } var lastToken:Null = TokenTreeCheckUtils.getLastToken(token); @@ -625,6 +632,14 @@ class MarkSameLine extends MarkerBase { } default: } + var prev:Null = getPreviousToken(token); + if ((prev == null) || (!TokenTreeCheckUtils.isMetadata(prev.token))) { + lineEndBefore(token); + return; + } + if (!parsedCode.isOriginalNewlineBefore(token)) { + return; + } lineEndBefore(token); } } diff --git a/test/testcases/lineends/issue_630_local_metadata.hxtest b/test/testcases/lineends/issue_630_local_metadata.hxtest index dab3beeb..52d51b99 100644 --- a/test/testcases/lineends/issue_630_local_metadata.hxtest +++ b/test/testcases/lineends/issue_630_local_metadata.hxtest @@ -6,9 +6,160 @@ public inline function next():{key:K, value:V} { var key = keys.next(); @:nullSafety(Off) return {value: map.get(key), key: key}; } +public inline function next():{key:K, value:V} { + var key = keys.next(); + @:nullSafety(Off) return {value: map.get(key), key: key}; +} + +public function unserialize():Dynamic { + switch (get(pos++)) { + case "n".code: @:nullSafety(Off) + return null; + } +} + +public function unserialize():Dynamic { + switch (get(pos++)) { + case "n".code: + @:nullSafety(Off) return null; + } +} + +static inline function fastCharCodeAt(s:String, pos:Int):Int { + #if php + return php.Global.ord((s : php.NativeString)[pos]); + #else @:nullSafety(Off) + return s.charCodeAt(pos); + #end +} + +static inline function fastCharCodeAt(s:String, pos:Int):Int { + #if php + return php.Global.ord((s : php.NativeString)[pos]); + #else + @:nullSafety(Off) return s.charCodeAt(pos); + #end +} + +public function first():Null {@:nullSafety(Off) + return if (h == null) null else h.item; +} + +public function first():Null { + @:nullSafety(Off) return if (h == null) null else h.item; +} + +public inline function resolveClass(name:String):Null> @:nullSafety(Off) + return null; + +public inline function resolveClass(name:String):Null> + @:nullSafety(Off) return null; + +public inline function resolveClass(name:String):Null> + @:nullSafety(Off) + return null; + +public function add(item:T) { + var x = ListNode.create(item, null); + if (h == null) + h = x; + else @:nullSafety(Off) + q.next = x; + q = x; + length++; +} + +public function add(item:T) { + var x = ListNode.create(item, null); + if (h == null) + h = x; + else + @:nullSafety(Off) q.next = x; + q = x; + length++; +} + --- public inline function next():{key:K, value:V} { var key = keys.next(); @:nullSafety(Off) return {value: map.get(key), key: key}; } + +public inline function next():{key:K, value:V} { + var key = keys.next(); + @:nullSafety(Off) return {value: map.get(key), key: key}; +} + +public function unserialize():Dynamic { + switch (get(pos++)) { + case "n".code: + @:nullSafety(Off) + return null; + } +} + +public function unserialize():Dynamic { + switch (get(pos++)) { + case "n".code: + @:nullSafety(Off) return null; + } +} + +static inline function fastCharCodeAt(s:String, pos:Int):Int { + #if php + return php.Global.ord((s : php.NativeString)[pos]); + #else + @:nullSafety(Off) + return s.charCodeAt(pos); + #end +} + +static inline function fastCharCodeAt(s:String, pos:Int):Int { + #if php + return php.Global.ord((s : php.NativeString)[pos]); + #else + @:nullSafety(Off) return s.charCodeAt(pos); + #end +} + +public function first():Null { + @:nullSafety(Off) + return if (h == null) null else h.item; +} + +public function first():Null { + @:nullSafety(Off) return if (h == null) null else h.item; +} + +public inline function resolveClass(name:String):Null> + @:nullSafety(Off) + return null; + +public inline function resolveClass(name:String):Null> + @:nullSafety(Off) return null; + +public inline function resolveClass(name:String):Null> + @:nullSafety(Off) + return null; + +public function add(item:T) { + var x = ListNode.create(item, null); + if (h == null) + h = x; + else + @:nullSafety(Off) + q.next = x; + q = x; + length++; +} + +public function add(item:T) { + var x = ListNode.create(item, null); + if (h == null) + h = x; + else + @:nullSafety(Off) q.next = x; + q = x; + length++; +}