Skip to content

Commit

Permalink
Merge pull request #42722 from poorna2152/xml_step_parsing
Browse files Browse the repository at this point in the history
[Step Extension] Fix parsing of xml step extension
  • Loading branch information
lochana-chathura authored Jul 16, 2024
2 parents 39a28cb + 16ade74 commit 2e1e1be
Show file tree
Hide file tree
Showing 62 changed files with 17,825 additions and 1,179 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@
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.XMLStepIndexedExtendNode;
import io.ballerina.compiler.syntax.tree.XMLTextNode;
import io.ballerina.identifier.Utils;
import io.ballerina.runtime.internal.XmlFactory;
Expand Down Expand Up @@ -2396,19 +2397,7 @@ public BLangNode transform(IndexedExpressionNode indexedExpressionNode) {
indexBasedAccess.indexExpr = listConstructorExpr;
}

Node containerExpr = indexedExpressionNode.containerExpression();
BLangExpression expression = createExpression(containerExpr);
if (containerExpr.kind() == SyntaxKind.XML_STEP_EXPRESSION) {
// TODO : This check will be removed after changes are done for spec issue #536

// The original expression position is overwritten here since the modeling of BLangXMLNavigationAccess is
// different from the normal index based access.
expression.pos = indexBasedAccess.pos;
((BLangXMLNavigationAccess) expression).childIndex = indexBasedAccess.indexExpr;
return expression;
}
indexBasedAccess.expr = expression;

indexBasedAccess.expr = createExpression(indexedExpressionNode.containerExpression());
return indexBasedAccess;
}

Expand Down Expand Up @@ -4457,10 +4446,17 @@ public BLangNode transform(XMLStepExpressionNode xmlStepExpressionNode) {
}

BLangExpression expr = createExpression(xmlStepExpressionNode.expression());
BLangExpression childIndex = null;
for (Node extension : xmlStepExpressionNode.xmlStepExtend()) {
if (extension.kind() == SyntaxKind.XML_STEP_INDEXED_EXTEND) {
childIndex = createExpression(((XMLStepIndexedExtendNode) extension).expression());
break;
}
}
// TODO : implement the value for childIndex
BLangXMLNavigationAccess xmlNavigationAccess =
new BLangXMLNavigationAccess(getPosition(xmlStepExpressionNode), expr, filters,
XMLNavigationAccess.NavAccessType.fromInt(starCount), null);
XMLNavigationAccess.NavAccessType.fromInt(starCount), childIndex);
return xmlNavigationAccess;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5686,7 +5686,8 @@ private STNode createXMLStepExpression(STNode lhsExpr) {
}

STNode namePattern = parseXMLNamePatternChain(slashLT);
newLhsExpr = STNodeFactory.createXMLStepExpressionNode(lhsExpr, namePattern);
STNode xmlStepExtends = parseXMLStepExtends();
newLhsExpr = STNodeFactory.createXMLStepExpressionNode(lhsExpr, namePattern, xmlStepExtends);
return newLhsExpr;
}

