Skip to content

Commit

Permalink
[incubator-kie-drools#5708] [new-parser] function definition causes a… (
Browse files Browse the repository at this point in the history
apache#5793)

* [incubator-kie-drools#5708] [new-parser] function definition causes an error

* - enhance getTextPreservingWhitespace to avoid string manipulation
  • Loading branch information
tkobayas authored and rgdoliveira committed Oct 24, 2024
1 parent 80f50b9 commit c0e2930
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3691,4 +3691,52 @@ void groupedConstraintsWithNullSafeDereferencing() {
.as("prefix should be appended to each element")
.isEqualToIgnoringWhitespace("address!.city!.startsWith(\"I\") && address!.city!.length() == 5");
}

@Test
public void functionWithStringLiteral() {
final String text = "function String star(String s) { return \"*\"; }";
PackageDescr packageDescr = parser.parse(text);
assertThat(parser.hasErrors()).as(parser.getErrors().toString()).isFalse();

FunctionDescr function = packageDescr.getFunctions().get( 0 );

assertThat(function.getName()).isEqualTo("star");
assertThat(function.getReturnType()).isEqualTo("String");
assertThat(function.getParameterTypes().get(0)).isEqualTo("String");
assertThat(function.getParameterNames().get(0)).isEqualTo("s");
assertThat(function.getBody()).isEqualToIgnoringWhitespace( "return \"*\";");
}

@Test
public void functionWithStringLiteralAddition() {
final String text = "function String addStar(String s) { return s + \"*\"; }";
PackageDescr packageDescr = parser.parse(text);
assertThat(parser.hasErrors()).as(parser.getErrors().toString()).isFalse();

FunctionDescr function = packageDescr.getFunctions().get( 0 );

assertThat(function.getName()).isEqualTo("addStar");
assertThat(function.getReturnType()).isEqualTo("String");
assertThat(function.getParameterTypes().get(0)).isEqualTo("String");
assertThat(function.getParameterNames().get(0)).isEqualTo("s");
assertThat(function.getBody()).isEqualToIgnoringWhitespace( "return s + \"*\";");
}

@Test
public void functionWithMultipleBlockStatements() {
final String text = "function String star(String s) {\n" +
" String result = s + \"*\";\n" +
" return result;\n" +
"}";
PackageDescr packageDescr = parser.parse(text);
assertThat(parser.hasErrors()).as(parser.getErrors().toString()).isFalse();

FunctionDescr function = packageDescr.getFunctions().get( 0 );

assertThat(function.getName()).isEqualTo("star");
assertThat(function.getReturnType()).isEqualTo("String");
assertThat(function.getParameterTypes().get(0)).isEqualTo("String");
assertThat(function.getParameterNames().get(0)).isEqualTo("s");
assertThat(function.getBody()).isEqualToIgnoringWhitespace( "String result = s + \"*\"; return result;");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ drlRelationalOperator
| DRL_NOT? DRL_STR LBRACK IDENTIFIER RBRACK ;

/* function := FUNCTION type? ID parameters(typed) chunk_{_} */
functiondef : DRL_FUNCTION typeTypeOrVoid? IDENTIFIER formalParameters block ;
functiondef : DRL_FUNCTION typeTypeOrVoid? IDENTIFIER formalParameters drlBlock ;


/* extending JavaParser qualifiedName */
Expand Down Expand Up @@ -380,7 +380,7 @@ fromAccumulate : (DRL_ACCUMULATE|DRL_ACC) LPAREN lhsAndDef (COMMA|SEMI)
RPAREN (SEMI)?
;

blockStatements : blockStatement* ;
blockStatements : drlBlockStatement* ;

/*
accumulateFunction := label? ID parameters
Expand Down Expand Up @@ -512,3 +512,57 @@ drlVariableInitializer
drlArrayInitializer
: LBRACE (drlVariableInitializer (COMMA drlVariableInitializer)* (COMMA)? )? RBRACE
;

/* extending JavaParser block */
drlBlock
: LBRACE drlBlockStatement* RBRACE
;
/* extending JavaParser blockStatement */
drlBlockStatement
: drlLocalVariableDeclaration SEMI
| drlStatement
| localTypeDeclaration
;

/* extending JavaParser statement */
drlStatement
: blockLabel=drlBlock
| ASSERT drlExpression (COLON drlExpression)? SEMI
| IF parExpression drlStatement (ELSE drlStatement)?
| FOR LPAREN forControl RPAREN drlStatement
| WHILE parExpression drlStatement
| DO drlStatement WHILE parExpression SEMI
| TRY drlBlock (catchClause+ finallyBlock? | finallyBlock)
| TRY resourceSpecification drlBlock catchClause* finallyBlock?
| SWITCH parExpression LBRACE switchBlockStatementGroup* switchLabel* RBRACE
| SYNCHRONIZED parExpression drlBlock
| RETURN drlExpression? SEMI
| THROW drlExpression SEMI
| BREAK drlIdentifier? SEMI
| CONTINUE drlIdentifier? SEMI
| YIELD drlExpression SEMI // Java17
| SEMI
| statementExpression=drlExpression SEMI
| switchExpression SEMI? // Java17
| identifierLabel=drlIdentifier COLON drlStatement
;

/* extending JavaParser localVariableDeclaration */
drlLocalVariableDeclaration
: variableModifier* (typeType drlVariableDeclarators | VAR drlIdentifier ASSIGN expression)
;

/* extending JavaParser variableDeclarators */
drlVariableDeclarators
: drlVariableDeclarator (COMMA drlVariableDeclarator)*
;

/* extending JavaParser variableDeclarator */
drlVariableDeclarator
: drlVariableDeclaratorId (ASSIGN drlVariableInitializer)?
;

/* extending JavaParser variableDeclaratorId */
drlVariableDeclaratorId
: drlIdentifier (LBRACK RBRACK)*
;
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
*/
package org.drools.drl.parser.antlr4;

import java.util.List;
import java.util.stream.Collectors;

import org.antlr.v4.runtime.ParserRuleContext;
import org.antlr.v4.runtime.TokenStream;
import org.antlr.v4.runtime.misc.Interval;
Expand Down Expand Up @@ -59,6 +62,13 @@ public static String getTextPreservingWhitespace(ParserRuleContext ctx) {
return ctx.start.getTokenSource().getInputStream().getText(interval);
}

/**
* Get text from List of ParserRuleContext's CharStream without trimming whitespace
*/
public static String getTextPreservingWhitespace(List<? extends ParserRuleContext> ctx) {
return ctx.stream().map(Antlr4ParserStringUtils::getTextPreservingWhitespace).collect(Collectors.joining());
}

/**
* Get text from ParserRuleContext's CharStream without trimming whitespace
* tokenStream is required to get hidden channel token (e.g. whitespace).
Expand All @@ -78,4 +88,5 @@ public static String trimThen(String rhs) {
throw new DRLParserException("rhs has to start with 'then' : rhs = " + rhs);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,11 @@
import org.drools.drl.ast.descr.UnitDescr;
import org.drools.drl.ast.descr.WindowDeclarationDescr;

import static org.drools.drl.parser.antlr4.DRLParserHelper.getTextWithoutErrorNode;
import static org.drools.drl.parser.antlr4.Antlr4ParserStringUtils.getTextPreservingWhitespace;
import static org.drools.drl.parser.antlr4.Antlr4ParserStringUtils.getTokenTextPreservingWhitespace;
import static org.drools.drl.parser.antlr4.Antlr4ParserStringUtils.safeStripStringDelimiters;
import static org.drools.drl.parser.antlr4.Antlr4ParserStringUtils.trimThen;
import static org.drools.drl.parser.antlr4.DRLParserHelper.getTextWithoutErrorNode;
import static org.drools.drl.parser.util.ParserStringUtils.appendPrefix;
import static org.drools.util.StringUtils.unescapeJava;

Expand Down Expand Up @@ -193,7 +193,7 @@ public FunctionDescr visitFunctiondef(DRLParser.FunctiondefContext ctx) {
functionDescr.addParameter(typeTypeContext.getText(), variableDeclaratorIdContext.getText());
});
}
functionDescr.setBody(getTextPreservingWhitespace(ctx.block()));
functionDescr.setBody(getTextPreservingWhitespace(ctx.drlBlock().drlBlockStatement()));
return functionDescr;
}

Expand Down

0 comments on commit c0e2930

Please sign in to comment.