diff --git a/misc/formatter/modules/formatter-core/src/main/java/org/ballerinalang/formatter/core/FormattingTreeModifier.java b/misc/formatter/modules/formatter-core/src/main/java/org/ballerinalang/formatter/core/FormattingTreeModifier.java index 5761803aefa2..57cf86d9ade3 100644 --- a/misc/formatter/modules/formatter-core/src/main/java/org/ballerinalang/formatter/core/FormattingTreeModifier.java +++ b/misc/formatter/modules/formatter-core/src/main/java/org/ballerinalang/formatter/core/FormattingTreeModifier.java @@ -36,7 +36,6 @@ import io.ballerina.compiler.syntax.tree.ByteArrayLiteralNode; import io.ballerina.compiler.syntax.tree.CaptureBindingPatternNode; import io.ballerina.compiler.syntax.tree.CheckExpressionNode; -import io.ballerina.compiler.syntax.tree.ChildNodeList; import io.ballerina.compiler.syntax.tree.ClassDefinitionNode; import io.ballerina.compiler.syntax.tree.ClauseNode; import io.ballerina.compiler.syntax.tree.ClientResourceAccessActionNode; @@ -254,6 +253,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Optional; +import java.util.function.Predicate; import java.util.stream.Collectors; import static org.ballerinalang.formatter.core.FormatterUtils.isInlineRange; @@ -289,7 +289,8 @@ public FormattingTreeModifier(FormattingOptions options, LineRange lineRange) { @Override public ModulePartNode transform(ModulePartNode modulePartNode) { NodeList imports = sortAndGroupImportDeclarationNodes(modulePartNode.imports()); - NodeList members = formatModuleMembers(modulePartNode.members()); + NodeList members = + formatMemberDeclarations(modulePartNode.members(), n -> isMultilineModuleMember(n)); Token eofToken = formatToken(modulePartNode.eofToken(), 0, 0); return modulePartNode.modify(imports, members, eofToken); } @@ -313,25 +314,8 @@ public FunctionDefinitionNode transform(FunctionDefinitionNode functionDefinitio } NodeList relativeResourcePath = formatNodeList(functionDefinitionNode.relativeResourcePath(), 0, 0, 0, 0); FunctionSignatureNode functionSignatureNode = formatNode(functionDefinitionNode.functionSignature(), 1, 0); - int trailingNL = env.trailingNL; - if (isMemberOfScope(functionDefinitionNode)) { - ChildNodeList parentChildren = functionDefinitionNode.parent().children(); - int nChildren = parentChildren.size(); - boolean lastNode = false; - - for (int i = nChildren - 1; i > -1; i--) { - Node child = parentChildren.get(i); - if (isMemberOfScope(child)) { - if (child.equals(functionDefinitionNode)) { - lastNode = true; - } - break; - } - } - trailingNL = (env.trailingNL > 2 || lastNode) ? env.trailingNL : 2; - } FunctionBodyNode functionBodyNode = - formatNode(functionDefinitionNode.functionBody(), env.trailingWS, trailingNL); + formatNode(functionDefinitionNode.functionBody(), env.trailingWS, env.trailingNL); return functionDefinitionNode.modify() .withMetadata(metadata) @@ -718,7 +702,7 @@ public ServiceDeclarationNode transform(ServiceDeclarationNode serviceDeclaratio formatSeparatedNodeList(serviceDeclarationNode.expressions(), 0, 0, 1, 0); Token openBrace = formatToken(serviceDeclarationNode.openBraceToken(), 0, 1); indent(); // increase the indentation of the following statements. - NodeList members = formatNodeList(serviceDeclarationNode.members(), 0, 1, 0, 1); + NodeList members = formatMemberDeclarations(serviceDeclarationNode.members(), n -> isMemberOfScope(n)); unindent(); // reset the indentation. Optional optSemicolon = serviceDeclarationNode.semicolonToken(); Token closeBrace = optSemicolon.isPresent() ? @@ -3480,7 +3464,7 @@ public ClassDefinitionNode transform(ClassDefinitionNode classDefinitionNode) { Token openBrace = formatToken(classDefinitionNode.openBrace(), 0, 1); indent(); - NodeList members = formatNodeList(classDefinitionNode.members(), 0, 1, 0, 1); + NodeList members = formatMemberDeclarations(classDefinitionNode.members(), n -> isMemberOfScope(n)); unindent(); Optional optSemicolon = classDefinitionNode.semicolonToken(); Token closeBrace = optSemicolon.isPresent() ? @@ -3855,7 +3839,14 @@ private T formatToken(T token, int trailingWS, int trailingNL) return formatToken(token, trailingWS, trailingNL, null); } - protected NodeList formatModuleMembers(NodeList members) { + /** + * Format members in module-level, class and service level. + * + * @param members Members of the scope + * @param filter filter to identify multiline members + * @return Formatted list of members + */ + protected NodeList formatMemberDeclarations(NodeList members, Predicate filter) { if (members.isEmpty()) { return members; } @@ -3873,7 +3864,7 @@ protected NodeList formatModuleMembers(NodeList members) // We need to do this check, because different kinds of children needs // different number of newlines in-between. int itemTrailingNL = 1; - if (isMultilineModuleMember(currentMember) || isMultilineModuleMember(nextMember)) { + if (filter.test(currentMember) || filter.test(nextMember)) { itemTrailingNL++; } @@ -3915,10 +3906,13 @@ private boolean isMultilineModuleMember(T node) { } private boolean isMemberOfScope(T node) { + if (node == null) { + return false; + } + switch (node.kind()) { case OBJECT_METHOD_DEFINITION: case RESOURCE_ACCESSOR_DEFINITION: - case OBJECT_FIELD: return true; default: return false; @@ -4259,8 +4253,7 @@ private MinutiaeList getLeadingMinutiae(Token token) { int consecutiveNewlines = 0; Minutiae prevMinutiae = null; - boolean missingTokenWithNL = token.isMissing() && env.hasNewline; - if (!token.isMissing() && env.hasNewline) { + if (env.hasNewline) { // 'hasNewlines == true' means a newline has already been added. // Therefore, increase the 'consecutiveNewlines' count consecutiveNewlines++; @@ -4318,9 +4311,6 @@ private MinutiaeList getLeadingMinutiae(Token token) { case INVALID_TOKEN_MINUTIAE_NODE: case INVALID_NODE_MINUTIAE: default: - if (missingTokenWithNL) { - missingTokenWithNL = false; - } consecutiveNewlines = 0; leadingMinutiae.add(minutiae); break; @@ -4330,7 +4320,7 @@ private MinutiaeList getLeadingMinutiae(Token token) { } // token.isMission() issue has to be discussed. - if ((consecutiveNewlines > 0 || missingTokenWithNL) && !env.preserveIndentation) { + if (consecutiveNewlines > 0 && !env.preserveIndentation) { addWhitespace(env.currentIndentation, leadingMinutiae); } diff --git a/misc/formatter/modules/formatter-core/src/test/resources/declarations/class-definition/assert/class_definition_declaration_2.bal b/misc/formatter/modules/formatter-core/src/test/resources/declarations/class-definition/assert/class_definition_declaration_2.bal index 3e236db3429b..73abf4af0e3f 100644 --- a/misc/formatter/modules/formatter-core/src/test/resources/declarations/class-definition/assert/class_definition_declaration_2.bal +++ b/misc/formatter/modules/formatter-core/src/test/resources/declarations/class-definition/assert/class_definition_declaration_2.bal @@ -10,6 +10,7 @@ class Person { public string name = "sample name"; int year = 50; + function bar() returns string { string b = "bar"; return b;