blob: a534b63f1b5709309b20174614db8c52c48fa67a [file] [log] [blame]
/*
* Copyright 2003-2004 The Apache Software Foundation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifdef WIN32
#pragma warning (disable : 4786)
#endif
#include <iostream>
#include <string>
#include <map>
using namespace std;
#include "actions.h"
#include "cppyacc.hpp"
#include "Variable.h"
#include "Method.h"
/* global variables used by the parser */
map<string,int> lexer_keys; /* keyword map in the lexical analyzer. */
TranslationUnit* g_pTranslationUnit;
/* ultimate container of parsed information */
string g_classname;
/* this holds the class name while the body of a class is being parsed. */
list<string> g_classesfound;
int g_currentclasstype;
WSClass* g_pCurrentWSClass;
BeanClass* g_pCurrentBeanClass;
bool g_bdestructor_seen;
int g_currentaccessspecifier;
extern string g_sWebServiceClass;
/* forward declarations of function in this file */
int map_var_type(int parsertype);
int get_var_type(const char* vartypename);
bool is_defined_class(const char* identifier)
{
for(list<string>::iterator it = g_classesfound.begin();
it != g_classesfound.end(); it++)
{
if (*it == identifier)
{
return true;
}
}
return false;
}
void translation_unit_start()
{
g_pTranslationUnit = new TranslationUnit();
}
bool is_webservice_class(const char* classname)
{
/* if (!baselist) return false;
for (base_specifier_list::iterator it = baselist->begin();
it != baselist->end(); it++)
{
if ((*(*it)->class_name) == "IAccessBean")
{
return true;
}
}
*/
return (g_sWebServiceClass == classname);
}
void add_member_declaration(string_list* decl_specs,
member_declarator_list* member_decl_list)
{
/* int nVarType; */
/* int nConvVarType; */
unsigned char nQualifier = 0;
Variable Var;
bool bIsCtor = false;
/* find current access qualifier */
switch (g_currentaccessspecifier)
{
case KW_private:
nQualifier |= Q_PRIVATE;
break;
case KW_protected:
nQualifier |= Q_PROTECTED;
break;
case KW_public:
/* nothing to be done */
break;
default:;
}
Var.SetQualification(nQualifier);
/* find variable type and qualifiers */
if (decl_specs)
{
for (string_list::iterator tlit = decl_specs->begin();
tlit != decl_specs->end(); tlit++)
{
if (VAR_UNKNOWN != get_var_type((*tlit)->c_str()))
/* this is variable type not a qualifier */
{
Var.SetType(get_var_type((*tlit)->c_str()));
}
else if (is_defined_class((*tlit)->c_str())) /* user types */
{
Var.SetType(VAR_USER, (*tlit)->c_str());
}
else
{
/* handle other variable qualifiers here */
}
}
}
else /* constructor or destructor */
{
bIsCtor = true;
}
for (member_declarator_list::iterator it = member_decl_list->begin();
it != member_decl_list->end(); it++)
{
if ((*it)->method) /* a method declaration */
{
if (g_currentclasstype == BEANCLASS)
{
/* just ignore this method because we donot wrap methods
* in a bean class
*/
cout << "Ignoring methods in a bean class" << endl;
}
else
{
Method* pMethod = new Method();
if (bIsCtor) /* constructor or destructor - no return type */
{
cout << "Ignoring constructor or destructor" << endl;
/* we dont wrap constructors or destructors. */
}
else /* other methods */
{
pMethod->AddReturnType(new Variable(Var));
pMethod->SetQualification(nQualifier);
pMethod->SetMethodName(*((*it)->declarator_id));
/* set parameters */
if ((*it)->params)
{
for (param_decl_list::iterator pit = (*it)->params->
begin(); pit != (*it)->params->end(); pit++)
{
Var.Reset();
if ((*pit)->decl_specs)
{
for (string_list::iterator slit =
(*pit)->decl_specs->begin();
slit != (*pit)->decl_specs->end(); slit++)
{
if (VAR_UNKNOWN != get_var_type((*slit)->
c_str()))
/* this is variable type not a
* qualifier
*/
{
Var.SetType(get_var_type((*slit)->
c_str()));
}
else if (is_defined_class((*slit)->
c_str()))
/* user types */
{
Var.SetType(VAR_USER, (*slit)->
c_str());
}
else
{
/* handle other variable qualifiers
* here
*/
}
}
}
if ((*pit)->param)
{
Var.SetVarName((*pit)->param->decl_id);
}
/* Add as a parameter to the method */
pMethod->AddParameter(new Variable(Var));
}
}
if (g_pCurrentWSClass)
{
g_pCurrentWSClass->AddMethod(pMethod);
}
}
}
}
else /* variable declaration */
{
Variable* pVar = new Variable(Var);
pVar->SetVarName(*((*it)->declarator_id));
/* check for arrays */
/* TODO */
if (g_currentclasstype == BEANCLASS)
{
if (g_pCurrentBeanClass)
{
g_pCurrentBeanClass->AddVariable(pVar);
}
else
{
cout << "Ignoring variables in the other classes than \
bean classes" << endl;
}
}
else
{
cout << "Ignoring variables in web service class : we dont \
wrap them :)" << endl;
}
}
}
}
/* match parser types to our types for basic data types */
int map_var_type(int parsertype)
{
switch (parsertype)
{
/* basic types */
case KW_int: return VAR_INT;
case KW_float: return VAR_FLOAT;
case KW_char: return VAR_CHAR;
case KW_double: return VAR_DOUBLE;
case KW_string: return VAR_STRING;
default:;
}
return VAR_UNKNOWN;
}
int get_var_type(const char* vartypename)
{
/* this should be in lexer_keys table */
if (lexer_keys.find(vartypename) == lexer_keys.end())
return false;
return map_var_type(lexer_keys[vartypename]);
}
string makeOperatorName(int op)
{
switch( op )
{
case PLUS: return string("operator+");
case MINUS: return string("operator-");
case STAR: return string("operator*");
case DIVIDE: return string("operator/");
case MOD: return string("operator%");
case GREATER: return string("operator>");
case LESS: return string("operator<");
case EQUAL: return string("operator=");
case AND: return string("operator&");
case OR: return string("operator|");
case NOT: return string("operator!");
case XOR: return string("operator^");
case COMMA: return string("operator,");
case COMPLEMENT: return string("operator~");
case PLUSEQ: return string("operator+=");
case MINUSEQ: return string("operator-=");
case STAREQ: return string("operator*=");
case DIVEQ: return string("operator/=");
case MODEQ: return string("operator%=");
case XOREQ: return string("operator^=");
case ANDEQ: return string("operator&=");
case OREQ: return string("operator|=");
case LTLT: return string("operator<<");
case GTGT: return string("operator>>");
case GTGTEQ: return string("operator>>=");
case LTLTEQ: return string("operator<<=");
case EQEQ: return string("operator==");
case NOTEQ: return string("operator!=");
case LEQ: return string("operator>=");
case ANDAND: return string("operator||");
case PLUSPLUS: return string("operator++");
case MINUSMINUS: return string("operator--");
case ARROW: return string("operator->");
}
return string("");
}