From ec6b230ae481c3b7c7d9261f10cdf929284a0995 Mon Sep 17 00:00:00 2001 From: KavinduZoysa Date: Sun, 8 Sep 2024 10:49:08 +0530 Subject: [PATCH 1/5] Initial working commit for CommentNode --- .../compiler/parser/BLangNodeBuilder.java | 247 +----------------- .../compiler/syntax/tree/CommentNode.java | 128 +++++++++ .../syntax/tree/FunctionBodyBlockNode.java | 4 + .../syntax/tree/NodeAndCommentList.java | 189 ++++++++++++++ .../compiler/syntax/tree/NodeTransformer.java | 4 + .../compiler/syntax/tree/NodeVisitor.java | 3 + 6 files changed, 335 insertions(+), 240 deletions(-) create mode 100644 compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/CommentNode.java create mode 100644 compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/NodeAndCommentList.java diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/parser/BLangNodeBuilder.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/parser/BLangNodeBuilder.java index 58d576a52fb0..6ebaddfad392 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/parser/BLangNodeBuilder.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/parser/BLangNodeBuilder.java @@ -17,246 +17,7 @@ */ package org.wso2.ballerinalang.compiler.parser; -import io.ballerina.compiler.syntax.tree.AlternateReceiveNode; -import io.ballerina.compiler.syntax.tree.AnnotAccessExpressionNode; -import io.ballerina.compiler.syntax.tree.AnnotationAttachPointNode; -import io.ballerina.compiler.syntax.tree.AnnotationDeclarationNode; -import io.ballerina.compiler.syntax.tree.AnnotationNode; -import io.ballerina.compiler.syntax.tree.ArrayDimensionNode; -import io.ballerina.compiler.syntax.tree.ArrayTypeDescriptorNode; -import io.ballerina.compiler.syntax.tree.AssignmentStatementNode; -import io.ballerina.compiler.syntax.tree.AsyncSendActionNode; -import io.ballerina.compiler.syntax.tree.BallerinaNameReferenceNode; -import io.ballerina.compiler.syntax.tree.BasicLiteralNode; -import io.ballerina.compiler.syntax.tree.BinaryExpressionNode; -import io.ballerina.compiler.syntax.tree.BindingPatternNode; -import io.ballerina.compiler.syntax.tree.BlockStatementNode; -import io.ballerina.compiler.syntax.tree.BracedExpressionNode; -import io.ballerina.compiler.syntax.tree.BreakStatementNode; -import io.ballerina.compiler.syntax.tree.BuiltinSimpleNameReferenceNode; -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.ClientResourceAccessActionNode; -import io.ballerina.compiler.syntax.tree.CollectClauseNode; -import io.ballerina.compiler.syntax.tree.CommitActionNode; -import io.ballerina.compiler.syntax.tree.CompoundAssignmentStatementNode; -import io.ballerina.compiler.syntax.tree.ComputedNameFieldNode; -import io.ballerina.compiler.syntax.tree.ComputedResourceAccessSegmentNode; -import io.ballerina.compiler.syntax.tree.ConditionalExpressionNode; -import io.ballerina.compiler.syntax.tree.ConstantDeclarationNode; -import io.ballerina.compiler.syntax.tree.ContinueStatementNode; -import io.ballerina.compiler.syntax.tree.DefaultableParameterNode; -import io.ballerina.compiler.syntax.tree.DistinctTypeDescriptorNode; -import io.ballerina.compiler.syntax.tree.DoStatementNode; -import io.ballerina.compiler.syntax.tree.ElseBlockNode; -import io.ballerina.compiler.syntax.tree.EnumDeclarationNode; -import io.ballerina.compiler.syntax.tree.EnumMemberNode; -import io.ballerina.compiler.syntax.tree.ErrorBindingPatternNode; -import io.ballerina.compiler.syntax.tree.ErrorConstructorExpressionNode; -import io.ballerina.compiler.syntax.tree.ErrorMatchPatternNode; -import io.ballerina.compiler.syntax.tree.ExplicitAnonymousFunctionExpressionNode; -import io.ballerina.compiler.syntax.tree.ExplicitNewExpressionNode; -import io.ballerina.compiler.syntax.tree.ExpressionFunctionBodyNode; -import io.ballerina.compiler.syntax.tree.ExpressionStatementNode; -import io.ballerina.compiler.syntax.tree.ExternalFunctionBodyNode; -import io.ballerina.compiler.syntax.tree.FailStatementNode; -import io.ballerina.compiler.syntax.tree.FieldAccessExpressionNode; -import io.ballerina.compiler.syntax.tree.FieldBindingPatternFullNode; -import io.ballerina.compiler.syntax.tree.FieldBindingPatternVarnameNode; -import io.ballerina.compiler.syntax.tree.FieldMatchPatternNode; -import io.ballerina.compiler.syntax.tree.FlushActionNode; -import io.ballerina.compiler.syntax.tree.ForEachStatementNode; -import io.ballerina.compiler.syntax.tree.ForkStatementNode; -import io.ballerina.compiler.syntax.tree.FromClauseNode; -import io.ballerina.compiler.syntax.tree.FunctionArgumentNode; -import io.ballerina.compiler.syntax.tree.FunctionBodyBlockNode; -import io.ballerina.compiler.syntax.tree.FunctionBodyNode; -import io.ballerina.compiler.syntax.tree.FunctionCallExpressionNode; -import io.ballerina.compiler.syntax.tree.FunctionDefinitionNode; -import io.ballerina.compiler.syntax.tree.FunctionSignatureNode; -import io.ballerina.compiler.syntax.tree.FunctionTypeDescriptorNode; -import io.ballerina.compiler.syntax.tree.GroupByClauseNode; -import io.ballerina.compiler.syntax.tree.GroupingKeyVarDeclarationNode; -import io.ballerina.compiler.syntax.tree.IdentifierToken; -import io.ballerina.compiler.syntax.tree.IfElseStatementNode; -import io.ballerina.compiler.syntax.tree.ImplicitAnonymousFunctionExpressionNode; -import io.ballerina.compiler.syntax.tree.ImplicitAnonymousFunctionParameters; -import io.ballerina.compiler.syntax.tree.ImplicitNewExpressionNode; -import io.ballerina.compiler.syntax.tree.ImportDeclarationNode; -import io.ballerina.compiler.syntax.tree.ImportOrgNameNode; -import io.ballerina.compiler.syntax.tree.ImportPrefixNode; -import io.ballerina.compiler.syntax.tree.IncludedRecordParameterNode; -import io.ballerina.compiler.syntax.tree.IndexedExpressionNode; -import io.ballerina.compiler.syntax.tree.InferredTypedescDefaultNode; -import io.ballerina.compiler.syntax.tree.InlineCodeReferenceNode; -import io.ballerina.compiler.syntax.tree.InterpolationNode; -import io.ballerina.compiler.syntax.tree.IntersectionTypeDescriptorNode; -import io.ballerina.compiler.syntax.tree.JoinClauseNode; -import io.ballerina.compiler.syntax.tree.KeySpecifierNode; -import io.ballerina.compiler.syntax.tree.KeyTypeConstraintNode; -import io.ballerina.compiler.syntax.tree.LetClauseNode; -import io.ballerina.compiler.syntax.tree.LetExpressionNode; -import io.ballerina.compiler.syntax.tree.LetVariableDeclarationNode; -import io.ballerina.compiler.syntax.tree.LimitClauseNode; -import io.ballerina.compiler.syntax.tree.ListBindingPatternNode; -import io.ballerina.compiler.syntax.tree.ListConstructorExpressionNode; -import io.ballerina.compiler.syntax.tree.ListMatchPatternNode; -import io.ballerina.compiler.syntax.tree.ListenerDeclarationNode; -import io.ballerina.compiler.syntax.tree.LockStatementNode; -import io.ballerina.compiler.syntax.tree.MapTypeDescriptorNode; -import io.ballerina.compiler.syntax.tree.MappingBindingPatternNode; -import io.ballerina.compiler.syntax.tree.MappingConstructorExpressionNode; -import io.ballerina.compiler.syntax.tree.MappingFieldNode; -import io.ballerina.compiler.syntax.tree.MappingMatchPatternNode; -import io.ballerina.compiler.syntax.tree.MarkdownCodeBlockNode; -import io.ballerina.compiler.syntax.tree.MarkdownDocumentationLineNode; -import io.ballerina.compiler.syntax.tree.MarkdownDocumentationNode; -import io.ballerina.compiler.syntax.tree.MarkdownParameterDocumentationLineNode; -import io.ballerina.compiler.syntax.tree.MatchClauseNode; -import io.ballerina.compiler.syntax.tree.MatchStatementNode; -import io.ballerina.compiler.syntax.tree.MemberTypeDescriptorNode; -import io.ballerina.compiler.syntax.tree.MetadataNode; -import io.ballerina.compiler.syntax.tree.MethodCallExpressionNode; -import io.ballerina.compiler.syntax.tree.MethodDeclarationNode; -import io.ballerina.compiler.syntax.tree.ModuleMemberDeclarationNode; -import io.ballerina.compiler.syntax.tree.ModulePartNode; -import io.ballerina.compiler.syntax.tree.ModuleVariableDeclarationNode; -import io.ballerina.compiler.syntax.tree.ModuleXMLNamespaceDeclarationNode; -import io.ballerina.compiler.syntax.tree.NameReferenceNode; -import io.ballerina.compiler.syntax.tree.NamedArgBindingPatternNode; -import io.ballerina.compiler.syntax.tree.NamedArgMatchPatternNode; -import io.ballerina.compiler.syntax.tree.NamedArgumentNode; -import io.ballerina.compiler.syntax.tree.NamedWorkerDeclarationNode; -import io.ballerina.compiler.syntax.tree.NamedWorkerDeclarator; -import io.ballerina.compiler.syntax.tree.NewExpressionNode; -import io.ballerina.compiler.syntax.tree.Node; -import io.ballerina.compiler.syntax.tree.NodeFactory; -import io.ballerina.compiler.syntax.tree.NodeList; -import io.ballerina.compiler.syntax.tree.NodeTransformer; -import io.ballerina.compiler.syntax.tree.NonTerminalNode; -import io.ballerina.compiler.syntax.tree.ObjectConstructorExpressionNode; -import io.ballerina.compiler.syntax.tree.ObjectFieldNode; -import io.ballerina.compiler.syntax.tree.ObjectTypeDescriptorNode; -import io.ballerina.compiler.syntax.tree.OnClauseNode; -import io.ballerina.compiler.syntax.tree.OnConflictClauseNode; -import io.ballerina.compiler.syntax.tree.OnFailClauseNode; -import io.ballerina.compiler.syntax.tree.OptionalFieldAccessExpressionNode; -import io.ballerina.compiler.syntax.tree.OptionalTypeDescriptorNode; -import io.ballerina.compiler.syntax.tree.OrderByClauseNode; -import io.ballerina.compiler.syntax.tree.OrderKeyNode; -import io.ballerina.compiler.syntax.tree.PanicStatementNode; -import io.ballerina.compiler.syntax.tree.ParameterNode; -import io.ballerina.compiler.syntax.tree.ParameterizedTypeDescriptorNode; -import io.ballerina.compiler.syntax.tree.ParenthesisedTypeDescriptorNode; -import io.ballerina.compiler.syntax.tree.ParenthesizedArgList; -import io.ballerina.compiler.syntax.tree.PositionalArgumentNode; -import io.ballerina.compiler.syntax.tree.QualifiedNameReferenceNode; -import io.ballerina.compiler.syntax.tree.QueryActionNode; -import io.ballerina.compiler.syntax.tree.QueryConstructTypeNode; -import io.ballerina.compiler.syntax.tree.QueryExpressionNode; -import io.ballerina.compiler.syntax.tree.ReAssertionNode; -import io.ballerina.compiler.syntax.tree.ReAtomCharOrEscapeNode; -import io.ballerina.compiler.syntax.tree.ReAtomQuantifierNode; -import io.ballerina.compiler.syntax.tree.ReBracedQuantifierNode; -import io.ballerina.compiler.syntax.tree.ReCapturingGroupsNode; -import io.ballerina.compiler.syntax.tree.ReCharSetAtomNoDashWithReCharSetNoDashNode; -import io.ballerina.compiler.syntax.tree.ReCharSetAtomWithReCharSetNoDashNode; -import io.ballerina.compiler.syntax.tree.ReCharSetRangeNoDashNode; -import io.ballerina.compiler.syntax.tree.ReCharSetRangeNoDashWithReCharSetNode; -import io.ballerina.compiler.syntax.tree.ReCharSetRangeNode; -import io.ballerina.compiler.syntax.tree.ReCharSetRangeWithReCharSetNode; -import io.ballerina.compiler.syntax.tree.ReCharacterClassNode; -import io.ballerina.compiler.syntax.tree.ReFlagExpressionNode; -import io.ballerina.compiler.syntax.tree.ReFlagsNode; -import io.ballerina.compiler.syntax.tree.ReFlagsOnOffNode; -import io.ballerina.compiler.syntax.tree.ReQuantifierNode; -import io.ballerina.compiler.syntax.tree.ReQuoteEscapeNode; -import io.ballerina.compiler.syntax.tree.ReSequenceNode; -import io.ballerina.compiler.syntax.tree.ReSimpleCharClassEscapeNode; -import io.ballerina.compiler.syntax.tree.ReUnicodeGeneralCategoryNode; -import io.ballerina.compiler.syntax.tree.ReUnicodePropertyEscapeNode; -import io.ballerina.compiler.syntax.tree.ReUnicodeScriptNode; -import io.ballerina.compiler.syntax.tree.ReceiveActionNode; -import io.ballerina.compiler.syntax.tree.ReceiveFieldNode; -import io.ballerina.compiler.syntax.tree.ReceiveFieldsNode; -import io.ballerina.compiler.syntax.tree.RecordFieldNode; -import io.ballerina.compiler.syntax.tree.RecordFieldWithDefaultValueNode; -import io.ballerina.compiler.syntax.tree.RecordRestDescriptorNode; -import io.ballerina.compiler.syntax.tree.RecordTypeDescriptorNode; -import io.ballerina.compiler.syntax.tree.RemoteMethodCallActionNode; -import io.ballerina.compiler.syntax.tree.RequiredParameterNode; -import io.ballerina.compiler.syntax.tree.ResourceAccessRestSegmentNode; -import io.ballerina.compiler.syntax.tree.ResourcePathParameterNode; -import io.ballerina.compiler.syntax.tree.RestArgumentNode; -import io.ballerina.compiler.syntax.tree.RestBindingPatternNode; -import io.ballerina.compiler.syntax.tree.RestDescriptorNode; -import io.ballerina.compiler.syntax.tree.RestMatchPatternNode; -import io.ballerina.compiler.syntax.tree.RestParameterNode; -import io.ballerina.compiler.syntax.tree.RetryStatementNode; -import io.ballerina.compiler.syntax.tree.ReturnStatementNode; -import io.ballerina.compiler.syntax.tree.ReturnTypeDescriptorNode; -import io.ballerina.compiler.syntax.tree.RollbackStatementNode; -import io.ballerina.compiler.syntax.tree.SelectClauseNode; -import io.ballerina.compiler.syntax.tree.SeparatedNodeList; -import io.ballerina.compiler.syntax.tree.ServiceDeclarationNode; -import io.ballerina.compiler.syntax.tree.SimpleNameReferenceNode; -import io.ballerina.compiler.syntax.tree.SingletonTypeDescriptorNode; -import io.ballerina.compiler.syntax.tree.SpecificFieldNode; -import io.ballerina.compiler.syntax.tree.SpreadFieldNode; -import io.ballerina.compiler.syntax.tree.SpreadMemberNode; -import io.ballerina.compiler.syntax.tree.StartActionNode; -import io.ballerina.compiler.syntax.tree.StatementNode; -import io.ballerina.compiler.syntax.tree.StreamTypeDescriptorNode; -import io.ballerina.compiler.syntax.tree.StreamTypeParamsNode; -import io.ballerina.compiler.syntax.tree.SyncSendActionNode; -import io.ballerina.compiler.syntax.tree.SyntaxKind; -import io.ballerina.compiler.syntax.tree.TableConstructorExpressionNode; -import io.ballerina.compiler.syntax.tree.TableTypeDescriptorNode; -import io.ballerina.compiler.syntax.tree.TemplateExpressionNode; -import io.ballerina.compiler.syntax.tree.Token; -import io.ballerina.compiler.syntax.tree.TransactionStatementNode; -import io.ballerina.compiler.syntax.tree.TransactionalExpressionNode; -import io.ballerina.compiler.syntax.tree.TrapExpressionNode; -import io.ballerina.compiler.syntax.tree.TupleTypeDescriptorNode; -import io.ballerina.compiler.syntax.tree.TypeCastExpressionNode; -import io.ballerina.compiler.syntax.tree.TypeCastParamNode; -import io.ballerina.compiler.syntax.tree.TypeDefinitionNode; -import io.ballerina.compiler.syntax.tree.TypeDescriptorNode; -import io.ballerina.compiler.syntax.tree.TypeParameterNode; -import io.ballerina.compiler.syntax.tree.TypeReferenceNode; -import io.ballerina.compiler.syntax.tree.TypeTestExpressionNode; -import io.ballerina.compiler.syntax.tree.TypedBindingPatternNode; -import io.ballerina.compiler.syntax.tree.TypeofExpressionNode; -import io.ballerina.compiler.syntax.tree.UnaryExpressionNode; -import io.ballerina.compiler.syntax.tree.UnionTypeDescriptorNode; -import io.ballerina.compiler.syntax.tree.VariableDeclarationNode; -import io.ballerina.compiler.syntax.tree.WaitActionNode; -import io.ballerina.compiler.syntax.tree.WaitFieldNode; -import io.ballerina.compiler.syntax.tree.WaitFieldsListNode; -import io.ballerina.compiler.syntax.tree.WhereClauseNode; -import io.ballerina.compiler.syntax.tree.WhileStatementNode; -import io.ballerina.compiler.syntax.tree.WildcardBindingPatternNode; -import io.ballerina.compiler.syntax.tree.XMLAtomicNamePatternNode; -import io.ballerina.compiler.syntax.tree.XMLAttributeNode; -import io.ballerina.compiler.syntax.tree.XMLAttributeValue; -import io.ballerina.compiler.syntax.tree.XMLCDATANode; -import io.ballerina.compiler.syntax.tree.XMLComment; -import io.ballerina.compiler.syntax.tree.XMLElementNode; -import io.ballerina.compiler.syntax.tree.XMLEmptyElementNode; -import io.ballerina.compiler.syntax.tree.XMLEndTagNode; -import io.ballerina.compiler.syntax.tree.XMLFilterExpressionNode; -import io.ballerina.compiler.syntax.tree.XMLNameNode; -import io.ballerina.compiler.syntax.tree.XMLNamePatternChainingNode; -import io.ballerina.compiler.syntax.tree.XMLNamespaceDeclarationNode; -import io.ballerina.compiler.syntax.tree.XMLProcessingInstruction; -import io.ballerina.compiler.syntax.tree.XMLQualifiedNameNode; -import io.ballerina.compiler.syntax.tree.XMLSimpleNameNode; -import io.ballerina.compiler.syntax.tree.XMLStartTagNode; -import io.ballerina.compiler.syntax.tree.XMLStepExpressionNode; -import io.ballerina.compiler.syntax.tree.XMLTextNode; +import io.ballerina.compiler.syntax.tree.*; import io.ballerina.identifier.Utils; import io.ballerina.runtime.internal.XmlFactory; import io.ballerina.tools.diagnostics.DiagnosticCode; @@ -1687,6 +1448,12 @@ public BLangNode transform(FunctionBodyBlockNode functionBodyBlockNode) { } } +// for (NonTerminalNode stmt : functionBodyBlockNode.statementsWithComments()) { +// NonTerminalNode s = stmt; +// if (stmt instanceof CommentNode) { +// +// } +// } generateAndAddBLangStatements(functionBodyBlockNode.statements(), stmtList, 0, functionBodyBlockNode); bLFuncBody.stmts = statements; diff --git a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/CommentNode.java b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/CommentNode.java new file mode 100644 index 000000000000..df13c2369349 --- /dev/null +++ b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/CommentNode.java @@ -0,0 +1,128 @@ +/* + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package io.ballerina.compiler.syntax.tree; + +import io.ballerina.compiler.internal.parser.tree.STNode; +import io.ballerina.compiler.internal.parser.tree.STNodeDiagnostic; +import io.ballerina.compiler.internal.parser.tree.STToken; +import io.ballerina.tools.diagnostics.Diagnostic; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * Represents a comment. This is not a part of the Ballerina syntax tree. + * + * @since 2201.10.0 + */ +public class CommentNode extends NonTerminalNode { + protected MinutiaeList leadingMinutiaeList; + protected MinutiaeList trailingMinutiaeList; + private final NonTerminalNode commentAttachedNode; + + public CommentNode(STNode commentAttachedSTNode, int position, NonTerminalNode commentAttachedNode) { + super(commentAttachedSTNode, position, commentAttachedNode); + this.commentAttachedNode = commentAttachedNode; + } + + public NonTerminalNode getParentNode() { + return this.commentAttachedNode; + } + + public String text() { + return ((STToken) this.internalNode).text(); + } + + public boolean containsLeadingMinutiae() { + return internalNode.leadingMinutiae().bucketCount() > 0; + } + + @Override + public MinutiaeList leadingMinutiae() { + if (leadingMinutiaeList != null) { + return leadingMinutiaeList; + } + // TODO: add proper node + leadingMinutiaeList = new MinutiaeList(null, internalNode.leadingMinutiae(), this.position()); + return leadingMinutiaeList; + } + + public boolean containsTrailingMinutiae() { + return internalNode.trailingMinutiae().bucketCount() > 0; + } + + @Override + public MinutiaeList trailingMinutiae() { + if (trailingMinutiaeList != null) { + return trailingMinutiaeList; + } + int trailingMinutiaeStartPos = this.position() + internalNode.widthWithLeadingMinutiae(); + trailingMinutiaeList = new MinutiaeList(null, internalNode.trailingMinutiae(), trailingMinutiaeStartPos); + return trailingMinutiaeList; + } + +// public CommentNode modify(MinutiaeList leadingMinutiae, MinutiaeList trailingMinutiae) { +// if (internalNode.leadingMinutiae() == leadingMinutiae.internalNode() && +// internalNode.trailingMinutiae() == trailingMinutiae.internalNode()) { +// return this; +// } else { +// return NodeFactory.createToken(this.kind(), leadingMinutiae, trailingMinutiae); +// } +// } + + @Override + public Iterable diagnostics() { + if (!internalNode.hasDiagnostics()) { + return Collections::emptyIterator; + } + + return () -> collectDiagnostics().iterator(); + } + + @Override + protected String[] childNames() { + return new String[0]; + } + + private List collectDiagnostics() { + List diagnosticList = new ArrayList<>(); + + // Collect diagnostics inside invalid token minutiae + leadingInvalidTokens().forEach(token -> token.diagnostics().forEach(diagnosticList::add)); + trailingInvalidTokens().forEach(token -> token.diagnostics().forEach(diagnosticList::add)); + + // Collect token diagnostics + for (STNodeDiagnostic stNodeDiagnostic : internalNode.diagnostics()) { + Diagnostic syntaxDiagnostic = createSyntaxDiagnostic(stNodeDiagnostic); + diagnosticList.add(syntaxDiagnostic); + } + + return diagnosticList; + } + + @Override + public void accept(NodeVisitor visitor) { + visitor.visit(this); + } + + @Override + public T apply(NodeTransformer visitor) { + return visitor.transform(this); + } +} diff --git a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/FunctionBodyBlockNode.java b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/FunctionBodyBlockNode.java index fd9f281c50ee..7413ab212c7e 100644 --- a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/FunctionBodyBlockNode.java +++ b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/FunctionBodyBlockNode.java @@ -45,6 +45,10 @@ public NodeList statements() { return new NodeList<>(childInBucket(2)); } + public NodeAndCommentList statementsWithComments() { + return new NodeAndCommentList<>(childInBucket(2), childInBucket(3)); + } + public Token closeBraceToken() { return childInBucket(3); } diff --git a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/NodeAndCommentList.java b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/NodeAndCommentList.java new file mode 100644 index 000000000000..a33e802490f5 --- /dev/null +++ b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/NodeAndCommentList.java @@ -0,0 +1,189 @@ +/* + * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * + * WSO2 Inc. licenses this file to you under the Apache License, + * Version 2.0 (the "License"); you may not use this file except + * in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ +package io.ballerina.compiler.syntax.tree; + +import io.ballerina.compiler.internal.parser.tree.STNode; +import io.ballerina.compiler.internal.parser.tree.STNodeList; +import io.ballerina.compiler.internal.syntax.NodeListUtils; + +import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; +import java.util.stream.StreamSupport; + +import static io.ballerina.compiler.internal.syntax.NodeListUtils.rangeCheck; +import static io.ballerina.compiler.internal.syntax.NodeListUtils.rangeCheckForAdd; + +/** + * Represents a list of {@code Node}s. + * + * @param the type of the constituent node instance + * + * @since 2201.10.0 + */ +public class NodeAndCommentList implements Iterable { + protected final STNodeList internalListNode; + protected final NonTerminalNode nonTerminalNode; + protected final Token semicolon; + protected final int size; + + NodeAndCommentList(NonTerminalNode nonTerminalNode, Token semicolon) { + this(nonTerminalNode, semicolon, nonTerminalNode.bucketCount() + 1); + } + + protected NodeAndCommentList(NonTerminalNode nonTerminalNode, Token semicolon, int size) { + if (!NodeListUtils.isSTNodeList(nonTerminalNode.internalNode())) { + throw new IllegalArgumentException("An STNodeList instance is expected"); + } + + this.internalListNode = (STNodeList) nonTerminalNode.internalNode(); + this.nonTerminalNode = nonTerminalNode; + this.semicolon = semicolon; + this.size = size; + } + + // Positional access methods + + public T get(int index) { + rangeCheck(index, size); + return this.nonTerminalNode.childInBucket(index); + } + + // Modification methods + + public NodeAndCommentList add(T node) { + Objects.requireNonNull(node, "node should not be null"); + return new NodeAndCommentList<>(internalListNode.add(node.internalNode()).createUnlinkedFacade(), null); + } + + public NodeAndCommentList add(int index, T node) { + Objects.requireNonNull(node, "node should not be null"); + rangeCheckForAdd(index, size); + return new NodeAndCommentList<>(internalListNode.add(index, node.internalNode()).createUnlinkedFacade(), null); + } + + public NodeAndCommentList addAll(Collection c) { + if (c.isEmpty()) { + return this; + } + + List stNodesToBeAdded = c.stream() + .map(node -> Objects.requireNonNull(node, "node should not be null")) + .map(Node::internalNode) + .collect(Collectors.toList()); + return new NodeAndCommentList<>(internalListNode.addAll(stNodesToBeAdded).createUnlinkedFacade(), null); + } + + public NodeAndCommentList set(int index, T node) { + Objects.requireNonNull(node, "node should not be null"); + rangeCheck(index, size); + if (nonTerminalNode.checkForReferenceEquality(index, node)) { + return this; + } + + return new NodeAndCommentList<>(internalListNode.set(index, node.internalNode()).createUnlinkedFacade(), null); + } + + public NodeAndCommentList remove(int index) { + rangeCheck(index, size); + return new NodeAndCommentList<>(internalListNode.remove(index).createUnlinkedFacade(), null); + } + + public NodeAndCommentList remove(T node) { + Objects.requireNonNull(node, "node should not be null"); + for (int bucket = 0; bucket < nonTerminalNode.bucketCount(); bucket++) { + if (nonTerminalNode.checkForReferenceEquality(bucket, node)) { + return remove(bucket); + } + } + return this; + } + + @SuppressWarnings("SuspiciousMethodCalls") + public NodeAndCommentList removeAll(Collection c) { + if (c.isEmpty()) { + return this; + } + c.forEach(node -> Objects.requireNonNull(node, "node should not be null")); + + List toBeDeletedList = new ArrayList<>(); + for (int bucket = 0; bucket < nonTerminalNode.bucketCount(); bucket++) { + Node childNode = nonTerminalNode.childBuckets[bucket]; + if (c.contains(childNode)) { + toBeDeletedList.add(childNode.internalNode()); + } + } + + return new NodeAndCommentList<>(internalListNode.removeAll(toBeDeletedList).createUnlinkedFacade(), null); + } + + //query methods + + public int size() { + return this.size; + } + + public boolean isEmpty() { + return this.size == 0; + } + + @Override + public Iterator iterator() { + return new NodeAndCommentListIterator(); + } + + public Stream stream() { + return StreamSupport.stream(spliterator(), false); + } + + NonTerminalNode underlyingListNode() { + return this.nonTerminalNode; + } + + /** + * An iterator for this list of nodes. + * + * @since 2201.10.0 + */ + protected class NodeAndCommentListIterator implements Iterator { + private int currentIndex = 0; + private T currentNode = null; + + @Override + public boolean hasNext() { + return this.currentIndex < size; + } + + @Override + public T next() { + if (currentNode != null) { + currentIndex++; + T temp = currentNode; + currentNode = null; + return temp; + } + if (currentIndex == size - 1) { + currentIndex++; + return (T) new CommentNode(semicolon.internalNode(), 0, null); + } + currentNode = get(currentIndex); + return (T) new CommentNode(currentNode.internalNode(), 0, currentNode); + } + } + +} diff --git a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/NodeTransformer.java b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/NodeTransformer.java index 6a07516d87e8..293814ff66a9 100644 --- a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/NodeTransformer.java +++ b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/NodeTransformer.java @@ -956,6 +956,10 @@ public T transform(ReceiveFieldNode receiveFieldNode) { return transformSyntaxNode(receiveFieldNode); } + public T transform(CommentNode commentNode) { + return transformSyntaxNode(commentNode); + } + // Tokens public T transform(Token token) { diff --git a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/NodeVisitor.java b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/NodeVisitor.java index 1fe6ddfa596e..6cbd1b01a35e 100644 --- a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/NodeVisitor.java +++ b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/NodeVisitor.java @@ -954,6 +954,9 @@ public void visit(MemberTypeDescriptorNode memberTypeDescriptorNode) { public void visit(ReceiveFieldNode receiveFieldNode) { visitSyntaxNode(receiveFieldNode); } + public void visit(CommentNode commentNode) { + visitSyntaxNode(commentNode); + } // Tokens From e161ddbabd2ef4ac3d6934458d20edffe59e0147 Mon Sep 17 00:00:00 2001 From: KavinduZoysa Date: Tue, 10 Sep 2024 11:14:02 +0530 Subject: [PATCH 2/5] Add simplified changes for comment node --- .../compiler/parser/BLangNodeBuilder.java | 19 ++- .../syntax/tree/BlockStatementNode.java | 4 + .../compiler/syntax/tree/CommentNode.java | 27 +++- .../syntax/tree/FunctionBodyBlockNode.java | 2 +- .../syntax/tree/NodeAndCommentList.java | 142 ++++++++++++++---- 5 files changed, 154 insertions(+), 40 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/parser/BLangNodeBuilder.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/parser/BLangNodeBuilder.java index 6ebaddfad392..6e427b82ed59 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/parser/BLangNodeBuilder.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/parser/BLangNodeBuilder.java @@ -1448,12 +1448,12 @@ public BLangNode transform(FunctionBodyBlockNode functionBodyBlockNode) { } } -// for (NonTerminalNode stmt : functionBodyBlockNode.statementsWithComments()) { -// NonTerminalNode s = stmt; -// if (stmt instanceof CommentNode) { -// -// } -// } + for (Node stmt : functionBodyBlockNode.statementsWithComments()) { + Node s = stmt; + if (stmt instanceof CommentNode commentNode) { + Node commentAttachedNode = commentNode.getCommentAttachedNode(); + } + } generateAndAddBLangStatements(functionBodyBlockNode.statements(), stmtList, 0, functionBodyBlockNode); bLFuncBody.stmts = statements; @@ -2759,6 +2759,13 @@ public BLangNode transform(IfElseStatementNode ifElseStmtNode) { public BLangNode transform(BlockStatementNode blockStatement) { BLangBlockStmt bLBlockStmt = (BLangBlockStmt) TreeBuilder.createBlockNode(); this.isInLocalContext = true; + for (Node stmt : blockStatement.statementsWithComments()) { + Node s = stmt; + if (stmt instanceof CommentNode commentNode) { + Node commentAttachedNode = commentNode.getCommentAttachedNode(); + } + } + bLBlockStmt.stmts = generateBLangStatements(blockStatement.statements(), blockStatement); this.isInLocalContext = false; bLBlockStmt.pos = getPosition(blockStatement); diff --git a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/BlockStatementNode.java b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/BlockStatementNode.java index 16c5271dd1c4..97d6874bc688 100644 --- a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/BlockStatementNode.java +++ b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/BlockStatementNode.java @@ -40,6 +40,10 @@ public NodeList statements() { return new NodeList<>(childInBucket(1)); } + public NodeAndCommentList statementsWithComments() { + return new NodeAndCommentList<>(childInBucket(1), childInBucket(2)); + } + public Token closeBraceToken() { return childInBucket(2); } diff --git a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/CommentNode.java b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/CommentNode.java index df13c2369349..c3ca15a7f7c8 100644 --- a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/CommentNode.java +++ b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/CommentNode.java @@ -34,21 +34,42 @@ public class CommentNode extends NonTerminalNode { protected MinutiaeList leadingMinutiaeList; protected MinutiaeList trailingMinutiaeList; - private final NonTerminalNode commentAttachedNode; + private Node commentAttachedNode; + private Minutiae lastMinutiae; + private List commentLines; public CommentNode(STNode commentAttachedSTNode, int position, NonTerminalNode commentAttachedNode) { super(commentAttachedSTNode, position, commentAttachedNode); - this.commentAttachedNode = commentAttachedNode; } - public NonTerminalNode getParentNode() { + public Node getCommentAttachedNode() { return this.commentAttachedNode; } + public void setCommentAttachedNode(Node commentAttachedNode) { + this.commentAttachedNode = commentAttachedNode; + } + + public Minutiae getLastMinutiae() { + return this.lastMinutiae; + } + + public void setLastMinutiae(Minutiae lastMinutiae) { + this.lastMinutiae = lastMinutiae; + } + public String text() { return ((STToken) this.internalNode).text(); } + public List getCommentLines() { + return this.commentLines; + } + + public void setCommentLines(List commentLines) { + this.commentLines = commentLines; + } + public boolean containsLeadingMinutiae() { return internalNode.leadingMinutiae().bucketCount() > 0; } diff --git a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/FunctionBodyBlockNode.java b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/FunctionBodyBlockNode.java index 7413ab212c7e..24267139d340 100644 --- a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/FunctionBodyBlockNode.java +++ b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/FunctionBodyBlockNode.java @@ -45,7 +45,7 @@ public NodeList statements() { return new NodeList<>(childInBucket(2)); } - public NodeAndCommentList statementsWithComments() { + public NodeAndCommentList statementsWithComments() { return new NodeAndCommentList<>(childInBucket(2), childInBucket(3)); } diff --git a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/NodeAndCommentList.java b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/NodeAndCommentList.java index a33e802490f5..5b164e23fe48 100644 --- a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/NodeAndCommentList.java +++ b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/NodeAndCommentList.java @@ -36,14 +36,15 @@ * * @since 2201.10.0 */ -public class NodeAndCommentList implements Iterable { +public class NodeAndCommentList implements Iterable { protected final STNodeList internalListNode; protected final NonTerminalNode nonTerminalNode; protected final Token semicolon; protected final int size; + protected final Node[] nodes; NodeAndCommentList(NonTerminalNode nonTerminalNode, Token semicolon) { - this(nonTerminalNode, semicolon, nonTerminalNode.bucketCount() + 1); + this(nonTerminalNode, semicolon, nonTerminalNode.bucketCount() * 2 + 1); } protected NodeAndCommentList(NonTerminalNode nonTerminalNode, Token semicolon, int size) { @@ -54,30 +55,81 @@ protected NodeAndCommentList(NonTerminalNode nonTerminalNode, Token semicolon, i this.internalListNode = (STNodeList) nonTerminalNode.internalNode(); this.nonTerminalNode = nonTerminalNode; this.semicolon = semicolon; - this.size = size; +// this.size = size; + this.nodes = new Node[size]; // TODO: Init with max size + int x = 0; + for (int i = 0; i < nonTerminalNode.bucketCount(); i++) { + List commentLines = new ArrayList<>(); + Minutiae lastMinutiae = null; + for (Minutiae minutiae : nonTerminalNode.childInBucket(i).leadingMinutiae()) { + String[] splits = minutiae.text().split("// "); + if (splits.length >= 2) { + commentLines.add(splits[1]); + lastMinutiae = minutiae; + } else if (splits.length == 1 && splits[0].contains("//")) { + commentLines.add(""); + lastMinutiae = minutiae; + } + } + if (!commentLines.isEmpty()) { + CommentNode commentNode = new CommentNode(nonTerminalNode.childInBucket(i).internalNode(), 0, null); + commentNode.setCommentAttachedNode(nonTerminalNode.childInBucket(i)); + commentNode.setLastMinutiae(lastMinutiae); + commentNode.setCommentLines(commentLines); + this.nodes[i] = commentNode; + x++; + } + this.nodes[x] = nonTerminalNode.childInBucket(i); + x++; + } + + List commentLines = new ArrayList<>(); + Minutiae lastMinutiae = null; + for (Minutiae minutiae : this.semicolon.leadingMinutiae()) { + String[] splits = minutiae.text().split("// "); + if (splits.length >= 2) { + commentLines.add(splits[1]); + lastMinutiae = minutiae; + } else if (splits.length == 1 && splits[0].contains("//")) { + commentLines.add(""); + lastMinutiae = minutiae; + } + } + if (!commentLines.isEmpty()) { + CommentNode commentNode = new CommentNode(semicolon.internalNode(), 0, null); + commentNode.setCommentAttachedNode(semicolon); + commentNode.setLastMinutiae(lastMinutiae); + commentNode.setCommentLines(commentLines); + this.nodes[x++] = commentNode; + } + this.size = x; } // Positional access methods - public T get(int index) { + public K get(int index) { // 3 + semi rangeCheck(index, size); - return this.nonTerminalNode.childInBucket(index); +// if (index == size - 1) { +// return (K) this.semicolon; +// } +// return this.nonTerminalNode.childInBucket(index / 2); + return (K) this.nodes[index]; } // Modification methods - public NodeAndCommentList add(T node) { + public NodeAndCommentList add(T node) { Objects.requireNonNull(node, "node should not be null"); return new NodeAndCommentList<>(internalListNode.add(node.internalNode()).createUnlinkedFacade(), null); } - public NodeAndCommentList add(int index, T node) { + public NodeAndCommentList add(int index, T node) { Objects.requireNonNull(node, "node should not be null"); rangeCheckForAdd(index, size); return new NodeAndCommentList<>(internalListNode.add(index, node.internalNode()).createUnlinkedFacade(), null); } - public NodeAndCommentList addAll(Collection c) { + public NodeAndCommentList addAll(Collection c) { if (c.isEmpty()) { return this; } @@ -89,7 +141,7 @@ public NodeAndCommentList addAll(Collection c) { return new NodeAndCommentList<>(internalListNode.addAll(stNodesToBeAdded).createUnlinkedFacade(), null); } - public NodeAndCommentList set(int index, T node) { + public NodeAndCommentList set(int index, T node) { Objects.requireNonNull(node, "node should not be null"); rangeCheck(index, size); if (nonTerminalNode.checkForReferenceEquality(index, node)) { @@ -99,12 +151,12 @@ public NodeAndCommentList set(int index, T node) { return new NodeAndCommentList<>(internalListNode.set(index, node.internalNode()).createUnlinkedFacade(), null); } - public NodeAndCommentList remove(int index) { + public NodeAndCommentList remove(int index) { rangeCheck(index, size); return new NodeAndCommentList<>(internalListNode.remove(index).createUnlinkedFacade(), null); } - public NodeAndCommentList remove(T node) { + public NodeAndCommentList remove(T node) { Objects.requireNonNull(node, "node should not be null"); for (int bucket = 0; bucket < nonTerminalNode.bucketCount(); bucket++) { if (nonTerminalNode.checkForReferenceEquality(bucket, node)) { @@ -115,7 +167,7 @@ public NodeAndCommentList remove(T node) { } @SuppressWarnings("SuspiciousMethodCalls") - public NodeAndCommentList removeAll(Collection c) { + public NodeAndCommentList removeAll(Collection c) { if (c.isEmpty()) { return this; } @@ -143,11 +195,11 @@ public boolean isEmpty() { } @Override - public Iterator iterator() { + public Iterator iterator() { return new NodeAndCommentListIterator(); } - public Stream stream() { + public Stream stream() { return StreamSupport.stream(spliterator(), false); } @@ -160,9 +212,9 @@ NonTerminalNode underlyingListNode() { * * @since 2201.10.0 */ - protected class NodeAndCommentListIterator implements Iterator { + protected class NodeAndCommentListIterator implements Iterator { private int currentIndex = 0; - private T currentNode = null; + private K currentNode = null; @Override public boolean hasNext() { @@ -170,20 +222,50 @@ public boolean hasNext() { } @Override - public T next() { - if (currentNode != null) { - currentIndex++; - T temp = currentNode; - currentNode = null; - return temp; - } - if (currentIndex == size - 1) { - currentIndex++; - return (T) new CommentNode(semicolon.internalNode(), 0, null); - } - currentNode = get(currentIndex); - return (T) new CommentNode(currentNode.internalNode(), 0, currentNode); + public K next() { +// if (currentNode != null) { +// currentIndex++; +// K temp = currentNode; +// currentNode = null; +// return temp; +// } +// currentNode = get(currentIndex); +// CommentNode commentNode = new CommentNode(currentNode.internalNode(), 0, null); +// commentNode.setCommentAttachedNode(currentNode); +// return (K) commentNode; +// } +// +// public K next2() { + //// +// K node; +// if (currentIndex % 2 == 0) { // gen comment +// currentNode = get(currentIndex); +// List commentLines = new ArrayList<>(); +// Minutiae lastMinutiae = null; +// for (Minutiae minutiae : currentNode.leadingMinutiae()) { +// String[] splits = minutiae.text().split("// "); +// if (splits.length >= 2) { +// commentLines.add(splits[1]); +// lastMinutiae = minutiae; +// } else if (splits.length == 1 && splits[0].contains("//")) { +// commentLines.add(""); +// lastMinutiae = minutiae; +// } +// } +// if (!commentLines.isEmpty()) { +//// return Optional.empty(); // set comment +// } +// CommentNode commentNode = new CommentNode(currentNode.internalNode(), 0, null); +// commentNode.setCommentAttachedNode(currentNode); +// node = (K) commentNode; +// } else { +// node = currentNode; +// } +// currentIndex++; +// return node; + /// + + return get(currentIndex++); } } - } From 4df0e3a281ed3bbb0b1394475366d74daaa7c8d1 Mon Sep 17 00:00:00 2001 From: KavinduZoysa Date: Tue, 10 Sep 2024 15:10:34 +0530 Subject: [PATCH 3/5] Clean the code --- .../compiler/syntax/tree/CommentNode.java | 68 ----------- .../syntax/tree/NodeAndCommentList.java | 111 ++++-------------- 2 files changed, 26 insertions(+), 153 deletions(-) diff --git a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/CommentNode.java b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/CommentNode.java index c3ca15a7f7c8..4ca58126567e 100644 --- a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/CommentNode.java +++ b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/CommentNode.java @@ -32,8 +32,6 @@ * @since 2201.10.0 */ public class CommentNode extends NonTerminalNode { - protected MinutiaeList leadingMinutiaeList; - protected MinutiaeList trailingMinutiaeList; private Node commentAttachedNode; private Minutiae lastMinutiae; private List commentLines; @@ -58,10 +56,6 @@ public void setLastMinutiae(Minutiae lastMinutiae) { this.lastMinutiae = lastMinutiae; } - public String text() { - return ((STToken) this.internalNode).text(); - } - public List getCommentLines() { return this.commentLines; } @@ -70,73 +64,11 @@ public void setCommentLines(List commentLines) { this.commentLines = commentLines; } - public boolean containsLeadingMinutiae() { - return internalNode.leadingMinutiae().bucketCount() > 0; - } - - @Override - public MinutiaeList leadingMinutiae() { - if (leadingMinutiaeList != null) { - return leadingMinutiaeList; - } - // TODO: add proper node - leadingMinutiaeList = new MinutiaeList(null, internalNode.leadingMinutiae(), this.position()); - return leadingMinutiaeList; - } - - public boolean containsTrailingMinutiae() { - return internalNode.trailingMinutiae().bucketCount() > 0; - } - - @Override - public MinutiaeList trailingMinutiae() { - if (trailingMinutiaeList != null) { - return trailingMinutiaeList; - } - int trailingMinutiaeStartPos = this.position() + internalNode.widthWithLeadingMinutiae(); - trailingMinutiaeList = new MinutiaeList(null, internalNode.trailingMinutiae(), trailingMinutiaeStartPos); - return trailingMinutiaeList; - } - -// public CommentNode modify(MinutiaeList leadingMinutiae, MinutiaeList trailingMinutiae) { -// if (internalNode.leadingMinutiae() == leadingMinutiae.internalNode() && -// internalNode.trailingMinutiae() == trailingMinutiae.internalNode()) { -// return this; -// } else { -// return NodeFactory.createToken(this.kind(), leadingMinutiae, trailingMinutiae); -// } -// } - - @Override - public Iterable diagnostics() { - if (!internalNode.hasDiagnostics()) { - return Collections::emptyIterator; - } - - return () -> collectDiagnostics().iterator(); - } - @Override protected String[] childNames() { return new String[0]; } - private List collectDiagnostics() { - List diagnosticList = new ArrayList<>(); - - // Collect diagnostics inside invalid token minutiae - leadingInvalidTokens().forEach(token -> token.diagnostics().forEach(diagnosticList::add)); - trailingInvalidTokens().forEach(token -> token.diagnostics().forEach(diagnosticList::add)); - - // Collect token diagnostics - for (STNodeDiagnostic stNodeDiagnostic : internalNode.diagnostics()) { - Diagnostic syntaxDiagnostic = createSyntaxDiagnostic(stNodeDiagnostic); - diagnosticList.add(syntaxDiagnostic); - } - - return diagnosticList; - } - @Override public void accept(NodeVisitor visitor) { visitor.visit(this); diff --git a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/NodeAndCommentList.java b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/NodeAndCommentList.java index 5b164e23fe48..23b96141b55e 100644 --- a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/NodeAndCommentList.java +++ b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/NodeAndCommentList.java @@ -30,16 +30,14 @@ import static io.ballerina.compiler.internal.syntax.NodeListUtils.rangeCheckForAdd; /** - * Represents a list of {@code Node}s. + * Represent both nodes and attached comments to each node. * - * @param the type of the constituent node instance - * - * @since 2201.10.0 + * @param The type of NonTerminalNode + * @param The type of Node */ public class NodeAndCommentList implements Iterable { protected final STNodeList internalListNode; protected final NonTerminalNode nonTerminalNode; - protected final Token semicolon; protected final int size; protected final Node[] nodes; @@ -54,38 +52,28 @@ protected NodeAndCommentList(NonTerminalNode nonTerminalNode, Token semicolon, i this.internalListNode = (STNodeList) nonTerminalNode.internalNode(); this.nonTerminalNode = nonTerminalNode; - this.semicolon = semicolon; -// this.size = size; this.nodes = new Node[size]; // TODO: Init with max size - int x = 0; + int nodeIndex = 0; for (int i = 0; i < nonTerminalNode.bucketCount(); i++) { - List commentLines = new ArrayList<>(); - Minutiae lastMinutiae = null; - for (Minutiae minutiae : nonTerminalNode.childInBucket(i).leadingMinutiae()) { - String[] splits = minutiae.text().split("// "); - if (splits.length >= 2) { - commentLines.add(splits[1]); - lastMinutiae = minutiae; - } else if (splits.length == 1 && splits[0].contains("//")) { - commentLines.add(""); - lastMinutiae = minutiae; - } - } - if (!commentLines.isEmpty()) { - CommentNode commentNode = new CommentNode(nonTerminalNode.childInBucket(i).internalNode(), 0, null); - commentNode.setCommentAttachedNode(nonTerminalNode.childInBucket(i)); - commentNode.setLastMinutiae(lastMinutiae); - commentNode.setCommentLines(commentLines); - this.nodes[i] = commentNode; - x++; + Node node = nonTerminalNode.childInBucket(i); + CommentNode commentNode = getCommentNode(node); + if (commentNode != null) { + this.nodes[nodeIndex++] = commentNode; } - this.nodes[x] = nonTerminalNode.childInBucket(i); - x++; + this.nodes[nodeIndex++] = node; + } + + CommentNode commentNodeBeforeEnd = getCommentNode(semicolon); + if (commentNodeBeforeEnd != null) { + this.nodes[nodeIndex++] = commentNodeBeforeEnd; } + this.size = nodeIndex; + } + private CommentNode getCommentNode(Node node) { List commentLines = new ArrayList<>(); Minutiae lastMinutiae = null; - for (Minutiae minutiae : this.semicolon.leadingMinutiae()) { + for (Minutiae minutiae : node.leadingMinutiae()) { String[] splits = minutiae.text().split("// "); if (splits.length >= 2) { commentLines.add(splits[1]); @@ -95,24 +83,20 @@ protected NodeAndCommentList(NonTerminalNode nonTerminalNode, Token semicolon, i lastMinutiae = minutiae; } } - if (!commentLines.isEmpty()) { - CommentNode commentNode = new CommentNode(semicolon.internalNode(), 0, null); - commentNode.setCommentAttachedNode(semicolon); - commentNode.setLastMinutiae(lastMinutiae); - commentNode.setCommentLines(commentLines); - this.nodes[x++] = commentNode; + if (commentLines.isEmpty()) { + return null; } - this.size = x; + CommentNode commentNode = new CommentNode(node.internalNode(), 0, null); + commentNode.setCommentAttachedNode(node); + commentNode.setLastMinutiae(lastMinutiae); + commentNode.setCommentLines(commentLines); + return commentNode; } // Positional access methods - public K get(int index) { // 3 + semi + public K get(int index) { rangeCheck(index, size); -// if (index == size - 1) { -// return (K) this.semicolon; -// } -// return this.nonTerminalNode.childInBucket(index / 2); return (K) this.nodes[index]; } @@ -214,7 +198,6 @@ NonTerminalNode underlyingListNode() { */ protected class NodeAndCommentListIterator implements Iterator { private int currentIndex = 0; - private K currentNode = null; @Override public boolean hasNext() { @@ -223,48 +206,6 @@ public boolean hasNext() { @Override public K next() { -// if (currentNode != null) { -// currentIndex++; -// K temp = currentNode; -// currentNode = null; -// return temp; -// } -// currentNode = get(currentIndex); -// CommentNode commentNode = new CommentNode(currentNode.internalNode(), 0, null); -// commentNode.setCommentAttachedNode(currentNode); -// return (K) commentNode; -// } -// -// public K next2() { - //// -// K node; -// if (currentIndex % 2 == 0) { // gen comment -// currentNode = get(currentIndex); -// List commentLines = new ArrayList<>(); -// Minutiae lastMinutiae = null; -// for (Minutiae minutiae : currentNode.leadingMinutiae()) { -// String[] splits = minutiae.text().split("// "); -// if (splits.length >= 2) { -// commentLines.add(splits[1]); -// lastMinutiae = minutiae; -// } else if (splits.length == 1 && splits[0].contains("//")) { -// commentLines.add(""); -// lastMinutiae = minutiae; -// } -// } -// if (!commentLines.isEmpty()) { -//// return Optional.empty(); // set comment -// } -// CommentNode commentNode = new CommentNode(currentNode.internalNode(), 0, null); -// commentNode.setCommentAttachedNode(currentNode); -// node = (K) commentNode; -// } else { -// node = currentNode; -// } -// currentIndex++; -// return node; - /// - return get(currentIndex++); } } From 410ecfaa39905067f345527e193e8d9a1681853d Mon Sep 17 00:00:00 2001 From: KavinduZoysa Date: Tue, 10 Sep 2024 23:06:01 +0530 Subject: [PATCH 4/5] Change NodeList type --- .../compiler/parser/BLangNodeBuilder.java | 254 +++++++++++++++++- .../syntax/tree/BlockStatementNode.java | 2 +- .../compiler/syntax/tree/CommentNode.java | 23 +- .../syntax/tree/FunctionBodyBlockNode.java | 2 +- .../syntax/tree/NodeAndCommentList.java | 56 ++-- 5 files changed, 280 insertions(+), 57 deletions(-) diff --git a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/parser/BLangNodeBuilder.java b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/parser/BLangNodeBuilder.java index 6e427b82ed59..58d576a52fb0 100644 --- a/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/parser/BLangNodeBuilder.java +++ b/compiler/ballerina-lang/src/main/java/org/wso2/ballerinalang/compiler/parser/BLangNodeBuilder.java @@ -17,7 +17,246 @@ */ package org.wso2.ballerinalang.compiler.parser; -import io.ballerina.compiler.syntax.tree.*; +import io.ballerina.compiler.syntax.tree.AlternateReceiveNode; +import io.ballerina.compiler.syntax.tree.AnnotAccessExpressionNode; +import io.ballerina.compiler.syntax.tree.AnnotationAttachPointNode; +import io.ballerina.compiler.syntax.tree.AnnotationDeclarationNode; +import io.ballerina.compiler.syntax.tree.AnnotationNode; +import io.ballerina.compiler.syntax.tree.ArrayDimensionNode; +import io.ballerina.compiler.syntax.tree.ArrayTypeDescriptorNode; +import io.ballerina.compiler.syntax.tree.AssignmentStatementNode; +import io.ballerina.compiler.syntax.tree.AsyncSendActionNode; +import io.ballerina.compiler.syntax.tree.BallerinaNameReferenceNode; +import io.ballerina.compiler.syntax.tree.BasicLiteralNode; +import io.ballerina.compiler.syntax.tree.BinaryExpressionNode; +import io.ballerina.compiler.syntax.tree.BindingPatternNode; +import io.ballerina.compiler.syntax.tree.BlockStatementNode; +import io.ballerina.compiler.syntax.tree.BracedExpressionNode; +import io.ballerina.compiler.syntax.tree.BreakStatementNode; +import io.ballerina.compiler.syntax.tree.BuiltinSimpleNameReferenceNode; +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.ClientResourceAccessActionNode; +import io.ballerina.compiler.syntax.tree.CollectClauseNode; +import io.ballerina.compiler.syntax.tree.CommitActionNode; +import io.ballerina.compiler.syntax.tree.CompoundAssignmentStatementNode; +import io.ballerina.compiler.syntax.tree.ComputedNameFieldNode; +import io.ballerina.compiler.syntax.tree.ComputedResourceAccessSegmentNode; +import io.ballerina.compiler.syntax.tree.ConditionalExpressionNode; +import io.ballerina.compiler.syntax.tree.ConstantDeclarationNode; +import io.ballerina.compiler.syntax.tree.ContinueStatementNode; +import io.ballerina.compiler.syntax.tree.DefaultableParameterNode; +import io.ballerina.compiler.syntax.tree.DistinctTypeDescriptorNode; +import io.ballerina.compiler.syntax.tree.DoStatementNode; +import io.ballerina.compiler.syntax.tree.ElseBlockNode; +import io.ballerina.compiler.syntax.tree.EnumDeclarationNode; +import io.ballerina.compiler.syntax.tree.EnumMemberNode; +import io.ballerina.compiler.syntax.tree.ErrorBindingPatternNode; +import io.ballerina.compiler.syntax.tree.ErrorConstructorExpressionNode; +import io.ballerina.compiler.syntax.tree.ErrorMatchPatternNode; +import io.ballerina.compiler.syntax.tree.ExplicitAnonymousFunctionExpressionNode; +import io.ballerina.compiler.syntax.tree.ExplicitNewExpressionNode; +import io.ballerina.compiler.syntax.tree.ExpressionFunctionBodyNode; +import io.ballerina.compiler.syntax.tree.ExpressionStatementNode; +import io.ballerina.compiler.syntax.tree.ExternalFunctionBodyNode; +import io.ballerina.compiler.syntax.tree.FailStatementNode; +import io.ballerina.compiler.syntax.tree.FieldAccessExpressionNode; +import io.ballerina.compiler.syntax.tree.FieldBindingPatternFullNode; +import io.ballerina.compiler.syntax.tree.FieldBindingPatternVarnameNode; +import io.ballerina.compiler.syntax.tree.FieldMatchPatternNode; +import io.ballerina.compiler.syntax.tree.FlushActionNode; +import io.ballerina.compiler.syntax.tree.ForEachStatementNode; +import io.ballerina.compiler.syntax.tree.ForkStatementNode; +import io.ballerina.compiler.syntax.tree.FromClauseNode; +import io.ballerina.compiler.syntax.tree.FunctionArgumentNode; +import io.ballerina.compiler.syntax.tree.FunctionBodyBlockNode; +import io.ballerina.compiler.syntax.tree.FunctionBodyNode; +import io.ballerina.compiler.syntax.tree.FunctionCallExpressionNode; +import io.ballerina.compiler.syntax.tree.FunctionDefinitionNode; +import io.ballerina.compiler.syntax.tree.FunctionSignatureNode; +import io.ballerina.compiler.syntax.tree.FunctionTypeDescriptorNode; +import io.ballerina.compiler.syntax.tree.GroupByClauseNode; +import io.ballerina.compiler.syntax.tree.GroupingKeyVarDeclarationNode; +import io.ballerina.compiler.syntax.tree.IdentifierToken; +import io.ballerina.compiler.syntax.tree.IfElseStatementNode; +import io.ballerina.compiler.syntax.tree.ImplicitAnonymousFunctionExpressionNode; +import io.ballerina.compiler.syntax.tree.ImplicitAnonymousFunctionParameters; +import io.ballerina.compiler.syntax.tree.ImplicitNewExpressionNode; +import io.ballerina.compiler.syntax.tree.ImportDeclarationNode; +import io.ballerina.compiler.syntax.tree.ImportOrgNameNode; +import io.ballerina.compiler.syntax.tree.ImportPrefixNode; +import io.ballerina.compiler.syntax.tree.IncludedRecordParameterNode; +import io.ballerina.compiler.syntax.tree.IndexedExpressionNode; +import io.ballerina.compiler.syntax.tree.InferredTypedescDefaultNode; +import io.ballerina.compiler.syntax.tree.InlineCodeReferenceNode; +import io.ballerina.compiler.syntax.tree.InterpolationNode; +import io.ballerina.compiler.syntax.tree.IntersectionTypeDescriptorNode; +import io.ballerina.compiler.syntax.tree.JoinClauseNode; +import io.ballerina.compiler.syntax.tree.KeySpecifierNode; +import io.ballerina.compiler.syntax.tree.KeyTypeConstraintNode; +import io.ballerina.compiler.syntax.tree.LetClauseNode; +import io.ballerina.compiler.syntax.tree.LetExpressionNode; +import io.ballerina.compiler.syntax.tree.LetVariableDeclarationNode; +import io.ballerina.compiler.syntax.tree.LimitClauseNode; +import io.ballerina.compiler.syntax.tree.ListBindingPatternNode; +import io.ballerina.compiler.syntax.tree.ListConstructorExpressionNode; +import io.ballerina.compiler.syntax.tree.ListMatchPatternNode; +import io.ballerina.compiler.syntax.tree.ListenerDeclarationNode; +import io.ballerina.compiler.syntax.tree.LockStatementNode; +import io.ballerina.compiler.syntax.tree.MapTypeDescriptorNode; +import io.ballerina.compiler.syntax.tree.MappingBindingPatternNode; +import io.ballerina.compiler.syntax.tree.MappingConstructorExpressionNode; +import io.ballerina.compiler.syntax.tree.MappingFieldNode; +import io.ballerina.compiler.syntax.tree.MappingMatchPatternNode; +import io.ballerina.compiler.syntax.tree.MarkdownCodeBlockNode; +import io.ballerina.compiler.syntax.tree.MarkdownDocumentationLineNode; +import io.ballerina.compiler.syntax.tree.MarkdownDocumentationNode; +import io.ballerina.compiler.syntax.tree.MarkdownParameterDocumentationLineNode; +import io.ballerina.compiler.syntax.tree.MatchClauseNode; +import io.ballerina.compiler.syntax.tree.MatchStatementNode; +import io.ballerina.compiler.syntax.tree.MemberTypeDescriptorNode; +import io.ballerina.compiler.syntax.tree.MetadataNode; +import io.ballerina.compiler.syntax.tree.MethodCallExpressionNode; +import io.ballerina.compiler.syntax.tree.MethodDeclarationNode; +import io.ballerina.compiler.syntax.tree.ModuleMemberDeclarationNode; +import io.ballerina.compiler.syntax.tree.ModulePartNode; +import io.ballerina.compiler.syntax.tree.ModuleVariableDeclarationNode; +import io.ballerina.compiler.syntax.tree.ModuleXMLNamespaceDeclarationNode; +import io.ballerina.compiler.syntax.tree.NameReferenceNode; +import io.ballerina.compiler.syntax.tree.NamedArgBindingPatternNode; +import io.ballerina.compiler.syntax.tree.NamedArgMatchPatternNode; +import io.ballerina.compiler.syntax.tree.NamedArgumentNode; +import io.ballerina.compiler.syntax.tree.NamedWorkerDeclarationNode; +import io.ballerina.compiler.syntax.tree.NamedWorkerDeclarator; +import io.ballerina.compiler.syntax.tree.NewExpressionNode; +import io.ballerina.compiler.syntax.tree.Node; +import io.ballerina.compiler.syntax.tree.NodeFactory; +import io.ballerina.compiler.syntax.tree.NodeList; +import io.ballerina.compiler.syntax.tree.NodeTransformer; +import io.ballerina.compiler.syntax.tree.NonTerminalNode; +import io.ballerina.compiler.syntax.tree.ObjectConstructorExpressionNode; +import io.ballerina.compiler.syntax.tree.ObjectFieldNode; +import io.ballerina.compiler.syntax.tree.ObjectTypeDescriptorNode; +import io.ballerina.compiler.syntax.tree.OnClauseNode; +import io.ballerina.compiler.syntax.tree.OnConflictClauseNode; +import io.ballerina.compiler.syntax.tree.OnFailClauseNode; +import io.ballerina.compiler.syntax.tree.OptionalFieldAccessExpressionNode; +import io.ballerina.compiler.syntax.tree.OptionalTypeDescriptorNode; +import io.ballerina.compiler.syntax.tree.OrderByClauseNode; +import io.ballerina.compiler.syntax.tree.OrderKeyNode; +import io.ballerina.compiler.syntax.tree.PanicStatementNode; +import io.ballerina.compiler.syntax.tree.ParameterNode; +import io.ballerina.compiler.syntax.tree.ParameterizedTypeDescriptorNode; +import io.ballerina.compiler.syntax.tree.ParenthesisedTypeDescriptorNode; +import io.ballerina.compiler.syntax.tree.ParenthesizedArgList; +import io.ballerina.compiler.syntax.tree.PositionalArgumentNode; +import io.ballerina.compiler.syntax.tree.QualifiedNameReferenceNode; +import io.ballerina.compiler.syntax.tree.QueryActionNode; +import io.ballerina.compiler.syntax.tree.QueryConstructTypeNode; +import io.ballerina.compiler.syntax.tree.QueryExpressionNode; +import io.ballerina.compiler.syntax.tree.ReAssertionNode; +import io.ballerina.compiler.syntax.tree.ReAtomCharOrEscapeNode; +import io.ballerina.compiler.syntax.tree.ReAtomQuantifierNode; +import io.ballerina.compiler.syntax.tree.ReBracedQuantifierNode; +import io.ballerina.compiler.syntax.tree.ReCapturingGroupsNode; +import io.ballerina.compiler.syntax.tree.ReCharSetAtomNoDashWithReCharSetNoDashNode; +import io.ballerina.compiler.syntax.tree.ReCharSetAtomWithReCharSetNoDashNode; +import io.ballerina.compiler.syntax.tree.ReCharSetRangeNoDashNode; +import io.ballerina.compiler.syntax.tree.ReCharSetRangeNoDashWithReCharSetNode; +import io.ballerina.compiler.syntax.tree.ReCharSetRangeNode; +import io.ballerina.compiler.syntax.tree.ReCharSetRangeWithReCharSetNode; +import io.ballerina.compiler.syntax.tree.ReCharacterClassNode; +import io.ballerina.compiler.syntax.tree.ReFlagExpressionNode; +import io.ballerina.compiler.syntax.tree.ReFlagsNode; +import io.ballerina.compiler.syntax.tree.ReFlagsOnOffNode; +import io.ballerina.compiler.syntax.tree.ReQuantifierNode; +import io.ballerina.compiler.syntax.tree.ReQuoteEscapeNode; +import io.ballerina.compiler.syntax.tree.ReSequenceNode; +import io.ballerina.compiler.syntax.tree.ReSimpleCharClassEscapeNode; +import io.ballerina.compiler.syntax.tree.ReUnicodeGeneralCategoryNode; +import io.ballerina.compiler.syntax.tree.ReUnicodePropertyEscapeNode; +import io.ballerina.compiler.syntax.tree.ReUnicodeScriptNode; +import io.ballerina.compiler.syntax.tree.ReceiveActionNode; +import io.ballerina.compiler.syntax.tree.ReceiveFieldNode; +import io.ballerina.compiler.syntax.tree.ReceiveFieldsNode; +import io.ballerina.compiler.syntax.tree.RecordFieldNode; +import io.ballerina.compiler.syntax.tree.RecordFieldWithDefaultValueNode; +import io.ballerina.compiler.syntax.tree.RecordRestDescriptorNode; +import io.ballerina.compiler.syntax.tree.RecordTypeDescriptorNode; +import io.ballerina.compiler.syntax.tree.RemoteMethodCallActionNode; +import io.ballerina.compiler.syntax.tree.RequiredParameterNode; +import io.ballerina.compiler.syntax.tree.ResourceAccessRestSegmentNode; +import io.ballerina.compiler.syntax.tree.ResourcePathParameterNode; +import io.ballerina.compiler.syntax.tree.RestArgumentNode; +import io.ballerina.compiler.syntax.tree.RestBindingPatternNode; +import io.ballerina.compiler.syntax.tree.RestDescriptorNode; +import io.ballerina.compiler.syntax.tree.RestMatchPatternNode; +import io.ballerina.compiler.syntax.tree.RestParameterNode; +import io.ballerina.compiler.syntax.tree.RetryStatementNode; +import io.ballerina.compiler.syntax.tree.ReturnStatementNode; +import io.ballerina.compiler.syntax.tree.ReturnTypeDescriptorNode; +import io.ballerina.compiler.syntax.tree.RollbackStatementNode; +import io.ballerina.compiler.syntax.tree.SelectClauseNode; +import io.ballerina.compiler.syntax.tree.SeparatedNodeList; +import io.ballerina.compiler.syntax.tree.ServiceDeclarationNode; +import io.ballerina.compiler.syntax.tree.SimpleNameReferenceNode; +import io.ballerina.compiler.syntax.tree.SingletonTypeDescriptorNode; +import io.ballerina.compiler.syntax.tree.SpecificFieldNode; +import io.ballerina.compiler.syntax.tree.SpreadFieldNode; +import io.ballerina.compiler.syntax.tree.SpreadMemberNode; +import io.ballerina.compiler.syntax.tree.StartActionNode; +import io.ballerina.compiler.syntax.tree.StatementNode; +import io.ballerina.compiler.syntax.tree.StreamTypeDescriptorNode; +import io.ballerina.compiler.syntax.tree.StreamTypeParamsNode; +import io.ballerina.compiler.syntax.tree.SyncSendActionNode; +import io.ballerina.compiler.syntax.tree.SyntaxKind; +import io.ballerina.compiler.syntax.tree.TableConstructorExpressionNode; +import io.ballerina.compiler.syntax.tree.TableTypeDescriptorNode; +import io.ballerina.compiler.syntax.tree.TemplateExpressionNode; +import io.ballerina.compiler.syntax.tree.Token; +import io.ballerina.compiler.syntax.tree.TransactionStatementNode; +import io.ballerina.compiler.syntax.tree.TransactionalExpressionNode; +import io.ballerina.compiler.syntax.tree.TrapExpressionNode; +import io.ballerina.compiler.syntax.tree.TupleTypeDescriptorNode; +import io.ballerina.compiler.syntax.tree.TypeCastExpressionNode; +import io.ballerina.compiler.syntax.tree.TypeCastParamNode; +import io.ballerina.compiler.syntax.tree.TypeDefinitionNode; +import io.ballerina.compiler.syntax.tree.TypeDescriptorNode; +import io.ballerina.compiler.syntax.tree.TypeParameterNode; +import io.ballerina.compiler.syntax.tree.TypeReferenceNode; +import io.ballerina.compiler.syntax.tree.TypeTestExpressionNode; +import io.ballerina.compiler.syntax.tree.TypedBindingPatternNode; +import io.ballerina.compiler.syntax.tree.TypeofExpressionNode; +import io.ballerina.compiler.syntax.tree.UnaryExpressionNode; +import io.ballerina.compiler.syntax.tree.UnionTypeDescriptorNode; +import io.ballerina.compiler.syntax.tree.VariableDeclarationNode; +import io.ballerina.compiler.syntax.tree.WaitActionNode; +import io.ballerina.compiler.syntax.tree.WaitFieldNode; +import io.ballerina.compiler.syntax.tree.WaitFieldsListNode; +import io.ballerina.compiler.syntax.tree.WhereClauseNode; +import io.ballerina.compiler.syntax.tree.WhileStatementNode; +import io.ballerina.compiler.syntax.tree.WildcardBindingPatternNode; +import io.ballerina.compiler.syntax.tree.XMLAtomicNamePatternNode; +import io.ballerina.compiler.syntax.tree.XMLAttributeNode; +import io.ballerina.compiler.syntax.tree.XMLAttributeValue; +import io.ballerina.compiler.syntax.tree.XMLCDATANode; +import io.ballerina.compiler.syntax.tree.XMLComment; +import io.ballerina.compiler.syntax.tree.XMLElementNode; +import io.ballerina.compiler.syntax.tree.XMLEmptyElementNode; +import io.ballerina.compiler.syntax.tree.XMLEndTagNode; +import io.ballerina.compiler.syntax.tree.XMLFilterExpressionNode; +import io.ballerina.compiler.syntax.tree.XMLNameNode; +import io.ballerina.compiler.syntax.tree.XMLNamePatternChainingNode; +import io.ballerina.compiler.syntax.tree.XMLNamespaceDeclarationNode; +import io.ballerina.compiler.syntax.tree.XMLProcessingInstruction; +import io.ballerina.compiler.syntax.tree.XMLQualifiedNameNode; +import io.ballerina.compiler.syntax.tree.XMLSimpleNameNode; +import io.ballerina.compiler.syntax.tree.XMLStartTagNode; +import io.ballerina.compiler.syntax.tree.XMLStepExpressionNode; +import io.ballerina.compiler.syntax.tree.XMLTextNode; import io.ballerina.identifier.Utils; import io.ballerina.runtime.internal.XmlFactory; import io.ballerina.tools.diagnostics.DiagnosticCode; @@ -1448,12 +1687,6 @@ public BLangNode transform(FunctionBodyBlockNode functionBodyBlockNode) { } } - for (Node stmt : functionBodyBlockNode.statementsWithComments()) { - Node s = stmt; - if (stmt instanceof CommentNode commentNode) { - Node commentAttachedNode = commentNode.getCommentAttachedNode(); - } - } generateAndAddBLangStatements(functionBodyBlockNode.statements(), stmtList, 0, functionBodyBlockNode); bLFuncBody.stmts = statements; @@ -2759,13 +2992,6 @@ public BLangNode transform(IfElseStatementNode ifElseStmtNode) { public BLangNode transform(BlockStatementNode blockStatement) { BLangBlockStmt bLBlockStmt = (BLangBlockStmt) TreeBuilder.createBlockNode(); this.isInLocalContext = true; - for (Node stmt : blockStatement.statementsWithComments()) { - Node s = stmt; - if (stmt instanceof CommentNode commentNode) { - Node commentAttachedNode = commentNode.getCommentAttachedNode(); - } - } - bLBlockStmt.stmts = generateBLangStatements(blockStatement.statements(), blockStatement); this.isInLocalContext = false; bLBlockStmt.pos = getPosition(blockStatement); diff --git a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/BlockStatementNode.java b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/BlockStatementNode.java index 97d6874bc688..61253a9cf1e2 100644 --- a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/BlockStatementNode.java +++ b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/BlockStatementNode.java @@ -40,7 +40,7 @@ public NodeList statements() { return new NodeList<>(childInBucket(1)); } - public NodeAndCommentList statementsWithComments() { + public NodeAndCommentList statementsWithComments() { return new NodeAndCommentList<>(childInBucket(1), childInBucket(2)); } diff --git a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/CommentNode.java b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/CommentNode.java index 4ca58126567e..08cfba08faeb 100644 --- a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/CommentNode.java +++ b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/CommentNode.java @@ -1,20 +1,19 @@ /* - * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2024, WSO2 LLC. (http://wso2.com) * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + package io.ballerina.compiler.syntax.tree; import io.ballerina.compiler.internal.parser.tree.STNode; diff --git a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/FunctionBodyBlockNode.java b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/FunctionBodyBlockNode.java index 24267139d340..7aeaef153cd1 100644 --- a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/FunctionBodyBlockNode.java +++ b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/FunctionBodyBlockNode.java @@ -45,7 +45,7 @@ public NodeList statements() { return new NodeList<>(childInBucket(2)); } - public NodeAndCommentList statementsWithComments() { + public NodeAndCommentList statementsWithComments() { return new NodeAndCommentList<>(childInBucket(2), childInBucket(3)); } diff --git a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/NodeAndCommentList.java b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/NodeAndCommentList.java index 23b96141b55e..36e0283dc54c 100644 --- a/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/NodeAndCommentList.java +++ b/compiler/ballerina-parser/src/main/java/io/ballerina/compiler/syntax/tree/NodeAndCommentList.java @@ -1,20 +1,19 @@ /* - * Copyright (c) 2020, WSO2 Inc. (http://www.wso2.org) All Rights Reserved. + * Copyright (c) 2024, WSO2 LLC. (http://wso2.com) * - * WSO2 Inc. licenses this file to you under the Apache License, - * Version 2.0 (the "License"); you may not use this file except - * in compliance with the License. - * You may obtain a copy of the License at + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at * - * http://www.apache.org/licenses/LICENSE-2.0 + * http://www.apache.org/licenses/LICENSE-2.0 * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. */ + package io.ballerina.compiler.syntax.tree; import io.ballerina.compiler.internal.parser.tree.STNode; @@ -32,10 +31,9 @@ /** * Represent both nodes and attached comments to each node. * - * @param The type of NonTerminalNode - * @param The type of Node + * @param The type of Node */ -public class NodeAndCommentList implements Iterable { +public class NodeAndCommentList implements Iterable { protected final STNodeList internalListNode; protected final NonTerminalNode nonTerminalNode; protected final int size; @@ -52,7 +50,7 @@ protected NodeAndCommentList(NonTerminalNode nonTerminalNode, Token semicolon, i this.internalListNode = (STNodeList) nonTerminalNode.internalNode(); this.nonTerminalNode = nonTerminalNode; - this.nodes = new Node[size]; // TODO: Init with max size + this.nodes = new Node[size]; int nodeIndex = 0; for (int i = 0; i < nonTerminalNode.bucketCount(); i++) { Node node = nonTerminalNode.childInBucket(i); @@ -95,25 +93,25 @@ private CommentNode getCommentNode(Node node) { // Positional access methods - public K get(int index) { + public T get(int index) { rangeCheck(index, size); - return (K) this.nodes[index]; + return (T) this.nodes[index]; } // Modification methods - public NodeAndCommentList add(T node) { + public NodeAndCommentList add(T node) { Objects.requireNonNull(node, "node should not be null"); return new NodeAndCommentList<>(internalListNode.add(node.internalNode()).createUnlinkedFacade(), null); } - public NodeAndCommentList add(int index, T node) { + public NodeAndCommentList add(int index, T node) { Objects.requireNonNull(node, "node should not be null"); rangeCheckForAdd(index, size); return new NodeAndCommentList<>(internalListNode.add(index, node.internalNode()).createUnlinkedFacade(), null); } - public NodeAndCommentList addAll(Collection c) { + public NodeAndCommentList addAll(Collection c) { if (c.isEmpty()) { return this; } @@ -125,7 +123,7 @@ public NodeAndCommentList addAll(Collection c) { return new NodeAndCommentList<>(internalListNode.addAll(stNodesToBeAdded).createUnlinkedFacade(), null); } - public NodeAndCommentList set(int index, T node) { + public NodeAndCommentList set(int index, T node) { Objects.requireNonNull(node, "node should not be null"); rangeCheck(index, size); if (nonTerminalNode.checkForReferenceEquality(index, node)) { @@ -135,12 +133,12 @@ public NodeAndCommentList set(int index, T node) { return new NodeAndCommentList<>(internalListNode.set(index, node.internalNode()).createUnlinkedFacade(), null); } - public NodeAndCommentList remove(int index) { + public NodeAndCommentList remove(int index) { rangeCheck(index, size); return new NodeAndCommentList<>(internalListNode.remove(index).createUnlinkedFacade(), null); } - public NodeAndCommentList remove(T node) { + public NodeAndCommentList remove(T node) { Objects.requireNonNull(node, "node should not be null"); for (int bucket = 0; bucket < nonTerminalNode.bucketCount(); bucket++) { if (nonTerminalNode.checkForReferenceEquality(bucket, node)) { @@ -151,7 +149,7 @@ public NodeAndCommentList remove(T node) { } @SuppressWarnings("SuspiciousMethodCalls") - public NodeAndCommentList removeAll(Collection c) { + public NodeAndCommentList removeAll(Collection c) { if (c.isEmpty()) { return this; } @@ -179,11 +177,11 @@ public boolean isEmpty() { } @Override - public Iterator iterator() { + public Iterator iterator() { return new NodeAndCommentListIterator(); } - public Stream stream() { + public Stream stream() { return StreamSupport.stream(spliterator(), false); } @@ -196,7 +194,7 @@ NonTerminalNode underlyingListNode() { * * @since 2201.10.0 */ - protected class NodeAndCommentListIterator implements Iterator { + protected class NodeAndCommentListIterator implements Iterator { private int currentIndex = 0; @Override @@ -205,7 +203,7 @@ public boolean hasNext() { } @Override - public K next() { + public T next() { return get(currentIndex++); } } From 81860e07d925f7efe6f202d3140fd9bd7dd61922 Mon Sep 17 00:00:00 2001 From: KavinduZoysa Date: Wed, 11 Sep 2024 13:13:41 +0530 Subject: [PATCH 5/5] Add more tests --- .../compiler/parser/test/ParserTestUtils.java | 12 ++++++++ .../nodeparser/ParseBlockStatementTest.java | 30 +++++++++++++++++++ .../nodeparser/ParseFunctionBodyBlock.java | 28 +++++++++++++++++ 3 files changed, 70 insertions(+) diff --git a/compiler/ballerina-parser/src/test/java/io/ballerinalang/compiler/parser/test/ParserTestUtils.java b/compiler/ballerina-parser/src/test/java/io/ballerinalang/compiler/parser/test/ParserTestUtils.java index 6dc3df46bfd5..b9cfe29df20c 100644 --- a/compiler/ballerina-parser/src/test/java/io/ballerinalang/compiler/parser/test/ParserTestUtils.java +++ b/compiler/ballerina-parser/src/test/java/io/ballerinalang/compiler/parser/test/ParserTestUtils.java @@ -32,6 +32,7 @@ import io.ballerina.compiler.internal.parser.tree.STNodeList; import io.ballerina.compiler.internal.parser.tree.STToken; import io.ballerina.compiler.internal.syntax.SyntaxUtils; +import io.ballerina.compiler.syntax.tree.CommentNode; import io.ballerina.compiler.syntax.tree.Node; import io.ballerina.compiler.syntax.tree.SyntaxKind; import io.ballerina.compiler.syntax.tree.SyntaxTree; @@ -47,6 +48,7 @@ import java.nio.file.Path; import java.nio.file.Paths; import java.util.Collection; +import java.util.List; import static io.ballerina.compiler.internal.syntax.SyntaxUtils.isSTNodePresent; import static io.ballerinalang.compiler.parser.test.ParserTestConstants.CHILDREN_FIELD; @@ -1476,4 +1478,14 @@ private static SyntaxKind getDocumentationKind(String kind) { throw new UnsupportedOperationException("cannot find syntax kind: " + kind); } } + + public static void assertCommentNode(Node node, List comments) { + Assert.assertTrue(node instanceof CommentNode); + CommentNode commentNode = (CommentNode) node; + List commentLines = commentNode.getCommentLines(); + Assert.assertEquals(commentLines.size(), comments.size()); + for (int i = 0; i < comments.size(); i++) { + Assert.assertEquals(commentLines.get(i), comments.get(i)); + } + } } diff --git a/compiler/ballerina-parser/src/test/java/io/ballerinalang/compiler/parser/test/tree/nodeparser/ParseBlockStatementTest.java b/compiler/ballerina-parser/src/test/java/io/ballerinalang/compiler/parser/test/tree/nodeparser/ParseBlockStatementTest.java index f665793167a0..d246eff02732 100644 --- a/compiler/ballerina-parser/src/test/java/io/ballerinalang/compiler/parser/test/tree/nodeparser/ParseBlockStatementTest.java +++ b/compiler/ballerina-parser/src/test/java/io/ballerinalang/compiler/parser/test/tree/nodeparser/ParseBlockStatementTest.java @@ -18,6 +18,8 @@ package io.ballerinalang.compiler.parser.test.tree.nodeparser; import io.ballerina.compiler.syntax.tree.BlockStatementNode; +import io.ballerina.compiler.syntax.tree.Node; +import io.ballerina.compiler.syntax.tree.NodeAndCommentList; import io.ballerina.compiler.syntax.tree.NodeList; import io.ballerina.compiler.syntax.tree.NodeParser; import io.ballerina.compiler.syntax.tree.StatementNode; @@ -28,6 +30,8 @@ import java.util.List; +import static io.ballerinalang.compiler.parser.test.ParserTestUtils.assertCommentNode; + /** * Test {@code parseBlockStatement} method. * @@ -177,4 +181,30 @@ public void testBlockStmtRecovery() { Assert.assertEquals(blockStmtNode.toString(), " INVALID[%]{ int a; INVALID[;] } INVALID[;] INVALID[;]"); } + + @Test + public void testCommentInBlockStatementBody() { + String blockStatement = """ + { + // Initialize x + int x = 1; + // Initialize y + int y = 1; + + // new comment + // another new comment + }"""; + BlockStatementNode blockStmtNode = NodeParser.parseBlockStatement(blockStatement); + Assert.assertEquals(blockStmtNode.kind(), SyntaxKind.BLOCK_STATEMENT); + Assert.assertFalse(blockStmtNode.hasDiagnostics()); + + NodeAndCommentList nodes = blockStmtNode.statementsWithComments(); + Assert.assertEquals(nodes.size(), 5); + + assertCommentNode(nodes.get(0), List.of("Initialize x")); + assertCommentNode(nodes.get(2), List.of("Initialize y")); + assertCommentNode(nodes.get(4), List.of("new comment", "another new comment")); + } + + } diff --git a/compiler/ballerina-parser/src/test/java/io/ballerinalang/compiler/parser/test/tree/nodeparser/ParseFunctionBodyBlock.java b/compiler/ballerina-parser/src/test/java/io/ballerinalang/compiler/parser/test/tree/nodeparser/ParseFunctionBodyBlock.java index 926702dab247..6d5ea710a004 100644 --- a/compiler/ballerina-parser/src/test/java/io/ballerinalang/compiler/parser/test/tree/nodeparser/ParseFunctionBodyBlock.java +++ b/compiler/ballerina-parser/src/test/java/io/ballerinalang/compiler/parser/test/tree/nodeparser/ParseFunctionBodyBlock.java @@ -20,6 +20,8 @@ import io.ballerina.compiler.syntax.tree.FunctionBodyBlockNode; import io.ballerina.compiler.syntax.tree.NamedWorkerDeclarationNode; import io.ballerina.compiler.syntax.tree.NamedWorkerDeclarator; +import io.ballerina.compiler.syntax.tree.Node; +import io.ballerina.compiler.syntax.tree.NodeAndCommentList; import io.ballerina.compiler.syntax.tree.NodeList; import io.ballerina.compiler.syntax.tree.NodeParser; import io.ballerina.compiler.syntax.tree.StatementNode; @@ -31,6 +33,8 @@ import java.util.List; import java.util.Optional; +import static io.ballerinalang.compiler.parser.test.ParserTestUtils.assertCommentNode; + /** * Test {@code parseFunctionBodyBlock} method. * @@ -255,4 +259,28 @@ public void testFuncBodyBlockRecovery() { Assert.assertEquals(funcBodyBlockNode.toString(), " INVALID[%]{ int a; INVALID[;] }; INVALID[;]"); } + + @Test + public void testCommentInFunctionBody() { + String funcBodyBlock = """ + { + // Initialize x + int x = 1; + // Initialize y + int y = 1; + + // new comment + // another new comment + }"""; + FunctionBodyBlockNode funcBodyBlockNode = NodeParser.parseFunctionBodyBlock(funcBodyBlock); + Assert.assertEquals(funcBodyBlockNode.kind(), SyntaxKind.FUNCTION_BODY_BLOCK); + Assert.assertFalse(funcBodyBlockNode.hasDiagnostics()); + + NodeAndCommentList nodes = funcBodyBlockNode.statementsWithComments(); + Assert.assertEquals(nodes.size(), 5); + + assertCommentNode(nodes.get(0), List.of("Initialize x")); + assertCommentNode(nodes.get(2), List.of("Initialize y")); + assertCommentNode(nodes.get(4), List.of("new comment", "another new comment")); + } }