|
From: <bl...@us...> - 2003-05-28 07:32:51
|
Update of /cvsroot/cpptool/rfta/src/rfta
In directory sc8-pr-cvs1:/tmp/cvs-serv17275/src/rfta
Added Files:
CodeModelGenerator.cpp
Log Message:
* renamed CodeModel.[ch] to CodeModelGenerator.[ch]
* introduced a level of indirection between the code model and ast node, there allowing for alternative parser implementation.
--- NEW FILE: CodeModelGenerator.cpp ---
// //////////////////////////////////////////////////////////////////////////
// (c)Copyright 2002, Baptiste Lepilleur.
// Created: 2002/12/21
// //////////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include <rfta/refactoring/CodeModelGenerator.h>
#include <rfta/parser/ASTNode.h>
#include <rfta/parser/ASTNodes.h>
#include <rfta/refactoring/CodeModelExpressions.h>
#include <rfta/refactoring/CodeModelStatements.h>
#include <rfta/refactoring/CodeModelDeclarations.h>
namespace {
class ASTNNodeElementASTSource : public Refactoring::CodeModel::ElementASTSource
{
public:
ASTNNodeElementASTSource( const Refactoring::ASTNodePtr &node )
: node_( node )
{
}
Refactoring::SourceRange getSourceRange() const
{
return node_->getRange();
}
std::string getSourceText() const
{
return node_->getOriginalText();
}
private:
Refactoring::ASTNodePtr node_;
};
}
namespace Refactoring { namespace CodeModel {
GeneratorError::GeneratorError( const std::string &message )
: std::logic_error( message )
{
}
GeneratorError::~GeneratorError() throw()
{
}
Generator::Generator()
{
addStatement( ASTNodeTypes::breakStatement,
&Generator::generateBreakStatement );
addStatement( ASTNodeTypes::caseStatement,
&Generator::generateCaseStatement );
addStatement( ASTNodeTypes::compoundStatement,
&Generator::generateCompoundStatement );
addStatement( ASTNodeTypes::declarationExpression,
&Generator::generateDeclarationStatement );
addStatement( ASTNodeTypes::defaultStatement,
&Generator::generateDefaultStatement );
addStatement( ASTNodeTypes::doWhileStatement,
&Generator::generateDoStatement );
addStatement( ASTNodeTypes::expression,
&Generator::generateExpressionStatement );
addStatement( ASTNodeTypes::forStatement,
&Generator::generateForStatement );
// addStatement( ASTNodeTypes::gotoStatement,
// &Generator::generateGotoStatement );
addStatement( ASTNodeTypes::selectionStatement,
&Generator::generateIfStatement );
// addStatement( ASTNodeTypes::labelStatement,
// &Generator::generateLabelStatement );
addStatement( ASTNodeTypes::nullStatement,
&Generator::generateNullStatement );
addStatement( ASTNodeTypes::returnStatement,
&Generator::generateReturnStatement );
addStatement( ASTNodeTypes::switchStatement,
&Generator::generateSwitchStatement );
addStatement( ASTNodeTypes::whileStatement,
&Generator::generateWhileStatement );
}
Generator::~Generator()
{
}
FunctionDeclarationPtr
Generator::generateFunctionDeclaration( const ASTNodePtr &functionDeclNode )
{
ASTNodePtr headerNode = functionDeclNode->getProperty( ASTNodeProperties::functionHeaderProperty );
if ( !headerNode )
throw std::invalid_argument( "Generator::generateFunctionDeclaration, functionDeclNode is not a function declaration node" );
ASTNodePtr bodyNode = functionDeclNode->getProperty( ASTNodeProperties::functionBodyProperty );
TypePtr returnType( new Type("") );
FunctionNamePtr name( new FunctionName( headerNode->getOriginalText() ) );
setElementSource( *name, headerNode );
ParametersPtr parameters( new Parameters() );
CompoundStatementPtr body;
if ( bodyNode )
body = generateCompound( bodyNode );
return FunctionDeclarationPtr( new FunctionDeclaration( returnType, name, parameters, body ) );
}
CompoundStatementPtr
Generator::generateCompound( const ASTNodePtr &compoundNode )
{
CompoundStatementPtr compound( new CompoundStatement() );
for ( int index = 0; index < compoundNode->getChildCount(); ++index )
{
StatementPtr statement =
generateStatement( compoundNode->getChildAt( index ) );
compound->appendStatement( statement );
}
setElementSource( *compound, compoundNode );
return compound;
}
StatementPtr
Generator::generateStatement( const ASTNodePtr &statementNode )
{
Generators::iterator it = statementGenerators_.find( statementNode->getType() );
if ( it == statementGenerators_.end() )
{
throw GeneratorError(
"Generator::generateStatement(): node type is not a statement"
+ statementNode->getType().getName() );
}
GeneratorFunction function = it->second;
StatementPtr statement = (this->*function)( statementNode );
setElementSource( *statement, statementNode );
return statement;
}
void
Generator::addStatement( const ASTNodeType &type,
GeneratorFunction function )
{
statementGenerators_.insert( Generators::value_type( type, function ) );
}
StatementPtr
Generator::generateBreakStatement( const ASTNodePtr &statement )
{
return StatementPtr( new BreakStatement() );
}
StatementPtr
Generator::generateCaseStatement( const ASTNodePtr &statement )
{
ASTNodePtr conditionValueNode =
statement->getProperty( ASTNodeProperties::constantValueProperty );
ExpressionPtr conditionValue = generateExpression( conditionValueNode );
return StatementPtr( new CaseStatement( conditionValue ) );
}
StatementPtr
Generator::generateCompoundStatement( const ASTNodePtr &statement )
{
return generateCompound( statement );
}
StatementPtr
Generator::generateDeclarationStatement( const ASTNodePtr &statement )
{
DeclaratorExpressionPtr declarator =
generateDeclarator( statement );
return StatementPtr( new DeclarationStatement( declarator ) );
}
StatementPtr
Generator::generateDefaultStatement( const ASTNodePtr &statement )
{
return StatementPtr( new DefaultStatement() );
}
StatementPtr
Generator::generateDoStatement( const ASTNodePtr &statement )
{
ASTNodePtr conditionNode =
statement->getProperty( ASTNodeProperties::iterationProperty );
ASTNodePtr iteratedNode =
statement->getProperty( ASTNodeProperties::iterationStatementProperty );
ExpressionPtr condition = generateExpression( conditionNode );
StatementPtr iterated = generateStatement( iteratedNode );
return StatementPtr( new DoStatement( condition, iterated ) );
}
StatementPtr
Generator::generateExpressionStatement( const ASTNodePtr &statement )
{
ExpressionPtr expression = generateExpression( statement );
return StatementPtr( new ExpressionStatement( expression ) );
}
StatementPtr
Generator::generateForStatement( const ASTNodePtr &statement )
{
ASTNodePtr iteratedNode =
statement->getProperty( ASTNodeProperties::iterationStatementProperty );
StatementPtr iterated = generateStatement( iteratedNode );
ASTNodePtr forIterationNode =
statement->getProperty( ASTNodeProperties::iterationProperty );
ASTNodePtr declarationNode =
forIterationNode->getProperty( ASTNodeProperties::declarationProperty );
ExpressionPtr declaration = generateExpression( declarationNode );
ASTNodePtr conditionNode =
forIterationNode->getProperty( ASTNodeProperties::conditionProperty );
ExpressionPtr condition = generateExpression( conditionNode );
ASTNodePtr iterationNode =
forIterationNode->getProperty( ASTNodeProperties::nextStepProperty );
ExpressionPtr iteration = generateExpression( iterationNode );
return StatementPtr( new ForStatement( declaration,
condition,
iteration,
iterated ) );
}
StatementPtr
Generator::generateIfStatement( const ASTNodePtr &statement )
{
ASTNodePtr conditionNode =
statement->getProperty( ASTNodeProperties::selectionProperty );
ASTNodePtr thenStatementNode =
statement->getProperty( ASTNodeProperties::thenStatementProperty );
ASTNodePtr elseStatementNode =
statement->getProperty( ASTNodeProperties::elseStatementProperty );
ExpressionPtr condition = generateExpression( conditionNode );
StatementPtr thenStatement = generateStatement( thenStatementNode );
if ( !elseStatementNode )
return StatementPtr( new IfStatement( condition, thenStatement ) );
StatementPtr elseStatement = generateStatement( elseStatementNode );
return StatementPtr( new IfStatement( condition, thenStatement, elseStatement ) );
}
StatementPtr
Generator::generateNullStatement( const ASTNodePtr &statement )
{
return StatementPtr( new NullStatement() );
}
StatementPtr
Generator::generateReturnStatement( const ASTNodePtr &statement )
{
ASTNodePtr valueNode = statement->getProperty( ASTNodeProperties::valueProperty );
if ( !valueNode )
return StatementPtr( new ReturnStatement() );
ExpressionPtr value = generateExpression( valueNode );
return StatementPtr( new ReturnStatement( value ) );
}
StatementPtr
Generator::generateSwitchStatement( const ASTNodePtr &statement )
{
ASTNodePtr conditionNode =
statement->getProperty( ASTNodeProperties::selectionProperty );
ASTNodePtr statementsNode =
statement->getProperty( ASTNodeProperties::switchStatementProperty );
ExpressionPtr condition = generateExpression( conditionNode );
CompoundStatementPtr statements = generateCompound( statementsNode );
return StatementPtr( new SwitchStatement( condition, statements ) );
}
StatementPtr
Generator::generateWhileStatement( const ASTNodePtr &statement )
{
ASTNodePtr conditionNode =
statement->getProperty( ASTNodeProperties::iterationProperty );
ASTNodePtr iteratedNode =
statement->getProperty( ASTNodeProperties::iterationStatementProperty );
ExpressionPtr condition = generateExpression( conditionNode );
StatementPtr iterated = generateStatement( iteratedNode );
return StatementPtr( new WhileStatement( condition, iterated ) );
}
ExpressionPtr
Generator::generateExpression( const ASTNodePtr &expression )
{
if ( expression->getType() == ASTNodeTypes::declarationExpression )
return generateDeclaratorExpression( expression );
if ( expression->getRange().getLength() == 0 )
return generateNullExpression( expression );
return generateGenericExpression( expression );
}
ExpressionPtr
Generator::generateDeclaratorExpression( const ASTNodePtr &expression )
{
return generateDeclarator( expression );
}
ExpressionPtr
Generator::generateGenericExpression( const ASTNodePtr &expressionNode )
{
std::string value = expressionNode->getOriginalText();
ExpressionPtr expression( new GenericExpression() );
setElementSource( *expression, expressionNode );
return expression;
}
ExpressionPtr
Generator::generateNullExpression( const ASTNodePtr &expressionNode )
{
ExpressionPtr expression( new NullExpression() );
setElementSource( *expression, expressionNode );
return expression;
}
DeclaratorExpressionPtr
Generator::generateDeclarator( const ASTNodePtr &expression )
{
TypePartPtr primaryType( getDeclaratorPrimaryType( expression ) );
DeclaratorExpressionPtr declaratorExpression( new DeclaratorExpression( primaryType ) );
for ( int index = 0; index < expression->getChildCount(); ++index )
{
const ASTNodePtr &declaratorNode = expression->getChildAt( index );
DeclaratorPtr declarator = makeVariableDeclarator( declaratorNode );
setElementSource( *declarator, declaratorNode );
declaratorExpression->appendDeclarator( declarator );
}
setElementSource( *declaratorExpression, expression );
return declaratorExpression;
}
TypePartPtr
Generator::getDeclaratorPrimaryType( const ASTNodePtr &declaratorNode )
{
ASTNodePtr firstDecl = declaratorNode->getChildAt( 0 );
ASTNodePtr typePrefix =
firstDecl->getProperty( ASTNodeProperties::typeDeclPrefixProperty );
TypePartPtr typePart( new TypePart() );
setElementSource( *typePart, typePrefix );
return typePart;
}
DeclaratorPtr
Generator::makeVariableDeclarator( const ASTNodePtr &node )
{
ASTNodePtr typeNode =
node->getProperty( ASTNodeProperties::typeDeclSecondaryPrefixProperty );
TypePartPtr type = makeOptionalType( typeNode );
ASTNodePtr typeSuffixNode =
node->getProperty( ASTNodeProperties::typeDeclSuffixProperty );
TypePartPtr typeSuffix = makeOptionalType( typeSuffixNode );
ASTNodePtr nameNode =
node->getProperty( ASTNodeProperties::variableNameProperty );
IdentifierPtr name = makeIdentifier( nameNode );
/*
std::string type = typeNode ? typeNode->getBlankedText() : std::string("");
ASTNodePtr nameNode =
node->getProperty( ASTNodeProperties::variableNameProperty );
std::string name = nameNode->getBlankedText();
ASTNodePtr typeSuffixNode =
node->getProperty( ASTNodeProperties::typeDeclSuffixProperty );
std::string typeSuffix = typeSuffixNode ? typeSuffixNode->getBlankedText()
: std::string("");
TypePartPtr typePtr( new TypePart( type ) );
setElementSource( *typePtr, typeNode );
TypePartPtr typeSuffixPtr( new TypePart( typeSuffix ) );
setElementSource( *typeSuffixPtr, typeSuffixNode );
IdentifierPtr namePtr( new Identifier( name ) );
setElementSource( *namePtr, nameNode );
*/
ASTNodePtr initializerNode =
node->getProperty( ASTNodeProperties::variableInitializerProperty );
if ( !initializerNode )
return DeclaratorPtr( new Declarator( type, name, typeSuffix ) );
ExpressionPtr initializer = makeVariableInitializerExpression( initializerNode );
return DeclaratorPtr( new Declarator( type, name, typeSuffix, initializer ) );
}
TypePartPtr
Generator::makeOptionalType( const ASTNodePtr &typeNode )
{
if ( !typeNode )
return TypePartPtr();
TypePartPtr typePtr( new TypePart( typeNode->getBlankedText() ) );
setElementSource( *typePtr, typeNode );
return typePtr;
}
IdentifierPtr
Generator::makeIdentifier( const ASTNodePtr &identifierNode )
{
IdentifierPtr namePtr( new Identifier( identifierNode->getBlankedText() ) );
setElementSource( *namePtr, identifierNode );
return namePtr;
}
ExpressionPtr
Generator::makeVariableInitializerExpression( const ASTNodePtr &initializerNode )
{
ASTNodePtr valueNode =
initializerNode->getProperty( ASTNodeProperties::valueProperty );
ExpressionPtr value = generateExpression( valueNode );
setElementSource( *value, valueNode );
ExpressionPtr initializer;
if ( initializerNode->getType() == ASTNodeTypes::assignVariableInitializerExpression )
initializer.reset( new AssignInitializerExpression( value ) );
else
initializer.reset( new ConstructorInitializerExpression( value ) );
setElementSource( *initializer, initializerNode );
return initializer;
}
void
Generator::setElementSource( Element &element, const ASTNodePtr &node )
{
element.setSource( ElementASTSourcePtr( new ASTNNodeElementASTSource( node ) ) );
}
} // namespace CodeModel
} // namespace Refactoring
|