Expand Down Expand Up @@ -5898,9 +5899,7 @@ private STNode parseCloseBracket() {
*/
private STNode parseFieldAccessOrMethodCall(STNode lhsExpr, boolean isInConditionalExpr) {
STNode dotToken = parseDotToken();
STToken token = peek();
if (token.kind == SyntaxKind.MAP_KEYWORD || token.kind == SyntaxKind.START_KEYWORD ||
token.kind == SyntaxKind.JOIN_KEYWORD) {
if (isSpecialMethodName(peek())) {
STNode methodName = getKeywordAsSimpleNameRef();
STNode openParen = parseArgListOpenParenthesis();
STNode args = parseArgsList();
Expand Down Expand Up @@ -14572,6 +14571,84 @@ private STNode parseXMLNamePatternChain(STNode startToken) {
return STNodeFactory.createXMLNamePatternChainingNode(startToken, xmlNamePattern, gtToken);
}

/**
* Parse xml step extends.
* <p>
* <code>
* xml-step-extends := xml-step-extend*
* </code>
*
* @return Parsed node
*/
private STNode parseXMLStepExtends() {
STToken nextToken = peek();
if (isEndOfXMLStepExtend(nextToken.kind)) {
return STNodeFactory.createEmptyNodeList();
}

List<STNode> xmlStepExtendList = new ArrayList<>();
startContext(ParserRuleContext.XML_STEP_EXTENDS);
STNode stepExtension;
while (!isEndOfXMLStepExtend(nextToken.kind)) {
if (nextToken.kind == SyntaxKind.DOT_TOKEN) {
stepExtension = parseXMLStepMethodCallExtend();
} else if (nextToken.kind == SyntaxKind.DOT_LT_TOKEN) {
stepExtension = parseXMLFilterExpressionRhs();
} else {
stepExtension = parseXMLIndexedStepExtend();
}
xmlStepExtendList.add(stepExtension);
nextToken = peek();
}
endContext();
return STNodeFactory.createNodeList(xmlStepExtendList);
}

/**
* <p>
* Parse xml indexed step extension.
* <br/>
* <code>
* xml-indexed-step-extend:= [ expression ]
* </code>
* </p>
*
* @return Parsed node
*/
private STNode parseXMLIndexedStepExtend() {
startContext(ParserRuleContext.MEMBER_ACCESS_KEY_EXPR);
STNode openBracket = parseOpenBracket();
STNode keyExpr = parseKeyExpr(true);
STNode closeBracket = parseCloseBracket();
endContext();
return STNodeFactory.createXMLStepIndexedExtendNode(openBracket, keyExpr, closeBracket);
}

/**
* <p>
* Parse xml method call step extension.
* <br/>
* <code>
* xml-method-call-step-extend:= . method-name ( arg-list )
* </code>
* </p>
*
* @return Parsed node
*/
private STNode parseXMLStepMethodCallExtend() {
STNode dotToken = parseDotToken();
STNode methodName = parseMethodName();
STNode parenthesizedArgsList = parseParenthesizedArgList();
return STNodeFactory.createXMLStepMethodCallExtendNode(dotToken, methodName, parenthesizedArgsList);
}

private STNode parseMethodName() {
if (isSpecialMethodName(peek())) {
return getKeywordAsSimpleNameRef();
}
return STNodeFactory.createSimpleNameReferenceNode(parseIdentifier(ParserRuleContext.IDENTIFIER));
}

/**
* Parse <code> .< </code> token.
*
Expand Down Expand Up @@ -14636,6 +14713,14 @@ private boolean isEndOfXMLNamePattern(SyntaxKind tokenKind) {
}
}

private boolean isEndOfXMLStepExtend(SyntaxKind tokenKind) {
return switch (tokenKind) {
case OPEN_BRACKET_TOKEN, DOT_LT_TOKEN -> false;
case DOT_TOKEN -> peek(3).kind != SyntaxKind.OPEN_PAREN_TOKEN;
default -> true;
};
}

private STNode parseXMLNamePatternSeparator() {
STToken token = peek();
switch (token.kind) {
Expand Down Expand Up @@ -14703,14 +14788,15 @@ private STNode parseXMLAtomicNameIdentifier(STNode identifier) {
/**
* Parse xml step expression.
* <p>
* <code>xml-step-expr := expression xml-step-start</code>
* <code>xml-step-expr := expression xml-step-start xml-step-extend*</code>
*
* @param lhsExpr Preceding expression of /*, /<, or /**\/< token
* @return Parsed node
*/
private STNode parseXMLStepExpression(STNode lhsExpr) {
STNode xmlStepStart = parseXMLStepStart();
return STNodeFactory.createXMLStepExpressionNode(lhsExpr, xmlStepStart);
STNode xmlStepExtends = parseXMLStepExtends();
return STNodeFactory.createXMLStepExpressionNode(lhsExpr, xmlStepStart, xmlStepExtends);
}

/**
Expand Down Expand Up @@ -19513,6 +19599,11 @@ private boolean isBlockContext(ParserRuleContext ctx) {
}
}

private boolean isSpecialMethodName(STToken token) {
return token.kind == SyntaxKind.MAP_KEYWORD || token.kind == SyntaxKind.START_KEYWORD ||
token.kind == SyntaxKind.JOIN_KEYWORD;
}

// ----------------------------------------- ~ End of Parser ~ ----------------------------------------

// NOTE: Please add any new methods to the relevant section of the class. Binding patterns related code is the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -611,6 +611,12 @@ public class BallerinaParserErrorHandler extends AbstractParserErrorHandler {
private static final ParserRuleContext[] XML_STEP_START = { ParserRuleContext.SLASH_ASTERISK_TOKEN,
ParserRuleContext.DOUBLE_SLASH_DOUBLE_ASTERISK_LT_TOKEN, ParserRuleContext.SLASH_LT_TOKEN };

private static final ParserRuleContext[] XML_STEP_EXTEND = { ParserRuleContext.XML_STEP_EXTEND_END,
ParserRuleContext.DOT, ParserRuleContext.DOT_LT_TOKEN, ParserRuleContext.MEMBER_ACCESS_KEY_EXPR };

private static final ParserRuleContext[] XML_STEP_START_END =
{ ParserRuleContext.EXPRESSION_RHS, ParserRuleContext.XML_STEP_EXTENDS };

private static final ParserRuleContext[] MATCH_PATTERN_LIST_MEMBER_RHS =
{ ParserRuleContext.MATCH_PATTERN_END, ParserRuleContext.PIPE };

Expand Down Expand Up @@ -1508,6 +1514,7 @@ protected boolean hasAlternativePaths(ParserRuleContext currentCtx) {
case XML_ATOMIC_NAME_PATTERN_START:
case XML_ATOMIC_NAME_IDENTIFIER_RHS:
case XML_STEP_START:
case XML_STEP_EXTEND:
case FUNC_TYPE_DESC_RHS_OR_ANON_FUNC_BODY:
case OPTIONAL_MATCH_GUARD:
case MATCH_PATTERN_LIST_MEMBER_RHS:
Expand Down Expand Up @@ -1611,6 +1618,7 @@ protected boolean hasAlternativePaths(ParserRuleContext currentCtx) {
case GROUPING_KEY_LIST_ELEMENT_END:
case RESULT_CLAUSE:
case SINGLE_OR_ALTERNATE_WORKER_SEPARATOR:
case XML_STEP_START_END:
return true;
default:
return false;
Expand Down Expand Up @@ -2081,6 +2089,10 @@ protected ParserRuleContext getShortestAlternative(ParserRuleContext currentCtx)
return ParserRuleContext.SELECT_CLAUSE;
case SINGLE_OR_ALTERNATE_WORKER_SEPARATOR:
return ParserRuleContext.SINGLE_OR_ALTERNATE_WORKER_END;
case XML_STEP_EXTEND:
return ParserRuleContext.XML_STEP_EXTEND_END;
case XML_STEP_START_END:
return ParserRuleContext.EXPRESSION_RHS;
default:
throw new IllegalStateException("Alternative path entry not found");
}
Expand Down Expand Up @@ -2829,6 +2841,12 @@ private Result seekMatchInExprRelatedAlternativePaths(ParserRuleContext currentC
case XML_STEP_START:
alternativeRules = XML_STEP_START;
break;
case XML_STEP_EXTEND:
alternativeRules = XML_STEP_EXTEND;
break;
case XML_STEP_START_END:
alternativeRules = XML_STEP_START_END;
break;
case OPTIONAL_MATCH_GUARD:
alternativeRules = OPTIONAL_MATCH_GUARD;
break;
Expand Down Expand Up @@ -3492,8 +3510,11 @@ protected ParserRuleContext getNextRule(ParserRuleContext currentCtx, int nextLo
return ParserRuleContext.TUPLE_MEMBER;
case SINGLE_OR_ALTERNATE_WORKER:
return ParserRuleContext.PEER_WORKER_NAME;
case XML_STEP_EXTENDS:
return ParserRuleContext.XML_STEP_EXTEND;
case XML_STEP_EXTEND_END:
case SINGLE_OR_ALTERNATE_WORKER_END:
endContext(); // end single-or-alternate-worker
endContext();
return ParserRuleContext.EXPRESSION_RHS;
default:
return getNextRuleInternal(currentCtx, nextLookahead);
Expand Down Expand Up @@ -3581,6 +3602,8 @@ private ParserRuleContext getNextRuleInternal(ParserRuleContext currentCtx, int
parentCtx = getParentContext();
if (parentCtx == ParserRuleContext.ERROR_CONSTRUCTOR) {
endContext();
} else if (parentCtx == ParserRuleContext.XML_STEP_EXTENDS) {
return ParserRuleContext.XML_STEP_EXTEND;
} else if (parentCtx == ParserRuleContext.CLIENT_RESOURCE_ACCESS_ACTION) {
return ParserRuleContext.ACTION_END;
}
Expand Down Expand Up @@ -3721,6 +3744,10 @@ private ParserRuleContext getNextRuleInternal(ParserRuleContext currentCtx, int
case TUPLE_TYPE_DESC_START:
return ParserRuleContext.TUPLE_MEMBERS;
case METHOD_NAME:
parentCtx = getParentContext();
if (parentCtx == ParserRuleContext.XML_STEP_EXTENDS) {
return ParserRuleContext.ARG_LIST_OPEN_PAREN;
}
return ParserRuleContext.OPTIONAL_RESOURCE_ACCESS_ACTION_ARG_LIST;
case DEFAULT_WORKER_NAME_IN_ASYNC_SEND:
return ParserRuleContext.SEMICOLON;
Expand Down Expand Up @@ -4289,6 +4316,7 @@ private void startContextIfRequired(ParserRuleContext currentCtx) {
case CLIENT_RESOURCE_ACCESS_ACTION:
case TUPLE_MEMBERS:
case SINGLE_OR_ALTERNATE_WORKER:
case XML_STEP_EXTENDS:

// Contexts that expect a type
case TYPE_DESC_IN_ANNOTATION_DECL:
Expand Down Expand Up @@ -5169,6 +5197,7 @@ private ParserRuleContext getNextRuleForDot() {
case RELATIVE_RESOURCE_PATH:
return ParserRuleContext.RESOURCE_ACCESSOR_DEF_OR_DECL_RHS;
case CLIENT_RESOURCE_ACCESS_ACTION:
case XML_STEP_EXTENDS:
return ParserRuleContext.METHOD_NAME;
default:
return ParserRuleContext.FIELD_ACCESS_IDENTIFIER;
Expand Down Expand Up @@ -5249,6 +5278,10 @@ private ParserRuleContext getNextRuleForCloseBracket() {
case TABLE_CONSTRUCTOR:
case MEMBER_ACCESS_KEY_EXPR:
endContext();
parentCtx = getParentContext();
if (parentCtx == ParserRuleContext.XML_STEP_EXTENDS) {
return ParserRuleContext.XML_STEP_EXTEND;
}
return getNextRuleForExpr();
case STMT_START_BRACKETED_LIST:
endContext();
Expand Down Expand Up @@ -5365,7 +5398,11 @@ private ParserRuleContext getNextRuleForGt() {

if (parentCtx == ParserRuleContext.XML_NAME_PATTERN) {
endContext();
return ParserRuleContext.EXPRESSION_RHS;
parentCtx = getParentContext();
if (parentCtx == ParserRuleContext.XML_STEP_EXTENDS) {
return ParserRuleContext.XML_STEP_EXTEND;
}
return ParserRuleContext.XML_STEP_START_END;
}

// Type cast expression:
Expand Down Expand Up @@ -5488,6 +5525,8 @@ private ParserRuleContext getNextRuleForIdentifier() {
return ParserRuleContext.ABSOLUTE_RESOURCE_PATH_END;
case CLIENT_RESOURCE_ACCESS_ACTION:
return ParserRuleContext.RESOURCE_ACCESS_SEGMENT_RHS;
case XML_STEP_EXTENDS:
return ParserRuleContext.ARG_LIST_OPEN_PAREN;
default:
if (isInTypeDescContext()) {
return ParserRuleContext.TYPE_DESC_RHS;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,10 @@ public enum ParserRuleContext {
SINGLE_OR_ALTERNATE_WORKER("single-or-alternate-worker"),
SINGLE_OR_ALTERNATE_WORKER_SEPARATOR("single-or-alternate-worker-separator"),
SINGLE_OR_ALTERNATE_WORKER_END("single-or-alternate-worker-end"),
XML_STEP_EXTENDS("xml-step-extends"),
XML_STEP_EXTEND("xml-step-extend"),
XML_STEP_EXTEND_END("xml-step-extend-end"),
XML_STEP_START_END("xml-step-start-end")
;

private final String value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2059,11 +2059,13 @@ public static STNode createXMLFilterExpressionNode(

public static STNode createXMLStepExpressionNode(
STNode expression,
STNode xmlStepStart) {
STNode xmlStepStart,
STNode xmlStepExtend) {

return new STXMLStepExpressionNode(
expression,
xmlStepStart);
xmlStepStart,
xmlStepExtend);
}

public static STNode createXMLNamePatternChainingNode(
Expand All @@ -2077,6 +2079,28 @@ public static STNode createXMLNamePatternChainingNode(
gtToken);
}

public static STNode createXMLStepIndexedExtendNode(
STNode openBracket,
STNode expression,
STNode closeBracket) {

return new STXMLStepIndexedExtendNode(
openBracket,
expression,
closeBracket);
}

public static STNode createXMLStepMethodCallExtendNode(
STNode dotToken,
STNode methodName,
STNode parenthesizedArgList) {

return new STXMLStepMethodCallExtendNode(
dotToken,
methodName,
parenthesizedArgList);
}

public static STNode createXMLAtomicNamePatternNode(
STNode prefix,
STNode colon,
Expand Down
Loading

0 comments on commit 2e1e1be

Please sign in to comment.