mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-25 09:55:29 +02:00
Bug: 331637 - ExpressionWriter & DeclaratorWriter do not support ICPPASTLambdaExpression patch by Pascal Kesseli
This commit is contained in:
parent
60281e5c58
commit
501fad33d6
4 changed files with 253 additions and 1 deletions
|
@ -48,6 +48,7 @@ public class AstWriterTestSuite{
|
|||
|
||||
suite.addTest(SourceRewriteTester.suite("CommentTests", "resources/rewrite/ASTWriterCommentedTestSource.awts"));
|
||||
suite.addTest(SourceRewriteTester.suite("NewCommentTests", "resources/rewrite/ASTWriterCommentedTestSource2.awts"));
|
||||
suite.addTestSuite(ExpressionWriterTest.class);
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,189 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2010 University of Applied Sciences Rapperswil (HSR).
|
||||
* All rights reserved. This program and the accompanying materials are made
|
||||
* available under the terms of the Eclipse Public License v1.0 which
|
||||
* accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors: Pascal Kesseli (HSR) - Initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.core.parser.tests.rewrite.astwriter;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCapture;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTCapture;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTCompoundStatement;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTDeclarator;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDeclarator;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTLambdaExpression;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTLiteralExpression;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTParameterDeclaration;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTReturnStatement;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclSpecifier;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTypeId;
|
||||
import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ASTWriterVisitor;
|
||||
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.NodeCommentMap;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
public class ExpressionWriterTest extends TestCase {
|
||||
private static final String BR = System.getProperty("line.separator");
|
||||
private static CPPASTSimpleDeclSpecifier INT = new CPPASTSimpleDeclSpecifier();
|
||||
private static IASTName NO_NAME = new CPPASTName(new char[] {});
|
||||
private NodeCommentMap commentMap = new NodeCommentMap();
|
||||
private ASTVisitor visitor;
|
||||
|
||||
static {
|
||||
INT.setType(CPPASTSimpleDeclSpecifier.t_int);
|
||||
}
|
||||
|
||||
@Override
|
||||
@Before
|
||||
protected void setUp() throws Exception {
|
||||
visitor = new ASTWriterVisitor(commentMap);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteLambdaExpressionEmptyIntroducerNoDeclarator() throws Exception {
|
||||
ICPPASTLambdaExpression lambda = getEmptyLambdaExpression();
|
||||
lambda.accept(visitor);
|
||||
String expected = "[] {" + BR + " return 7;" + BR + "}" + BR;
|
||||
Assert.assertEquals(expected, visitor.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteLambdaExpressionDefaultCaptureByCopyNoDeclarator() {
|
||||
ICPPASTLambdaExpression lambda = getEmptyLambdaExpression();
|
||||
lambda.setCaptureDefault(ICPPASTLambdaExpression.CaptureDefault.BY_COPY);
|
||||
lambda.accept(visitor);
|
||||
String expected = "[=] {" + BR + " return 7;" + BR + "}" + BR;
|
||||
Assert.assertEquals(expected, visitor.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteLambdaExpressionDefaultCaptureByReferenceNoDeclarator() {
|
||||
ICPPASTLambdaExpression lambda = getEmptyLambdaExpression();
|
||||
lambda.setCaptureDefault(ICPPASTLambdaExpression.CaptureDefault.BY_REFERENCE);
|
||||
lambda.accept(visitor);
|
||||
String expected = "[&] {" + BR + " return 7;" + BR + "}" + BR;
|
||||
Assert.assertEquals(expected, visitor.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteLambdaExpressionThisCaptureNoDeclarator() {
|
||||
ICPPASTLambdaExpression lambda = getEmptyLambdaExpression();
|
||||
lambda.addCapture(new CPPASTCapture());
|
||||
lambda.accept(visitor);
|
||||
String expected = "[this] {" + BR + " return 7;" + BR + "}" + BR;
|
||||
Assert.assertEquals(expected, visitor.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteLambdaExpressionMixedCaptureNoDeclarator() {
|
||||
ICPPASTLambdaExpression lambda = getEmptyLambdaExpression();
|
||||
lambda.setCaptureDefault(ICPPASTLambdaExpression.CaptureDefault.BY_COPY);
|
||||
lambda.addCapture(new CPPASTCapture());
|
||||
ICPPASTCapture x = new CPPASTCapture(), y = new CPPASTCapture();
|
||||
x.setIdentifier(new CPPASTName(new char[] { 'x' }));
|
||||
x.setIsByReference(true);
|
||||
y.setIdentifier(new CPPASTName(new char[] { 'y' }));
|
||||
lambda.addCapture(x);
|
||||
lambda.addCapture(y);
|
||||
lambda.accept(visitor);
|
||||
String r = "[=, this, &x, y] {" + BR + " return 7;" + BR + "}" + BR;
|
||||
Assert.assertEquals(r, visitor.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteLambdaExpressionEmptyIntroducerSimpleDeclarator() throws Exception {
|
||||
ICPPASTLambdaExpression lambda = getEmptyLambdaExpression();
|
||||
lambda.setDeclarator(getSimpleFunctionDeclarator());
|
||||
lambda.accept(visitor);
|
||||
String r = "[](int i, int j) {" + BR + " return 7;" + BR + "}" + BR;
|
||||
Assert.assertEquals(r, visitor.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteLambdaExpressionEmptyIntroducerMutableDeclarator() throws Exception {
|
||||
ICPPASTLambdaExpression lambda = getEmptyLambdaExpression();
|
||||
ICPPASTFunctionDeclarator f = getSimpleFunctionDeclarator();
|
||||
f.setMutable(true);
|
||||
lambda.setDeclarator(f);
|
||||
lambda.accept(visitor);
|
||||
String r = "[](int i, int j) mutable {" + BR + " return 7;" + BR + "}" + BR;
|
||||
Assert.assertEquals(r, visitor.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteLambdaExpressionEmptyIntroducerExceptionSpecificationDeclarator() throws Exception {
|
||||
ICPPASTLambdaExpression lambda = getEmptyLambdaExpression();
|
||||
ICPPASTFunctionDeclarator f = getSimpleFunctionDeclarator();
|
||||
f.addExceptionSpecificationTypeId(new CPPASTTypeId(INT, new CPPASTDeclarator(NO_NAME)));
|
||||
lambda.setDeclarator(f);
|
||||
lambda.accept(visitor);
|
||||
String r = "[](int i, int j) throw (int) {" + BR + " return 7;" + BR + "}" + BR;
|
||||
Assert.assertEquals(r, visitor.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteLambdaExpressionEmptyIntroducerTrailingReturnTypeDeclarator() throws Exception {
|
||||
ICPPASTLambdaExpression lambda = getEmptyLambdaExpression();
|
||||
ICPPASTFunctionDeclarator f = getSimpleFunctionDeclarator();
|
||||
f.setTrailingReturnType(new CPPASTTypeId(INT, new CPPASTDeclarator(NO_NAME)));
|
||||
lambda.setDeclarator(f);
|
||||
lambda.accept(visitor);
|
||||
String r = "[](int i, int j) -> int {" + BR + " return 7;" + BR + "}" + BR;
|
||||
Assert.assertEquals(r, visitor.toString());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testWriteAllEmbracingLambdaExpression() {
|
||||
ICPPASTLambdaExpression lambda = getEmptyLambdaExpression();
|
||||
ICPPASTFunctionDeclarator f = getSimpleFunctionDeclarator();
|
||||
lambda.setCaptureDefault(ICPPASTLambdaExpression.CaptureDefault.BY_REFERENCE);
|
||||
ICPPASTCapture x = new CPPASTCapture(), y = new CPPASTCapture();
|
||||
x.setIdentifier(new CPPASTName(new char[] { 'x' }));
|
||||
y.setIdentifier(new CPPASTName(new char[] { 'y' }));
|
||||
y.setIsByReference(true);
|
||||
lambda.addCapture(x);
|
||||
lambda.addCapture(y);
|
||||
lambda.addCapture(new CPPASTCapture());
|
||||
f.setMutable(true);
|
||||
f.setTrailingReturnType(new CPPASTTypeId(INT, new CPPASTDeclarator(NO_NAME)));
|
||||
f.addExceptionSpecificationTypeId(new CPPASTTypeId(INT, new CPPASTDeclarator(NO_NAME)));
|
||||
lambda.setDeclarator(f);
|
||||
lambda.accept(visitor);
|
||||
String r = "[&, x, &y, this](int i, int j) mutable throw (int) -> int {" + BR + " return 7;" + BR + "}" + BR;
|
||||
Assert.assertEquals(r, visitor.toString());
|
||||
}
|
||||
|
||||
private static ICPPASTFunctionDeclarator getSimpleFunctionDeclarator() {
|
||||
ICPPASTFunctionDeclarator f = new CPPASTFunctionDeclarator(new CPPASTName());
|
||||
IASTName name = new CPPASTName(new char[] { 'i' });
|
||||
IASTDeclarator d = new CPPASTDeclarator(name);
|
||||
f.addParameterDeclaration(new CPPASTParameterDeclaration(INT, d));
|
||||
name = new CPPASTName(new char[] { 'j' });
|
||||
d = new CPPASTDeclarator(name);
|
||||
f.addParameterDeclaration(new CPPASTParameterDeclaration(INT, d));
|
||||
return f;
|
||||
}
|
||||
|
||||
private static ICPPASTLambdaExpression getEmptyLambdaExpression() {
|
||||
ICPPASTLambdaExpression lambda = new CPPASTLambdaExpression();
|
||||
CPPASTCompoundStatement stmt = new CPPASTCompoundStatement();
|
||||
stmt.addStatement(new CPPASTReturnStatement(new CPPASTLiteralExpression(
|
||||
IASTLiteralExpression.lk_integer_constant,
|
||||
new char[] { '7' })));
|
||||
lambda.setBody(stmt);
|
||||
return lambda;
|
||||
}
|
||||
}
|
|
@ -49,6 +49,8 @@ public class DeclaratorWriter extends NodeWriter {
|
|||
private static final String AMPERSAND__AMPERSAND_SPACE = "&& "; //$NON-NLS-1$
|
||||
private static final String STAR_SPACE = "* "; //$NON-NLS-1$
|
||||
private static final String PURE_VIRTUAL = " =0"; //$NON-NLS-1$
|
||||
private static final String MUTABLE = "mutable"; //$NON-NLS-1$
|
||||
private static final String ARROW_OPERATOR = "->"; //$NON-NLS-1$
|
||||
|
||||
public DeclaratorWriter(Scribe scribe, ASTVisitor visitor, NodeCommentMap commentMap) {
|
||||
super(scribe, visitor, commentMap);
|
||||
|
@ -93,7 +95,10 @@ public class DeclaratorWriter extends NodeWriter {
|
|||
private void writeFunctionDeclarator(IASTStandardFunctionDeclarator funcDec) {
|
||||
IASTPointerOperator[] pointOps = funcDec.getPointerOperators();
|
||||
writePointerOperators(funcDec, pointOps);
|
||||
funcDec.getName().accept(visitor);
|
||||
// XXX: Lambda declarators happen to have null names rather than empty ones when parsed
|
||||
if (funcDec.getName() != null) {
|
||||
funcDec.getName().accept(visitor);
|
||||
}
|
||||
writeNestedDeclarator(funcDec);
|
||||
writeParameters(funcDec);
|
||||
writeInitializer(funcDec);
|
||||
|
@ -134,10 +139,20 @@ public class DeclaratorWriter extends NodeWriter {
|
|||
scribe.printSpace();
|
||||
scribe.print(VOLATILE);
|
||||
}
|
||||
if (funcDec.isMutable()) {
|
||||
scribe.printSpace();
|
||||
scribe.print(MUTABLE);
|
||||
}
|
||||
if(funcDec.isPureVirtual()) {
|
||||
scribe.print(PURE_VIRTUAL);
|
||||
}
|
||||
writeExceptionSpecification(funcDec, funcDec.getExceptionSpecification());
|
||||
if (funcDec.getTrailingReturnType() != null) {
|
||||
scribe.printSpace();
|
||||
scribe.print(ARROW_OPERATOR);
|
||||
scribe.printSpace();
|
||||
funcDec.getTrailingReturnType().accept(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
protected void writeExceptionSpecification(ICPPASTFunctionDeclarator funcDec, IASTTypeId[] exceptions) {
|
||||
|
|
|
@ -30,9 +30,11 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCapture;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCastExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeleteExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFieldReference;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLambdaExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeIdExpression;
|
||||
|
@ -112,6 +114,9 @@ public class ExpressionWriter extends NodeWriter{
|
|||
private static final String MODULO_OP = " % "; //$NON-NLS-1$
|
||||
private static final String DIVIDE_OP = " / "; //$NON-NLS-1$
|
||||
private static final String MULTIPLY_OP = " * "; //$NON-NLS-1$
|
||||
private static final String OPENING_SQUARE_BRACKET = "["; //$NON-NLS-1$
|
||||
private static final String CLOSING_SQUARE_BRACKET = "]"; //$NON-NLS-1$
|
||||
private static final String THIS = "this"; //$NON-NLS-1$
|
||||
private final MacroExpansionHandler macroHandler;
|
||||
|
||||
public ExpressionWriter(Scribe scribe, CPPASTVisitor visitor, MacroExpansionHandler macroHandler, NodeCommentMap commentMap) {
|
||||
|
@ -150,6 +155,8 @@ public class ExpressionWriter extends NodeWriter{
|
|||
writeDeleteExpression((ICPPASTDeleteExpression) expression);
|
||||
}else if (expression instanceof ICPPASTSimpleTypeConstructorExpression) {
|
||||
writeSimpleTypeConstructorExpression((ICPPASTSimpleTypeConstructorExpression) expression);
|
||||
} else if (expression instanceof ICPPASTLambdaExpression) {
|
||||
writeLambdaExpression((ICPPASTLambdaExpression) expression);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -525,5 +532,45 @@ public class ExpressionWriter extends NodeWriter{
|
|||
simpTypeCtorExp.getDeclSpecifier().accept(visitor);
|
||||
visitNodeIfNotNull(simpTypeCtorExp.getInitializer());
|
||||
}
|
||||
|
||||
private void writeLambdaExpression(ICPPASTLambdaExpression lambdaExpression) {
|
||||
writeLambdaIntroducer(lambdaExpression);
|
||||
if (lambdaExpression.getDeclarator() != null) {
|
||||
lambdaExpression.getDeclarator().accept(visitor);
|
||||
}
|
||||
scribe.printSpace();
|
||||
lambdaExpression.getBody().accept(visitor);
|
||||
}
|
||||
|
||||
private void writeLambdaIntroducer(ICPPASTLambdaExpression lambdaExpression) {
|
||||
scribe.print(OPENING_SQUARE_BRACKET);
|
||||
ICPPASTLambdaExpression.CaptureDefault captureDefault = lambdaExpression.getCaptureDefault();
|
||||
if (captureDefault.equals(ICPPASTLambdaExpression.CaptureDefault.BY_COPY)) {
|
||||
scribe.print('=');
|
||||
} else if (captureDefault.equals(ICPPASTLambdaExpression.CaptureDefault.BY_REFERENCE)) {
|
||||
scribe.print('&');
|
||||
}
|
||||
for (ICPPASTCapture capture : lambdaExpression.getCaptures()) {
|
||||
boolean isNotFirst = capture != lambdaExpression.getCaptures()[0];
|
||||
boolean hasDefaultCapture = captureDefault != ICPPASTLambdaExpression.CaptureDefault.UNSPECIFIED;
|
||||
if (isNotFirst || hasDefaultCapture) {
|
||||
scribe.print(COMMA_SPACE);
|
||||
}
|
||||
writeCapture(capture);
|
||||
}
|
||||
scribe.print(CLOSING_SQUARE_BRACKET);
|
||||
}
|
||||
|
||||
private void writeCapture(ICPPASTCapture capture) {
|
||||
if (capture.capturesThisPointer()) {
|
||||
scribe.print(THIS);
|
||||
} else {
|
||||
if (capture.isByReference()) {
|
||||
scribe.print(AMPERSAND_OP);
|
||||
}
|
||||
capture.getIdentifier().accept(visitor);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue