Skip to content

Commit

Permalink
Fixed parsing for expression ending with a parenthesis expression.
Browse files Browse the repository at this point in the history
  • Loading branch information
ylussaud committed Dec 14, 2023
1 parent 238f6f5 commit f401537
Show file tree
Hide file tree
Showing 38 changed files with 261 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
import org.eclipse.acceleo.VisibilityKind;
import org.eclipse.acceleo.aql.AcceleoUtil;
import org.eclipse.acceleo.query.AQLUtils;
import org.eclipse.acceleo.query.AQLUtils.AcceleoAQLResult;
import org.eclipse.acceleo.query.ast.ASTNode;
import org.eclipse.acceleo.query.parser.AstResult;
import org.eclipse.acceleo.query.parser.Positions;
Expand Down Expand Up @@ -2090,13 +2091,15 @@ protected ExpressionStatement parseExpressionStatement(boolean inlined) {
protected Expression parseExpression(int endLimit) {
final Expression res = AcceleoPackage.eINSTANCE.getAcceleoFactory().createExpression();

final AstResult astResult = parseWhileAqlExpression(text.substring(currentPosition, endLimit));
final AcceleoAQLResult acceleoAqlResult = parseWhileAqlExpression(text.substring(currentPosition,
endLimit));
final AstResult astResult = acceleoAqlResult.getAstResult();
final int startPosition = currentPosition;
res.setAst(astResult);
res.setAql(astResult.getAst());
final int endPosition = currentPosition + astResult.getEndPosition(astResult.getAst());
setPositions(res, startPosition, endPosition);
currentPosition = endPosition;
currentPosition = currentPosition + acceleoAqlResult.getEndPosition();
astResult.addAllPositonsTo(positions, startPosition, lines[startPosition], columns[startPosition]);

return res;
Expand Down Expand Up @@ -2335,9 +2338,9 @@ private TextStatement getNonEmptyLineNonEmptyTextTextStatement(int significantTe
*
* @param expression
* the expression to parse
* @return the corresponding {@link AstResult}
* @return the corresponding {@link AcceleoAQLResult}
*/
protected AstResult parseWhileAqlExpression(String expression) {
protected AcceleoAQLResult parseWhileAqlExpression(String expression) {
return AQLUtils.parseWhileAqlExpression(expression);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -636,7 +636,7 @@ private String getSignature(String serviceName, List<IType> argumentTypes) {
* @return the corresponding {@link AstResult}
*/
protected AstResult parseWhileAqlExpression(String expression) {
return AQLUtils.parseWhileAqlExpression(expression);
return AQLUtils.parseWhileAqlExpression(expression).getAstResult();
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import org.eclipse.acceleo.query.ast.ASTNode;
import org.eclipse.acceleo.query.ast.AstPackage;
import org.eclipse.acceleo.query.ast.ErrorTypeLiteral;
import org.eclipse.acceleo.query.ast.Expression;
import org.eclipse.acceleo.query.parser.AstBuilderListener;
import org.eclipse.acceleo.query.parser.AstResult;
import org.eclipse.acceleo.query.parser.AstSerializer;
Expand Down Expand Up @@ -73,6 +74,58 @@
*/
public final class AQLUtils {

/**
* Adds the parsing end position to the {@link AstResult}. This can be useful when an {@link Expression}
* ends with a parenthesis expression that has no node in the AST.
*
* @author <a href="mailto:yvan.lussaud@obeo.fr">Yvan Lussaud</a>
*/
public static class AcceleoAQLResult {

/**
* The {@link AstResult}.
*/
private final AstResult astResult;

/**
* The end position of the parsed expression.
*/
private final int endPosition;

/**
* Constructor.
*
* @param astResult
* the {@link AstResult}
* @param endPosition
* the end position of the parsed expression
*/
public AcceleoAQLResult(AstResult astResult, int endPosition) {
super();
this.astResult = astResult;
this.endPosition = endPosition;
}

/**
* Gets the {@link AstResult}.
*
* @return the {@link AstResult}
*/
public AstResult getAstResult() {
return astResult;
}

/**
* Gets the expression end position.
*
* @return the expression end position
*/
public int getEndPosition() {
return endPosition;
}

}

/**
* The {@link List} of {@link #registerServicesConfigurator(IServicesConfiguratorDescriptor) registered}
* {@link IServicesConfiguratorDescriptor}.
Expand Down Expand Up @@ -181,10 +234,10 @@ private static List<String> getEClassifiers(EPackage ePkg) {
*
* @param expression
* the expression to parse
* @return the corresponding {@link AstResult}
* @return the corresponding {@link AcceleoAQLResult}
*/
public static AstResult parseWhileAqlExpression(String expression) {
final AstResult result;
public static AcceleoAQLResult parseWhileAqlExpression(String expression) {
final AcceleoAQLResult result;

if (expression != null && expression.length() > 0) {
AstBuilderListener astBuilder = new AstBuilderListener();
Expand All @@ -200,7 +253,9 @@ public static AstResult parseWhileAqlExpression(String expression) {
parser.addErrorListener(astBuilder.getErrorListener());
// parser.setTrace(true);
parser.expression();
result = astBuilder.getAstResult();
result = new AcceleoAQLResult(astBuilder.getAstResult(), rewindWhiteSpaces(expression, parser
.getCurrentToken().getStartIndex()));

} else {
org.eclipse.acceleo.query.ast.ErrorExpression errorExpression = (org.eclipse.acceleo.query.ast.ErrorExpression)EcoreUtil
.create(AstPackage.eINSTANCE.getErrorExpression());
Expand All @@ -225,12 +280,41 @@ public static AstResult parseWhileAqlExpression(String expression) {
final BasicDiagnostic diagnostic = new BasicDiagnostic();
diagnostic.add(new BasicDiagnostic(Diagnostic.ERROR, AstBuilderListener.PLUGIN_ID, 0,
"missing expression", new Object[] {errorExpression }));
result = new AstResult(errorExpression, aqlPositions, aqlErrors, diagnostic);
result = new AcceleoAQLResult(new AstResult(errorExpression, aqlPositions, aqlErrors, diagnostic),
0);
}

return result;
}

/**
* Get the position after rewinding white spaces.
*
* @param text
* the input {@link String}
* @param position
* the current position
* @return the position after rewinding white spaces
*/
private static int rewindWhiteSpaces(String text, int position) {
final int res;
if (text != null && !text.isEmpty()) {
int index = position - 1;
if (Character.isWhitespace(text.charAt(index))) {
do {
index--;
} while (index >= 0 && Character.isWhitespace(text.charAt(index)));
res = index + 1;
} else {
res = position;
}
} else {
res = position;
}

return res;
}

/**
* Parses while matching an AQL expression.
*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

header position 0..59
module myModule
metamodel http://www.eclipse.org/emf/2002/Ecore (18..56)

public template myTemplate(myParam : EPackage (89..114))
[file url .add(.aqlFeatureAccess(myParam, 'name'), '.txt') (126..148) mode overwrite
some static text. (newLineNeeded) (167..185) (162..187)
[/file] (119..194)
(newLineNeeded) (194..195) (116..195)
[/template] (61..206) (0..206)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[module myModule('http://www.eclipse.org/emf/2002/Ecore')/]

[template public myTemplate(myParam : ecore::EPackage)]
[file ((myParam.name + '.txt'), overwrite)]
some static text.
[/file]
[/template]
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

header position 0..59
module myModule
metamodel http://www.eclipse.org/emf/2002/Ecore (18..56)

public template myTemplate(myParam : EPackage (89..114))
[for myVariable : EString = Sequence{'', '', '', } (155..176) (125..177)
some static text. (newLineNeeded) (184..202) (179..204)
[/for] (119..210)
(newLineNeeded) (210..211) (116..211)
[/template] (61..222) (0..222)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[module myModule('http://www.eclipse.org/emf/2002/Ecore')/]

[template public myTemplate(myParam : ecore::EPackage)]
[for (myVariable : ecore::EString | (Sequence{'', '', ''}))]
some static text.
[/for]
[/template]
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

header position 0..59
module myModule
metamodel http://www.eclipse.org/emf/2002/Ecore (18..56)

public template myTemplate(myParam : EPackage (89..114))
[if .equals(->size(.aqlFeatureAccess(myParam, 'eClassifiers')), 0) (124..157)
some static text. (newLineNeeded) (165..183) (160..185)
[/if] (119..190)
(newLineNeeded) (190..191) (116..191)
[/template] (61..202) (0..202)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[module myModule('http://www.eclipse.org/emf/2002/Ecore')/]

[template public myTemplate(myParam : ecore::EPackage)]
[if ((myParam.eClassifiers->size() = 0))]
some static text.
[/if]
[/template]
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

header position 0..59
module myModule
metamodel http://www.eclipse.org/emf/2002/Ecore (18..56)

public template myTemplate(myParam : EPackage (89..114))
[let
myVariable : EString = .aqlFeatureAccess(->first(.aqlFeatureAccess(myParam, 'eClassifiers')), 'name') (154..189) (124..190)
some static text. (newLineNeeded) (196..214) (191..216)
[/let] (119..222)
(newLineNeeded) (222..223) (116..223)
[/template] (61..234) (0..234)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[module myModule('http://www.eclipse.org/emf/2002/Ecore')/]

[template public myTemplate(myParam : ecore::EPackage)]
[let myVariable : ecore::EString = (myParam.eClassifiers->first().name)]
some static text.
[/let]
[/template]
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@

header position 0..59
module myModule
metamodel http://www.eclipse.org/emf/2002/Ecore (18..56)

public template myTemplate(myParam : EPackage (89..114))
[let
myVariable : EString = .add(->first(.aqlFeatureAccess(myParam, 'eClassifiers')), ')') (154..189) (124..189)
some static text. (newLineNeeded) (195..213) (190..215)
[/let] (119..221)
(newLineNeeded) (221..222) (116..222)
[/template] (61..233) (0..233)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[module myModule('http://www.eclipse.org/emf/2002/Ecore')/]

[template public myTemplate(myParam : ecore::EPackage)]
[let myVariable : ecore::EString = myParam.eClassifiers->first() + ')']
some static text.
[/let]
[/template]
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@

header position 0..59
module myModule
metamodel http://www.eclipse.org/emf/2002/Ecore (18..56)

public template myTemplate(myParam : EPackage (89..114))
[protected .add(.aqlFeatureAccess(myParam, 'name'), ')') (131..149)
some static text. (newLineNeeded) (156..174) (151..176)
[/protected] (119..188)
(newLineNeeded) (188..189) (116..189)
[/template] (61..200) (0..200)
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[module myModule('http://www.eclipse.org/emf/2002/Ecore')/]

[template public myTemplate(myParam : ecore::EPackage)]
[protected (myParam.name + ')')]
some static text.
[/protected]
[/template]
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@

header position 0..59
module myModule
metamodel http://www.eclipse.org/emf/2002/Ecore (18..56)
public query myQuery(myParam : EPackage (83..108)) ) : EClassifier ->first(.aqlFeatureAccess(myParam, 'eClassifiers')) (133..163)
/] (61..166) (0..166)
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[module myModule('http://www.eclipse.org/emf/2002/Ecore')/]

[query public myQuery(myParam : ecore::EPackage) : ecore::EClassifier = (myParam.eClassifiers->first())/]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[module myModule('http://www.eclipse.org/emf/2002/Ecore')/]

[template public myTemplate(myParam : ecore::EPackage)]
[file (myParam.name + '.txt', overwrite)]
some static text.
[/file]
[/template]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[module myModule('http://www.eclipse.org/emf/2002/Ecore')/]

[template public myTemplate(myParam : ecore::EPackage)]
[for (myVariable : ecore::EString | Sequence{'', '', ''})]
some static text.
[/for]
[/template]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[module myModule('http://www.eclipse.org/emf/2002/Ecore')/]

[template public myTemplate(myParam : ecore::EPackage)]
[if (myParam.eClassifiers->size() = 0)]
some static text.
[/if]
[/template]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[module myModule('http://www.eclipse.org/emf/2002/Ecore')/]

[template public myTemplate(myParam : ecore::EPackage)]
[let myVariable : ecore::EString = myParam.eClassifiers->first().name]
some static text.
[/let]
[/template]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[module myModule('http://www.eclipse.org/emf/2002/Ecore')/]

[template public myTemplate(myParam : ecore::EPackage)]
[let myVariable : ecore::EString = myParam.eClassifiers->first() + ')']
some static text.
[/let]
[/template]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[module myModule('http://www.eclipse.org/emf/2002/Ecore')/]

[template public myTemplate(myParam : ecore::EPackage)]
[protected (myParam.name + ')')]
some static text.
[/protected]
[/template]
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[module myModule('http://www.eclipse.org/emf/2002/Ecore')/]

[query public myQuery(myParam : ecore::EPackage) : ecore::EClassifier = myParam.eClassifiers->first()/]

0 comments on commit f401537

Please sign in to comment.