1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Create formatter junit tests

This commit is contained in:
Anton Leherbauer 2006-12-04 16:17:24 +00:00
parent b9f960d0c8
commit b9391d98b1
12 changed files with 609 additions and 39 deletions

View file

@ -80,6 +80,7 @@ import org.eclipse.cdt.core.dom.ast.c.ICASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.c.ICASTPointer;
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTForStatement;
@ -88,8 +89,11 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionTryBlockDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceAlias;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTReferenceOperator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
@ -244,6 +248,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
IASTDeclaration declaration = decls[i];
try {
declaration.accept(this);
scribe.printNewLine();
} catch (ASTProblemException e) {
if (i < decls.length - 1) {
exitAlignments();
@ -291,12 +296,12 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
// return visit((ICPPASTUsingDirective)declaration);
} else if (node instanceof ICPPASTLinkageSpecification) {
return visit((ICPPASTLinkageSpecification)node);
} else if (node instanceof ICPPASTTemplateDeclaration) {
return visit((ICPPASTTemplateDeclaration)node);
} else if (node instanceof ICPPASTTemplateSpecialization) {
formatNode(node);
// return visit((ICPPASTTemplateSpecialization)declaration);
return visit((ICPPASTTemplateSpecialization)node);
} else if (node instanceof ICPPASTExplicitTemplateInstantiation) {
formatNode(node);
// return visit((ICPPASTExplicitTemplateInstantiation)declaration);
return visit((ICPPASTExplicitTemplateInstantiation)node);
} else if (node instanceof IASTProblemDeclaration) {
return visit((IASTProblemDeclaration)node);
} else {
@ -327,6 +332,8 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
} else
if (node instanceof ICPPASTQualifiedName) {
visit((ICPPASTQualifiedName)node);
} else if (node instanceof ICPPASTTemplateId) {
visit((ICPPASTTemplateId)node);
} else {
formatNode(node);
}
@ -365,9 +372,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
skipNode(node);
return PROCESS_SKIP;
} else if (node instanceof ICPPASTFunctionDeclarator) {
visit((IASTStandardFunctionDeclarator)node);
skipNode(node);
return PROCESS_SKIP;
return visit((ICPPASTFunctionDeclarator)node);
} else if (node instanceof IASTStandardFunctionDeclarator) {
visit((IASTStandardFunctionDeclarator)node);
} else if (node instanceof ICASTKnRFunctionDeclarator) {
@ -621,6 +626,22 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
return PROCESS_SKIP;
}
private int visit(ICPPASTConstructorChainInitializer node) {
final IASTName member= node.getMemberInitializerId();
if (member!= null) {
member.accept(this);
scribe.printNextToken(Token.tLPAREN, false);
final IASTExpression value= node.getInitializerValue();
if (value != null) {
value.accept(this);
}
scribe.printNextToken(Token.tRPAREN, false);
} else {
formatNode(node);
}
return PROCESS_SKIP;
}
private int visit(IASTFunctionDefinition node) {
scribe.printComment();
final int line= scribe.line;
@ -648,26 +669,32 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
return PROCESS_SKIP;
}
private int visit(ICPPASTFunctionDeclarator node) {
visit((IASTStandardFunctionDeclarator)node);
final ICPPASTConstructorChainInitializer[] constructorChain= node.getConstructorChain();
if (constructorChain != null && constructorChain.length > 0) {
scribe.printNextToken(Token.tCOLON, true);
// TODO need special constructor chain alignment
scribe.printNewLine();
scribe.indent();
final ListAlignment align= new ListAlignment(Alignment.M_COMPACT_SPLIT);
formatList(Arrays.asList(constructorChain), align, false, false);
scribe.unIndent();
}
// skip const, throw, etc.
skipNode(node);
return PROCESS_SKIP;
}
private int visit(IASTStandardFunctionDeclarator node) {
scribe.printComment();
IASTPointerOperator[] pointers= node.getPointerOperators();
if (pointers.length > 0) {
for (int i = 0; i < pointers.length; i++) {
IASTPointerOperator pointer= pointers[i];
if (pointer instanceof ICPPASTReferenceOperator) {
scribe.printNextToken(Token.tAMPER, false);
} else if (pointer instanceof ICASTPointer) {
scribe.printNextToken(Token.tSTAR, false);
} else {
formatNode(pointer);
}
}
}
formatPointers(node.getPointerOperators());
IASTName name= node.getName();
if (name != null) {
name.accept(this);
}
IASTDeclarator nestedDecl= node.getNestedDeclarator();
if (nestedDecl != null) {
scribe.printNextToken(Token.tLPAREN, false);
@ -686,24 +713,36 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
return PROCESS_SKIP;
}
private void formatPointers(IASTPointerOperator[] pointers) {
for (int i = 0; i < pointers.length; i++) {
IASTPointerOperator pointer= pointers[i];
scribe.printModifiers();
if (pointer instanceof ICPPASTReferenceOperator) {
scribe.printNextToken(Token.tAMPER, false);
} else if (pointer instanceof ICASTPointer) {
scribe.printNextToken(Token.tSTAR, false);
} else if (pointer instanceof ICPPASTPointerToMember) {
final ICPPASTPointerToMember ptrToMember= (ICPPASTPointerToMember)pointer;
final IASTName name= ptrToMember.getName();
if (name != null) {
name.accept(this);
}
scribe.printNextToken(Token.tSTAR, false);
} else {
skipNode(pointer);
}
}
}
private int visit(ICASTKnRFunctionDeclarator node) {
scribe.printComment();
IASTPointerOperator[] pointers= node.getPointerOperators();
if (pointers.length > 0) {
for (int i = 0; i < pointers.length; i++) {
IASTPointerOperator pointer= pointers[i];
if (pointer instanceof ICASTPointer) {
scribe.printNextToken(Token.tSTAR, false);
} else {
assert false : "Unhandled pointer operator";
}
}
}
formatPointers(node.getPointerOperators());
IASTName name= node.getName();
if (name != null) {
name.accept(this);
}
IASTDeclarator nestedDecl= node.getNestedDeclarator();
if (nestedDecl != null) {
scribe.printNextToken(Token.tLPAREN, false);
@ -748,6 +787,30 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
return PROCESS_SKIP;
}
private int visit(ICPPASTTemplateDeclaration node) {
scribe.printNextToken(Token.t_template, false);
scribe.printNextToken(Token.tLT, false);
final ICPPASTTemplateParameter[] templateParameters= node.getTemplateParameters();
if (templateParameters.length > 0) {
final ListAlignment align= new ListAlignment(Alignment.M_COMPACT_SPLIT);
formatList(Arrays.asList(templateParameters), align, false, false);
}
scribe.printNextToken(Token.tGT, false);
scribe.space();
node.getDeclaration().accept(this);
return PROCESS_SKIP;
}
private int visit(ICPPASTTemplateSpecialization node) {
node.getDeclaration().accept(this);
return PROCESS_SKIP;
}
private int visit(ICPPASTExplicitTemplateInstantiation node) {
node.getDeclaration().accept(this);
return PROCESS_SKIP;
}
private int visit(IASTSimpleDeclSpecifier node) {
formatNode(node);
scribe.space();
@ -954,7 +1017,13 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
if (i > 0 && align.fSpaceAfterComma) {
scribe.space();
}
((IASTNode) elements.get(i)).accept(this);
final IASTNode node= (IASTNode) elements.get(i);
if (node instanceof ICPPASTConstructorChainInitializer) {
// this is a special case
visit((ICPPASTConstructorChainInitializer)node);
} else {
node.accept(this);
}
}
if (addEllipsis) {
if (i > 0) {
@ -1271,7 +1340,7 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
private int visit(ICPPASTQualifiedName node) {
IASTName[] names= node.getNames();
for (int i = 0; i < names.length-1; i++) {
scribe.printNextToken(Token.tIDENTIFIER, false);
names[i].accept(this);
scribe.printNextToken(Token.tCOLONCOLON);
}
if (peekNextToken() == Token.tCOMPL) {
@ -1282,6 +1351,19 @@ public class CodeFormatterVisitor extends CPPASTVisitor {
return PROCESS_SKIP;
}
private int visit(ICPPASTTemplateId node) {
IASTName name= node.getTemplateName();
name.accept(this);
scribe.printNextToken(Token.tLT, false);
final IASTNode[] templateArguments= node.getTemplateArguments();
if (templateArguments.length > 0) {
final ListAlignment align= new ListAlignment(Alignment.M_COMPACT_SPLIT);
formatList(Arrays.asList(templateArguments), align, false, false);
}
scribe.printNextToken(Token.tGT, false);
return PROCESS_SKIP;
}
private int visit(IASTReturnStatement node) {
scribe.printNextToken(Token.t_return);
final IASTExpression expression = node.getReturnValue();

View file

@ -1529,7 +1529,6 @@ public class Scribe {
/**
*/
public void printModifiers() {
int modifiersIndex= 0;
boolean isFirstModifier= true;
int currentTokenStartPosition= scanner.getCurrentPosition();
boolean hasComment= false;
@ -1541,16 +1540,18 @@ public class Scribe {
case Token.t_auto:
case Token.t_register:
case Token.t_const:
case Token.t_signed:
case Token.t_unsigned:
case Token.t_volatile:
case Token.t_virtual:
case Token.t_mutable:
case Token.t_explicit:
case Token.t_friend:
case Token.t_inline:
case Token.t_restrict:
print(currentToken.getLength(), !isFirstModifier);
isFirstModifier= false;
currentTokenStartPosition= scanner.getCurrentPosition();
modifiersIndex++;
break;
case Token.tBLOCKCOMMENT:
printBlockComment(false);

View file

@ -0,0 +1,26 @@
/* This is sample code to test the formatter */
class Complex {
private:
float re;
float im;
public:
Complex(float re, float im) :
re(re), im(im) {
}
float GetRe() {
return re;
}
float GetIm() {
return im;
}
void Set(float r, float i);
/* Set real part */
void SetRe(float r);
/*
* Set imaginary part
*/
void SetIm(float i);
void Print();
};

View file

@ -0,0 +1,24 @@
/* This is sample code to test the formatter */
class Complex {
private :
float re ; float im;
public:
Complex(float re, float im) :
re(re), im(im) {}
float GetRe() { return re;}
float GetIm() {
return im;
}
void Set(float r, float i);
/* Set real part */
void SetRe(float r) ;
/*
* Set imaginary part
*/
void SetIm(float i);void Print();
};

View file

@ -0,0 +1,43 @@
/*
* Indentation
*/
#include <math.h>
class Point {
public:
Point(double xc, double yc) :
x(xc), y(yc) {
}
double distance(const Point& other) const;
int compareX(const Point& other) const;
double x;
double y;
};
double Point::distance(const Point& other) const {
double dx = x - other.x;
double dy = y - other.y;
return sqrt(dx * dx + dy * dy);
}
int Point::compareX(const Point& other) const {
if (x < other.x) {
return -1;
} else if (x > other.x) {
return 1;
} else {
return 0;
}
}
namespace FOO {
int foo(int bar) const {
switch (bar) {
case 0:
++bar;
break;
case 1:
--bar;
default: {
bar += bar;
break;
}
}
}
} // end namespace FOO

View file

@ -0,0 +1,5 @@
/*
* Indentation
*/
#include <math.h>
class Point {public:Point(double xc, double yc) : x(xc), y(yc) {}double distance(const Point& other) const;int compareX(const Point& other) const;double x;double y;};double Point::distance(const Point& other) const {double dx = x - other.x;double dy = y - other.y;return sqrt(dx * dx + dy * dy);}int Point::compareX(const Point& other) const {if (x < other.x) {return -1;} else if (x > other.x) {return 1;} else {return 0;}}namespace FOO {int foo(int bar) const {switch (bar) {case 0:++bar;break;case 1:--bar;default: {bar += bar;break;}}}} // end namespace FOO

View file

@ -0,0 +1,55 @@
#include <Simple.h>
const SimpleStruct simpleStruct =
{
1
, "mySimple"
, 0.1232
};
#define SIZEOF( A, B ) sizeof( A.B )
#define FOREVER \
for(;;)\
{\
\
}
const OtherStruct array[] =
{
{
#if FOO
"foo"
# else
"bar"
#endif
, SIZEOF( simpleStruct, num )
, &t_int
, 0
}
, {
"name"
, SIZEOF( simpleStruct, floatnum )
, &t_float
, 1
}
};
// single line outside scope
void SimpleStruct_construct(
struct SimpleStruct * const this )
{
// single line
this->num = 1;
this->name = "boo";
this->floatNum = 1.5;
}
int ConnectParams_doSomething(const struct SimpleStruct * const this )
{
/*
* multiline
*/
return 1;
}

View file

@ -0,0 +1,55 @@
#include <Simple.h>
const SimpleStruct simpleStruct =
{
1
, "mySimple"
, 0.1232
};
#define SIZEOF( A, B ) sizeof( A.B )
#define FOREVER \
for(;;)\
{\
\
}
const OtherStruct array[] =
{
{
#if FOO
"foo"
# else
"bar"
#endif
, SIZEOF( simpleStruct, num )
, &t_int
, 0
}
, {
"name"
, SIZEOF( simpleStruct, floatnum )
, &t_float
, 1
}
};
// single line outside scope
void SimpleStruct_construct(
struct SimpleStruct * const this )
{
// single line
this->num = 1;
this->name = "boo";
this->floatNum = 1.5;
}
int ConnectParams_doSomething( const struct SimpleStruct * const this )
{
/*
* multiline
*/
return 1;
}

View file

@ -0,0 +1,74 @@
class Key;
class Value;
class SortAlgorithm;
class DefaultSort;
class T;
class X;
class Y;
class Bar;
class Foo {
template<class Bar> void fum(int i);
};
// TEMPLATE_STRUCT
template<class Key, class Value, class SortAlgorithm=DefaultSort> struct Map {
Key * keys;
Value * values;
SortAlgorithm * sortAlgorithm;
Map();
};
// TEMPLATE_CLASS
template<class T> class nonVector {
private:
T * head;
public:
nonVector() {
head =new T();
}
int length() {
return 1;
}
const T &first() const;
};
// TEMPLATE_UNION
template<class X, class Y, int size=16> union ArrayOverlay {
public:
X x[size];
Y y[size];
static int numArrays;
};
// TEMPLATE_METHODS
class TemplateContainer {
// these are in an enclosing class
template<class Bar> void fum(int i);
template<int> void scrum(void) {
}
;
};
// TEMPLATE_FUNCTION
template<class T> const T &nonVector<T>::first() const {
return *head;
}
template<class X> bool IsGreaterThan(X, X);
template<class Bar> void Foo::fum(int i) {
}
// TEMPLATE_VARIABLES
template<bool threads, int inst> char
* default_alloc_template<threads, inst>::S_start_free = 0;
// an instantiation, not a template:
complex
<float> cf(0,0);
//template<class Language, class CharacterSet, class SortAlgorithm<CharacterSet> >
//Dictionary* TheSpellCheckDictionary;
int success;

View file

@ -0,0 +1,70 @@
class Key;
class Value;
class SortAlgorithm;
class DefaultSort;
class T;
class X;
class Y;
class Bar;
class Foo {
template<class Bar> void fum(int i);
};
// TEMPLATE_STRUCT
template<class Key, class Value, class SortAlgorithm=DefaultSort>
struct Map
{
Key* keys;
Value* values;
SortAlgorithm* sortAlgorithm;
Map();
};
// TEMPLATE_CLASS
template<class T> class nonVector {
private: T* head;
public:
nonVector() {head =new T();}
int length() {return 1;}
const T& first() const;
};
// TEMPLATE_UNION
template<class X, class Y, int size=16>
union ArrayOverlay {
public:
X x[size]; Y y[size];
static int numArrays;
};
// TEMPLATE_METHODS
class TemplateContainer {
// these are in an enclosing class
template<class Bar> void fum(int i);
template<int>
void scrum(void) {}
;
};
// TEMPLATE_FUNCTION
template<class T> const T& nonVector<T>::first() const
{
return *head;
}
template<class X> bool IsGreaterThan(X,X);
template<class Bar> void Foo::fum(int i) {}
// TEMPLATE_VARIABLES
template <bool threads, int inst> char* default_alloc_template<threads, inst>::S_start_free = 0;
// an instantiation, not a template:
complex
<float> cf(0,0);
//template<class Language, class CharacterSet, class SortAlgorithm<CharacterSet> >
//Dictionary* TheSpellCheckDictionary;
int success;

View file

@ -0,0 +1,134 @@
/*******************************************************************************
* Copyright (c) 2005, 2006 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
* Anton Leherbauer (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.ui.tests.text;
import java.util.ListResourceBundle;
import junit.extensions.TestSetup;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
import org.eclipse.jface.action.IAction;
import org.eclipse.jface.text.IDocument;
import org.eclipse.jface.text.source.SourceViewer;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.formatter.DefaultCodeFormatterConstants;
import org.eclipse.cdt.core.model.ICProject;
import org.eclipse.cdt.core.testplugin.CProjectHelper;
import org.eclipse.cdt.internal.ui.editor.CEditor;
/**
* Test the Formatter.
*/
public class FormatActionTest extends TestCase {
private static final String PROJECT= "FormatTests";
private static final class EmptyBundle extends ListResourceBundle {
protected Object[][] getContents() {
return new Object[0][];
}
}
protected static class IndentTestSetup extends TestSetup {
private ICProject fCProject;
public IndentTestSetup(Test test) {
super(test);
}
protected void setUp() throws Exception {
super.setUp();
fCProject= EditorTestHelper.createCProject(PROJECT, "resources/formatter");
fCProject.setOption(DefaultCodeFormatterConstants.FORMATTER_TAB_CHAR, CCorePlugin.TAB);
}
protected void tearDown () throws Exception {
if (fCProject != null)
CProjectHelper.delete(fCProject);
super.tearDown();
}
}
private static final Class THIS= FormatActionTest.class;
public static Test suite() {
return new IndentTestSetup(new TestSuite(THIS));
}
private CEditor fEditor;
private SourceViewer fSourceViewer;
private IDocument fDocument;
/*
* @see junit.framework.TestCase#setUp()
*/
protected void setUp() throws Exception {
String filename= createFileName("Before");
fEditor= (CEditor) EditorTestHelper.openInEditor(ResourceTestHelper.findFile(filename), true);
fSourceViewer= EditorTestHelper.getSourceViewer(fEditor);
fDocument= fSourceViewer.getDocument();
}
/*
* @see junit.framework.TestCase#tearDown()
*/
protected void tearDown() throws Exception {
EditorTestHelper.closeEditor(fEditor);
}
private void assertFormatResult() throws Exception {
String afterFile= createFileName("After");
String expected= ResourceTestHelper.read(afterFile).toString();
IAction formatAction= fEditor.getAction("Format");
assertNotNull("No format action", formatAction);
formatAction.run();
assertEquals(expected, fDocument.get());
}
private String createFileName(String qualifier) {
String name= getName();
name= name.substring(4, 5).toLowerCase() + name.substring(5);
return "/" + PROJECT + "/src/" + name + "/" + qualifier + ".cpp";
}
private void selectAll() {
fSourceViewer.setSelectedRange(0, fDocument.getLength());
}
public void testTemplates() throws Exception {
selectAll();
assertFormatResult();
}
public void testPreview() throws Exception {
selectAll();
assertFormatResult();
}
public void testSample() throws Exception {
selectAll();
assertFormatResult();
}
public void testComplex() throws Exception {
selectAll();
assertFormatResult();
}
}

View file

@ -31,6 +31,7 @@ public class TextTestSuite extends TestSuite {
addTest(CHeuristicScannerTest.suite());
addTest(BracketInserterTest.suite());
addTest(IndentActionTest.suite());
addTest(FormatActionTest.suite());
// Break iterator tests.
addTest(CBreakIteratorTest.suite());