Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add parser changes for isolated functions #25292

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,10 @@ public enum Flag {
* Indicates Flagged node is a resource node.
*/
RESOURCE,
/**
* Indicates Flagged node is an isolated node.
*/
ISOLATED,
/**
* Indicates Flagged node is a service node.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1221,6 +1221,9 @@ private void setFunctionQualifiers(BLangFunction bLFunction, NodeList<Token> qua
case RESOURCE_KEYWORD:
bLFunction.flagSet.add(Flag.RESOURCE);
break;
case ISOLATED_KEYWORD:
bLFunction.flagSet.add(Flag.ISOLATED);
break;
default:
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ public class Flags {
public static final int TRANSACTIONAL = FORKED << 1;
public static final int PARAMETERIZED = TRANSACTIONAL << 1;
public static final int DISTINCT = PARAMETERIZED << 1;
public static final int ISOLATED = DISTINCT << 1;

public static int asMask(Set<Flag> flagSet) {
int mask = 0;
Expand Down Expand Up @@ -141,6 +142,9 @@ public static int asMask(Set<Flag> flagSet) {
case DISTINCT:
mask |= DISTINCT;
break;
case ISOLATED:
mask |= ISOLATED;
break;
}
}
return mask;
Expand Down Expand Up @@ -226,6 +230,9 @@ public static Set<Flag> unMask(int mask) {
case DISTINCT:
flagVal = DISTINCT;
break;
case ISOLATED:
flagVal = ISOLATED;
break;
default:
continue;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -913,6 +913,8 @@ private STToken processIdentifierOrKeyword() {
return getSyntaxToken(SyntaxKind.PARAMETER_KEYWORD);
case LexerTerminals.FIELD:
return getSyntaxToken(SyntaxKind.FIELD_KEYWORD);
case LexerTerminals.ISOLATED:
return getSyntaxToken(SyntaxKind.ISOLATED_KEYWORD);
case LexerTerminals.XMLNS:
return getSyntaxToken(SyntaxKind.XMLNS_KEYWORD);
case LexerTerminals.FORK:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,7 @@ protected STNode parseTopLevelNode() {
case SERVICE_KEYWORD:
case ENUM_KEYWORD:
case TRANSACTIONAL_KEYWORD:
case ISOLATED_KEYWORD:
metadata = STNodeFactory.createEmptyNode();
break;
case IDENTIFIER_TOKEN:
Expand Down Expand Up @@ -266,6 +267,7 @@ private STNode parseTopLevelNode(STNode metadata) {
case XMLNS_KEYWORD:
case ENUM_KEYWORD:
case TRANSACTIONAL_KEYWORD:
case ISOLATED_KEYWORD:
break;
case IDENTIFIER_TOKEN:
// Here we assume that after recovering, we'll never reach here.
Expand Down Expand Up @@ -526,6 +528,7 @@ private boolean isEndOfImportDecl(STToken nextToken) {
case IMPORT_KEYWORD:
case FINAL_KEYWORD:
case TRANSACTIONAL_KEYWORD:
case ISOLATED_KEYWORD:
return true;
default:
return false;
Expand Down Expand Up @@ -738,6 +741,7 @@ private STNode parseTopLevelNode(STNode metadata, STNode qualifier) {
return null;
case FUNCTION_KEYWORD:
case TRANSACTIONAL_KEYWORD:
case ISOLATED_KEYWORD:
// ANything starts with a function keyword could be a function definition
// or a module-var-decl with function type desc.
List<STNode> qualifiers = new ArrayList<>();
Expand Down Expand Up @@ -4519,6 +4523,7 @@ private STNode parseObjectMember() {
case REMOTE_KEYWORD:
case FUNCTION_KEYWORD:
case TRANSACTIONAL_KEYWORD:
case ISOLATED_KEYWORD:
case RESOURCE_KEYWORD:// resource qualifier is not allowed but let it pass here and validate in
// parseFunctionQualifiers method
metadata = STNodeFactory.createEmptyNode();
Expand Down Expand Up @@ -4563,6 +4568,7 @@ private STNode parseObjectMemberWithoutMeta(STNode metadata) {
case REMOTE_KEYWORD:
case FUNCTION_KEYWORD:
case TRANSACTIONAL_KEYWORD:
case ISOLATED_KEYWORD:
case RESOURCE_KEYWORD: // resource qualifier is not allowed but let it pass here and validate in
// parseFunctionQualifiers method
member = parseObjectMethod(metadata, new ArrayList<>());
Expand Down Expand Up @@ -4611,6 +4617,7 @@ private STNode parseObjectMethodOrField(STNode metadata, STNode visibilityQualif
case REMOTE_KEYWORD:
case FUNCTION_KEYWORD:
case TRANSACTIONAL_KEYWORD:
case ISOLATED_KEYWORD:
case RESOURCE_KEYWORD: // resource qualifier is not allowed but let it pass here and validate in
// parseFunctionQualifiers method
if (visibilityQualifier != null) {
Expand Down Expand Up @@ -4658,6 +4665,9 @@ private STNode parseFunctionQualifiers(ParserRuleContext context, List<STNode> q
case RESOURCE_KEYWORD:
qualifier = parseResourceKeyword();
break;
case ISOLATED_KEYWORD:
qualifier = parseIsolatedKeyword();
break;
default:
recover(peek(), context, context, qualifierList);
return parseFunctionQualifiers(context, qualifierList);
Expand Down Expand Up @@ -4701,6 +4711,7 @@ private DiagnosticCode validateFunctionQualifier(STNode currentQualifier, Parser
}
break;
case TRANSACTIONAL_KEYWORD:
case ISOLATED_KEYWORD:
break;
default:// RESOURCE_KEYWORD
if (context != ParserRuleContext.RESOURCE_DEF_QUALIFIERS) {
Expand Down Expand Up @@ -5741,6 +5752,7 @@ private STNode parseResource() {
switch (nextToken.kind) {
case RESOURCE_KEYWORD:
case TRANSACTIONAL_KEYWORD:
case ISOLATED_KEYWORD:
case FUNCTION_KEYWORD:
case REMOTE_KEYWORD: // remote qualifier is not allowed but let it pass here and validate in
// parseFunctionQualifiers method
Expand Down Expand Up @@ -5782,6 +5794,16 @@ private STNode parseResourceKeyword() {
}
}

private STNode parseIsolatedKeyword() {
STToken token = peek();
if (token.kind == SyntaxKind.ISOLATED_KEYWORD) {
return consume();
} else {
Solution sol = recover(token, ParserRuleContext.ISOLATED_KEYWORD);
return sol.recoveredNode;
}
}

/**
* Check whether next construct is a service declaration or not. This method is
* used to determine whether an end-of-block is reached, if the next token is
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -196,13 +196,19 @@ public class BallerinaParserErrorHandler extends AbstractParserErrorHandler {

private static final ParserRuleContext[] OBJECT_METHOD_START =
{ ParserRuleContext.REMOTE_KEYWORD, ParserRuleContext.FUNCTION_KEYWORD,
ParserRuleContext.TRANSACTIONAL_KEYWORD };
ParserRuleContext.TRANSACTIONAL_KEYWORD, ParserRuleContext.ISOLATED_KEYWORD };

private static final ParserRuleContext[] OBJECT_METHOD_WITHOUT_REMOTE =
{ ParserRuleContext.TRANSACTIONAL_KEYWORD, ParserRuleContext.FUNCTION_KEYWORD };
{ ParserRuleContext.TRANSACTIONAL_KEYWORD, ParserRuleContext.FUNCTION_KEYWORD,
ParserRuleContext.ISOLATED_KEYWORD };

private static final ParserRuleContext[] OBJECT_METHOD_WITHOUT_TRANSACTIONAL =
{ ParserRuleContext.REMOTE_KEYWORD, ParserRuleContext.FUNCTION_KEYWORD };
{ ParserRuleContext.REMOTE_KEYWORD, ParserRuleContext.FUNCTION_KEYWORD,
ParserRuleContext.ISOLATED_KEYWORD };

private static final ParserRuleContext[] OBJECT_METHOD_WITHOUT_ISOLATED =
{ ParserRuleContext.REMOTE_KEYWORD, ParserRuleContext.FUNCTION_KEYWORD,
ParserRuleContext.TRANSACTIONAL_KEYWORD };

private static final ParserRuleContext[] OBJECT_TYPE_DESCRIPTOR_START =
{ ParserRuleContext.OBJECT_TYPE_QUALIFIER, ParserRuleContext.OBJECT_KEYWORD };
Expand Down Expand Up @@ -242,7 +248,8 @@ public class BallerinaParserErrorHandler extends AbstractParserErrorHandler {
ParserRuleContext.ANON_FUNC_EXPRESSION, ParserRuleContext.ERROR_KEYWORD, ParserRuleContext.NEW_KEYWORD,
ParserRuleContext.START_KEYWORD, ParserRuleContext.FLUSH_KEYWORD, ParserRuleContext.LEFT_ARROW_TOKEN,
ParserRuleContext.WAIT_KEYWORD, ParserRuleContext.COMMIT_KEYWORD, ParserRuleContext.TRANSACTIONAL_KEYWORD,
ParserRuleContext.SERVICE_CONSTRUCTOR_EXPRESSION, ParserRuleContext.FAIL_KEYWORD };
ParserRuleContext.ISOLATED_KEYWORD, ParserRuleContext.SERVICE_CONSTRUCTOR_EXPRESSION,
ParserRuleContext.FAIL_KEYWORD };

private static final ParserRuleContext[] FIRST_MAPPING_FIELD_START =
{ ParserRuleContext.MAPPING_FIELD, ParserRuleContext.CLOSE_BRACE };
Expand All @@ -263,14 +270,17 @@ public class BallerinaParserErrorHandler extends AbstractParserErrorHandler {
{ ParserRuleContext.SERVICE_NAME, ParserRuleContext.ON_KEYWORD };

private static final ParserRuleContext[] RESOURCE_DEF_START =
{ ParserRuleContext.RESOURCE_KEYWORD, ParserRuleContext.TRANSACTIONAL_KEYWORD, ParserRuleContext.FUNC_DEF,
ParserRuleContext.CLOSE_BRACE };
{ ParserRuleContext.RESOURCE_KEYWORD, ParserRuleContext.TRANSACTIONAL_KEYWORD,
ParserRuleContext.ISOLATED_KEYWORD, ParserRuleContext.FUNC_DEF, ParserRuleContext.CLOSE_BRACE };

private static final ParserRuleContext[] RESOURCE_DEF_START_WITHOUT_RESOURCE =
{ ParserRuleContext.TRANSACTIONAL_KEYWORD, ParserRuleContext.FUNC_DEF };
{ ParserRuleContext.TRANSACTIONAL_KEYWORD, ParserRuleContext.ISOLATED_KEYWORD, ParserRuleContext.FUNC_DEF };

private static final ParserRuleContext[] RESOURCE_DEF_START_WITHOUT_TRANSACTIONAL =
{ ParserRuleContext.RESOURCE_KEYWORD, ParserRuleContext.FUNC_DEF };
{ ParserRuleContext.RESOURCE_KEYWORD, ParserRuleContext.ISOLATED_KEYWORD, ParserRuleContext.FUNC_DEF };

private static final ParserRuleContext[] RESOURCE_DEF_START_WITHOUT_ISOLATED =
{ ParserRuleContext.RESOURCE_KEYWORD, ParserRuleContext.TRANSACTION_KEYWORD, ParserRuleContext.FUNC_DEF };

private static final ParserRuleContext[] CONST_DECL_RHS =
{ ParserRuleContext.TYPE_NAME_OR_VAR_NAME, ParserRuleContext.ASSIGN_OP };
Expand Down Expand Up @@ -638,6 +648,7 @@ protected boolean isProductionWithAlternatives(ParserRuleContext currentCtx) {
case RESOURCE_DEF_QUALIFIERS:
case RESOURCE_DEF_START_WITHOUT_RESOURCE:
case RESOURCE_DEF_START_WITHOUT_TRANSACTIONAL:
case RESOURCE_DEF_START_WITHOUT_ISOLATED:
case PARAMETER_WITHOUT_ANNOTS:
case PARAMETER_START:
case STMT_START_WITH_EXPR_RHS:
Expand Down Expand Up @@ -715,6 +726,7 @@ protected boolean isProductionWithAlternatives(ParserRuleContext currentCtx) {
case TUPLE_TYPE_DESC_OR_LIST_CONST_MEMBER:
case OBJECT_METHOD_WITHOUT_REMOTE:
case OBJECT_METHOD_WITHOUT_TRANSACTIONAL:
case OBJECT_METHOD_WITHOUT_ISOLATED:
case TOP_LEVEL_FUNC_DEF_OR_FUNC_TYPE_DESC:
case MAPPING_BP_OR_MAPPING_CONSTRUCTOR_MEMBER:
case TYPE_DESC_OR_EXPR_RHS:
Expand Down Expand Up @@ -971,6 +983,9 @@ protected Result seekMatch(ParserRuleContext currentCtx, int lookahead, int curr
case TRANSACTIONAL_KEYWORD:
hasMatch = nextToken.kind == SyntaxKind.TRANSACTIONAL_KEYWORD;
break;
case ISOLATED_KEYWORD:
hasMatch = nextToken.kind == SyntaxKind.ISOLATED_KEYWORD;
break;
case MODULE_ENUM_NAME:
case ENUM_MEMBER_NAME:
case NAMED_ARG_BINDING_PATTERN:
Expand Down Expand Up @@ -1094,6 +1109,7 @@ private boolean isKeyword(ParserRuleContext currentCtx) {
case DO_KEYWORD:
case TRANSACTION_KEYWORD:
case TRANSACTIONAL_KEYWORD:
case ISOLATED_KEYWORD:
case COMMIT_KEYWORD:
case RETRY_KEYWORD:
case ROLLBACK_KEYWORD:
Expand Down Expand Up @@ -1215,6 +1231,7 @@ private boolean hasAlternativePaths(ParserRuleContext currentCtx) {
case RESOURCE_DEF_QUALIFIERS:
case RESOURCE_DEF_START_WITHOUT_RESOURCE:
case RESOURCE_DEF_START_WITHOUT_TRANSACTIONAL:
case RESOURCE_DEF_START_WITHOUT_ISOLATED:
case CONST_DECL_TYPE:
case CONST_DECL_RHS:
case ARRAY_LENGTH:
Expand Down Expand Up @@ -1323,6 +1340,7 @@ private boolean hasAlternativePaths(ParserRuleContext currentCtx) {
case TUPLE_TYPE_DESC_OR_LIST_CONST_MEMBER:
case OBJECT_METHOD_WITHOUT_REMOTE:
case OBJECT_METHOD_WITHOUT_TRANSACTIONAL:
case OBJECT_METHOD_WITHOUT_ISOLATED:
case TOP_LEVEL_FUNC_DEF_OR_FUNC_TYPE_DESC:
case JOIN_CLAUSE_START:
case INTERMEDIATE_CLAUSE_START:
Expand Down Expand Up @@ -1433,6 +1451,9 @@ private Result seekMatchInAlternativePaths(ParserRuleContext currentCtx, int loo
case OBJECT_METHOD_WITHOUT_TRANSACTIONAL:
alternativeRules = OBJECT_METHOD_WITHOUT_TRANSACTIONAL;
break;
case OBJECT_METHOD_WITHOUT_ISOLATED:
alternativeRules = OBJECT_METHOD_WITHOUT_ISOLATED;
break;
case OBJECT_FUNC_OR_FIELD:
alternativeRules = OBJECT_FUNC_OR_FIELD;
break;
Expand Down Expand Up @@ -1470,6 +1491,9 @@ private Result seekMatchInAlternativePaths(ParserRuleContext currentCtx, int loo
case RESOURCE_DEF_START_WITHOUT_TRANSACTIONAL:
alternativeRules = RESOURCE_DEF_START_WITHOUT_TRANSACTIONAL;
break;
case RESOURCE_DEF_START_WITHOUT_ISOLATED:
alternativeRules = RESOURCE_DEF_START_WITHOUT_ISOLATED;
break;
case CONST_DECL_TYPE:
alternativeRules = CONST_DECL_TYPE;
break;
Expand Down Expand Up @@ -2918,6 +2942,19 @@ private ParserRuleContext getNextRuleForKeywords(ParserRuleContext currentCtx, i
default:
return ParserRuleContext.EXPRESSION_RHS;
}
case ISOLATED_KEYWORD:
parentCtx = getParentContext();
switch (parentCtx) {
case COMP_UNIT:
return ParserRuleContext.FUNC_DEF_OR_FUNC_TYPE;
case OBJECT_MEMBER:
return ParserRuleContext.OBJECT_METHOD_WITHOUT_ISOLATED;
case SERVICE_CONSTRUCTOR_EXPRESSION:
case SERVICE_DECL:
return ParserRuleContext.RESOURCE_DEF_START_WITHOUT_ISOLATED;
default:
return ParserRuleContext.EXPRESSION_RHS; // TODO: 8/14/20 verify
}
case ENUM_KEYWORD:
return ParserRuleContext.MODULE_ENUM_NAME;
case MATCH_KEYWORD:
Expand Down Expand Up @@ -4595,6 +4632,8 @@ protected SyntaxKind getExpectedKeywordKind(ParserRuleContext ctx) {
return SyntaxKind.TRANSACTION_KEYWORD;
case TRANSACTIONAL_KEYWORD:
return SyntaxKind.TRANSACTIONAL_KEYWORD;
case ISOLATED_KEYWORD:
return SyntaxKind.ISOLATED_KEYWORD;
case COMMIT_KEYWORD:
return SyntaxKind.COMMIT_KEYWORD;
case RETRY_KEYWORD:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ public class LexerTerminals {
public static final String WORKER = "worker";
public static final String PARAMETER = "parameter";
public static final String FIELD = "field";
public static final String ISOLATED = "isolated";
public static final String XMLNS = "xmlns";
public static final String FORK = "fork";
public static final String TRAP = "trap";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ public enum ParserRuleContext {
OBJECT_METHOD_START("object-method-start"),
OBJECT_METHOD_WITHOUT_REMOTE("object.method.without.remote"),
OBJECT_METHOD_WITHOUT_TRANSACTIONAL("object.method.without.transactional"),
OBJECT_METHOD_WITHOUT_ISOLATED("object.method.without.isolated"),
OBJECT_FIELD_RHS("object-field-rhs"),
OBJECT_TYPE_QUALIFIER("object-type-qualifier"),
OBJECT_TYPE_DESCRIPTOR_START("object-type-desc-start"),
Expand All @@ -104,6 +105,7 @@ public enum ParserRuleContext {
RESOURCE_DEF("resource-def"),
RESOURCE_DEF_QUALIFIERS("resource-def-qualifiers"),
RESOURCE_DEF_START_WITHOUT_TRANSACTIONAL("resource-def-start-without-transactional"),
RESOURCE_DEF_START_WITHOUT_ISOLATED("resource-def-start-without-isolated"),
RESOURCE_DEF_START_WITHOUT_RESOURCE("resource-def-start-without-resource"),
LISTENER_DECL("listener-decl"),
CONSTANT_DECL("const-decl"),
Expand Down Expand Up @@ -339,6 +341,7 @@ public enum ParserRuleContext {
SOURCE_KEYWORD("source"),
XMLNS_KEYWORD("xmlns"),
WORKER_KEYWORD("worker"),
ISOLATED_KEYWORD("isolated"),
FORK_KEYWORD("fork"),
TRAP_KEYWORD("trap"),
IN_KEYWORD("in"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ public enum SyntaxKind {
WORKER_KEYWORD(117, "worker"),
PARAMETER_KEYWORD(118, "parameter"),
FIELD_KEYWORD(119, "field"),
ISOLATED_KEYWORD(120, "isolated"),

RETURNS_KEYWORD(200, "returns"),
RETURN_KEYWORD(201, "return"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -630,6 +630,8 @@ private static SyntaxKind getNodeKind(String kind) {
return SyntaxKind.ROLLBACK_KEYWORD;
case "TRANSACTIONAL_KEYWORD":
return SyntaxKind.TRANSACTIONAL_KEYWORD;
case "ISOLATED_KEYWORD":
return SyntaxKind.ISOLATED_KEYWORD;
case "ENUM_KEYWORD":
return SyntaxKind.ENUM_KEYWORD;
case "BASE16_KEYWORD":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ public void testExternalFuncDef() {
test("func-definition/func_def_source_08.bal", "func-definition/func_def_assert_08.json");
}

@Test
public void testFunctionWithIsolatedQualifier() {
test("func-definition/isolated_func_def_01.bal", "func-definition/isolated_func_def_assert_01.json");
test("func-definition/isolated_func_def_02.bal", "func-definition/isolated_func_def_assert_02.json");
test("func-definition/isolated_func_def_03.bal", "func-definition/isolated_func_def_assert_03.json");
test("func-definition/isolated_func_def_04.bal", "func-definition/isolated_func_def_assert_04.json");
test("func-definition/isolated_func_def_05.bal", "func-definition/isolated_func_def_assert_05.json");
test("func-definition/isolated_func_def_06.bal", "func-definition/isolated_func_def_assert_06.json");
}

// Recovery tests

@Test
Expand Down Expand Up @@ -146,4 +156,19 @@ public void testIncompleteExternalFunctionBodyRecovery() {
public void testFunctionWithInvalidExpressionStatement() {
testFile("func-definition/func_def_source_24.bal", "func-definition/func_def_assert_24.json");
}

@Test
public void testMissingFunctionKeywordWithQualifiers() {
testFile("func-definition/func_def_source_25.bal", "func-definition/func_def_assert_25.json");
}

@Test
public void testMissingFunctionNameWithQualifiers() {
testFile("func-definition/func_def_source_26.bal", "func-definition/func_def_assert_26.json");
}

@Test
public void testMissingTokensWithQualifiers() {
testFile("func-definition/func_def_source_27.bal", "func-definition/func_def_assert_27.json");
}
}
Loading