Update of /cvsroot/cpptool/rfta/src/rftaparser
In directory sc8-pr-cvs1:/tmp/cvs-serv19772/src/rftaparser
Modified Files:
rftaparser.dsp
Added Files:
ExpressionOperationMutatorTest.h
ExpressionOperationMutatorTest.cpp
ExpressionOperationMutator.cpp
Log Message:
-- extended expression parsing with new ExpressionOperationMutator
--- NEW FILE: ExpressionOperationMutatorTest.h ---
// //////////////////////////////////////////////////////////////////////////
// (c)Copyright 2002, Baptiste Lepilleur.
// Created: 2002/12/27
// //////////////////////////////////////////////////////////////////////////
#ifndef RFTA_EXPRESSIONOPERATIONMUTATORTEST_H
#define RFTA_EXPRESSIONOPERATIONMUTATORTEST_H
#include "UnitTesting.h"
namespace Refactoring
{
/// Unit tests for ExpressionOperationMutatorTest
class ExpressionOperationMutatorTest : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE( ExpressionOperationMutatorTest );
CPPUNIT_TEST( testSplitToAssignment );
CPPUNIT_TEST( testSplitToExpressionList );
CPPUNIT_TEST_SUITE_END();
public:
/*! Constructs a ExpressionOperationMutatorTest object.
*/
ExpressionOperationMutatorTest();
/// Destructor.
virtual ~ExpressionOperationMutatorTest();
void setUp();
void tearDown();
void testSplitToAssignment();
void testSplitToExpressionList();
private:
/// Prevents the use of the copy constructor.
ExpressionOperationMutatorTest( const ExpressionOperationMutatorTest &other );
/// Prevents the use of the copy operator.
void operator =( const ExpressionOperationMutatorTest &other );
private:
};
// Inlines methods for ExpressionOperationMutatorTest:
// ---------------------------------------------------
} // namespace Refactoring
#endif // RFTA_EXPRESSIONOPERATIONMUTATORTEST_H
--- NEW FILE: ExpressionOperationMutatorTest.cpp ---
// //////////////////////////////////////////////////////////////////////////
// (c)Copyright 2002, Baptiste Lepilleur.
// Created: 2002/12/27
// //////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ExpressionOperationMutatorTest.h"
#include "ParserTesting.h"
#include <rfta/parser/ASTNode.h>
#include <rfta/parser/ASTNodes.h>
#include <rfta/parser/ParseContext.h>
#include <rfta/parser/SourceASTNode.h>
#include <rfta/parser/ExpressionOperationMutator.h>
namespace Refactoring
{
CPPUNIT_TEST_SUITE_REGISTRATION( ExpressionOperationMutatorTest );
ExpressionOperationMutatorTest::ExpressionOperationMutatorTest()
{
}
ExpressionOperationMutatorTest::~ExpressionOperationMutatorTest()
{
}
void
ExpressionOperationMutatorTest::setUp()
{
}
void
ExpressionOperationMutatorTest::tearDown()
{
}
namespace Testing {
static SourceASTNodePtr createAST( const std::string &expression,
const CppUnit::SourceLine &sourceLine )
{
SourceASTNodePtr sourceNode = SourceASTNode::create( expression, expression );
ParseContext context( sourceNode );
ASTNodePtr expressionNode = ASTNode::create( ASTNodeTypes::unparsedExpressionStatement,
sourceNode,
0, expression.length(),
sourceNode );
sourceNode->addChild( expressionNode );
ExpressionOperationMutator mutator(context,expressionNode, sourceNode);
mutator.mutate();
return sourceNode;
}
}
void
ExpressionOperationMutatorTest::testSplitToAssignment()
{
SourceASTNodePtr sourceAST = Testing::createAST("a=10",CPPUNIT_SOURCELINE() );
ASTNodePtr expr = sourceAST->getChildAt(0);
// check existence of expression-type-property
if (!expr->hasProperty(ASTNodeProperties::expressionTypeProperty))
{
CppUnit::Asserter::fail( CppUnit::Message( "Expected an expression type property." ), CPPUNIT_SOURCELINE() );
return;
}
// check property contents:
ASTNodePtr typeProperty = expr->getProperty(ASTNodeProperties::expressionTypeProperty);
if ( typeProperty->getType() != ASTNodeTypes::assignmentExpression )
{
CppUnit::Asserter::fail( CppUnit::Message( "Expected an assignment expression on top level." ), CPPUNIT_SOURCELINE() );
return;
}
// check left and right side of the expression
ASTNodePtr left = expr->getChildAt(0);
ASTNodePtr right = expr->getChildAt(1);
if (! (left->getRange() == SourceRange(0,1)) )
CPPUNIT_FAIL("Wrong range on left side");
if (! (right->getRange() == SourceRange(2,2)) )
CPPUNIT_FAIL("Wrong range on right side");
}
void
ExpressionOperationMutatorTest::testSplitToExpressionList()
{
SourceASTNodePtr sourceAST = Testing::createAST("a=10,i=2",CPPUNIT_SOURCELINE() );
ASTNodePtr expr = sourceAST->getChildAt(0);
if (!expr->hasProperty(ASTNodeProperties::expressionTypeProperty))
{
CppUnit::Asserter::fail( CppUnit::Message( "Expected an expression type property." ), CPPUNIT_SOURCELINE() );
return;
}
ASTNodePtr typeProperty = expr->getProperty(ASTNodeProperties::expressionTypeProperty);
if ( typeProperty->getType() != ASTNodeTypes::expressionList )
{
CppUnit::Asserter::fail( CppUnit::Message( "Expected an expression list on top level." ), CPPUNIT_SOURCELINE() );
return;
}
// check left and right side of the expression
RFTA_ASSERT_NODE_HAS(expr->getChildAt(0),
ASTNodeTypes::expression,
0,
4 );
RFTA_ASSERT_NODE_HAS(expr->getChildAt(1),
ASTNodeTypes::expression,
5,
3 );
}
} // namespace Refactoring
--- NEW FILE: ExpressionOperationMutator.cpp ---
// //////////////////////////////////////////////////////////////////////////
// (c)Copyright 2002, Andre Baresel.
// Created: 2002/12/27
// //////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <rfta/parser/ExpressionOperationMutator.h>
#include <rfta/parser/ASTNodes.h>
namespace Refactoring
{
ExpressionOperationMutator::ExpressionOperationMutator( ParseContext &context,
const ASTNodePtr &node,
const SourceASTNodePtr &sourceNode)
: ExpressionMutator( context, node, sourceNode )
, sourceNode_ ( sourceNode )
{
}
ExpressionOperationMutator::~ExpressionOperationMutator()
{
}
void
ExpressionOperationMutator::mutate()
{
ExpressionMutator::Tokens tokens;
parseTokens(tokens);
splitExpressionList(tokens);
}
void ExpressionOperationMutator::skipBalancedBraces(ExpressionMutator::Tokens::iterator& i,
ExpressionMutator::Tokens& token) const
{
int cntOpen=1;
i++;
// skip until balanced close brace:
while (i!=token.end() && cntOpen>0)
{
if ((*i).type_ == ExpressionMutator::openBrace)
{
cntOpen++;i++;
} else if ((*i).type_ == ExpressionMutator::closeBrace)
{
cntOpen--;
} else
i++;
}
}
void ExpressionOperationMutator::splitExpressionList(ExpressionMutator::Tokens token) const
{
bool exprListDetectedBefore = false;
// find first ',' or '('
ExpressionMutator::Tokens::iterator i = token.begin();
while (i!=token.end())
{
if ((*i).type_ == ExpressionMutator::openBrace)
{
skipBalancedBraces(i,token);
}
if ((*i).type_ == ExpressionMutator::comma)
{
// collect a expression-list element:
if (!exprListDetectedBefore)
{
exprListDetectedBefore = true;
// add a property marking this expression as expression-list
int OpStart = (*i).start_ - sourceNode_->getBlankedSourceStart();
ASTNodePtr property = createASTNode(ASTNodeTypes::expressionList,node_,OpStart,1);
node_->setPropertyNode(ASTNodeProperties::expressionTypeProperty,property);
}
}
i++;
}
// check if a comma was found:
if (i!=token.end())
{
// split assignment at this iterator position:
// stop here - further mutation can be done by request.
return;
}
// we didn't found an expression list so check for assignment expression:
splitAssignmentExpression(token);
}
void ExpressionOperationMutator::splitAssignmentExpression(ExpressionMutator::Tokens token) const
{
ExpressionMutator::Tokens::iterator i = token.begin();
while (i!=token.end())
{
if ((*i).type_ == ExpressionMutator::assign ||
(*i).type_ == ExpressionMutator::mulAssign ||
(*i).type_ == ExpressionMutator::divAssign ||
(*i).type_ == ExpressionMutator::modAssign ||
(*i).type_ == ExpressionMutator::plusAssign ||
(*i).type_ == ExpressionMutator::minusAssign ||
(*i).type_ == ExpressionMutator::rshiftAssign ||
(*i).type_ == ExpressionMutator::lshiftAssign ||
(*i).type_ == ExpressionMutator::andAssign ||
(*i).type_ == ExpressionMutator::xorAssign ||
(*i).type_ == ExpressionMutator::orAssign)
break; // expression needs to be splitted here
if ((*i).type_ == ExpressionMutator::questMark)
{
splitConditionalExpression(token);
return;
}
if ((*i).type_ == ExpressionMutator::openBrace)
{
skipBalancedBraces(i,token);
}
i++;
}
// check if an assignment operation was found:
if (i!=token.end())
{
// split assignment at this iterator position:
int exprStart = node_->getRange().getStartIndex();
int exprEnd = node_->getRange().getEndIndex();
int asngOpStart = (*i).start_ - sourceNode_->getBlankedSourceStart();
int asngOpEnd = (*i).end_ - sourceNode_->getBlankedSourceStart();
ASTNodePtr property = createASTNode(ASTNodeTypes::assignmentExpression,node_,asngOpStart,asngOpEnd-asngOpStart);
node_->setPropertyNode(ASTNodeProperties::expressionTypeProperty,property);
ASTNodePtr leftOperand = createASTNode(ASTNodeTypes::expression,node_,exprStart, asngOpStart - exprStart);
ASTNodePtr rightOperand = createASTNode(ASTNodeTypes::expression,node_,asngOpEnd, exprEnd - asngOpEnd);
node_->addChild(leftOperand);
node_->addChild(rightOperand);
return;
}
}
void ExpressionOperationMutator::splitConditionalExpression(ExpressionMutator::Tokens token) const
{
// not yet implemented
return;
}
} // namespace Refactoring
Index: rftaparser.dsp
===================================================================
RCS file: /cvsroot/cpptool/rfta/src/rftaparser/rftaparser.dsp,v
retrieving revision 1.25
retrieving revision 1.26
diff -C2 -d -r1.25 -r1.26
*** rftaparser.dsp 22 Dec 2002 16:03:53 -0000 1.25
--- rftaparser.dsp 28 Dec 2002 10:37:57 -0000 1.26
***************
*** 56,61 ****
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\build\rftaparser\Release/rftaparser_mdr.ext" /libpath:"../../deplib/cppunit/lib"
# Begin Special Build Tool
! TargetDir=\prg\vc\Rfta\build\rftaparser\Release
! TargetPath=\prg\vc\Rfta\build\rftaparser\Release\rftaparser_mdr.ext
TargetName=rftaparser_mdr
SOURCE="$(InputPath)"
--- 56,61 ----
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /dll /machine:I386 /out:"..\..\build\rftaparser\Release/rftaparser_mdr.ext" /libpath:"../../deplib/cppunit/lib"
# Begin Special Build Tool
! TargetDir=\Projects\Cpptool\rfta\build\rftaparser\Release
! TargetPath=\Projects\Cpptool\rfta\build\rftaparser\Release\rftaparser_mdr.ext
TargetName=rftaparser_mdr
SOURCE="$(InputPath)"
***************
*** 90,95 ****
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib cppunitd_dll.lib /nologo /dll /debug /machine:I386 /out:"..\..\build\rftaparser\Debug/rftaparser_mdd.ext" /pdbtype:sept /libpath:"../../deplib/cppunit/lib"
# Begin Special Build Tool
! TargetDir=\prg\vc\Rfta\build\rftaparser\Debug
! TargetPath=\prg\vc\Rfta\build\rftaparser\Debug\rftaparser_mdd.ext
TargetName=rftaparser_mdd
SOURCE="$(InputPath)"
--- 90,95 ----
# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib cppunitd_dll.lib /nologo /dll /debug /machine:I386 /out:"..\..\build\rftaparser\Debug/rftaparser_mdd.ext" /pdbtype:sept /libpath:"../../deplib/cppunit/lib"
# Begin Special Build Tool
! TargetDir=\Projects\Cpptool\rfta\build\rftaparser\Debug
! TargetPath=\Projects\Cpptool\rfta\build\rftaparser\Debug\rftaparser_mdd.ext
TargetName=rftaparser_mdd
SOURCE="$(InputPath)"
***************
*** 322,325 ****
--- 322,333 ----
# Begin Source File
+ SOURCE=.\ExpressionOperationMutator.cpp
+ # End Source File
+ # Begin Source File
+
+ SOURCE=..\..\include\rfta\parser\ExpressionOperationMutator.h
+ # End Source File
+ # Begin Source File
+
SOURCE=.\MaxLODMutator.cpp
# End Source File
***************
*** 555,558 ****
--- 563,574 ----
!ENDIF
+ # End Source File
+ # Begin Source File
+
+ SOURCE=.\ExpressionOperationMutatorTest.cpp
+ # End Source File
+ # Begin Source File
+
+ SOURCE=.\ExpressionOperationMutatorTest.h
# End Source File
# Begin Source File
|