summaryrefslogtreecommitdiff
path: root/cpp/src/slice2java/Gen.cpp
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2001-11-08 20:09:44 +0000
committerMark Spruiell <mes@zeroc.com>2001-11-08 20:09:44 +0000
commitf9400f25d80b8eec0a59d89225cfd15f1e750bc3 (patch)
treec8c162c5e08a1602e0cddb42e97068dc01591509 /cpp/src/slice2java/Gen.cpp
parentbug fix (diff)
downloadice-f9400f25d80b8eec0a59d89225cfd15f1e750bc3.tar.bz2
ice-f9400f25d80b8eec0a59d89225cfd15f1e750bc3.tar.xz
ice-f9400f25d80b8eec0a59d89225cfd15f1e750bc3.zip
initial check-in
Diffstat (limited to 'cpp/src/slice2java/Gen.cpp')
-rw-r--r--cpp/src/slice2java/Gen.cpp931
1 files changed, 931 insertions, 0 deletions
diff --git a/cpp/src/slice2java/Gen.cpp b/cpp/src/slice2java/Gen.cpp
new file mode 100644
index 00000000000..d595a2684fa
--- /dev/null
+++ b/cpp/src/slice2java/Gen.cpp
@@ -0,0 +1,931 @@
+// **********************************************************************
+//
+// Copyright (c) 2001
+// MutableRealms, Inc.
+// Huntsville, AL, USA
+//
+// All Rights Reserved
+//
+// **********************************************************************
+
+#include <IceUtil/Functional.h>
+#include <Gen.h>
+//#include <JavaUtil.h>
+#include <limits>
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+using namespace std;
+using namespace Slice;
+
+Slice::JavaVisitor::JavaVisitor(const string& dir, const string& package) :
+ _dir(dir),
+ _package(package),
+ _out(0)
+{
+}
+
+Slice::JavaVisitor::~JavaVisitor()
+{
+ assert(_out == 0);
+}
+
+bool
+Slice::JavaVisitor::open(const string& absolute)
+{
+ string package;
+ string file;
+ string path = _dir;
+
+ assert(_out == 0);
+
+ string::size_type pos = absolute.rfind('.');
+ if (pos != string::npos)
+ {
+ package = absolute.substr(0, pos);
+ file = absolute.substr(pos + 1);
+ string dir = package;
+
+ //
+ // Create package directories if necessary
+ //
+ pos = 0;
+ string::size_type start = 0;
+ do
+ {
+ if (!path.empty())
+ {
+ path += "/";
+ }
+ pos = dir.find('.', start);
+ if (pos != string::npos)
+ {
+ path += dir.substr(start, pos);
+ start = pos + 1;
+ }
+ else
+ {
+ path += dir.substr(start);
+ }
+
+ struct stat st;
+ int result;
+ result = stat(path.c_str(), &st);
+ if (result == 0)
+ {
+ continue;
+ }
+#ifdef WIN32
+ result = _mkdir(path.c_str());
+#else
+ result = mkdir(path.c_str(), S_IRWXU | S_IRWXG | S_IRWXO);
+#endif
+ if (result != 0)
+ {
+ cerr << "can't create directory `" << path << "': "
+ << strerror(errno) << endl;
+ return false;
+ }
+ }
+ while (pos != string::npos);
+ }
+ else
+ {
+ file = absolute;
+ }
+ file += ".java";
+
+ //
+ // Open class file
+ //
+ if (!path.empty())
+ {
+ path += "/";
+ }
+ path += file;
+ _out = new Output();
+ _out->open(path.c_str());
+ if (!(*_out))
+ {
+ cerr << "can't open `" << path << "' for writing: "
+ << strerror(errno) << endl;
+ close();
+ return false;
+ }
+
+ printHeader();
+
+ if (!package.empty())
+ {
+ *_out << sp << nl << "package " << package << ';';
+ }
+
+ return true;
+}
+
+void
+Slice::JavaVisitor::close()
+{
+ assert(_out != 0);
+ *_out << nl;
+ delete _out;
+ _out = 0;
+}
+
+Output&
+Slice::JavaVisitor::output() const
+{
+ assert(_out != 0);
+ return *_out;
+}
+
+string
+Slice::JavaVisitor::getAbsolute(const string& scoped,
+ const string& scope) const
+{
+ string str = scoped;
+ string::size_type pos = 0;
+
+ if (!scope.empty())
+ {
+ //
+ // Only remove the scope if the resulting symbol is unscoped.
+ // For example:
+ //
+ // scope=::A, scoped=::A::B, result=B
+ // scope=::A, scoped=::A::B::C, result=::A::B::C
+ //
+ if (str.compare(0, scope.size(), scope) == 0 &&
+ str.find('.', scope.size()) == string::npos)
+ {
+ str.erase(0, scope.size());
+ }
+ }
+
+ //
+ // Skip leading "::"
+ //
+ if (str[0] == ':')
+ {
+ assert(str[1] == ':');
+ str.erase(0, 2);
+ }
+
+ //
+ // Convert all occurrences of "::" to "."
+ //
+ while ((pos = str.find(':', pos)) != string::npos)
+ {
+ assert(str[pos + 1] == ':');
+ str.replace(pos, 2, ".");
+ }
+
+ if (!_package.empty())
+ {
+ return _package + "." + str;
+ }
+ else
+ {
+ return str;
+ }
+}
+
+string
+Slice::JavaVisitor::typeToString(const TypePtr& type, TypeMode mode,
+ const string& scope) const
+{
+ static const char* builtinTable[] =
+ {
+ "byte",
+ "boolean",
+ "short",
+ "int",
+ "long",
+ "float",
+ "double",
+ "String", // string
+ "String", // wstring
+ "Ice.Object",
+ "Ice.ObjectPrx",
+ "Ice.LocalObject"
+ };
+ static const char* builtinHolderTable[] =
+ {
+ "Ice.ByteHolder",
+ "Ice.BooleanHolder",
+ "Ice.ShortHolder",
+ "Ice.IntHolder",
+ "Ice.LongHolder",
+ "Ice.FloatHolder",
+ "Ice.DoubleHolder",
+ "Ice.StringHolder", // string
+ "Ice.StringHolder", // wstring
+ "Ice.ObjectHolder",
+ "Ice.ObjectPrxHolder",
+ "Ice.LocalObjectHolder"
+ };
+
+ if (!type)
+ {
+ assert(mode == TypeModeReturn);
+ return "void";
+ }
+
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
+ if (builtin)
+ {
+ if (mode == TypeModeOut)
+ {
+ return builtinHolderTable[builtin->kind()];
+ }
+ else
+ {
+ return builtinTable[builtin->kind()];
+ }
+ }
+
+ ClassDeclPtr cl = ClassDeclPtr::dynamicCast(type);
+ if (cl)
+ {
+ //return cl->scoped() + "Ptr"; // TODO: Use Ptr suffix?
+ string result = getAbsolute(cl->scoped(), scope);
+ if (mode == TypeModeOut)
+ {
+ result += "Holder";
+ }
+ return result;
+ }
+
+ ProxyPtr proxy = ProxyPtr::dynamicCast(type);
+ if (proxy)
+ {
+ string result = getAbsolute(proxy->_class()->scoped() + "Prx", scope);
+ if (mode == TypeModeOut)
+ {
+ result += "Holder";
+ }
+ return result;
+ }
+
+ DictionaryPtr dict = DictionaryPtr::dynamicCast(type);
+ if (dict)
+ {
+ if (mode == TypeModeOut)
+ {
+ return "Ice.HashtableHolder";
+ }
+ else
+ {
+ return "java.util.Hashtable";
+ }
+ }
+
+ SequencePtr seq = SequencePtr::dynamicCast(type);
+ if (seq)
+ {
+ if (mode == TypeModeOut)
+ {
+ return getAbsolute(seq->scoped(), scope) + "Holder";
+ }
+ else
+ {
+ TypePtr content = seq->type();
+ return typeToString(content, mode, scope) + "[]";
+ }
+ }
+
+ ContainedPtr contained = ContainedPtr::dynamicCast(type);
+ if (contained)
+ {
+ return getAbsolute(contained->scoped(), scope);
+ }
+
+ return "???";
+}
+
+void
+Slice::JavaVisitor::printHeader()
+{
+ static const char* header =
+"// **********************************************************************\n"
+"//\n"
+"// Copyright (c) 2001\n"
+"// MutableRealms, Inc.\n"
+"// Huntsville, AL, USA\n"
+"//\n"
+"// All Rights Reserved\n"
+"//\n"
+"// **********************************************************************\n"
+ ;
+
+ Output& out = output();
+ out << header;
+ out << "\n// Ice version " << ICE_STRING_VERSION;
+}
+
+Slice::Gen::Gen(const string& name, const string& base,
+ const vector<string>& includePaths,
+ const string& package, const string& dir) :
+ _base(base),
+ _includePaths(includePaths),
+ _package(package),
+ _dir(dir)
+{
+}
+
+Slice::Gen::~Gen()
+{
+}
+
+bool
+Slice::Gen::operator!() const
+{
+ return false;
+}
+
+void
+Slice::Gen::generate(const UnitPtr& unit)
+{
+ TypesVisitor typesVisitor(_dir, _package);
+ unit->visit(&typesVisitor);
+
+ HolderVisitor holderVisitor(_dir, _package);
+ unit->visit(&holderVisitor);
+}
+
+Slice::Gen::TypesVisitor::TypesVisitor(const string& dir,
+ const string& package) :
+ JavaVisitor(dir, package)
+{
+}
+
+bool
+Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ string name = p->name();
+ string scoped = p->scoped();
+ ClassList bases = p->bases();
+ string scope = p->scope();
+ string absolute = getAbsolute(scoped);
+
+ if (!open(absolute))
+ {
+ return false;
+ }
+
+ Output& out = output();
+
+ //
+ // Local interfaces map to Java interfaces
+ //
+ if (p->isInterface())
+ {
+ out << sp << nl << "public interface " << name;
+ if (!bases.empty())
+ {
+ out << " extends ";
+ out.useCurrentPosAsIndent();
+ ClassList::const_iterator q = bases.begin();
+ while (q != bases.end())
+ {
+ out << getAbsolute((*q)->scoped(), scope);
+ if (++q != bases.end())
+ {
+ out << ',' << nl;
+ }
+ }
+ out.restoreIndent();
+ }
+ }
+ else
+ {
+ out << sp << nl << "public abstract class " << name;
+ out.useCurrentPosAsIndent();
+ if (bases.empty() || bases.front()->isInterface())
+ {
+ if (p->isLocal())
+ {
+ out << " extends Ice.LocalObject";
+ }
+ else
+ {
+ out << " extends Ice.Object";
+ }
+ }
+ else
+ {
+ out << " extends ";
+ ClassDefPtr base = bases.front();
+ out << getAbsolute(base->scoped(), scope);
+ bases.pop_front();
+ }
+
+ //
+ // Implement interfaces
+ //
+ if (!bases.empty())
+ {
+ out << nl << " implements ";
+ out.useCurrentPosAsIndent();
+ ClassList::const_iterator q = bases.begin();
+ while (q != bases.end())
+ {
+ out << getAbsolute((*q)->scoped(), scope);
+ if (++q != bases.end())
+ {
+ out << ',' << nl;
+ }
+ }
+ out.restoreIndent();
+ }
+ out.restoreIndent();
+ }
+
+ out << sb;
+
+ if (!p->isInterface() && !p->isLocal())
+ {
+ // TODO: ids, _isA, dispatching, etc.
+ }
+
+ return true;
+}
+
+void
+Slice::Gen::TypesVisitor::visitClassDefEnd(const ClassDefPtr& p)
+{
+ Output& out = output();
+ out << eb;
+ close();
+}
+
+void
+Slice::Gen::TypesVisitor::visitOperation(const OperationPtr& p)
+{
+ ContainerPtr container = p->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container);
+ string name = p->name();
+ string scoped = p->scoped();
+ string scope = p->scope();
+
+ TypePtr ret = p->returnType();
+ string retS = typeToString(ret, TypeModeReturn, scope);
+
+ TypeStringList inParams = p->inputParameters();
+ TypeStringList outParams = p->outputParameters();
+ TypeStringList::const_iterator q;
+
+ string params = "(";
+ string args = "(";
+
+ for (q = inParams.begin(); q != inParams.end(); ++q)
+ {
+ if (q != inParams.begin())
+ {
+ params += ", ";
+ args += ", ";
+ }
+
+ string typeString = typeToString(q->first, TypeModeIn, scope);
+ params += typeString;
+ params += ' ';
+ params += q->second;
+ args += q->second;
+ }
+
+ for (q = outParams.begin(); q != outParams.end(); ++q)
+ {
+ if (q != outParams.begin() || !inParams.empty())
+ {
+ params += ", ";
+ args += ", ";
+ }
+
+ string typeString = typeToString(q->first, TypeModeOut, scope);
+ params += typeString;
+ params += ' ';
+ params += q->second;
+ args += q->second;
+ }
+
+ params += ')';
+ args += ')';
+
+ Output& out = output();
+
+ out << sp;
+ out << nl;
+ if (!cl->isInterface())
+ {
+ out << "public ";
+ }
+ out << retS << ' ' << name << params;
+
+ //
+ // Don't include local exceptions in the throws clause
+ //
+ ExceptionList throws = p->throws();
+ throws.sort();
+ throws.unique();
+ int localCount = 0;
+ count_if(throws.begin(), throws.end(),
+ ::IceUtil::memFun(&Exception::isLocal), localCount);
+ if (throws.size() - localCount > 0)
+ {
+ out.inc();
+ out << nl;
+ out << "throws ";
+ out.useCurrentPosAsIndent();
+ ExceptionList::const_iterator r;
+ int count = 0;
+ for (r = throws.begin(); r != throws.end(); ++r)
+ {
+ if (!(*r)->isLocal())
+ {
+ if (count > 0)
+ {
+ out << "," << nl;
+ }
+ out << getAbsolute((*r)->scoped(), scope);
+ count++;
+ }
+ }
+ out.restoreIndent();
+ out.dec();
+ }
+
+ out << ';';
+}
+
+bool
+Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
+{
+ string name = p->name();
+ string scoped = p->scoped();
+ ExceptionPtr base = p->base();
+ string absolute = getAbsolute(scoped);
+
+ if (!open(absolute))
+ {
+ return false;
+ }
+
+ Output& out = output();
+
+ out << sp << nl << "public class " << name << " extends ";
+
+ if (!base)
+ {
+ if (p->isLocal())
+ {
+ out << "Ice.LocalException";
+ }
+ else
+ {
+ out << "Ice.UserException";
+ }
+ }
+ else
+ {
+ out << getAbsolute(base->scoped(), p->scope());
+ }
+ out << sb;
+
+ out << sp << nl << "public String" << nl << "_name()";
+ out << sb;
+ out << nl << "return \"" << scoped.substr(2) << "\";";
+ out << eb;
+
+ // TODO - need _print() in Java? Already have printStackTrace()
+#if 0
+ if (p->isLocal())
+ {
+ H << nl << _dllExport << "virtual void _print(::std::ostream&) const;";
+ }
+#endif
+
+ // TODO - need _clone()?
+#if 0
+ H << nl << _dllExport << "virtual ::Ice::Exception* _clone() const;";
+ C << sp << nl << "::Ice::Exception*" << nl << scoped.substr(2) << "::_clone() const";
+ C << sb;
+ C << nl << "return new " << name << "(*this);";
+ C << eb;
+
+ H << nl << _dllExport << "virtual void _throw() const;";
+ C << sp << nl << "void" << nl << scoped.substr(2) << "::_throw() const";
+ C << sb;
+ C << nl << "throw *this;";
+ C << eb;
+#endif
+
+ if (!p->isLocal())
+ {
+ ExceptionList allBases = p->allBases();
+ StringList exceptionIds;
+ transform(allBases.begin(), allBases.end(),
+ back_inserter(exceptionIds),
+ ::IceUtil::memFun(&Exception::scoped));
+ exceptionIds.push_front(scoped);
+ exceptionIds.push_back("::Ice::UserException");
+
+ StringList::const_iterator q;
+
+ out << sp << nl << "private static final String[] __exceptionIds =";
+ out << sb;
+ q = exceptionIds.begin();
+ while (q != exceptionIds.end())
+ {
+ out << nl << '"' << *q << '"';
+ if (++q != exceptionIds.end())
+ {
+ out << ',';
+ }
+ }
+ out << eb << ';';
+ out << sp << nl << "public String[]" << nl << "__getExceptionIds()";
+ out << sb;
+ out << nl << "return __exceptionIds;";
+ out << eb;
+ }
+
+ return true;
+}
+
+void
+Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p)
+{
+ Output& out = output();
+
+ if (!p->isLocal())
+ {
+ string name = p->name();
+ string scoped = p->scoped();
+
+ ExceptionPtr base = p->base();
+
+ TypeStringList memberList;
+ DataMemberList dataMembers = p->dataMembers();
+ for (DataMemberList::const_iterator q = dataMembers.begin();
+ q != dataMembers.end();
+ ++q)
+ {
+ memberList.push_back(make_pair((*q)->type(), (*q)->name()));
+ }
+ out << sp << nl << "public void" << nl
+ << "__write(IceInternal.Stream __os)";
+ out << sb;
+ // TODO
+ //writeMarshalCode(_out, memberList, 0);
+ if (base)
+ {
+ out << nl << "super.__write(__os);";
+ }
+ out << eb;
+ out << sp << nl << "public void" << nl
+ << "__read(IceInternal.Stream __is)";
+ out << sb;
+ // TODO
+ //writeUnmarshalCode(_out, memberList, 0);
+ if (base)
+ {
+ out << nl << "super.__read(__os);";
+ }
+ out << eb;
+ }
+
+ out << eb;
+ close();
+}
+
+bool
+Slice::Gen::TypesVisitor::visitStructStart(const StructPtr& p)
+{
+ string name = p->name();
+ string scoped = p->scoped();
+ string absolute = getAbsolute(scoped);
+
+ if (!open(absolute))
+ {
+ return false;
+ }
+
+ Output& out = output();
+
+ out << sp << nl << "public final class " << name;
+ out << sb;
+
+ return true;
+}
+
+void
+Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p)
+{
+ string name = p->name();
+ string scoped = p->scoped();
+
+ Output& out = output();
+
+ TypeStringList memberList;
+ DataMemberList dataMembers = p->dataMembers();
+ for (DataMemberList::const_iterator q = dataMembers.begin();
+ q != dataMembers.end();
+ ++q)
+ {
+ memberList.push_back(make_pair((*q)->type(), (*q)->name()));
+ }
+ out << sp << nl << "public final void" << nl
+ << "__write(IceInternal.Stream __os)";
+ out << sb;
+ // TODO
+ //writeMarshalCode(_out, memberList, 0);
+ out << eb;
+ out << sp << nl << "public final void" << nl
+ << "__read(IceInternal.Stream __is)";
+ out << sb;
+ // TODO
+ //writeUnmarshalCode(_out, memberList, 0);
+ out << eb;
+
+ out << eb;
+ close();
+}
+
+void
+Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p)
+{
+ string name = p->name();
+ ContainerPtr container = p->container();
+ ContainedPtr contained = ContainedPtr::dynamicCast(container);
+ string s = typeToString(p->type(), TypeModeMember, contained->scope());
+ Output& out = output();
+ out << sp << nl << "public " << s << ' ' << name << ';';
+}
+
+void
+Slice::Gen::TypesVisitor::visitSequence(const SequencePtr& p)
+{
+ // TODO: Marshalling code - need Helper?
+}
+
+void
+Slice::Gen::TypesVisitor::visitDictionary(const DictionaryPtr& p)
+{
+ // TODO: Marshalling code - need Helper?
+}
+
+void
+Slice::Gen::TypesVisitor::visitEnum(const EnumPtr& p)
+{
+ string name = p->name();
+ EnumeratorList enumerators = p->getEnumerators();
+ string scoped = p->scoped();
+ string absolute = getAbsolute(scoped);
+
+ if (!open(absolute))
+ {
+ return;
+ }
+
+ Output& out = output();
+
+ out << sp << nl << "public final class " << name;
+ out << sb;
+ EnumeratorList::const_iterator en = enumerators.begin();
+ int n;
+ for (en = enumerators.begin(), n = 0; en != enumerators.end(); ++en, ++n)
+ {
+ out << nl << "public static final long _" << (*en)->name() << " = "
+ << n << ';';
+ out << nl << "public static final " << name << ' ' << (*en)->name()
+ << " = new " << name << "(_" << (*en)->name() << ");";
+ }
+
+ int sz = enumerators.size();
+
+ out << sp << nl << "public static " << name << nl << "convert(long val)";
+ out << sb;
+ out << nl << "assert val < " << sz << ';';
+ out << nl << "return __values[val];";
+ out << eb;
+
+ out << sp << nl << "public long" << nl << "value()";
+ out << sb;
+ out << nl << "return __value;";
+ out << eb;
+
+ out << sp << nl << "public void" << nl
+ << "__write(IceInternal.Stream __os, " << name << " v)";
+ out << sb;
+ if (sz <= 0x7f)
+ {
+ out << nl << "__os.write_byte((byte)(v));";
+ }
+ else if (sz <= 0x7fff)
+ {
+ out << nl << "__os.write_short((short)(v));";
+ }
+ else if (sz <= 0x7fffffff)
+ {
+ out << nl << "__os.write_int((int)(v));";
+ }
+ else
+ {
+ out << nl << "__os.write_long(v);";
+ }
+ out << eb;
+ out << sp << nl << "public static " << name << nl
+ << "__read(IceInternal.Stream __is)";
+ out << sb;
+ out << nl << "long val;";
+ if (sz <= 0x7f)
+ {
+ out << nl << "val = __is.read_byte(val);";
+ }
+ else if (sz <= 0x7fff)
+ {
+ out << nl << "val = __is.read_short(val);";
+ }
+ else if (sz <= 0x7fffffff)
+ {
+ out << nl << "val = __is.read_int(val);";
+ }
+ else
+ {
+ out << nl << "val = __is.read_long(val);";
+ }
+ out << nl << "return convert(val);";
+ out << eb;
+
+ out << sp << nl << "private" << nl << name << "(long val)";
+ out << sb;
+ out << nl << "__value = val;";
+ out << nl << "__values[val] = this;";
+ out << eb;
+ out << sp << nl << "private static " << name << "[] __values = new "
+ << name << "[" << sz << "];";
+ out << sp << nl << "private long __value;";
+
+ out << eb;
+ close();
+}
+
+Slice::Gen::HolderVisitor::HolderVisitor(const string& dir,
+ const string& package) :
+ JavaVisitor(dir, package)
+{
+}
+
+void
+Slice::Gen::HolderVisitor::visitClassDecl(const ClassDeclPtr& p)
+{
+ writeHolder(p);
+}
+
+bool
+Slice::Gen::HolderVisitor::visitStructStart(const StructPtr& p)
+{
+ writeHolder(p);
+ return false;
+}
+
+void
+Slice::Gen::HolderVisitor::visitSequence(const SequencePtr& p)
+{
+ writeHolder(p);
+}
+
+void
+Slice::Gen::HolderVisitor::visitDictionary(const DictionaryPtr& p)
+{
+ writeHolder(p);
+}
+
+void
+Slice::Gen::HolderVisitor::visitEnum(const EnumPtr& p)
+{
+ writeHolder(p);
+}
+
+void
+Slice::Gen::HolderVisitor::writeHolder(const TypePtr& p)
+{
+ ContainedPtr contained = ContainedPtr::dynamicCast(p);
+ assert(contained);
+ string name = contained->name();
+ string absolute = getAbsolute(contained->scoped());
+ string holder = absolute + "Holder";
+
+ if (open(holder))
+ {
+ Output& out = output();
+ string typeS = typeToString(p, TypeModeIn, contained->scope());
+ out << sp << nl << "public final class " << name << "Holder";
+ out << sb;
+ out << nl << "public " << typeS << " value;";
+ out << eb;
+ close();
+ }
+}