From 60bad586df0e32bc559029638bd4b030afae5bf6 Mon Sep 17 00:00:00 2001 From: webdevred <148627186+webdevred@users.noreply.github.com> Date: Tue, 10 Mar 2026 19:50:54 +0100 Subject: [PATCH 1/3] Track blank-line-before in parsed single-line comments Add `cHadNewlineBefore` field to `InternalComment` to record whether a single-line `//` comment was preceded by a blank line (2+ newlines) in the source. The parser's `separatorParser` now counts total newlines to detect blank lines and stores the result in `ParseState`. The formatter uses this to suppress the extra blank line before a `//` comment when it directly follows another `//` comment with no blank line between them in the source, preserving the original grouping of consecutive comments. --- examples/ast/jbeam/fender.hs | 27 +++++++++++++++++++ examples/ast/jbeam/frame.hs | 20 ++++++++++++++ examples/ast/jbeam/suspension.hs | 23 ++++++++++++++++ .../JbeamEdit/Transformation.hs | 4 +-- .../Transformation/VertexExtraction.hs | 2 +- src/JbeamEdit/Core/Node.hs | 3 ++- src/JbeamEdit/Formatting.hs | 9 +++++-- src/JbeamEdit/Parsing/Jbeam.hs | 20 +++++++++++--- test/Core/NodePathSpec.hs | 2 +- test/Core/NodeSpec.hs | 2 +- test/FormattingSpec.hs | 4 +-- test/Parsing/JbeamSpec.hs | 6 ++++- 12 files changed, 107 insertions(+), 15 deletions(-) diff --git a/examples/ast/jbeam/fender.hs b/examples/ast/jbeam/fender.hs index 701a875c..29b03063 100644 --- a/examples/ast/jbeam/fender.hs +++ b/examples/ast/jbeam/fender.hs @@ -92,6 +92,7 @@ Object { cText = "Left side" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -182,6 +183,7 @@ Object { cText = "Right side" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -283,6 +285,7 @@ Object { cText = "Support nodes" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -338,6 +341,7 @@ Object { cText = "Structural beams" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = False } ) , Object @@ -379,6 +383,7 @@ Object { cText = "Front" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Array @@ -434,6 +439,7 @@ Object { cText = "Middle" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -463,6 +469,7 @@ Object { cText = "Rear" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Array @@ -526,6 +533,7 @@ Object { cText = "Crossing beams" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -539,6 +547,7 @@ Object { cText = "Front" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = False } ) , Array @@ -578,6 +587,7 @@ Object { cText = "Rear" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Array @@ -617,6 +627,7 @@ Object { cText = "Support beams" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Array @@ -712,6 +723,7 @@ Object { cText = "Front rigid" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -735,6 +747,7 @@ Object { cText = "Left side" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Array @@ -750,6 +763,7 @@ Object { cText = "Right side" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Array @@ -765,6 +779,7 @@ Object { cText = "Attachment beams" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -802,6 +817,7 @@ Object { cText = "Frame" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Comment @@ -809,6 +825,7 @@ Object { cText = "Left side" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Comment @@ -816,6 +833,7 @@ Object { cText = "Front" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -859,6 +877,7 @@ Object { cText = "Middle" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -902,6 +921,7 @@ Object { cText = "Rear" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -967,6 +987,7 @@ Object { cText = "Right side" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Comment @@ -974,6 +995,7 @@ Object { cText = "Front" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -1035,6 +1057,7 @@ Object { cText = "Middle" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -1090,6 +1113,7 @@ Object { cText = "Rear" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -1197,6 +1221,7 @@ Object { cText = "Body" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = False } ) , Comment @@ -1204,6 +1229,7 @@ Object { cText = "Left side" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -1229,6 +1255,7 @@ Object { cText = "Right side" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object diff --git a/examples/ast/jbeam/frame.hs b/examples/ast/jbeam/frame.hs index ef252ff6..b36885f3 100644 --- a/examples/ast/jbeam/frame.hs +++ b/examples/ast/jbeam/frame.hs @@ -24,6 +24,7 @@ Object { cText = "\nThe purpose of this file is prove that moving metadata\nalong with vertices when moving vertices works as intended.\nSee issue for #69 explanation on the transformation part of the codebase.\n" , cMultiline = True , cAssociationDirection = NextNode + , cHadNewlineBefore = False } ) , Comment @@ -31,6 +32,7 @@ Object { cText = "--Nodes--" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = False } ) , ObjectKey @@ -164,6 +166,7 @@ Object { cText = "support for front" , cMultiline = False , cAssociationDirection = PreviousNode + , cHadNewlineBefore = False } ) , Array @@ -208,6 +211,7 @@ Object { cText = "support" , cMultiline = False , cAssociationDirection = PreviousNode + , cHadNewlineBefore = False } ) , Array @@ -401,6 +405,7 @@ Object { cText = "support for rear" , cMultiline = False , cAssociationDirection = PreviousNode + , cHadNewlineBefore = False } ) , Array @@ -454,6 +459,7 @@ Object { cText = "--Beams--" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = False } ) , ObjectKey @@ -468,6 +474,7 @@ Object { cText = "Structural beams" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -495,6 +502,7 @@ Object { cText = "Front end" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -604,6 +612,7 @@ Object { cText = "Middle" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -749,6 +758,7 @@ Object { cText = "Rear end" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -898,6 +908,7 @@ Object { cText = "Crossing beams" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Comment @@ -905,6 +916,7 @@ Object { cText = "Front end" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -982,6 +994,7 @@ Object { cText = "Middle" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -1091,6 +1104,7 @@ Object { cText = "Rear end" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -1200,6 +1214,7 @@ Object { cText = "Support beams" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Comment @@ -1207,6 +1222,7 @@ Object { cText = "Front end" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -1276,6 +1292,7 @@ Object { cText = "Middle" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -1361,6 +1378,7 @@ Object { cText = "Rear end" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -1438,6 +1456,7 @@ Object { cText = "Front crush" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -1461,6 +1480,7 @@ Object { cText = "--Collision Triangles--" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = False } ) , ObjectKey diff --git a/examples/ast/jbeam/suspension.hs b/examples/ast/jbeam/suspension.hs index 4ef7d516..4d040094 100644 --- a/examples/ast/jbeam/suspension.hs +++ b/examples/ast/jbeam/suspension.hs @@ -24,6 +24,7 @@ Object { cText = "The purpose of this file is prove that moving metadata along with vertices when\nmoving vertices works as intended.\nSee issue for #69 explanation on the transformation part of the codebase." , cMultiline = True , cAssociationDirection = NextNode + , cHadNewlineBefore = False } ) , Comment @@ -31,6 +32,7 @@ Object { cText = "--Nodes--" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = False } ) , ObjectKey @@ -109,6 +111,7 @@ Object { cText = "ref node front" , cMultiline = False , cAssociationDirection = PreviousNode + , cHadNewlineBefore = False } ) , Array @@ -183,6 +186,7 @@ Object { cText = "support" , cMultiline = False , cAssociationDirection = PreviousNode + , cHadNewlineBefore = False } ) , Object @@ -239,6 +243,7 @@ Object { cText = "support" , cMultiline = False , cAssociationDirection = PreviousNode + , cHadNewlineBefore = False } ) , Array @@ -252,6 +257,7 @@ Object { cText = "ref node left" , cMultiline = False , cAssociationDirection = PreviousNode + , cHadNewlineBefore = False } ) , Array @@ -310,6 +316,7 @@ Object { cText = "ref node right" , cMultiline = False , cAssociationDirection = PreviousNode + , cHadNewlineBefore = False } ) , Array @@ -452,6 +459,7 @@ Object { cText = "support" , cMultiline = False , cAssociationDirection = PreviousNode + , cHadNewlineBefore = False } ) , Array @@ -505,6 +513,7 @@ Object { cText = "--Beams--" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = False } ) , ObjectKey @@ -519,6 +528,7 @@ Object { cText = "Structural beams" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -546,6 +556,7 @@ Object { cText = "Front end" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -655,6 +666,7 @@ Object { cText = "Middle" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -800,6 +812,7 @@ Object { cText = "Rear end" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -949,6 +962,7 @@ Object { cText = "Crossing beams" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Comment @@ -956,6 +970,7 @@ Object { cText = "Front end" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -1033,6 +1048,7 @@ Object { cText = "Middle" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -1142,6 +1158,7 @@ Object { cText = "Rear end" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -1251,6 +1268,7 @@ Object { cText = "Support beams" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Comment @@ -1258,6 +1276,7 @@ Object { cText = "Front end" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -1327,6 +1346,7 @@ Object { cText = "Middle" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -1412,6 +1432,7 @@ Object { cText = "Rear end" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -1489,6 +1510,7 @@ Object { cText = "Front crush" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = True } ) , Object @@ -1512,6 +1534,7 @@ Object { cText = "--Collision Triangles--" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = False } ) , ObjectKey diff --git a/src-extra/transformation/JbeamEdit/Transformation.hs b/src-extra/transformation/JbeamEdit/Transformation.hs index b49574ca..bb56377e 100644 --- a/src-extra/transformation/JbeamEdit/Transformation.hs +++ b/src-extra/transformation/JbeamEdit/Transformation.hs @@ -51,7 +51,7 @@ sideCommentText RightTree = "Right side" sideCommentText SupportTree = "Support nodes" sideComment :: VertexTreeType -> InternalComment -sideComment t = InternalComment (sideCommentText t) False NextNode +sideComment t = InternalComment (sideCommentText t) False NextNode False addSideComment :: Ord k @@ -72,7 +72,7 @@ addPrefixComments _ trees = bool trees (fmap addToAnnotatedVertex trees) (length where addToAnnotatedVertex (VertexTree [] namedVertexGroups) = let commentName = dropIndex . vName . aVertex . NE.head $ namedVertexGroups - newComment = InternalComment ("prefix group " <> commentName) False NextNode + newComment = InternalComment ("prefix group " <> commentName) False NextNode True in VertexTree [newComment] namedVertexGroups addToAnnotatedVertex (VertexTree comments namedVertexGroups) = VertexTree comments namedVertexGroups diff --git a/src-extra/transformation/JbeamEdit/Transformation/VertexExtraction.hs b/src-extra/transformation/JbeamEdit/Transformation/VertexExtraction.hs index 1ac9902b..3f0251d1 100644 --- a/src-extra/transformation/JbeamEdit/Transformation/VertexExtraction.hs +++ b/src-extra/transformation/JbeamEdit/Transformation/VertexExtraction.hs @@ -188,7 +188,7 @@ nodesToAnnotatedVertices initialMeta nodes = go initialMeta [] nodes ([], []) in go newMeta pendingComments ns acc | isCommentNode n -> case (toInternalComment n, acc) of - (Just ic@(InternalComment _ _ PreviousNode), (_, an : ans)) -> + (Just ic@(InternalComment _ _ PreviousNode _), (_, an : ans)) -> go pendingMeta pendingComments ns (badNodes, addCommentToAn ic an : ans) (Just ic, _) -> go pendingMeta (ic : pendingComments) ns acc diff --git a/src/JbeamEdit/Core/Node.hs b/src/JbeamEdit/Core/Node.hs index dca96190..c65ba489 100644 --- a/src/JbeamEdit/Core/Node.hs +++ b/src/JbeamEdit/Core/Node.hs @@ -37,6 +37,7 @@ data InternalComment = InternalComment { cText :: Text , cMultiline :: Bool , cAssociationDirection :: AssociationDirection + , cHadNewlineBefore :: Bool } deriving (Eq, Ord, Read, Show) @@ -105,7 +106,7 @@ isNumberNode (Number _) = True isNumberNode _ = False isSinglelineComment :: Node -> Bool -isSinglelineComment (Comment (InternalComment _ False _)) = True +isSinglelineComment (Comment (InternalComment _ False _ _)) = True isSinglelineComment _ = False expectArray :: Node -> Maybe (Vector Node) diff --git a/src/JbeamEdit/Formatting.hs b/src/JbeamEdit/Formatting.hs index 1d96653e..c16b4e17 100644 --- a/src/JbeamEdit/Formatting.hs +++ b/src/JbeamEdit/Formatting.hs @@ -73,7 +73,7 @@ splitTrailing comma txt = ) normalizeCommentNode :: Bool -> Node -> Node -normalizeCommentNode False (Comment (InternalComment txt False dir)) = Comment (InternalComment txt True dir) +normalizeCommentNode False (Comment (InternalComment txt False dir hadNl)) = Comment (InternalComment txt True dir hadNl) normalizeCommentNode _ node = node singleCharIf :: Char -> Bool -> Text @@ -124,7 +124,12 @@ addDelimiters rs index rowIdx c complexChildren state acc ns@(node : rest) new_acc = (baseTxt <> singleCharIf ' ' space <> singleCharIf '\n' newline) : acc in addDelimiters rs (index + 1) nextRowIdx c complexChildren state new_acc rest where - newlineBeforeComment = singleCharIfNot '\n' (any isObjectKeyNode rest || ["\n"] == acc) + newlineBeforeComment = case node of + Comment ic | not (cMultiline ic) && not (cHadNewlineBefore ic) -> + case acc of + (prev : _) | T.isPrefixOf "// " (T.dropWhile (== '\n') prev) -> "" + _ -> singleCharIfNot '\n' (any isObjectKeyNode rest || ["\n"] == acc) + _ -> singleCharIfNot '\n' (any isObjectKeyNode rest || ["\n"] == acc) nextRowIdx = rowIdx + case node of diff --git a/src/JbeamEdit/Parsing/Jbeam.hs b/src/JbeamEdit/Parsing/Jbeam.hs index 5459b37d..e9a88ca5 100644 --- a/src/JbeamEdit/Parsing/Jbeam.hs +++ b/src/JbeamEdit/Parsing/Jbeam.hs @@ -34,8 +34,9 @@ import Text.Megaparsec.Byte qualified as B import Text.Megaparsec.Byte.Lexer qualified as L (scientific) import Text.Megaparsec.Char qualified as C -newtype ParseState = ParseState +data ParseState = ParseState { lastNodeEndedWithNewline :: Bool + , lastSeparatorHadBlankLine :: Bool } type JbeamParser a = Parser (State ParseState) a @@ -46,11 +47,19 @@ separatorParser = do comma <- MP.optional (MP.label "comma" $ byteChar ',') ws2 <- MP.takeWhileP Nothing wordIsSpace - let hasNewline = + let countNewlines = length . filter (== '\n') . map toChar . LBS.unpack + totalNewlines = countNewlines ws1 + countNewlines ws2 + hasNewline = isNothing comma && '\n' `elem` map toChar (LBS.unpack ws1) || '\n' `elem` map toChar (LBS.unpack ws2) - modify (\s -> s {lastNodeEndedWithNewline = hasNewline}) + modify + ( \s -> + s + { lastNodeEndedWithNewline = hasNewline + , lastSeparatorHadBlankLine = totalNewlines >= 2 + } + ) pure () @@ -85,6 +94,7 @@ multilineCommentParser = do { cText = text , cMultiline = True , cAssociationDirection = associationDirection st + , cHadNewlineBefore = False } parseComment = parseWord8s (multilineComment . commentStripSpace) C.string "/*" >> parseComment (MP.manyTill B.asciiChar (B.string "*/")) @@ -99,6 +109,7 @@ singlelineCommentParser = do { cText = T.strip . decodeUtf8Lenient $ BS.pack txt , cMultiline = False , cAssociationDirection = associationDirection st + , cHadNewlineBefore = lastSeparatorHadBlankLine st } commentParser :: JbeamParser Node @@ -175,7 +186,8 @@ parseNodesState -> LBS.ByteString -> Either (MP.ParseErrorBundle LBS.ByteString Void) a parseNodesState parser input = - let initialState = ParseState {lastNodeEndedWithNewline = True} + let initialState = + ParseState {lastNodeEndedWithNewline = True, lastSeparatorHadBlankLine = False} in evalState (MP.runParserT parser "" input) initialState parseNodes :: LBS.ByteString -> Either Text Node diff --git a/test/Core/NodePathSpec.hs b/test/Core/NodePathSpec.hs index ab73be10..8dfb4c99 100644 --- a/test/Core/NodePathSpec.hs +++ b/test/Core/NodePathSpec.hs @@ -11,7 +11,7 @@ spec = describe "select" $ do let arr = Array $ fromList - [Comment (InternalComment "c" False NextNode), String "first", String "second"] + [Comment (InternalComment "c" False NextNode False), String "first", String "second"] NP.select (NP.ArrayIndex 0) arr `shouldBe` Just (String "first") NP.select (NP.ArrayIndex 1) arr `shouldBe` Just (String "second") NP.select (NP.ArrayIndex 2) arr `shouldBe` Nothing diff --git a/test/Core/NodeSpec.hs b/test/Core/NodeSpec.hs index 703bee01..46825348 100644 --- a/test/Core/NodeSpec.hs +++ b/test/Core/NodeSpec.hs @@ -7,7 +7,7 @@ spec :: Spec spec = do describe "isCommentNode" . works $ ( do - isCommentNode (Comment (InternalComment "test" False NextNode)) `shouldBe` True + isCommentNode (Comment (InternalComment "test" False NextNode False)) `shouldBe` True isCommentNode (Number 123) `shouldBe` False ) describe "isObjectNode" . works $ diff --git a/test/FormattingSpec.hs b/test/FormattingSpec.hs index 3c650cef..b73320dc 100644 --- a/test/FormattingSpec.hs +++ b/test/FormattingSpec.hs @@ -30,10 +30,10 @@ nullSpec :: [(String, Node)] nullSpec = [("null", Null)] multilineCommentSpec :: [(String, Node)] -multilineCommentSpec = [("/* test */", Comment (InternalComment "test" True NextNode))] +multilineCommentSpec = [("/* test */", Comment (InternalComment "test" True NextNode False))] singlelineCommentSpec :: [(String, Node)] -singlelineCommentSpec = [("// test", Comment (InternalComment "test" False NextNode))] +singlelineCommentSpec = [("// test", Comment (InternalComment "test" False NextNode False))] arraySpec :: [(String, Node)] arraySpec = diff --git a/test/Parsing/JbeamSpec.hs b/test/Parsing/JbeamSpec.hs index aba8472c..184c3daa 100644 --- a/test/Parsing/JbeamSpec.hs +++ b/test/Parsing/JbeamSpec.hs @@ -42,6 +42,7 @@ multilineCommentSpec = { cText = "test" , cMultiline = True , cAssociationDirection = NextNode + , cHadNewlineBefore = False } ) ) @@ -56,6 +57,7 @@ singlelineCommentSpec = { cText = "" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = False } ) ) @@ -66,6 +68,7 @@ singlelineCommentSpec = { cText = "test" , cMultiline = False , cAssociationDirection = NextNode + , cHadNewlineBefore = False } ) ) @@ -80,6 +83,7 @@ singlelineCommentSpec = { cText = "cool comment" , cMultiline = False , cAssociationDirection = PreviousNode + , cHadNewlineBefore = False } ) ] @@ -109,7 +113,7 @@ objectSpec = ( "{\n//test\n\"test\" : 1, \"test2\" : 2}" , Object ( fromList - [ Comment (InternalComment "test" False NextNode) + [ Comment (InternalComment "test" False NextNode False) , ObjectKey (String "test", Number 1) , ObjectKey (String "test2", Number 2) ] From ff7b6c0ae160ad5ba064cff256c056afc032b190 Mon Sep 17 00:00:00 2001 From: webdevred <148627186+webdevred@users.noreply.github.com> Date: Tue, 10 Mar 2026 19:55:47 +0100 Subject: [PATCH 2/3] Updated fender example --- examples/ast/jbeam/fender.hs | 16 ++++++++++++++++ .../formatted_jbeam/fender-complex-jbfl.jbeam | 2 ++ .../formatted_jbeam/fender-minimal-jbfl.jbeam | 2 ++ examples/jbeam/fender.jbeam | 2 ++ .../fender-after-frame-cfg-default.jbeam | 2 ++ .../fender-after-frame-cfg-example.jbeam | 2 ++ .../transformed_jbeam/fender-cfg-default.jbeam | 2 ++ .../transformed_jbeam/fender-cfg-example.jbeam | 2 ++ .../data/fender-custom-minimal-jbfl.jbeam | 2 ++ 9 files changed, 32 insertions(+) diff --git a/examples/ast/jbeam/fender.hs b/examples/ast/jbeam/fender.hs index 29b03063..8cf10925 100644 --- a/examples/ast/jbeam/fender.hs +++ b/examples/ast/jbeam/fender.hs @@ -344,6 +344,22 @@ Object , cHadNewlineBefore = False } ) + , Comment + ( InternalComment + { cText = "beamSpring: 451000, beamDamp: 50" + , cMultiline = False + , cAssociationDirection = NextNode + , cHadNewlineBefore = False + } + ) + , Comment + ( InternalComment + { cText = "beamStrength: FLT_MAX" + , cMultiline = False + , cAssociationDirection = NextNode + , cHadNewlineBefore = False + } + ) , Object [ ObjectKey ( String "beamType" diff --git a/examples/formatted_jbeam/fender-complex-jbfl.jbeam b/examples/formatted_jbeam/fender-complex-jbfl.jbeam index 2db54559..96de2e77 100644 --- a/examples/formatted_jbeam/fender-complex-jbfl.jbeam +++ b/examples/formatted_jbeam/fender-complex-jbfl.jbeam @@ -61,6 +61,8 @@ ["id1:", "id2:"], // Structural beams + // beamSpring: 451000, beamDamp: 50 + // beamStrength: FLT_MAX {"beamType" : "|NORMAL"}, {"beamSpring" : 451000, "beamDamp" : 50}, {"beamStrength" : "FLT_MAX"}, diff --git a/examples/formatted_jbeam/fender-minimal-jbfl.jbeam b/examples/formatted_jbeam/fender-minimal-jbfl.jbeam index 2db54559..96de2e77 100644 --- a/examples/formatted_jbeam/fender-minimal-jbfl.jbeam +++ b/examples/formatted_jbeam/fender-minimal-jbfl.jbeam @@ -61,6 +61,8 @@ ["id1:", "id2:"], // Structural beams + // beamSpring: 451000, beamDamp: 50 + // beamStrength: FLT_MAX {"beamType" : "|NORMAL"}, {"beamSpring" : 451000, "beamDamp" : 50}, {"beamStrength" : "FLT_MAX"}, diff --git a/examples/jbeam/fender.jbeam b/examples/jbeam/fender.jbeam index 32a3e024..43a08944 100644 --- a/examples/jbeam/fender.jbeam +++ b/examples/jbeam/fender.jbeam @@ -63,6 +63,8 @@ "beams":[ ["id1:", "id2:"], //Structural beams + //beamSpring: 451000, beamDamp: 50 + //beamStrength: FLT_MAX {"beamType": "|NORMAL"}, {"beamSpring": 451000,"beamDamp": 50}, {"beamStrength": "FLT_MAX"}, {"deformLimitExpansion": 1.1}, {"beamDeform": 6000}, diff --git a/examples/transformed_jbeam/fender-after-frame-cfg-default.jbeam b/examples/transformed_jbeam/fender-after-frame-cfg-default.jbeam index 8e8b8ddf..706b7c5d 100644 --- a/examples/transformed_jbeam/fender-after-frame-cfg-default.jbeam +++ b/examples/transformed_jbeam/fender-after-frame-cfg-default.jbeam @@ -61,6 +61,8 @@ ["id1:", "id2:"], // Structural beams + // beamSpring: 451000, beamDamp: 50 + // beamStrength: FLT_MAX {"beamType" : "|NORMAL"}, {"beamSpring" : 451000, "beamDamp" : 50}, {"beamStrength" : "FLT_MAX"}, diff --git a/examples/transformed_jbeam/fender-after-frame-cfg-example.jbeam b/examples/transformed_jbeam/fender-after-frame-cfg-example.jbeam index 8e8b8ddf..706b7c5d 100644 --- a/examples/transformed_jbeam/fender-after-frame-cfg-example.jbeam +++ b/examples/transformed_jbeam/fender-after-frame-cfg-example.jbeam @@ -61,6 +61,8 @@ ["id1:", "id2:"], // Structural beams + // beamSpring: 451000, beamDamp: 50 + // beamStrength: FLT_MAX {"beamType" : "|NORMAL"}, {"beamSpring" : 451000, "beamDamp" : 50}, {"beamStrength" : "FLT_MAX"}, diff --git a/examples/transformed_jbeam/fender-cfg-default.jbeam b/examples/transformed_jbeam/fender-cfg-default.jbeam index 2cfb3584..efe99497 100644 --- a/examples/transformed_jbeam/fender-cfg-default.jbeam +++ b/examples/transformed_jbeam/fender-cfg-default.jbeam @@ -61,6 +61,8 @@ ["id1:", "id2:"], // Structural beams + // beamSpring: 451000, beamDamp: 50 + // beamStrength: FLT_MAX {"beamType" : "|NORMAL"}, {"beamSpring" : 451000, "beamDamp" : 50}, {"beamStrength" : "FLT_MAX"}, diff --git a/examples/transformed_jbeam/fender-cfg-example.jbeam b/examples/transformed_jbeam/fender-cfg-example.jbeam index 2cfb3584..efe99497 100644 --- a/examples/transformed_jbeam/fender-cfg-example.jbeam +++ b/examples/transformed_jbeam/fender-cfg-example.jbeam @@ -61,6 +61,8 @@ ["id1:", "id2:"], // Structural beams + // beamSpring: 451000, beamDamp: 50 + // beamStrength: FLT_MAX {"beamType" : "|NORMAL"}, {"beamSpring" : 451000, "beamDamp" : 50}, {"beamStrength" : "FLT_MAX"}, diff --git a/test-extra/language-server/data/fender-custom-minimal-jbfl.jbeam b/test-extra/language-server/data/fender-custom-minimal-jbfl.jbeam index 913a8166..90146df8 100644 --- a/test-extra/language-server/data/fender-custom-minimal-jbfl.jbeam +++ b/test-extra/language-server/data/fender-custom-minimal-jbfl.jbeam @@ -61,6 +61,8 @@ ["id1:", "id2:"], // Structural beams + // beamSpring: 451000, beamDamp: 50 + // beamStrength: FLT_MAX {"beamType" : "|NORMAL"}, {"beamSpring" : 451000, "beamDamp" : 50}, {"beamStrength" : "FLT_MAX"}, From cac4e8da0355902e67f29e33824f608923f44450 Mon Sep 17 00:00:00 2001 From: webdevred <148627186+webdevred@users.noreply.github.com> Date: Tue, 10 Mar 2026 20:01:53 +0100 Subject: [PATCH 3/3] Ran formatter --- test/Core/NodePathSpec.hs | 5 ++++- test/Core/NodeSpec.hs | 3 ++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/test/Core/NodePathSpec.hs b/test/Core/NodePathSpec.hs index 8dfb4c99..cb6b2933 100644 --- a/test/Core/NodePathSpec.hs +++ b/test/Core/NodePathSpec.hs @@ -11,7 +11,10 @@ spec = describe "select" $ do let arr = Array $ fromList - [Comment (InternalComment "c" False NextNode False), String "first", String "second"] + [ Comment (InternalComment "c" False NextNode False) + , String "first" + , String "second" + ] NP.select (NP.ArrayIndex 0) arr `shouldBe` Just (String "first") NP.select (NP.ArrayIndex 1) arr `shouldBe` Just (String "second") NP.select (NP.ArrayIndex 2) arr `shouldBe` Nothing diff --git a/test/Core/NodeSpec.hs b/test/Core/NodeSpec.hs index 46825348..cdb049a0 100644 --- a/test/Core/NodeSpec.hs +++ b/test/Core/NodeSpec.hs @@ -7,7 +7,8 @@ spec :: Spec spec = do describe "isCommentNode" . works $ ( do - isCommentNode (Comment (InternalComment "test" False NextNode False)) `shouldBe` True + isCommentNode (Comment (InternalComment "test" False NextNode False)) + `shouldBe` True isCommentNode (Number 123) `shouldBe` False ) describe "isObjectNode" . works $