diff --git a/CHANGELOG.md b/CHANGELOG.md index 6ffe1ad..c3246fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ - Fixed `TokenTreeCheckUtils.getColonType` detection of type check in array comprehension [#136](https://github.com/HaxeCheckstyle/tokentree/issues/136) - Fixed handling of multiple `implements` [#137](https://github.com/HaxeCheckstyle/tokentree/issues/137) +- Fixed comments after typedefs without semicolon [#138](https://github.com/HaxeCheckstyle/tokentree/issues/138) ## version 1.0.14 (2018-12-05) diff --git a/src/tokentree/TokenStream.hx b/src/tokentree/TokenStream.hx index de7efbb..470e762 100644 --- a/src/tokentree/TokenStream.hx +++ b/src/tokentree/TokenStream.hx @@ -45,7 +45,7 @@ class TokenStream { return new TokenTree(token.tok, space, token.pos, current - 1); } - public function consumeConstIdent():TokenTree { + public function consumeConstIdent():Null { switch (token()) { case Dollar(_): return consumeToken(); @@ -68,9 +68,7 @@ class TokenStream { default: switch (MODE) { case RELAXED: return createDummyToken(Const(CString("autoInsert"))); - case STRICT: - error('bad token ${token()} != Const(_)'); - return null; + case STRICT: error('bad token ${token()} != Const(_)'); } } } @@ -82,7 +80,6 @@ class TokenStream { return createDummyToken(tokenDef); case STRICT: error('bad token ${token()} != $tokenDef'); - return null; } } @@ -172,7 +169,7 @@ class TokenStream { return tokens[current].tok; } - public function peekNonCommentToken():TokenDef { + public function peekNonCommentToken():Null { if ((current < 0) || (current >= tokens.length)) { switch (MODE) { case RELAXED: @@ -196,7 +193,7 @@ class TokenStream { return null; } - public function getTokenPos():Position { + public function getTokenPos():Null { if ((current < 0) || (current >= tokens.length)) { return null; } @@ -307,7 +304,8 @@ class TokenStream { } public function popSharpIf():TokenTree { - if (sharpIfStack.length <= 0) { + var token:Null = sharpIfStack.pop(); + if (token == null) { switch (MODE) { case RELAXED: return createDummyToken(CommentLine("dummy token")); @@ -315,7 +313,7 @@ class TokenStream { throw NO_MORE_TOKENS; } } - return sharpIfStack.pop(); + return token; } public function peekSharpIf():TokenTree { @@ -331,7 +329,7 @@ class TokenStream { } function createDummyToken(tokDef:TokenDef):TokenTree { - var pos:Position = null; + var pos:Null = null; if ((current < 0) || (current >= tokens.length)) { pos = tokens[tokens.length - 1].pos; pos.min = pos.max; diff --git a/src/tokentree/TokenTree.hx b/src/tokentree/TokenTree.hx index 8dfb303..64c270f 100644 --- a/src/tokentree/TokenTree.hx +++ b/src/tokentree/TokenTree.hx @@ -50,7 +50,8 @@ class TokenTree extends Token { } } - public function addChild(child:TokenTree) { + public function addChild(child:Null) { + if (child == null) return; if (children == null) children = []; if (children.length > 0) { child.previousSibling = children[children.length - 1]; @@ -65,12 +66,12 @@ class TokenTree extends Token { return children.length > 0; } - public function getFirstChild():TokenTree { + public function getFirstChild():Null { if (!hasChildren()) return null; return children[0]; } - public function getLastChild():TokenTree { + public function getLastChild():Null { if (!hasChildren()) return null; return children[children.length - 1]; } diff --git a/src/tokentree/TokenTreeAccessHelper.hx b/src/tokentree/TokenTreeAccessHelper.hx index 672d61b..b7ed5be 100644 --- a/src/tokentree/TokenTreeAccessHelper.hx +++ b/src/tokentree/TokenTreeAccessHelper.hx @@ -11,27 +11,27 @@ abstract TokenTreeAccessHelper(TokenTree) from TokenTree { return tok; } - public function parent():TokenTreeAccessHelper { + public function parent():Null { return if (exists()) this.parent else null; } - public function previousSibling():TokenTreeAccessHelper { + public function previousSibling():Null { return if (exists()) this.previousSibling else null; } - public function nextSibling():TokenTreeAccessHelper { + public function nextSibling():Null { return if (exists()) this.nextSibling else null; } - public function firstChild():TokenTreeAccessHelper { + public function firstChild():Null { return if (exists()) this.getFirstChild() else null; } - public function lastChild():TokenTreeAccessHelper { + public function lastChild():Null { return if (exists()) this.getLastChild() else null; } - public function firstOf(tokenDef:TokenDef):TokenTreeAccessHelper { + public function firstOf(tokenDef:TokenDef):Null { if (!exists() || this.children == null) return null; for (tok in this.children) { if (tok.is(tokenDef)) return tok; @@ -39,28 +39,28 @@ abstract TokenTreeAccessHelper(TokenTree) from TokenTree { return null; } - public function lastOf(tokenDef:TokenDef):TokenTreeAccessHelper { + public function lastOf(tokenDef:TokenDef):Null { if (!exists() || this.children == null) return null; - var found:TokenTree = null; + var found:Null = null; for (tok in this.children) { if (tok.is(tokenDef)) found = tok; } return found; } - public function child(index:Int):TokenTreeAccessHelper { + public function child(index:Int):Null { return if (exists() && this.children != null) this.children[index] else null; } - public function is(tokenDef:TokenDef):TokenTreeAccessHelper { + public function is(tokenDef:TokenDef):Null { return if (exists() && this.is(tokenDef)) this else null; } - public function isComment():TokenTreeAccessHelper { + public function isComment():Null { return if (exists() && this.isComment()) this else null; } - public function isCIdent():TokenTreeAccessHelper { + public function isCIdent():Null { return if (exists() && this.isCIdent()) this else null; } diff --git a/src/tokentree/utils/FieldUtils.hx b/src/tokentree/utils/FieldUtils.hx index 507846b..4430602 100644 --- a/src/tokentree/utils/FieldUtils.hx +++ b/src/tokentree/utils/FieldUtils.hx @@ -4,7 +4,7 @@ using tokentree.utils.TokenTreeCheckUtils; using Lambda; class FieldUtils { - public static function getFieldType(field:TokenTree, defaultVisibility:TokenFieldVisibility):TokenFieldType { + public static function getFieldType(field:Null, defaultVisibility:TokenFieldVisibility):TokenFieldType { if (field == null) { return UNKNOWN; } diff --git a/src/tokentree/utils/TokenTreeCheckUtils.hx b/src/tokentree/utils/TokenTreeCheckUtils.hx index b14dbc8..7e7ba9d 100644 --- a/src/tokentree/utils/TokenTreeCheckUtils.hx +++ b/src/tokentree/utils/TokenTreeCheckUtils.hx @@ -46,7 +46,8 @@ class TokenTreeCheckUtils { public static function isOpGtTypedefExtension(token:TokenTree):Bool { return switch (token.tok) { - case Binop(OpGt): (token.access().parent().is(BrOpen).parent().is(Binop(OpAssign)).parent().isCIdent().parent().is(Kwd(KwdTypedef)).token != null); + case Binop(OpGt): (token.access().parent().is(BrOpen).parent().is(Binop(OpAssign)).parent().isCIdent().parent().is(Kwd(KwdTypedef)) + .token != null); default: false; } } @@ -595,7 +596,7 @@ class TokenTreeCheckUtils { return FUNCTION_TYPE_HAXE4; } - static function checkArrowPOpen(token:TokenTree):ArrowType { + static function checkArrowPOpen(token:TokenTree):Null { if ((token.children == null) || (token.children.length <= 1)) { return null; } @@ -613,7 +614,7 @@ class TokenTreeCheckUtils { return FUNCTION_TYPE_HAXE3; } - static function checkArrowParent(parent:TokenTree):ArrowType { + static function checkArrowParent(parent:TokenTree):Null { if (parent == null) { return ARROW_FUNCTION; } @@ -712,7 +713,7 @@ class TokenTreeCheckUtils { return UNKNOWN; } - public static function getLastToken(token:TokenTree):TokenTree { + public static function getLastToken(token:TokenTree):Null { if (token == null) { return null; } diff --git a/src/tokentree/walk/WalkArrayAccess.hx b/src/tokentree/walk/WalkArrayAccess.hx index 55e4bf3..3477f33 100644 --- a/src/tokentree/walk/WalkArrayAccess.hx +++ b/src/tokentree/walk/WalkArrayAccess.hx @@ -30,11 +30,11 @@ class WalkArrayAccess { WalkFunction.walkFunction(stream, bkOpen); case Comma: var comma:TokenTree = stream.consumeToken(); - var child:TokenTree = bkOpen.getLastChild(); + var child:Null = bkOpen.getLastChild(); if (child == null) child = bkOpen; child.addChild(comma); case Binop(OpArrow): - var child:TokenTree = bkOpen.getLastChild(); + var child:Null = bkOpen.getLastChild(); if (child == null) child = bkOpen; WalkStatement.walkStatement(stream, child); default: diff --git a/src/tokentree/walk/WalkFor.hx b/src/tokentree/walk/WalkFor.hx index ddc9a3a..ca4bc94 100644 --- a/src/tokentree/walk/WalkFor.hx +++ b/src/tokentree/walk/WalkFor.hx @@ -54,7 +54,7 @@ class WalkFor { var pOpen:TokenTree = stream.consumeTokenDef(POpen); parent.addChild(pOpen); WalkComment.walkComment(stream, pOpen); - var identifier:TokenTree = null; + var identifier:Null = null; switch (stream.token()) { case Dollar(_): WalkStatement.walkStatement(stream, pOpen); @@ -67,10 +67,10 @@ class WalkFor { if (stream.is(Binop(OpArrow))) { var arrowTok:TokenTree = stream.consumeToken(); identifier.addChild(arrowTok); - var valueIdent:TokenTree = stream.consumeConstIdent(); + var valueIdent:Null = stream.consumeConstIdent(); arrowTok.addChild(valueIdent); } - var inTok:TokenTree = null; + var inTok:Null = null; switch (stream.token()) { case #if (haxe_ver < 4.0) Kwd(KwdIn) #else Binop(OpIn) #end: inTok = stream.consumeToken(); diff --git a/src/tokentree/walk/WalkFunction.hx b/src/tokentree/walk/WalkFunction.hx index 0ad95e0..dd26d78 100644 --- a/src/tokentree/walk/WalkFunction.hx +++ b/src/tokentree/walk/WalkFunction.hx @@ -2,7 +2,7 @@ package tokentree.walk; class WalkFunction { public static function walkFunction(stream:TokenStream, parent:TokenTree) { - var funcTok:TokenTree = stream.consumeTokenDef(Kwd(KwdFunction)); + var funcTok:Null = stream.consumeTokenDef(Kwd(KwdFunction)); parent.addChild(funcTok); WalkComment.walkComment(stream, funcTok); @@ -22,7 +22,7 @@ class WalkFunction { WalkFunction.walkFunctionParameters(stream, name); WalkComment.walkComment(stream, name); if (stream.is(DblDot)) { - var dblDot:TokenTree = stream.consumeTokenDef(DblDot); + var dblDot:Null = stream.consumeTokenDef(DblDot); name.addChild(dblDot); WalkTypeNameDef.walkTypeNameDef(stream, dblDot); } diff --git a/src/tokentree/walk/WalkPackageImport.hx b/src/tokentree/walk/WalkPackageImport.hx index c5b610b..48e036f 100644 --- a/src/tokentree/walk/WalkPackageImport.hx +++ b/src/tokentree/walk/WalkPackageImport.hx @@ -16,8 +16,7 @@ class WalkPackageImport { * */ public static function walkPackageImport(stream:TokenStream, parent:TokenTree) { - var newChild:TokenTree = null; - newChild = stream.consumeToken(); + var newChild:TokenTree = stream.consumeToken(); parent.addChild(newChild); if (Type.enumEq(Semicolon, newChild.tok)) return; if (!stream.hasMore()) return; diff --git a/src/tokentree/walk/WalkStatement.hx b/src/tokentree/walk/WalkStatement.hx index 46653e0..4b24335 100644 --- a/src/tokentree/walk/WalkStatement.hx +++ b/src/tokentree/walk/WalkStatement.hx @@ -273,8 +273,8 @@ class WalkStatement { } } - static function findQuestionParent(token:TokenTree):TokenTree { - var parent:TokenTree = token; + static function findQuestionParent(token:TokenTree):Null { + var parent:Null = token; while (parent != null && parent.tok != null) { switch (parent.tok) { case Question: diff --git a/src/tokentree/walk/WalkTypeNameDef.hx b/src/tokentree/walk/WalkTypeNameDef.hx index 8b5619e..7343a23 100644 --- a/src/tokentree/walk/WalkTypeNameDef.hx +++ b/src/tokentree/walk/WalkTypeNameDef.hx @@ -10,7 +10,7 @@ class WalkTypeNameDef { parent = questTok; WalkComment.walkComment(stream, parent); } - var name:TokenTree; + var name:Null; var bAdd:Bool = true; switch (stream.token()) { case BrOpen: @@ -48,7 +48,7 @@ class WalkTypeNameDef { } static function walkTypeNameDefContinue(stream:TokenStream, parent:TokenTree) { - WalkComment.walkComment(stream, parent); + walkTypeNameDefComment(stream, parent); if (stream.is(Dot)) { var dot:TokenTree = stream.consumeTokenDef(Dot); parent.addChild(dot); @@ -63,6 +63,26 @@ class WalkTypeNameDef { return; } if (stream.is(BkOpen)) WalkArrayAccess.walkArrayAccess(stream, parent); - WalkComment.walkComment(stream, parent); + walkTypeNameDefComment(stream, parent); + } + + static function walkTypeNameDefComment(stream:TokenStream, parent:TokenTree) { + var currentPos:Int = stream.getStreamIndex(); + var progress:TokenStreamProgress = new TokenStreamProgress(stream); + var comments:Array = []; + while (stream.hasMore() && progress.streamHasChanged()) { + switch (stream.token()) { + case Comment(_), CommentLine(_): + comments.push(stream.consumeToken()); + case DblDot, Comma, Semicolon, Dot, BrOpen, BkOpen, POpen, Binop(_): + for (comment in comments) { + parent.addChild(comment); + } + return; + default: + stream.rewindTo(currentPos); + return; + } + } } } \ No newline at end of file diff --git a/src/tokentree/walk/WalkVar.hx b/src/tokentree/walk/WalkVar.hx index f4de269..ac2c30a 100644 --- a/src/tokentree/walk/WalkVar.hx +++ b/src/tokentree/walk/WalkVar.hx @@ -2,8 +2,8 @@ package tokentree.walk; class WalkVar { public static function walkVar(stream:TokenStream, parent:TokenTree) { - var name:TokenTree = null; - var varTok:TokenTree = stream.consumeTokenDef(Kwd(KwdVar)); + var name:Null = null; + var varTok:Null = stream.consumeTokenDef(Kwd(KwdVar)); parent.addChild(varTok); WalkComment.walkComment(stream, parent); var progress:TokenStreamProgress = new TokenStreamProgress(stream);