summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorDwayne Boone <dwayne@zeroc.com>2007-11-15 12:31:05 -0330
committerDwayne Boone <dwayne@zeroc.com>2007-11-15 12:31:05 -0330
commitdbfa59a84326ff04403aac3437ea6135ea3de087 (patch)
tree1db9e25aa37a2d058a29fcf68a98ef7b3a169dc7 /cpp/src
parentFixed bug 2527 & 2530 (diff)
downloadice-dbfa59a84326ff04403aac3437ea6135ea3de087.tar.bz2
ice-dbfa59a84326ff04403aac3437ea6135ea3de087.tar.xz
ice-dbfa59a84326ff04403aac3437ea6135ea3de087.zip
Added slice2sl to mainline
Diffstat (limited to 'cpp/src')
-rw-r--r--cpp/src/Makefile5
-rw-r--r--cpp/src/Makefile.mak5
-rw-r--r--cpp/src/slice2sl/.depend2
-rwxr-xr-xcpp/src/slice2sl/Gen.cpp3292
-rw-r--r--cpp/src/slice2sl/Gen.h260
-rw-r--r--cpp/src/slice2sl/Main.cpp182
-rw-r--r--cpp/src/slice2sl/Makefile32
-rw-r--r--cpp/src/slice2sl/Makefile.mak56
8 files changed, 3830 insertions, 4 deletions
diff --git a/cpp/src/Makefile b/cpp/src/Makefile
index 497ce1253e0..1008738359d 100644
--- a/cpp/src/Makefile
+++ b/cpp/src/Makefile
@@ -15,15 +15,16 @@ SUBDIRS = IceUtil \
icecpp \
Slice \
slice2cpp \
+ slice2cppe \
slice2cs \
slice2freeze \
slice2freezej \
slice2docbook \
slice2java \
- slice2py \
- slice2cppe \
slice2javae \
+ slice2py \
slice2rb \
+ slice2sl \
slice2html \
Ice \
IceXML \
diff --git a/cpp/src/Makefile.mak b/cpp/src/Makefile.mak
index 04cb6872dee..9fce6f07267 100644
--- a/cpp/src/Makefile.mak
+++ b/cpp/src/Makefile.mak
@@ -18,15 +18,16 @@ SUBDIRS = icecpp
SUBDIRS = $(SUBDIRS) IceUtil \
Slice \
slice2cpp \
+ slice2cppe \
slice2cs \
slice2freeze \
slice2freezej \
slice2docbook \
slice2java \
- slice2py \
- slice2cppe \
slice2javae \
+ slice2py \
slice2rb \
+ slice2sl \
slice2html \
Ice \
IceXML \
diff --git a/cpp/src/slice2sl/.depend b/cpp/src/slice2sl/.depend
new file mode 100644
index 00000000000..fa885fb7b71
--- /dev/null
+++ b/cpp/src/slice2sl/.depend
@@ -0,0 +1,2 @@
+Gen$(OBJEXT): Gen.cpp ../../include/IceUtil/DisableWarnings.h ../../include/IceUtil/Functional.h ../../include/IceUtil/Handle.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Config.h Gen.h ../../include/Slice/CsUtil.h ../../include/Slice/Parser.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/InputUtil.h ../../include/IceUtil/OutputUtil.h ../../include/IceUtil/Algorithm.h ../../include/IceUtil/Iterator.h ../../include/IceUtil/UUID.h ../../include/Slice/Checksum.h ../../include/Slice/DotNetNames.h
+Main$(OBJEXT): Main.cpp ../../include/IceUtil/Options.h ../../include/IceUtil/Config.h ../../include/IceUtil/RecMutex.h ../../include/IceUtil/Lock.h ../../include/IceUtil/ThreadException.h ../../include/IceUtil/Exception.h ../../include/IceUtil/Shared.h ../../include/IceUtil/Mutex.h ../../include/IceUtil/Handle.h ../../include/Slice/Preprocessor.h Gen.h ../../include/Slice/CsUtil.h ../../include/Slice/Parser.h ../../include/IceUtil/InputUtil.h ../../include/IceUtil/OutputUtil.h
diff --git a/cpp/src/slice2sl/Gen.cpp b/cpp/src/slice2sl/Gen.cpp
new file mode 100755
index 00000000000..fef16d18686
--- /dev/null
+++ b/cpp/src/slice2sl/Gen.cpp
@@ -0,0 +1,3292 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2007 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <IceUtil/DisableWarnings.h>
+#include <IceUtil/Functional.h>
+#include <Gen.h>
+#include <limits>
+#include <sys/stat.h>
+#ifndef _WIN32
+#include <unistd.h>
+#else
+#include <direct.h>
+#endif
+#include <IceUtil/Algorithm.h>
+#include <IceUtil/Iterator.h>
+#include <IceUtil/UUID.h>
+#include <Slice/DotNetNames.h>
+
+using namespace std;
+using namespace Slice;
+
+//
+// Don't use "using namespace IceUtil", or VC++ 6.0 complains about
+// ambigious symbols for constructs like
+// "IceUtil::constMemFun(&Slice::Exception::isLocal)".
+//
+using IceUtil::Output;
+using IceUtil::nl;
+using IceUtil::sp;
+using IceUtil::sb;
+using IceUtil::eb;
+using IceUtil::spar;
+using IceUtil::epar;
+
+static string // Should be an anonymous namespace, but VC++ 6 can't handle that.
+sliceModeToIceMode(Operation::Mode opMode)
+{
+ string mode;
+ switch(opMode)
+ {
+ case Operation::Normal:
+ {
+ mode = "Ice.OperationMode.Normal";
+ break;
+ }
+ case Operation::Nonmutating:
+ {
+ mode = "Ice.OperationMode.Nonmutating";
+ break;
+ }
+ case Operation::Idempotent:
+ {
+ mode = "Ice.OperationMode.Idempotent";
+ break;
+ }
+ default:
+ {
+ assert(false);
+ break;
+ }
+ }
+ return mode;
+}
+
+static void
+emitDeprecate(const ContainedPtr& p1, const ContainedPtr& p2, Output& out, const string& type)
+{
+ string deprecateMetadata;
+ if(p1->findMetaData("deprecate", deprecateMetadata) ||
+ (p2 != 0 && p2->findMetaData("deprecate", deprecateMetadata)))
+ {
+ string deprecateReason = "This " + type + " has been deprecated.";
+ if(deprecateMetadata.find("deprecate:") == 0 && deprecateMetadata.size() > 10)
+ {
+ deprecateReason = deprecateMetadata.substr(10);
+ }
+ out << nl << "[System.Obsolete(\"" << deprecateReason << "\")]";
+ }
+}
+
+Slice::CsVisitor::CsVisitor(Output& out) : _out(out)
+{
+}
+
+Slice::CsVisitor::~CsVisitor()
+{
+}
+
+void
+Slice::CsVisitor::writeInheritedOperations(const ClassDefPtr& p)
+{
+ ClassList bases = p->bases();
+ if(!bases.empty() && !bases.front()->isInterface())
+ {
+ bases.pop_front();
+ }
+ if(!bases.empty())
+ {
+ _out << sp << nl << "#region Inherited Slice operations";
+
+ OperationList allOps;
+ for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q)
+ {
+ OperationList tmp = (*q)->allOperations();
+ allOps.splice(allOps.end(), tmp);
+ }
+ allOps.sort();
+ allOps.unique();
+ for(OperationList::const_iterator op = allOps.begin(); op != allOps.end(); ++op)
+ {
+ ClassDefPtr containingClass = ClassDefPtr::dynamicCast((*op)->container());
+ string name = fixId((*op)->name(), DotNet::ICloneable, true);
+
+ vector<string> params = getParams(*op);
+ vector<string> args = getArgs(*op);
+ string retS = typeToString((*op)->returnType());
+
+ _out << sp << nl << "public abstract " << retS << ' ' << name << spar << params;
+ _out << epar << ';';
+ }
+
+ _out << sp << nl << "#endregion"; // Inherited Slice operations
+ }
+}
+
+void
+Slice::CsVisitor::writeDispatchAndMarshalling(const ClassDefPtr& p)
+{
+ string name = fixId(p->name());
+ string scoped = p->scoped();
+ ClassList allBases = p->allBases();
+ StringList ids;
+
+#if defined(__IBMCPP__) && defined(NDEBUG)
+ //
+ // VisualAge C++ 6.0 does not see that ClassDef is a Contained,
+ // when inlining is on. The code below issues a warning: better
+ // than an error!
+ //
+ transform(allBases.begin(), allBases.end(), back_inserter(ids), ::IceUtil::constMemFun<string,ClassDef>(&Contained::scoped));
+#else
+ transform(allBases.begin(), allBases.end(), back_inserter(ids), ::IceUtil::constMemFun(&Contained::scoped));
+#endif
+
+ StringList other;
+ other.push_back(p->scoped());
+ other.push_back("::Ice::Object");
+ other.sort();
+ ids.merge(other);
+ ids.unique();
+
+ StringList::const_iterator firstIter = ids.begin();
+ StringList::const_iterator scopedIter = find(ids.begin(), ids.end(), scoped);
+ assert(scopedIter != ids.end());
+ StringList::difference_type scopedPos = ice_distance(firstIter, scopedIter);
+
+ _out << sp << nl << "#region Slice type-related members";
+
+ _out << sp << nl << "public static new string[] ids__ = ";
+ _out << sb;
+
+ {
+ StringList::const_iterator q = ids.begin();
+ while(q != ids.end())
+ {
+ _out << nl << '"' << *q << '"';
+ if(++q != ids.end())
+ {
+ _out << ',';
+ }
+ }
+ }
+ _out << eb << ";";
+
+ _out << sp << nl << "public override bool ice_isA(string s)";
+ _out << sb;
+ _out << nl << "return _System.Array.BinarySearch(ids__, 0, ids__.Length, s, IceUtil.StringUtil.OrdinalStringComparer) >= 0;";
+ _out << eb;
+
+ _out << sp << nl << "public override string[] ice_ids()";
+ _out << sb;
+ _out << nl << "return ids__;";
+ _out << eb;
+
+ _out << sp << nl << "public override string ice_id()";
+ _out << sb;
+ _out << nl << "return ids__[" << scopedPos << "];";
+ _out << eb;
+
+ _out << sp << nl << "public static new string ice_staticId()";
+ _out << sb;
+ _out << nl << "return ids__[" << scopedPos << "];";
+ _out << eb;
+
+ _out << sp << nl << "#endregion"; // Slice type-related members
+
+ // Marshalling support
+ DataMemberList allClassMembers = p->allClassDataMembers();
+ DataMemberList::const_iterator d;
+ DataMemberList members = p->dataMembers();
+ DataMemberList classMembers = p->classDataMembers();
+ ClassList bases = p->bases();
+ bool hasBaseClass = !bases.empty() && !bases.front()->isInterface();
+
+ _out << sp << nl << "#region Marshaling support";
+
+ _out << sp << nl << "public override void write__(IceInternal.BasicStream os__)";
+ _out << sb;
+ _out << nl << "os__.writeTypeId(ice_staticId());";
+ _out << nl << "os__.startWriteSlice();";
+ for(d = members.begin(); d != members.end(); ++d)
+ {
+ writeMarshalUnmarshalCode(_out, (*d)->type(), fixId(*d, DotNet::ICloneable, true),
+ true, false, false);
+ }
+ _out << nl << "os__.endWriteSlice();";
+ _out << nl << "base.write__(os__);";
+ _out << eb;
+
+ if(allClassMembers.size() != 0)
+ {
+ _out << sp << nl << "public sealed ";
+ if(hasBaseClass && bases.front()->declaration()->usesClasses())
+ {
+ _out << "new ";
+ }
+ _out << "class Patcher__ : IceInternal.Patcher<" << name << ">";
+ _out << sb;
+ _out << sp << nl << "internal Patcher__(string type, Ice.ObjectImpl instance";
+ if(allClassMembers.size() > 1)
+ {
+ _out << ", int member";
+ }
+ _out << ") : base(type)";
+ _out << sb;
+ _out << nl << "_instance = (" << name << ")instance;";
+ if(allClassMembers.size() > 1)
+ {
+ _out << nl << "_member = member;";
+ }
+ _out << eb;
+
+ _out << sp << nl << "public override void patch(Ice.Object v)";
+ _out << sb;
+ _out << nl << "try";
+ _out << sb;
+ if(allClassMembers.size() > 1)
+ {
+ _out << nl << "switch(_member)";
+ _out << sb;
+ }
+ int memberCount = 0;
+ for(d = allClassMembers.begin(); d != allClassMembers.end(); ++d)
+ {
+ if(allClassMembers.size() > 1)
+ {
+ _out.dec();
+ _out << nl << "case " << memberCount << ":";
+ _out.inc();
+ }
+ string memberName = fixId((*d)->name(), DotNet::ICloneable, true);
+ string memberType = typeToString((*d)->type());
+ _out << nl << "_instance." << memberName << " = (" << memberType << ")v;";
+ ContainedPtr contained = ContainedPtr::dynamicCast((*d)->type());
+ string sliceId = contained ? contained->scoped() : "::Ice::Object";
+ _out << nl << "_typeId = \"" << sliceId << "\";";
+ if(allClassMembers.size() > 1)
+ {
+ _out << nl << "break;";
+ }
+ memberCount++;
+ }
+ if(allClassMembers.size() > 1)
+ {
+ _out << eb;
+ }
+ _out << eb;
+ _out << nl << "catch(System.InvalidCastException)";
+ _out << sb;
+ _out << nl << "IceInternal.Ex.throwUOE(_typeId, v.ice_id());";
+ _out << eb;
+ _out << eb;
+
+ _out << sp << nl << "private " << name << " _instance;";
+ if(allClassMembers.size() > 1)
+ {
+ _out << nl << "private int _member;";
+ }
+ _out << nl << "private string _typeId;";
+ _out << eb;
+ }
+
+ _out << sp << nl << "public override void read__(IceInternal.BasicStream is__, bool rid__)";
+ _out << sb;
+ _out << nl << "if(rid__)";
+ _out << sb;
+ _out << nl << "/* string myId = */ is__.readTypeId();";
+ _out << eb;
+ _out << nl << "is__.startReadSlice();";
+ int classMemberCount = static_cast<int>(allClassMembers.size() - classMembers.size());
+ for(d = members.begin(); d != members.end(); ++d)
+ {
+ ostringstream patchParams;
+ patchParams << "this";
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast((*d)->type());
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast((*d)->type()))
+ {
+ if(classMembers.size() > 1 || allClassMembers.size() > 1)
+ {
+ patchParams << ", " << classMemberCount++;
+ }
+ }
+ writeMarshalUnmarshalCode(_out, (*d)->type(), fixId(*d, DotNet::ICloneable, true),
+ false, false, false, patchParams.str());
+ }
+ _out << nl << "is__.endReadSlice();";
+ _out << nl << "base.read__(is__, true);";
+ _out << eb;
+
+ _out << sp << nl << "#endregion"; // Marshalling support
+}
+
+string
+Slice::CsVisitor::getParamAttributes(const ParamDeclPtr& p)
+{
+ string result;
+ StringList metaData = p->getMetaData();
+ for(StringList::const_iterator i = metaData.begin(); i != metaData.end(); ++i)
+ {
+ static const string prefix = "cs:attribute:";
+ if(i->find(prefix) == 0)
+ {
+ result += "[" + i->substr(prefix.size()) + "] ";
+ }
+ }
+ return result;
+}
+
+vector<string>
+Slice::CsVisitor::getParams(const OperationPtr& op)
+{
+ vector<string> params;
+ ParamDeclList paramList = op->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ string param = getParamAttributes(*q);
+ if((*q)->isOutParam())
+ {
+ param += "out ";
+ }
+ param += typeToString((*q)->type()) + " " + fixId((*q)->name());
+ params.push_back(param);
+ }
+ return params;
+}
+
+vector<string>
+Slice::CsVisitor::getParamsAsync(const OperationPtr& op, bool amd)
+{
+ vector<string> params;
+
+ string name = fixId(op->name());
+ ContainerPtr container = op->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container); // Get the class containing the op.
+ string scope = fixId(cl->scope());
+ params.push_back(scope + (amd ? "AMD_" : "AMI_") + cl->name() + '_' + op->name() + " cb__");
+
+ ParamDeclList paramList = op->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if(!(*q)->isOutParam())
+ {
+ params.push_back(getParamAttributes(*q) + typeToString((*q)->type()) + " " + fixId((*q)->name()));
+ }
+ }
+ return params;
+}
+
+vector<string>
+Slice::CsVisitor::getParamsAsyncCB(const OperationPtr& op)
+{
+ vector<string> params;
+
+ TypePtr ret = op->returnType();
+ if(ret)
+ {
+ params.push_back(typeToString(ret) + " ret__");
+ }
+
+ ParamDeclList paramList = op->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if((*q)->isOutParam())
+ {
+ params.push_back(getParamAttributes(*q) + typeToString((*q)->type()) + ' ' + fixId((*q)->name()));
+ }
+ }
+
+ return params;
+}
+
+vector<string>
+Slice::CsVisitor::getArgs(const OperationPtr& op)
+{
+ vector<string> args;
+ ParamDeclList paramList = op->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ string arg = fixId((*q)->name());
+ if((*q)->isOutParam())
+ {
+ arg = "out " + arg;
+ }
+ args.push_back(arg);
+ }
+ return args;
+}
+
+vector<string>
+Slice::CsVisitor::getArgsAsync(const OperationPtr& op)
+{
+ vector<string> args;
+
+ args.push_back("cb__");
+
+ ParamDeclList paramList = op->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if(!(*q)->isOutParam())
+ {
+ args.push_back(fixId((*q)->name()));
+ }
+ }
+ return args;
+}
+
+vector<string>
+Slice::CsVisitor::getArgsAsyncCB(const OperationPtr& op)
+{
+ vector<string> args;
+
+ TypePtr ret = op->returnType();
+ if(ret)
+ {
+ args.push_back("ret__");
+ }
+
+ ParamDeclList paramList = op->parameters();
+ for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
+ {
+ if((*q)->isOutParam())
+ {
+ args.push_back(fixId((*q)->name()));
+ }
+ }
+
+ return args;
+}
+
+void
+Slice::CsVisitor::emitAttributes(const ContainedPtr& p)
+{
+ StringList metaData = p->getMetaData();
+ for(StringList::const_iterator i = metaData.begin(); i != metaData.end(); ++i)
+ {
+ static const string prefix = "cs:attribute:";
+ if(i->find(prefix) == 0)
+ {
+ _out << nl << '[' << i->substr(prefix.size()) << ']';
+ }
+ }
+}
+
+Slice::Gen::Gen(const string& name, const string& base, const vector<string>& includePaths, const string& dir) :
+ _includePaths(includePaths)
+{
+ string fileBase = base;
+ string::size_type pos = base.find_last_of("/\\");
+ if(pos != string::npos)
+ {
+ fileBase = base.substr(pos + 1);
+ }
+ string file = fileBase + ".cs";
+ string fileImpl = fileBase + "I.cs";
+
+ if(!dir.empty())
+ {
+ file = dir + '/' + file;
+ fileImpl = dir + '/' + fileImpl;
+ }
+
+ _out.open(file.c_str());
+ if(!_out)
+ {
+ cerr << name << ": can't open `" << file << "' for writing" << endl;
+ return;
+ }
+ printHeader();
+
+ _out << nl << "// Generated from file `" << fileBase << ".ice'";
+
+ _out << sp << nl << "using _System = global::System;";
+ _out << nl << "using _Microsoft = global::Microsoft;";
+}
+
+Slice::Gen::~Gen()
+{
+ if(_out.isOpen())
+ {
+ _out << '\n';
+ }
+ if(_impl.isOpen())
+ {
+ _impl << '\n';
+ }
+}
+
+bool
+Slice::Gen::operator!() const
+{
+ return !_out;
+}
+
+void
+Slice::Gen::generate(const UnitPtr& p)
+{
+
+ CsGenerator::validateMetaData(p);
+
+ UnitVisitor unitVisitor(_out);
+ p->visit(&unitVisitor, false);
+
+ TypesVisitor typesVisitor(_out);
+ p->visit(&typesVisitor, false);
+
+ ProxyVisitor proxyVisitor(_out);
+ p->visit(&proxyVisitor, false);
+
+ OpsVisitor opsVisitor(_out);
+ p->visit(&opsVisitor, false);
+
+ HelperVisitor helperVisitor(_out);
+ p->visit(&helperVisitor, false);
+
+ DispatcherVisitor dispatcherVisitor(_out);
+ p->visit(&dispatcherVisitor, false);
+
+ AsyncVisitor asyncVisitor(_out);
+ p->visit(&asyncVisitor, false);
+}
+
+void
+Slice::Gen::printHeader()
+{
+ static const char* header =
+"// **********************************************************************\n"
+"//\n"
+"// Copyright (c) 2003-2007 ZeroC, Inc. All rights reserved.\n"
+"//\n"
+"// This copy of Ice is licensed to you under the terms described in the\n"
+"// ICE_LICENSE file included in this distribution.\n"
+"//\n"
+"// **********************************************************************\n"
+ ;
+
+ _out << header;
+ _out << "\n// Ice version " << ICE_STRING_VERSION;
+}
+
+Slice::Gen::UnitVisitor::UnitVisitor(IceUtil::Output& out) :
+ CsVisitor(out), _globalMetaDataDone(false)
+{
+}
+
+bool
+Slice::Gen::UnitVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!_globalMetaDataDone)
+ {
+ DefinitionContextPtr dc = p->definitionContext();
+ StringList globalMetaData = dc->getMetaData();
+
+ static const string attributePrefix = "cs:attribute:";
+
+ if(!globalMetaData.empty())
+ {
+ _out << sp;
+ }
+ for(StringList::const_iterator q = globalMetaData.begin(); q != globalMetaData.end(); ++q)
+ {
+ string::size_type pos = q->find(attributePrefix);
+ if(pos == 0)
+ {
+ string attrib = q->substr(pos + attributePrefix.size());
+ _out << nl << '[' << attrib << ']';
+ }
+ }
+ _globalMetaDataDone = true; // Do this only once per source file.
+ }
+ return false;
+}
+
+Slice::Gen::TypesVisitor::TypesVisitor(IceUtil::Output& out) :
+ CsVisitor(out)
+{
+}
+
+bool
+Slice::Gen::TypesVisitor::visitModuleStart(const ModulePtr& p)
+{
+ DictionaryList dicts;
+ if(p->hasOnlyDictionaries(dicts))
+ {
+ //
+ // If this module contains only dictionaries and they
+ // all use the new dictionary mapping, we don't need to generate
+ // anything for the dictionary types. The early return prevents
+ // an empty namespace from being emitted--the namespace will
+ // be emitted later by the dictionary helper (which is generated
+ // for both old and new dictionaries).
+ //
+ bool foundOld = false;
+ for(DictionaryList::const_iterator i = dicts.begin(); i != dicts.end() && !foundOld; ++i)
+ {
+ if((*i)->hasMetaData("clr:collection"))
+ {
+ foundOld = true;
+ }
+ }
+ if(!foundOld)
+ {
+ return false;
+ }
+ }
+
+ string name = fixId(p->name());
+ _out << sp;
+ emitAttributes(p);
+ _out << nl << "namespace " << name;
+
+ _out << sb;
+
+ return true;
+}
+
+void
+Slice::Gen::TypesVisitor::visitModuleEnd(const ModulePtr&)
+{
+ _out << eb;
+}
+
+bool
+Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+/*
+ if(p->isInterface() && !p->isLocal())
+ {
+ return false;
+ }
+*/
+
+ string name = p->name();
+ ClassList bases = p->bases();
+ bool hasBaseClass = !bases.empty() && !bases.front()->isInterface();
+
+ _out << sp;
+ emitAttributes(p);
+
+ if(p->isInterface())
+ {
+ _out << nl << "public interface " << fixId(name) << " : ";
+ if(p->isLocal())
+ {
+ _out << name << "OperationsNC_";
+ }
+ else
+ {
+ _out << "Ice.Object, " << name << "OperationsNC_";
+ }
+ if(!bases.empty())
+ {
+ ClassList::const_iterator q = bases.begin();
+ while(q != bases.end())
+ {
+ _out << ", " << fixId((*q)->scoped());
+ q++;
+ }
+ }
+ }
+ else
+ {
+ _out << nl << "public ";
+ if(p->isAbstract())
+ {
+ _out << "abstract ";
+ }
+ _out << "class " << fixId(name);
+
+ bool baseWritten = false;
+
+ if(!hasBaseClass)
+ {
+ if(!p->isLocal())
+ {
+ _out << " : Ice.ObjectImpl";
+ baseWritten = true;
+ }
+ }
+ else
+ {
+ _out << " : " << fixId(bases.front()->scoped());
+ baseWritten = true;
+ bases.pop_front();
+ }
+ if(p->isAbstract())
+ {
+ if(baseWritten)
+ {
+ _out << ", ";
+ }
+ else
+ {
+ _out << " : ";
+ baseWritten = true;
+ }
+
+ _out << name << "OperationsNC_";
+ }
+ for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q)
+ {
+ if((*q)->isAbstract())
+ {
+ if(baseWritten)
+ {
+ _out << ", ";
+ }
+ else
+ {
+ _out << " : ";
+ baseWritten = true;
+ }
+
+ _out << fixId((*q)->scoped());
+ }
+ }
+ }
+
+ _out << sb;
+
+ if(!p->isInterface())
+ {
+ if(p->hasDataMembers() && !p->hasOperations())
+ {
+ _out << sp << nl << "#region Slice data members";
+ }
+ else if(p->hasDataMembers())
+ {
+ _out << sp << nl << "#region Slice data members and operations";
+ }
+ else if(p->hasOperations())
+ {
+ _out << sp << nl << "#region Slice operations";
+ }
+ }
+
+ return true;
+}
+
+void
+Slice::Gen::TypesVisitor::visitClassDefEnd(const ClassDefPtr& p)
+{
+ string name = fixId(p->name());
+ DataMemberList classMembers = p->classDataMembers();
+ DataMemberList allClassMembers = p->allClassDataMembers();
+ DataMemberList dataMembers = p->dataMembers();
+ DataMemberList allDataMembers = p->allDataMembers();
+ ClassList bases = p->bases();
+ bool hasBaseClass = !bases.empty() && !bases.front()->isInterface();
+ DataMemberList::const_iterator d;
+
+ if(p->isInterface())
+ {
+ _out << eb;
+ return;
+ }
+
+ if(p->hasDataMembers() && !p->hasOperations())
+ {
+ _out << sp << nl << "#endregion"; // Slice data members"
+ }
+ else if(p->hasDataMembers())
+ {
+ _out << sp << nl << "#endregion"; // Slice data members and operations"
+ }
+ else if(p->hasOperations())
+ {
+ _out << sp << nl << "#endregion"; // Slice operations"
+ }
+
+ if(!allDataMembers.empty())
+ {
+ _out << sp << nl << "#region Constructors";
+
+ _out << sp << nl << "public " << name << spar << epar;
+ if(hasBaseClass)
+ {
+ _out << " : base()";
+ }
+ _out << sb;
+ _out << eb;
+
+ _out << sp << nl << "public " << name << spar;
+ vector<string> paramDecl;
+ for(d = allDataMembers.begin(); d != allDataMembers.end(); ++d)
+ {
+ string memberName = fixId((*d)->name());
+ string memberType = typeToString((*d)->type());
+ paramDecl.push_back(memberType + " " + memberName);
+ }
+ _out << paramDecl << epar;
+ if(hasBaseClass && allDataMembers.size() != dataMembers.size())
+ {
+ _out << " : base" << spar;
+ vector<string> baseParamNames;
+ DataMemberList baseDataMembers = bases.front()->allDataMembers();
+ for(d = baseDataMembers.begin(); d != baseDataMembers.end(); ++d)
+ {
+ baseParamNames.push_back(fixId((*d)->name()));
+ }
+ _out << baseParamNames << epar;
+ }
+ _out << sb;
+ vector<string> paramNames;
+ for(d = dataMembers.begin(); d != dataMembers.end(); ++d)
+ {
+ paramNames.push_back(fixId((*d)->name()));
+ }
+ for(vector<string>::const_iterator i = paramNames.begin(); i != paramNames.end(); ++i)
+ {
+ _out << nl << "this." << *i << " = " << *i << ';';
+ }
+ _out << eb;
+
+ _out << sp << nl << "#endregion"; // Constructors
+ }
+
+ writeInheritedOperations(p);
+ if(!p->isLocal())
+ {
+ string scoped = p->scoped();
+ ClassList allBases = p->allBases();
+ StringList ids;
+
+ #if defined(__IBMCPP__) && defined(NDEBUG)
+ //
+ // VisualAge C++ 6.0 does not see that ClassDef is a Contained,
+ // when inlining is on. The code below issues a warning: better
+ // than an error!
+ //
+ transform(allBases.begin(), allBases.end(), back_inserter(ids), ::IceUtil::constMemFun<string,ClassDef>(&Contained::scoped));
+ #else
+ transform(allBases.begin(), allBases.end(), back_inserter(ids), ::IceUtil::constMemFun(&Contained::scoped));
+ #endif
+
+ StringList other;
+ other.push_back(scoped);
+ other.push_back("::Ice::Object");
+ other.sort();
+ ids.merge(other);
+ ids.unique();
+
+ StringList::const_iterator firstIter = ids.begin();
+ StringList::const_iterator scopedIter = find(ids.begin(), ids.end(), scoped);
+ assert(scopedIter != ids.end());
+ StringList::difference_type scopedPos = ice_distance(firstIter, scopedIter);
+
+ _out << sp << nl << "#region Slice type-related members";
+
+ _out << sp << nl << "public static new string[] ids__ = ";
+ _out << sb;
+
+ {
+ StringList::const_iterator q = ids.begin();
+ while(q != ids.end())
+ {
+ _out << nl << '"' << *q << '"';
+ if(++q != ids.end())
+ {
+ _out << ',';
+ }
+ }
+ }
+ _out << eb << ";";
+
+ _out << sp << nl << "public override bool ice_isA(string s)";
+ _out << sb;
+ _out << nl << "return _System.Array.BinarySearch(ids__, 0, ids__.Length, s, IceUtil.StringUtil.OrdinalStringComparer) >= 0;";
+ _out << eb;
+
+ _out << sp << nl << "public override string[] ice_ids()";
+ _out << sb;
+ _out << nl << "return ids__;";
+ _out << eb;
+
+ _out << sp << nl << "public override string ice_id()";
+ _out << sb;
+ _out << nl << "return ids__[" << scopedPos << "];";
+ _out << eb;
+
+ _out << sp << nl << "public static new string ice_staticId()";
+ _out << sb;
+ _out << nl << "return ids__[" << scopedPos << "];";
+ _out << eb;
+
+ _out << sp << nl << "#endregion"; // Slice type-related members
+
+ // Marshalling support
+ _out << sp << nl << "#region Marshaling support";
+
+ _out << sp << nl << "public override void write__(IceInternal.BasicStream os__)";
+ _out << sb;
+ _out << nl << "os__.writeTypeId(ice_staticId());";
+ _out << nl << "os__.startWriteSlice();";
+ for(d = dataMembers.begin(); d != dataMembers.end(); ++d)
+ {
+ writeMarshalUnmarshalCode(_out, (*d)->type(), fixId(*d, DotNet::ICloneable, true),
+ true, false, false);
+ }
+ _out << nl << "os__.endWriteSlice();";
+ _out << nl << "base.write__(os__);";
+ _out << eb;
+
+ if(allClassMembers.size() != 0)
+ {
+ _out << sp << nl << "public sealed ";
+ if(hasBaseClass && bases.front()->declaration()->usesClasses())
+ {
+ _out << "new ";
+ }
+ _out << "class Patcher__ : IceInternal.Patcher<" << name << ">";
+ _out << sb;
+ _out << sp << nl << "internal Patcher__(string type, Ice.ObjectImpl instance";
+ if(allClassMembers.size() > 1)
+ {
+ _out << ", int member";
+ }
+ _out << ") : base(type)";
+ _out << sb;
+ _out << nl << "_instance = (" << name << ")instance;";
+ if(allClassMembers.size() > 1)
+ {
+ _out << nl << "_member = member;";
+ }
+ _out << eb;
+
+ _out << sp << nl << "public override void patch(Ice.Object v)";
+ _out << sb;
+ _out << nl << "try";
+ _out << sb;
+ if(allClassMembers.size() > 1)
+ {
+ _out << nl << "switch(_member)";
+ _out << sb;
+ }
+ int memberCount = 0;
+ for(d = allClassMembers.begin(); d != allClassMembers.end(); ++d)
+ {
+ if(allClassMembers.size() > 1)
+ {
+ _out.dec();
+ _out << nl << "case " << memberCount << ":";
+ _out.inc();
+ }
+ string memberName = fixId((*d)->name(), DotNet::ICloneable, true);
+ string memberType = typeToString((*d)->type());
+ _out << nl << "_instance." << memberName << " = (" << memberType << ")v;";
+ _out << nl << "_typeId = \"" << memberType << "\";";
+ if(allClassMembers.size() > 1)
+ {
+ _out << nl << "break;";
+ }
+ memberCount++;
+ }
+ if(allClassMembers.size() > 1)
+ {
+ _out << eb;
+ }
+ _out << eb;
+ _out << nl << "catch(System.InvalidCastException)";
+ _out << sb;
+ _out << nl << "IceInternal.Ex.throwUOE(_typeId, v.ice_id());";
+ _out << eb;
+ _out << eb;
+
+ _out << sp << nl << "private " << name << " _instance;";
+ if(allClassMembers.size() > 1)
+ {
+ _out << nl << "private int _member;";
+ }
+ _out << nl << "private string _typeId;";
+ _out << eb;
+ }
+
+ _out << sp << nl << "public override void read__(IceInternal.BasicStream is__, bool rid__)";
+ _out << sb;
+ _out << nl << "if(rid__)";
+ _out << sb;
+ _out << nl << "/* string myId = */ is__.readTypeId();";
+ _out << eb;
+ _out << nl << "is__.startReadSlice();";
+ int classMemberCount = static_cast<int>(allClassMembers.size() - classMembers.size());
+ for(d = dataMembers.begin(); d != dataMembers.end(); ++d)
+ {
+ ostringstream patchParams;
+ patchParams << "this";
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast((*d)->type());
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast((*d)->type()))
+ {
+ if(classMembers.size() > 1 || allClassMembers.size() > 1)
+ {
+ patchParams << ", " << classMemberCount++;
+ }
+ }
+ writeMarshalUnmarshalCode(_out, (*d)->type(), fixId(*d, DotNet::ICloneable, true),
+ false, false, false, patchParams.str());
+ }
+ _out << nl << "is__.endReadSlice();";
+ _out << nl << "base.read__(is__, true);";
+ _out << eb;
+
+ _out << sp << nl << "#endregion"; // Marshalling support
+ }
+
+ _out << eb;
+}
+
+void
+Slice::Gen::TypesVisitor::visitOperation(const OperationPtr& p)
+{
+ ClassDefPtr classDef = ClassDefPtr::dynamicCast(p->container());
+ if(classDef->isInterface())
+ {
+ return;
+ }
+
+ string name = p->name();
+ ParamDeclList paramList = p->parameters();
+ vector<string> params;
+ vector<string> args;
+ string retS;
+
+ params = getParams(p);
+ args = getArgs(p);
+ name = fixId(name, DotNet::ICloneable, true);
+ retS = typeToString(p->returnType());
+
+ _out << sp;
+ emitAttributes(p);
+ _out << nl << "public abstract ";
+ _out << retS << " " << name << spar << params << epar;
+ _out << ";";
+}
+
+void
+Slice::Gen::TypesVisitor::visitSequence(const SequencePtr& p)
+{
+ //
+ // No need to generate anything if the sequence is mapped as an array.
+ //
+ if(!p->hasMetaData("clr:collection"))
+ {
+ return;
+ }
+
+ //
+ // No need to generate anything for custom sequences.
+ //
+ string prefix = "clr:type:";
+ string meta;
+ if(p->findMetaData(prefix, meta))
+ {
+ return;
+ }
+
+ string name = fixId(p->name());
+ string s = typeToString(p->type());
+
+ _out << sp;
+
+ emitDeprecate(p, 0, _out, "type");
+
+ emitAttributes(p);
+ _out << nl << "public class " << name
+ << " : Ice.CollectionBase<" << s << ">, _System.ICloneable";
+ _out << sb;
+
+ _out << sp << nl << "#region Constructors";
+
+ _out << sp << nl << "public " << name << "() : base()";
+ _out << sb;
+ _out << eb;
+
+ _out << sp << nl << "public " << name << "(int capacity) : base(capacity)";
+ _out << sb;
+ _out << eb;
+
+ _out << sp << nl << "public " << name << "(" << s << "[] a__) : base(a__)";
+ _out << sb;
+ _out << eb;
+
+ _out << sp << nl << "public " << name << "(_System.Collections.Generic.IEnumerable<" << s << "> l__) : base(l__)";
+ _out << sb;
+ _out << eb;
+
+ _out << sp << nl << "#endregion"; // Constructors
+
+ _out << sp << nl << "#region Implicit conversion to generic List";
+
+ _out << sp << nl << "public static implicit operator _System.Collections.Generic.List<"
+ << s << ">(" << name << " s__)";
+ _out << sb;
+ _out << nl << "return s__.list_;";
+ _out << eb;
+
+ _out << sp << nl << "#endregion"; // Implicit conversion to generic List
+
+ _out << sp << nl << "#region Operations returning a new sequence";
+
+ _out << sp << nl << "public virtual " << name << " GetRange(int index, int count)";
+ _out << sb;
+ _out << nl << "_System.Collections.Generic.List<" << s << "> l = list_.GetRange(index, count);";
+ _out << nl << name << " r = new " << name << "(l.Count);";
+ _out << nl << "r.list_.AddRange(l);";
+ _out << nl << "return r;";
+ _out << eb;
+
+ _out << sp << nl << "public static " << name << " Repeat(" << s << " value, int count)";
+ _out << sb;
+ _out << nl << name << " r = new " << name << "(count);";
+ _out << nl << "for(int i = 0; i < count; ++i)";
+ _out << sb;
+ _out << nl << "r.Add(value);";
+ _out << eb;
+ _out << nl << "return r;";
+ _out << eb;
+
+ _out << sp << nl << "public object Clone()";
+ _out << sb;
+ _out << nl << name << " s = new " << name << "(Count);";
+ _out << nl << "s.list_.AddRange(list_);";
+ _out << nl << "return s;";
+ _out << eb;
+
+ _out << sp << nl << "#endregion"; // Operations returning a new sequence
+
+ _out << eb;
+}
+
+bool
+Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
+{
+ string name = fixId(p->name());
+ ExceptionPtr base = p->base();
+
+ _out << sp;
+
+ emitDeprecate(p, 0, _out, "type");
+
+ emitAttributes(p);
+ _out << nl << "public class " << name << " : ";
+ if(base)
+ {
+ _out << fixId(base->scoped());
+ }
+ else
+ {
+ _out << (p->isLocal() ? "Ice.LocalException" : "Ice.UserException");
+ }
+ _out << sb;
+
+ if(!p->dataMembers().empty())
+ {
+ _out << sp << nl << "#region Slice data members";
+ }
+
+ return true;
+}
+
+void
+Slice::Gen::TypesVisitor::visitExceptionEnd(const ExceptionPtr& p)
+{
+ string name = fixId(p->name());
+
+ DataMemberList allDataMembers = p->allDataMembers();
+ DataMemberList dataMembers = p->dataMembers();
+ DataMemberList::const_iterator q;
+
+ vector<string> allParamDecl;
+ for(q = allDataMembers.begin(); q != allDataMembers.end(); ++q)
+ {
+ string memberName = fixId((*q)->name());
+ string memberType = typeToString((*q)->type());
+ allParamDecl.push_back(memberType + " " + memberName);
+ }
+
+ vector<string> paramNames;
+ for(q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ paramNames.push_back(fixId((*q)->name()));
+ }
+
+ vector<string> paramDecl;
+ for(q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ string memberName = fixId((*q)->name());
+ string memberType = typeToString((*q)->type());
+ paramDecl.push_back(memberType + " " + memberName);
+ }
+
+ vector<string> baseParamNames;
+ DataMemberList baseDataMembers;
+
+ if(p->base())
+ {
+ baseDataMembers = p->base()->allDataMembers();
+ for(q = baseDataMembers.begin(); q != baseDataMembers.end(); ++q)
+ {
+ baseParamNames.push_back(fixId((*q)->name()));
+ }
+ }
+
+ if(!dataMembers.empty())
+ {
+ _out << sp << nl << "#endregion"; // Slice data members
+ }
+
+ _out << sp << nl << "#region Constructors";
+
+ _out << sp << nl << "public " << name << "()";
+ _out << sb;
+ _out << eb;
+
+ _out << sp << nl << "public " << name << "(_System.Exception ex__) : base(ex__)";
+ _out << sb;
+ _out << eb;
+
+ if(!allDataMembers.empty())
+ {
+ if(!dataMembers.empty())
+ {
+ _out << sp << nl << "private void initDM__" << spar << paramDecl << epar;
+ _out << sb;
+ for(q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ string name = fixId((*q)->name(), DotNet::ApplicationException, false);
+ _out << nl << "this." << name << " = " << fixId((*q)->name()) << ';';
+ }
+ _out << eb;
+ }
+
+ _out << sp << nl << "public " << name << spar << allParamDecl << epar;
+ if(p->base() && allDataMembers.size() != dataMembers.size())
+ {
+ _out << " : base" << spar << baseParamNames << epar;
+ }
+ _out << sb;
+ if(!dataMembers.empty())
+ {
+ _out << nl << "initDM__" << spar << paramNames << epar << ';';
+ }
+ _out << eb;
+
+ vector<string> exceptionParam;
+ exceptionParam.push_back("ex__");
+ vector<string> exceptionDecl;
+ exceptionDecl.push_back("_System.Exception ex__");
+ _out << sp << nl << "public " << name << spar << allParamDecl << exceptionDecl << epar << " : base" << spar;
+ if(p->base() && allDataMembers.size() != dataMembers.size())
+ {
+ _out << baseParamNames;
+ }
+ _out << exceptionParam << epar;
+ _out << sb;
+ if(!dataMembers.empty())
+ {
+ _out << nl << "initDM__" << spar << paramNames << epar << ';';
+ }
+ _out << eb;
+ }
+
+ _out << sp << nl << "#endregion"; // Constructors
+
+ _out << sp << nl << "#region Object members";
+
+ _out << sp << nl << "public override int GetHashCode()";
+ _out << sb;
+ _out << nl << "int h__ = 0;";
+ for(q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ string memberName = fixId((*q)->name(), DotNet::ApplicationException);
+ bool isValue = isValueType((*q)->type());
+ if(!isValue)
+ {
+ _out << nl << "if((object)" << memberName << " != null)";
+ _out << sb;
+ }
+ _out << nl << "h__ = 5 * h__ + " << memberName << ".GetHashCode();";
+ if(!isValue)
+ {
+ _out << eb;
+ }
+ }
+ _out << nl << "return h__;";
+ _out << eb;
+
+ _out << sp << nl << "public override bool Equals(object other__)";
+ _out << sb;
+ _out << nl << "if(other__ == null)";
+ _out << sb;
+ _out << nl << "return false;";
+ _out << eb;
+ _out << nl << "if(object.ReferenceEquals(this, other__))";
+ _out << sb;
+ _out << nl << "return true;";
+ _out << eb;
+ _out << nl << "if(!(other__ is " << name << "))";
+ _out << sb;
+ _out << nl << "return false;";
+ _out << eb;
+ for(q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ string memberName = fixId((*q)->name(), DotNet::ApplicationException);
+ bool isValue = isValueType((*q)->type());
+ if(!isValue)
+ {
+ _out << nl << "if(" << memberName << " == null)";
+ _out << sb;
+ _out << nl << "if(((" << name << ")other__)." << memberName << " != null)";
+ _out << sb;
+ _out << nl << "return false;";
+ _out << eb;
+ _out << eb;
+ _out << nl << "else";
+ _out << sb;
+ }
+ _out << nl << "if(!" << memberName << ".Equals(((" << name << ")other__)." << memberName << "))";
+ _out << sb;
+ _out << nl << "return false;";
+ _out << eb;
+ if(!isValue)
+ {
+ _out << eb;
+ }
+ }
+ _out << nl << "return true;";
+ _out << eb;
+
+ _out << sp << nl << "#endregion"; // Object members
+
+ _out << sp << nl << "#region Comparison members";
+
+ _out << sp << nl << "public static bool operator==(" << name << " lhs__, " << name << " rhs__)";
+ _out << sb;
+ _out << nl << "return Equals(lhs__, rhs__);";
+ _out << eb;
+
+ _out << sp << nl << "public static bool operator!=(" << name << " lhs__, " << name << " rhs__)";
+ _out << sb;
+ _out << nl << "return !Equals(lhs__, rhs__);";
+ _out << eb;
+
+ _out << sp << nl << "#endregion"; // Comparison members
+
+ if(!p->isLocal())
+ {
+ _out << sp << nl << "#region Marshaling support";
+
+ string scoped = p->scoped();
+ ExceptionPtr base = p->base();
+
+ _out << sp << nl << "public override void write__(IceInternal.BasicStream os__)";
+ _out << sb;
+ _out << nl << "os__.writeString(\"" << scoped << "\");";
+ _out << nl << "os__.startWriteSlice();";
+ for(q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ writeMarshalUnmarshalCode(_out, (*q)->type(), fixId(*q, DotNet::ApplicationException),
+ true, false, false);
+ }
+ _out << nl << "os__.endWriteSlice();";
+ if(base)
+ {
+ _out << nl << "base.write__(os__);";
+ }
+ _out << eb;
+
+ DataMemberList allClassMembers = p->allClassDataMembers();
+ if(allClassMembers.size() != 0)
+ {
+ _out << sp << nl << "public sealed ";
+ if(base && base->usesClasses())
+ {
+ _out << "new ";
+ }
+ _out << "class Patcher__ : IceInternal.Patcher<" << name << ">";
+ _out << sb;
+ _out << sp << nl << "internal Patcher__(string type, Ice.Exception instance";
+ if(allClassMembers.size() > 1)
+ {
+ _out << ", int member";
+ }
+ _out << ") : base(type)";
+ _out << sb;
+ _out << nl << "_instance = (" << name << ")instance;";
+ if(allClassMembers.size() > 1)
+ {
+ _out << nl << "_member = member;";
+ }
+ _out << eb;
+
+ _out << sp << nl << "public override void patch(Ice.Object v)";
+ _out << sb;
+ _out << nl << "try";
+ _out << sb;
+ if(allClassMembers.size() > 1)
+ {
+ _out << nl << "switch(_member)";
+ _out << sb;
+ }
+ int memberCount = 0;
+ for(q = allClassMembers.begin(); q != allClassMembers.end(); ++q)
+ {
+ if(allClassMembers.size() > 1)
+ {
+ _out.dec();
+ _out << nl << "case " << memberCount << ":";
+ _out.inc();
+ }
+ string memberName = fixId((*q)->name(), DotNet::ApplicationException);
+ string memberType = typeToString((*q)->type());
+ _out << nl << "_instance." << memberName << " = (" << memberType << ")v;";
+ ContainedPtr contained = ContainedPtr::dynamicCast((*q)->type());
+ string sliceId = contained ? contained->scoped() : "::Ice::Object";
+ _out << nl << "_typeId = \"" << sliceId << "\";";
+ if(allClassMembers.size() > 1)
+ {
+ _out << nl << "break;";
+ }
+ memberCount++;
+ }
+ if(allClassMembers.size() > 1)
+ {
+ _out << eb;
+ }
+ _out << eb;
+ _out << nl << "catch(System.InvalidCastException)";
+ _out << sb;
+ _out << nl << "IceInternal.Ex.throwUOE(_typeId, v.ice_id());";
+ _out << eb;
+ _out << eb;
+
+ _out << sp << nl << "private " << name << " _instance;";
+ if(allClassMembers.size() > 1)
+ {
+ _out << nl << "private int _member;";
+ }
+ _out << nl << "private string _typeId;";
+ _out << eb;
+ }
+
+ _out << sp << nl << "public override void read__(IceInternal.BasicStream is__, bool rid__)";
+ _out << sb;
+ _out << nl << "if(rid__)";
+ _out << sb;
+ _out << nl << "/* string myId = */ is__.readString();";
+ _out << eb;
+ _out << nl << "is__.startReadSlice();";
+ DataMemberList classMembers = p->classDataMembers();
+ int classMemberCount = static_cast<int>(allClassMembers.size() - classMembers.size());
+ for(q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ ostringstream patchParams;
+ patchParams << "this";
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast((*q)->type());
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast((*q)->type()))
+ {
+ if(classMembers.size() > 1 || allClassMembers.size() > 1)
+ {
+ patchParams << ", " << classMemberCount++;
+ }
+ }
+ writeMarshalUnmarshalCode(_out, (*q)->type(), fixId((*q)->name(), DotNet::ApplicationException),
+ false, false, false, patchParams.str());
+ }
+ _out << nl << "is__.endReadSlice();";
+ if(base)
+ {
+ _out << nl << "base.read__(is__, true);";
+ }
+ _out << eb;
+
+ if(!base || base && !base->usesClasses())
+ {
+ _out << sp << nl << "public override bool usesClasses__()";
+ _out << sb;
+ _out << nl << "return true;";
+ _out << eb;
+ }
+
+ _out << sp << nl << "#endregion"; // Marshalling support
+ }
+
+ _out << eb;
+}
+
+bool
+Slice::Gen::TypesVisitor::visitStructStart(const StructPtr& p)
+{
+ string name = fixId(p->name());
+
+ _out << sp;
+
+ emitDeprecate(p, 0, _out, "type");
+
+ emitAttributes(p);
+ if(isValueType(p))
+ {
+ _out << nl << "public struct " << name;
+ }
+ else
+ {
+ _out << nl << "public class " << name << " : _System.ICloneable";
+ }
+ _out << sb;
+
+ _out << sp << nl << "#region Slice data members";
+
+ return true;
+}
+
+void
+Slice::Gen::TypesVisitor::visitStructEnd(const StructPtr& p)
+{
+ string name = fixId(p->name());
+
+ DataMemberList classMembers = p->classDataMembers();
+ DataMemberList dataMembers = p->dataMembers();
+ DataMemberList::const_iterator q;
+
+ bool propertyMapping = p->hasMetaData("clr:property");
+
+ _out << sp << nl << "#endregion"; // Slice data members
+
+ bool isClass = !isValueType(p);
+
+ _out << sp << nl << "#region Constructor";
+ if(isClass)
+ {
+ _out << "s";
+ _out << sp << nl << "public " << name << "()";
+ _out << sb;
+ _out << eb;
+ }
+
+ _out << sp << nl << "public " << name << spar;
+ vector<string> paramDecl;
+ vector<string> paramNames;
+ for(q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ string memberName = fixId((*q)->name(), isClass ? DotNet::ICloneable : 0);
+ string memberType = typeToString((*q)->type());
+ paramDecl.push_back(memberType + " " + memberName);
+ paramNames.push_back(memberName);
+ }
+ _out << paramDecl << epar;
+ _out << sb;
+ for(vector<string>::const_iterator i = paramNames.begin(); i != paramNames.end(); ++i)
+ {
+ _out << nl << "this." << *i;
+ if(propertyMapping)
+ {
+ _out << "_prop";
+ }
+ _out << " = " << *i << ';';
+ }
+ _out << eb;
+
+ _out << sp << nl << "#endregion"; // Constructor(s)
+
+ if(isClass)
+ {
+ _out << sp << nl << "#region ICloneable members";
+
+ _out << sp << nl << "public object Clone()";
+ _out << sb;
+ _out << nl << "return MemberwiseClone();";
+ _out << eb;
+
+ _out << sp << nl << "#endregion"; // ICloneable members
+ }
+
+ _out << sp << nl << "#region Object members";
+
+ _out << sp << nl << "public override int GetHashCode()";
+ _out << sb;
+ _out << nl << "int h__ = 0;";
+ for(q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ string memberName = fixId((*q)->name(), isClass ? DotNet::ICloneable : 0);
+ bool isValue = isValueType((*q)->type());
+ if(!isValue)
+ {
+ _out << nl << "if(" << memberName << " != null)";
+ _out << sb;
+ }
+ _out << nl << "h__ = 5 * h__ + " << memberName << ".GetHashCode();";
+ if(!isValue)
+ {
+ _out << eb;
+ }
+ }
+ _out << nl << "return h__;";
+ _out << eb;
+
+ _out << sp << nl << "public override bool Equals(object other__)";
+ _out << sb;
+ if(isClass)
+ {
+ _out << nl << "if(object.ReferenceEquals(this, other__))";
+ _out << sb;
+ _out << nl << "return true;";
+ _out << eb;
+ }
+ if(isClass)
+ {
+ _out << nl << "if(other__ == null)";
+ _out << sb;
+ _out << nl << "return false;";
+ _out << eb;
+ _out << nl << "if(GetType() != other__.GetType())";
+ }
+ else
+ {
+ _out << nl << "if(!(other__ is " << name << "))";
+ }
+ _out << sb;
+ _out << nl << "return false;";
+ _out << eb;
+ if(!dataMembers.empty())
+ {
+ _out << nl << name << " o__ = (" << name << ")other__;";
+ }
+ for(q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ string memberName = fixId((*q)->name(), isClass ? DotNet::ICloneable : 0);
+ if(!isValueType((*q)->type()))
+ {
+ _out << nl << "if(" << memberName << " == null)";
+ _out << sb;
+ _out << nl << "if(o__." << memberName << " != null)";
+ _out << sb;
+ _out << nl << "return false;";
+ _out << eb;
+ _out << eb;
+ _out << nl << "else";
+ _out << sb;
+ _out << nl << "if(!" << memberName << ".Equals(o__." << memberName << "))";
+ _out << sb;
+ _out << nl << "return false;";
+ _out << eb;
+ _out << eb;
+ }
+ else
+ {
+ _out << nl << "if(!" << memberName << ".Equals(o__." << memberName << "))";
+ _out << sb;
+ _out << nl << "return false;";
+ _out << eb;
+ }
+ }
+ _out << nl << "return true;";
+ _out << eb;
+
+ _out << sp << nl << "#endregion"; // Object members
+
+ _out << sp << nl << "#region Comparison members";
+
+ _out << sp << nl << "public static bool operator==(" << name << " lhs__, " << name << " rhs__)";
+ _out << sb;
+ _out << nl << "return Equals(lhs__, rhs__);";
+ _out << eb;
+
+ _out << sp << nl << "public static bool operator!=(" << name << " lhs__, " << name << " rhs__)";
+ _out << sb;
+ _out << nl << "return !Equals(lhs__, rhs__);";
+ _out << eb;
+
+ _out << sp << nl << "#endregion"; // Comparison members
+
+ if(!p->isLocal())
+ {
+ _out << sp << nl << "#region Marshalling support";
+
+ _out << sp << nl << "public void write__(IceInternal.BasicStream os__)";
+ _out << sb;
+ for(q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ writeMarshalUnmarshalCode(_out, (*q)->type(), fixId(*q, isClass ? DotNet::ICloneable : 0),
+ true, false, false);
+ }
+ _out << eb;
+
+
+ if(isClass && classMembers.size() != 0)
+ {
+ _out << sp << nl << "public sealed class Patcher__ : IceInternal.Patcher<" << name << ">";
+ _out << sb;
+ _out << sp << nl << "internal Patcher__(string type, " << name << " instance";
+ if(classMembers.size() > 1)
+ {
+ _out << ", int member";
+ }
+ _out << ") : base(type)";
+ _out << sb;
+ _out << nl << "_instance = (" << name << ")instance;";
+ if(classMembers.size() > 1)
+ {
+ _out << nl << "_member = member;";
+ }
+ _out << eb;
+
+ _out << sp << nl << "public override void patch(Ice.Object v)";
+ _out << sb;
+ _out << nl << "try";
+ _out << sb;
+ if(classMembers.size() > 1)
+ {
+ _out << nl << "switch(_member)";
+ _out << sb;
+ }
+ int memberCount = 0;
+ for(q = classMembers.begin(); q != classMembers.end(); ++q)
+ {
+ if(classMembers.size() > 1)
+ {
+ _out.dec();
+ _out << nl << "case " << memberCount << ":";
+ _out.inc();
+ }
+ string memberType = typeToString((*q)->type());
+ string memberName = fixId((*q)->name(), isClass ? DotNet::ICloneable : 0);
+ _out << nl << "_instance." << memberName << " = (" << memberType << ")v;";
+ ContainedPtr contained = ContainedPtr::dynamicCast((*q)->type());
+ string sliceId = contained ? contained->scoped() : "::Ice::Object";
+ _out << nl << "_typeId = \"" << sliceId << "\";";
+ if(classMembers.size() > 1)
+ {
+ _out << nl << "break;";
+ }
+ memberCount++;
+ }
+ if(classMembers.size() > 1)
+ {
+ _out << eb;
+ }
+ _out << eb;
+ _out << nl << "catch(System.InvalidCastException)";
+ _out << sb;
+ _out << nl << "IceInternal.Ex.throwUOE(_typeId, v.ice_id());";
+ _out << eb;
+ _out << eb;
+
+ _out << sp << nl << "private " << name;
+ _out << " _instance;";
+ if(classMembers.size() > 1)
+ {
+ _out << nl << "private int _member;";
+ }
+ _out << nl << "private string _typeId;";
+ _out << eb;
+ }
+
+ _out << sp << nl << "public void read__(IceInternal.BasicStream is__)";
+ _out << sb;
+ int classMemberCount = 0;
+ for(q = dataMembers.begin(); q != dataMembers.end(); ++q)
+ {
+ ostringstream patchParams;
+ patchParams << "this";
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast((*q)->type());
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast((*q)->type()))
+ {
+ if(classMembers.size() > 1)
+ {
+ patchParams << ", " << classMemberCount++;
+ }
+ }
+ writeMarshalUnmarshalCode(_out, (*q)->type(), fixId(*q, isClass ? DotNet::ICloneable : 0 ),
+ false, false, false, patchParams.str());
+ }
+ _out << eb;
+
+ _out << sp << nl << "#endregion"; // Marshalling support
+ }
+
+ _out << eb;
+}
+
+void
+Slice::Gen::TypesVisitor::visitDictionary(const DictionaryPtr& p)
+{
+ if(!p->hasMetaData("clr:collection"))
+ {
+ return;
+ }
+
+ string name = fixId(p->name());
+ string ks = typeToString(p->keyType());
+ string vs = typeToString(p->valueType());
+
+ _out << sp;
+
+ emitDeprecate(p, 0, _out, "type");
+
+ emitAttributes(p);
+ _out << nl << "public class " << name
+ << " : Ice.DictionaryBase<" << ks << ", " << vs << ">, _System.ICloneable";
+ _out << sb;
+
+ _out << sp << nl << "#region " << name << " members";
+
+ _out << sp << nl << "public void AddRange(" << name << " d__)";
+ _out << sb;
+ _out << nl << "foreach(_System.Collections.Generic.KeyValuePair<" << ks << ", " << vs << "> e in d__.dict_)";
+ _out << sb;
+ _out << nl << "try";
+ _out << sb;
+ _out << nl << "dict_.Add(e.Key, e.Value);";
+ _out << eb;
+ _out << nl << "catch(_System.ArgumentException)";
+ _out << sb;
+ _out << nl << "// ignore";
+ _out << eb;
+ _out << eb;
+ _out << eb;
+
+ _out << sp << nl << "#endregion"; // <name> members
+
+ _out << sp << nl << "#region ICloneable members";
+
+ _out << sp << nl << "public object Clone()";
+ _out << sb;
+ _out << nl << name << " d = new " << name << "();";
+ _out << nl << "foreach(_System.Collections.Generic.KeyValuePair<" << ks << ", " << vs <<"> e in dict_)";
+ _out << sb;
+ _out << nl << "d.dict_.Add(e.Key, e.Value);";
+ _out << eb;
+ _out << nl << "return d;";
+ _out << eb;
+
+ _out << sp << nl << "#endregion"; // ICloneable members
+
+ _out << eb;
+}
+
+void
+Slice::Gen::TypesVisitor::visitEnum(const EnumPtr& p)
+{
+ string name = fixId(p->name());
+ string scoped = fixId(p->scoped());
+ EnumeratorList enumerators = p->getEnumerators();
+ _out << sp;
+
+ emitDeprecate(p, 0, _out, "type");
+
+ emitAttributes(p);
+ _out << nl << "public enum " << name;
+ _out << sb;
+ EnumeratorList::const_iterator en = enumerators.begin();
+ while(en != enumerators.end())
+ {
+ _out << nl << fixId((*en)->name());
+ if(++en != enumerators.end())
+ {
+ _out << ',';
+ }
+ }
+ _out << eb;
+}
+
+void
+Slice::Gen::TypesVisitor::visitConst(const ConstPtr& p)
+{
+ string name = fixId(p->name());
+ _out << sp;
+ emitAttributes(p);
+ _out << nl << "public abstract class " << name;
+ _out << sb;
+ _out << sp << nl << "public const " << typeToString(p->type()) << " value = ";
+ BuiltinPtr bp = BuiltinPtr::dynamicCast(p->type());
+ if(bp && bp->kind() == Builtin::KindString)
+ {
+ //
+ // Expand strings into the basic source character set. We can't use isalpha() and the like
+ // here because they are sensitive to the current locale.
+ //
+ static const string basicSourceChars = "abcdefghijklmnopqrstuvwxyz"
+ "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "0123456789"
+ "_{}[]#()<>%:;.?*+-/^&|~!=,\\\"' ";
+ static const set<char> charSet(basicSourceChars.begin(), basicSourceChars.end());
+
+ _out << "\""; // Opening "
+
+ const string val = p->value();
+ for(string::const_iterator c = val.begin(); c != val.end(); ++c)
+ {
+ if(charSet.find(*c) == charSet.end())
+ {
+ unsigned char uc = *c; // char may be signed, so make it positive
+ ostringstream s;
+ s << "\\u"; // Print as unicode if not in basic source character set
+ s << hex;
+ s.width(4);
+ s.fill('0');
+ s << static_cast<unsigned>(uc);
+ _out << s.str();
+ }
+ else
+ {
+ _out << *c; // Print normally if in basic source character set
+ }
+ }
+
+ _out << "\""; // Closing "
+ }
+ else if(bp && bp->kind() == Builtin::KindLong)
+ {
+ _out << p->value() << "L";
+ }
+ else if(bp && bp->kind() == Builtin::KindFloat)
+ {
+ _out << p->value() << "F";
+ }
+ else
+ {
+ EnumPtr ep = EnumPtr::dynamicCast(p->type());
+ if(ep)
+ {
+ _out << typeToString(p->type()) << "." << fixId(p->value());
+ }
+ else
+ {
+ _out << p->value();
+ }
+ }
+ _out << ";";
+ _out << eb;
+}
+
+void
+Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p)
+{
+ int baseTypes = 0;
+ bool isClass = false;
+ bool propertyMapping = false;
+ bool isValue = false;
+ bool isProtected = false;
+ ContainedPtr cont = ContainedPtr::dynamicCast(p->container());
+ assert(cont);
+ if(StructPtr::dynamicCast(cont))
+ {
+ isValue = isValueType(StructPtr::dynamicCast(cont));
+ if(!isValue || cont->hasMetaData("clr:class"))
+ {
+ baseTypes = DotNet::ICloneable;
+ }
+ if(cont->hasMetaData("clr:property"))
+ {
+ propertyMapping = true;
+ }
+ }
+ else if(ExceptionPtr::dynamicCast(cont))
+ {
+ baseTypes = DotNet::ApplicationException;
+ }
+ else if(ClassDefPtr::dynamicCast(cont))
+ {
+ baseTypes = DotNet::ICloneable;
+ isClass = true;
+ if(cont->hasMetaData("clr:property"))
+ {
+ propertyMapping = true;
+ }
+ isProtected = cont->hasMetaData("protected") || p->hasMetaData("protected");
+ }
+
+ _out << sp;
+
+ emitDeprecate(p, cont, _out, "member");
+
+ emitAttributes(p);
+
+ string type = typeToString(p->type());
+ string propertyName = fixId(p->name(), baseTypes, isClass);
+ string dataMemberName = propertyName;
+ if(propertyMapping)
+ {
+ dataMemberName += "_prop";
+ }
+
+ _out << nl;
+ if(propertyMapping)
+ {
+ _out << "private";
+ }
+ else if(isProtected)
+ {
+ _out << "protected";
+ }
+ else
+ {
+ _out << "public";
+ }
+ _out << ' ' << type << ' ' << dataMemberName << ';';
+
+ if(!propertyMapping)
+ {
+ return;
+ }
+
+ _out << nl << (isProtected ? "protected" : "public");
+ if(!isValue)
+ {
+ _out << " virtual";
+ }
+ _out << ' ' << type << ' ' << propertyName;
+ _out << sb;
+ _out << nl << "get";
+ _out << sb;
+ _out << nl << "return " << dataMemberName << ';';
+ _out << eb;
+ _out << nl << "set";
+ _out << sb;
+ _out << nl << dataMemberName << " = value;";
+ _out << eb;
+ _out << eb;
+}
+
+Slice::Gen::ProxyVisitor::ProxyVisitor(IceUtil::Output& out)
+ : CsVisitor(out)
+{
+}
+
+bool
+Slice::Gen::ProxyVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!p->hasNonLocalClassDecls())
+ {
+ return false;
+ }
+
+ _out << sp << nl << "namespace " << fixId(p->name());
+ _out << sb;
+ return true;
+}
+
+void
+Slice::Gen::ProxyVisitor::visitModuleEnd(const ModulePtr&)
+{
+ _out << eb;
+}
+
+bool
+Slice::Gen::ProxyVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ if(p->isLocal())
+ {
+ return false;
+ }
+
+ string name = p->name();
+ ClassList bases = p->bases();
+
+ _out << sp << nl << "public interface " << name << "Prx : ";
+ if(bases.empty())
+ {
+ _out << "Ice.ObjectPrx";
+ }
+ else
+ {
+ ClassList::const_iterator q = bases.begin();
+ while(q != bases.end())
+ {
+ _out << fixId((*q)->scoped() + "Prx");
+ if(++q != bases.end())
+ {
+ _out << ", ";
+ }
+ }
+ }
+
+ _out << sb;
+
+ return true;
+}
+
+void
+Slice::Gen::ProxyVisitor::visitClassDefEnd(const ClassDefPtr&)
+{
+ _out << eb;
+}
+
+void
+Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p)
+{
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(p->container());
+ string name = fixId(p->name(), DotNet::ICloneable, true);
+ vector<string> params = getParams(p);
+
+ _out << sp;
+
+ string deprecateMetadata, deprecateReason;
+ if(p->findMetaData("deprecate", deprecateMetadata) || cl->findMetaData("deprecate", deprecateMetadata))
+ {
+ deprecateReason = "This operation has been deprecated.";
+ if(deprecateMetadata.find("deprecate:") == 0 && deprecateMetadata.size() > 10)
+ {
+ deprecateReason = deprecateMetadata.substr(10);
+ }
+ }
+
+ //
+ // Write two versions of the operation - with and without a
+ // context parameter.
+ //
+ if(!deprecateReason.empty())
+ {
+ _out << nl << "[System.Obsolete(\"" << deprecateReason << "\")]";
+ }
+ _out << nl << typeToString(p->returnType()) << " " << name << spar << params << epar << ';';
+
+ if(!deprecateReason.empty())
+ {
+ _out << nl << "[System.Obsolete(\"" << deprecateReason << "\")]";
+ }
+ _out << nl << typeToString(p->returnType()) << " " << name
+ << spar << params << "_System.Collections.Generic.Dictionary<string, string> context__" << epar << ';';
+
+ if(cl->hasMetaData("ami") || p->hasMetaData("ami"))
+ {
+ vector<string> paramsAMI = getParamsAsync(p, false);
+
+ //
+ // Write two versions of the operation - with and without a
+ // context parameter.
+ //
+ _out << sp;
+ if(!deprecateReason.empty())
+ {
+ _out << nl << "[System.Obsolete(\"" << deprecateReason << "\")]";
+ }
+ _out << nl << "void " << p->name() << "_async" << spar << paramsAMI << epar << ';';
+ if(!deprecateReason.empty())
+ {
+ _out << nl << "[System.Obsolete(\"" << deprecateReason << "\")]";
+ }
+ _out << nl << "void " << p->name() << "_async" << spar << paramsAMI
+ << "_System.Collections.Generic.Dictionary<string, string> ctx__" << epar << ';';
+ }
+}
+
+Slice::Gen::OpsVisitor::OpsVisitor(IceUtil::Output& out)
+ : CsVisitor(out)
+{
+}
+
+bool
+Slice::Gen::OpsVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!p->hasAbstractClassDefs())
+ {
+ return false;
+ }
+
+ _out << sp << nl << "namespace " << fixId(p->name());
+ _out << sb;
+ return true;
+}
+
+void
+Slice::Gen::OpsVisitor::visitModuleEnd(const ModulePtr&)
+{
+ _out << eb;
+}
+
+bool
+Slice::Gen::OpsVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ //
+ // Don't generate Operations interfaces for non-abstract classes.
+ //
+ if(!p->isAbstract())
+ {
+ return false;
+ }
+
+ writeOperations(p, true);
+
+ return false;
+}
+
+void
+Slice::Gen::OpsVisitor::writeOperations(const ClassDefPtr& p, bool noCurrent)
+{
+ string name = p->name();
+ string scoped = fixId(p->scoped());
+ ClassList bases = p->bases();
+ string opIntfName = "Operations";
+ if(noCurrent || p->isLocal())
+ {
+ opIntfName += "NC";
+ }
+
+ _out << sp << nl << "public interface " << name << opIntfName << '_';
+ if((bases.size() == 1 && bases.front()->isAbstract()) || bases.size() > 1)
+ {
+ _out << " : ";
+ ClassList::const_iterator q = bases.begin();
+ bool first = true;
+ while(q != bases.end())
+ {
+ if((*q)->isAbstract())
+ {
+ if(!first)
+ {
+ _out << ", ";
+ }
+ else
+ {
+ first = false;
+ }
+ string s = (*q)->scoped();
+ s += "Operations";
+ if(noCurrent)
+ {
+ s += "NC";
+ }
+ _out << fixId(s) << '_';
+ }
+ ++q;
+ }
+ }
+ _out << sb;
+
+ OperationList ops = p->operations();
+ OperationList::const_iterator r;
+ for(r = ops.begin(); r != ops.end(); ++r)
+ {
+ OperationPtr op = *r;
+ bool amd = !p->isLocal() && (p->hasMetaData("amd") || op->hasMetaData("amd"));
+ string opname = amd ? (op->name() + "_async") : fixId(op->name(), DotNet::ICloneable, true);
+
+ TypePtr ret;
+ vector<string> params;
+
+ if(amd)
+ {
+ params = getParamsAsync(op, true);
+ }
+ else
+ {
+ params = getParams(op);
+ ret = op->returnType();
+ }
+
+ _out << sp;
+
+ emitDeprecate(op, p, _out, "operation");
+
+ emitAttributes(op);
+ string retS = typeToString(ret);
+ _out << nl << retS << ' ' << opname << spar << params;
+ if(!noCurrent && !p->isLocal())
+ {
+ _out << "Ice.Current current__";
+ }
+ _out << epar << ';';
+ }
+
+ _out << eb;
+}
+
+Slice::Gen::HelperVisitor::HelperVisitor(IceUtil::Output& out) :
+ CsVisitor(out)
+{
+}
+
+bool
+Slice::Gen::HelperVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!p->hasNonLocalClassDecls() && !p->hasNonLocalSequences() && !p->hasDictionaries())
+ {
+ return false;
+ }
+
+ _out << sp << nl << "namespace " << fixId(p->name());
+ _out << sb;
+ return true;
+}
+
+void
+Slice::Gen::HelperVisitor::visitModuleEnd(const ModulePtr&)
+{
+ _out << eb;
+}
+
+bool
+Slice::Gen::HelperVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ if(p->isLocal())
+ return false;
+
+ string name = p->name();
+ ClassList bases = p->bases();
+
+ _out << sp << nl << "public sealed class " << name << "PrxHelper : Ice.ObjectPrxHelperBase, " << name << "Prx";
+ _out << sb;
+
+ OperationList ops = p->allOperations();
+
+ if(!ops.empty())
+ {
+ _out << sp << nl << "#region Synchronous operations";
+ }
+
+ OperationList::const_iterator r;
+ for(r = ops.begin(); r != ops.end(); ++r)
+ {
+ OperationPtr op = *r;
+ string opName = fixId(op->name(), DotNet::ICloneable, true);
+ TypePtr ret = op->returnType();
+ string retS = typeToString(ret);
+
+ TypeStringList inParams;
+ TypeStringList outParams;
+ ParamDeclList paramList = op->parameters();
+ for(ParamDeclList::const_iterator pli = paramList.begin(); pli != paramList.end(); ++pli)
+ {
+ if((*pli)->isOutParam())
+ {
+ outParams.push_back(make_pair((*pli)->type(), (*pli)->name()));
+ }
+ else
+ {
+ inParams.push_back(make_pair((*pli)->type(), (*pli)->name()));
+ }
+ }
+
+ TypeStringList::const_iterator q;
+
+ ExceptionList throws = op->throws();
+ throws.sort();
+ throws.unique();
+
+ //
+ // Arrange exceptions into most-derived to least-derived order. If we don't
+ // do this, a base exception handler can appear before a derived exception
+ // handler, causing compiler warnings and resulting in the base exception
+ // being marshaled instead of the derived exception.
+ //
+#if defined(__SUNPRO_CC)
+ throws.sort(Slice::derivedToBaseCompare);
+#else
+ throws.sort(Slice::DerivedToBaseCompare());
+#endif
+
+ vector<string> params = getParams(op);
+ vector<string> args = getArgs(op);
+
+ _out << sp << nl << "public " << retS << " " << opName << spar << params << epar;
+ _out << sb;
+ _out << nl;
+ if(ret)
+ {
+ _out << "return ";
+ }
+ _out << opName << spar << args << "null" << "false" << epar << ';';
+ _out << eb;
+
+ _out << sp << nl << "public " << retS << " " << opName << spar << params
+ << "_System.Collections.Generic.Dictionary<string, string> context__" << epar;
+ _out << sb;
+ _out << nl;
+ if(ret)
+ {
+ _out << "return ";
+ }
+ _out << opName << spar << args << "context__" << "true" << epar << ';';
+ _out << eb;
+
+ _out << sp << nl << "private " << retS << " " << opName << spar << params
+ << "_System.Collections.Generic.Dictionary<string, string> context__"
+ << "bool explicitContext__" << epar;
+ _out << sb;
+
+ _out << nl << "if(explicitContext__ && context__ == null)";
+ _out << sb;
+ _out << nl << "context__ = emptyContext_;";
+ _out << eb;
+ _out << nl << "int cnt__ = 0;";
+ _out << nl << "while(true)";
+ _out << sb;
+ //XXX:
+ _out << nl << "try";
+ _out << sb;
+ _out << nl << "IceInternal.Outgoing og__ = getOutgoing(\"" << op->name() << "\", "
+ << sliceModeToIceMode(op->sendMode())
+ << ", context__);";
+ if(!inParams.empty())
+ {
+ _out << nl << "IceInternal.BasicStream os__ = og__.ostr();";
+ for(q = inParams.begin(); q != inParams.end(); ++q)
+ {
+ writeMarshalUnmarshalCode(_out, q->first, fixId(q->second), true, false, false);
+ }
+ if(op->sendsClasses())
+ {
+ _out << nl << "os__.writePendingObjects();";
+ }
+ }
+ _out << nl << "bool ok__ = og__.invoke();";
+ _out << nl << "try";
+ _out << sb;
+ _out << nl << "IceInternal.BasicStream is__ = og__.istr();";
+ _out << nl << "if(!ok__)";
+ _out << sb;
+ //
+ // The try/catch block is necessary because throwException()
+ // can raise UserException.
+ //
+ _out << nl << "try";
+ _out << sb;
+ _out << nl << "is__.throwException();";
+ _out << eb;
+ for(ExceptionList::const_iterator t = throws.begin(); t != throws.end(); ++t)
+ {
+ _out << nl << "catch(" << fixId((*t)->scoped()) << ')';
+ _out << sb;
+ _out << nl << "throw;";
+ _out << eb;
+ }
+ _out << nl << "catch(Ice.UserException ex)";
+ _out << sb;
+ _out << nl << "throw new Ice.UnknownUserException(ex);";
+ _out << eb;
+ _out << eb;
+ for(q = outParams.begin(); q != outParams.end(); ++q)
+ {
+ string param = fixId(q->second);
+ StructPtr st = StructPtr::dynamicCast(q->first);
+ if(st)
+ {
+ if(isValueType(q->first))
+ {
+ _out << nl << param << " = new " << typeToString(q->first) << "();";
+ }
+ else
+ {
+ _out << nl << param << " = null;";
+ }
+ }
+ writeMarshalUnmarshalCode(_out, q->first, fixId(q->second), false, false, true, "");
+ }
+ if(ret)
+ {
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(ret);
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(ret))
+ {
+ _out << nl << retS << " ret__;";
+ ContainedPtr contained = ContainedPtr::dynamicCast(ret);
+ string sliceId = contained ? contained->scoped() : "::Ice::Object";
+ _out << nl << "IceInternal.ParamPatcher<" << retS << "> ret___PP = new IceInternal.ParamPatcher<"
+ << retS << ">(\"" << sliceId << "\");";
+ _out << nl << "is__.readObject(ret___PP);";
+ }
+ else
+ {
+ _out << nl << retS << " ret__;";
+ StructPtr st = StructPtr::dynamicCast(ret);
+ if(st)
+ {
+ if(isValueType(st))
+ {
+ _out << nl << "ret__ = new " << retS << "();";
+ }
+ else
+ {
+ _out << nl << "ret__ = null;";
+ }
+ }
+ writeMarshalUnmarshalCode(_out, ret, "ret__", false, false, true, "");
+ }
+ }
+ if(op->returnsClasses())
+ {
+ _out << nl << "is__.readPendingObjects();";
+ for(q = outParams.begin(); q != outParams.end(); ++q)
+ {
+ string param = fixId(q->second);
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(q->first);
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(q->first))
+ {
+ string type = typeToString(q->first);
+ _out << nl << "try";
+ _out << sb;
+ _out << nl << param << " = (" << type << ")" << param << "_PP.value;";
+ _out << eb;
+ _out << nl << "catch(System.InvalidCastException)";
+ _out << sb;
+ _out << nl << param << " = null;";
+ _out << nl << "IceInternal.Ex.throwUOE(" << param << "_PP.type(), "
+ << param << "_PP.value.ice_id());";
+ _out << eb;
+ }
+ }
+ }
+ if(ret)
+ {
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(ret);
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(ret))
+ {
+ _out << nl << "try";
+ _out << sb;
+ _out << nl << "ret__ = (" << retS << ")ret___PP.value;";
+ _out << eb;
+ _out << nl << "catch(System.InvalidCastException)";
+ _out << sb;
+ _out << nl << "Ice.UnexpectedObjectException ex = new Ice.UnexpectedObjectException();";
+ _out << nl << "ret__ = null;";
+ _out << nl << "IceInternal.Ex.throwUOE(ret___PP.type(), ret___PP.value.ice_id());";
+ _out << eb;
+ }
+ _out << nl << "return ret__;";
+ }
+ _out << eb;
+ _out << nl << "catch(Ice.LocalException ex__)";
+ _out << sb;
+ _out << nl << "throw new IceInternal.LocalExceptionWrapper(ex__, false);";
+ _out << eb;
+
+ if(!ret)
+ {
+ _out << nl << "return;";
+ }
+
+ // XXX: Generated code for marshaling, etc.
+ _out << eb;
+ _out << nl << "catch(IceInternal.LocalExceptionWrapper ex__)";
+ _out << sb;
+ if(op->mode() == Operation::Idempotent || op->mode() == Operation::Nonmutating)
+ {
+ _out << nl << "cnt__ = handleExceptionWrapperRelaxed__(ex__, cnt__);";
+ }
+ else
+ {
+ _out << nl << "handleExceptionWrapper__(ex__);";
+ }
+ _out << eb;
+ _out << nl << "catch(Ice.LocalException ex__)";
+ _out << sb;
+ _out << nl << "cnt__ = handleException__(ex__, cnt__);";
+ _out << eb;
+ _out << eb;
+
+ _out << eb;
+ }
+
+ if(!ops.empty())
+ {
+ _out << sp << nl << "#endregion"; // Synchronous operations
+ }
+
+ bool hasAsyncOps = false;
+
+ for(r = ops.begin(); r != ops.end(); ++r)
+ {
+ OperationPtr op = *r;
+
+ ClassDefPtr containingClass = ClassDefPtr::dynamicCast(op->container());
+ if(containingClass->hasMetaData("ami") || op->hasMetaData("ami"))
+ {
+ if(!hasAsyncOps)
+ {
+ _out << sp << nl << "#region Asynchronous operations";
+ hasAsyncOps = true;
+ }
+ vector<string> paramsAMI = getParamsAsync(op, false);
+ vector<string> argsAMI = getArgsAsync(op);
+
+ string opName = op->name();
+
+ //
+ // Write two versions of the operation - with and without a
+ // context parameter
+ //
+ _out << sp;
+ _out << nl << "public void " << opName << "_async" << spar << paramsAMI << epar;
+ _out << sb;
+ _out << nl << opName << "_async" << spar << argsAMI << "null" << "false" << epar << ';';
+ _out << eb;
+
+ _out << sp;
+ _out << nl << "public void " << opName << "_async" << spar << paramsAMI
+ << "_System.Collections.Generic.Dictionary<string, string> ctx__" << epar;
+ _out << sb;
+ _out << nl << opName << "_async" << spar << argsAMI << "ctx__" << "true" << epar << ';';
+ _out << eb;
+
+ _out << sp;
+ _out << nl << "public void " << opName << "_async" << spar << paramsAMI
+ << "_System.Collections.Generic.Dictionary<string, string> ctx__"
+ << "bool explicitContext__" << epar;
+ _out << sb;
+ _out << nl << "if(explicitContext__ && ctx__ == null)";
+ _out << sb;
+ _out << nl << "ctx__ = emptyContext_;";
+ _out << eb;
+ _out << nl << "cb__.invoke__" << spar << "this" << argsAMI << "ctx__" << epar << ';';
+ _out << eb;
+ }
+ }
+
+ if(hasAsyncOps)
+ {
+ _out << sp << nl << "#endregion"; // Asynchronous operations
+ }
+
+ _out << sp << nl << "#region Checked and unchecked cast operations";
+
+ _out << sp << nl << "public static " << name << "Prx checkedCast(Ice.ObjectPrx b)";
+ _out << sb;
+ _out << nl << "if(b == null)";
+ _out << sb;
+ _out << nl << "return null;";
+ _out << eb;
+ _out << nl << "if(b is " << name << "Prx)";
+ _out << sb;
+ _out << nl << "return (" << name << "Prx)b;";
+ _out << eb;
+ _out << nl << "if(b.ice_isA(\"" << p->scoped() << "\"))";
+ _out << sb;
+ _out << nl << name << "PrxHelper h = new " << name << "PrxHelper();";
+ _out << nl << "h.copyFrom__(b);";
+ _out << nl << "return h;";
+ _out << eb;
+ _out << nl << "return null;";
+ _out << eb;
+
+ _out << sp << nl << "public static " << name
+ << "Prx checkedCast(Ice.ObjectPrx b, _System.Collections.Generic.Dictionary<string, string> ctx)";
+ _out << sb;
+ _out << nl << "if(b == null)";
+ _out << sb;
+ _out << nl << "return null;";
+ _out << eb;
+ _out << nl << "if(b is " << name << "Prx)";
+ _out << sb;
+ _out << nl << "return (" << name << "Prx)b;";
+ _out << eb;
+ _out << nl << "if(b.ice_isA(\"" << p->scoped() << "\", ctx))";
+ _out << sb;
+ _out << nl << name << "PrxHelper h = new " << name << "PrxHelper();";
+ _out << nl << "h.copyFrom__(b);";
+ _out << nl << "return h;";
+ _out << eb;
+ _out << nl << "return null;";
+ _out << eb;
+
+ _out << sp << nl << "public static " << name << "Prx checkedCast(Ice.ObjectPrx b, string f)";
+ _out << sb;
+ _out << nl << "if(b == null)";
+ _out << sb;
+ _out << nl << "return null;";
+ _out << eb;
+ _out << nl << "Ice.ObjectPrx bb = b.ice_facet(f);";
+ _out << nl << "try";
+ _out << sb;
+ _out << nl << "if(bb.ice_isA(\"" << p->scoped() << "\"))";
+ _out << sb;
+ _out << nl << name << "PrxHelper h = new " << name << "PrxHelper();";
+ _out << nl << "h.copyFrom__(bb);";
+ _out << nl << "return h;";
+ _out << eb;
+ _out << eb;
+ _out << nl << "catch(Ice.FacetNotExistException)";
+ _out << sb;
+ _out << eb;
+ _out << nl << "return null;";
+ _out << eb;
+
+ _out << sp << nl << "public static " << name
+ << "Prx checkedCast(Ice.ObjectPrx b, string f, "
+ << "_System.Collections.Generic.Dictionary<string, string> ctx)";
+ _out << sb;
+ _out << nl << "if(b == null)";
+ _out << sb;
+ _out << nl << "return null;";
+ _out << eb;
+ _out << nl << "Ice.ObjectPrx bb = b.ice_facet(f);";
+ _out << nl << "try";
+ _out << sb;
+ _out << nl << "if(bb.ice_isA(\"" << p->scoped() << "\", ctx))";
+ _out << sb;
+ _out << nl << name << "PrxHelper h = new " << name << "PrxHelper();";
+ _out << nl << "h.copyFrom__(bb);";
+ _out << nl << "return h;";
+ _out << eb;
+ _out << eb;
+ _out << nl << "catch(Ice.FacetNotExistException)";
+ _out << sb;
+ _out << eb;
+ _out << nl << "return null;";
+ _out << eb;
+
+ _out << sp << nl << "public static " << name << "Prx uncheckedCast(Ice.ObjectPrx b)";
+ _out << sb;
+ _out << nl << "if(b == null)";
+ _out << sb;
+ _out << nl << "return null;";
+ _out << eb;
+ _out << nl << name << "PrxHelper h = new " << name << "PrxHelper();";
+ _out << nl << "h.copyFrom__(b);";
+ _out << nl << "return h;";
+ _out << eb;
+
+ _out << sp << nl << "public static " << name << "Prx uncheckedCast(Ice.ObjectPrx b, string f)";
+ _out << sb;
+ _out << nl << "if(b == null)";
+ _out << sb;
+ _out << nl << "return null;";
+ _out << eb;
+ _out << nl << "Ice.ObjectPrx bb = b.ice_facet(f);";
+ _out << nl << name << "PrxHelper h = new " << name << "PrxHelper();";
+ _out << nl << "h.copyFrom__(bb);";
+ _out << nl << "return h;";
+ _out << eb;
+
+ _out << sp << nl << "#endregion"; // Checked and unchecked cast operations
+
+ _out << sp << nl << "#region Marshaling support";
+
+ _out << sp << nl << "public static void write__(IceInternal.BasicStream os__, " << name << "Prx v__)";
+ _out << sb;
+ _out << nl << "os__.writeProxy(v__);";
+ _out << eb;
+
+ _out << sp << nl << "public static " << name << "Prx read__(IceInternal.BasicStream is__)";
+ _out << sb;
+ _out << nl << "Ice.ObjectPrx proxy = is__.readProxy();";
+ _out << nl << "if(proxy != null)";
+ _out << sb;
+ _out << nl << name << "PrxHelper result = new " << name << "PrxHelper();";
+ _out << nl << "result.copyFrom__(proxy);";
+ _out << nl << "return result;";
+ _out << eb;
+ _out << nl << "return null;";
+ _out << eb;
+
+ _out << sp << nl << "#endregion"; // Marshaling support
+
+ return true;
+}
+
+void
+Slice::Gen::HelperVisitor::visitClassDefEnd(const ClassDefPtr&)
+{
+ _out << eb;
+}
+
+void
+Slice::Gen::HelperVisitor::visitSequence(const SequencePtr& p)
+{
+ //
+ // Don't generate helper for sequence of a local type.
+ //
+ if(p->isLocal())
+ {
+ return;
+ }
+
+ string typeS = typeToString(p);
+
+ _out << sp << nl << "public sealed class " << p->name() << "Helper";
+ _out << sb;
+
+ _out << sp << nl << "public static void write(IceInternal.BasicStream os__, " << typeS << " v__)";
+ _out << sb;
+ writeSequenceMarshalUnmarshalCode(_out, p, "v__", true, false);
+ _out << eb;
+
+ _out << sp << nl << "public static " << typeS << " read(IceInternal.BasicStream is__)";
+ _out << sb;
+ _out << nl << typeS << " v__;";
+ writeSequenceMarshalUnmarshalCode(_out, p, "v__", false, false);
+ _out << nl << "return v__;";
+ _out << eb;
+
+ _out << eb;
+
+ string prefix = "clr:generic:";
+ string meta;
+ if(p->findMetaData(prefix, meta))
+ {
+ string type = meta.substr(prefix.size());
+ if(type == "List" || type == "LinkedList" || type == "Queue" || type == "Stack")
+ {
+ return;
+ }
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(p->type());
+ bool isClass = (builtin && builtin->kind() == Builtin::KindObject)
+ || ClassDeclPtr::dynamicCast(p->type());
+
+ if(!isClass)
+ {
+ return;
+ }
+
+ //
+ // The sequence is a custom sequence with elements of class type.
+ // Emit a dummy class that causes a compile-time error if the
+ // custom sequence type does not implement an indexer.
+ //
+ _out << sp << nl << "public class " << p->name() << "_Tester";
+ _out << sb;
+ _out << nl << p->name() << "_Tester()";
+ _out << sb;
+ _out << nl << typeS << " test = new " << typeS << "();";
+ _out << nl << "test[0] = null;";
+ _out << eb;
+ _out << eb;
+ }
+}
+
+void
+Slice::Gen::HelperVisitor::visitDictionary(const DictionaryPtr& p)
+{
+ //
+ // Don't generate helper for a dictionary containing a local type
+ //
+ if(p->isLocal())
+ {
+ return;
+ }
+
+ TypePtr key = p->keyType();
+ TypePtr value = p->valueType();
+
+ string meta;
+ bool isNewMapping = !p->hasMetaData("clr:collection");
+
+ string prefix = "clr:generic:";
+ string genericType;
+ if(!p->findMetaData(prefix, meta))
+ {
+ genericType = "Dictionary";
+ }
+ else
+ {
+ genericType = meta.substr(prefix.size());
+ }
+
+ string keyS = typeToString(key);
+ string valueS = typeToString(value);
+ string name = isNewMapping
+ ? "_System.Collections.Generic." + genericType + "<" + keyS + ", " + valueS + ">"
+ : fixId(p->name());
+
+ _out << sp << nl << "public sealed class " << p->name() << "Helper";
+ _out << sb;
+
+ _out << sp << nl << "public static void write(";
+ _out.useCurrentPosAsIndent();
+ _out << "IceInternal.BasicStream os__,";
+ _out << nl << name << " v__)";
+ _out.restoreIndent();
+ _out << sb;
+ _out << nl << "if(v__ == null)";
+ _out << sb;
+ _out << nl << "os__.writeSize(0);";
+ _out << eb;
+ _out << nl << "else";
+ _out << sb;
+ _out << nl << "os__.writeSize(v__.Count);";
+ _out << nl << "foreach(_System.Collections.";
+ if(isNewMapping)
+ {
+ _out << "Generic.KeyValuePair<" << keyS << ", " << valueS << ">";
+ }
+ else
+ {
+ _out << "DictionaryEntry";
+ }
+ _out << " e__ in v__)";
+ _out << sb;
+ string keyArg = isNewMapping ? "e__.Key" : "((" + keyS + ")e__.Key)";
+ writeMarshalUnmarshalCode(_out, key, keyArg, true, false, false);
+ string valueArg = isNewMapping ? "e__.Value" : "((" + valueS + ")e__.Value)";
+ writeMarshalUnmarshalCode(_out, value, valueArg, true, false, false);
+ _out << eb;
+ _out << eb;
+ _out << eb;
+
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(value);
+ bool hasClassValue = (builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(value);
+ if(hasClassValue)
+ {
+ string expectedType = ContainedPtr::dynamicCast(value)->scoped();
+ _out << sp << nl << "public sealed class Patcher__ : IceInternal.Patcher<" << valueS << ">";
+ _out << sb;
+ _out << sp << nl << "internal Patcher__(string type, " << name << " m, " << keyS << " key) : base(type)";
+ _out << sb;
+ _out << nl << "_m = m;";
+ _out << nl << "_key = key;";
+ _out << eb;
+
+ _out << sp << nl << "public override void" << nl << "patch(Ice.Object v)";
+ _out << sb;
+ _out << nl << "try";
+ _out << sb;
+ _out << nl << "_m[_key] = (" << valueS << ")v;";
+ _out << eb;
+ _out << nl << "catch(System.InvalidCastException)";
+ _out << sb;
+ _out << nl << "IceInternal.Ex.throwUOE(type(), v.ice_id());";
+ _out << eb;
+ _out << eb;
+
+ _out << sp << nl << "private " << name << " _m;";
+ _out << nl << "private " << keyS << " _key;";
+ _out << eb;
+ }
+
+ _out << sp << nl << "public static " << name << " read(IceInternal.BasicStream is__)";
+ _out << sb;
+ _out << nl << "int sz__ = is__.readSize();";
+ _out << nl << name << " r__ = new " << name << "();";
+ _out << nl << "for(int i__ = 0; i__ < sz__; ++i__)";
+ _out << sb;
+ _out << nl << keyS << " k__;";
+ StructPtr st = StructPtr::dynamicCast(key);
+ if(st)
+ {
+ if(isValueType(key))
+ {
+ _out << nl << "v__ = new " << typeToString(key) << "();";
+ }
+ else
+ {
+ _out << nl << "k__ = null;";
+ }
+ }
+ writeMarshalUnmarshalCode(_out, key, "k__", false, false, false);
+ if(!hasClassValue)
+ {
+ _out << nl << valueS << " v__;";
+
+ StructPtr st = StructPtr::dynamicCast(value);
+ if(st)
+ {
+ if(isValueType(value))
+ {
+ _out << nl << "v__ = new " << typeToString(value) << "();";
+ }
+ else
+ {
+ _out << nl << "v__ = null;";
+ }
+ }
+ }
+ writeMarshalUnmarshalCode(_out, value, "v__", false, false, false, "r__, k__");
+ if(!hasClassValue)
+ {
+ _out << nl << "r__[k__] = v__;";
+ }
+ _out << eb;
+ _out << nl << "return r__;";
+ _out << eb;
+
+ _out << eb;
+}
+
+Slice::Gen::DispatcherVisitor::DispatcherVisitor(::IceUtil::Output &out) :
+ CsVisitor(out)
+{
+}
+
+bool
+Slice::Gen::DispatcherVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!p->hasNonLocalClassDecls())
+ {
+ return false;
+ }
+
+ _out << sp << nl << "namespace " << fixId(p->name());
+ _out << sb;
+ return true;
+}
+
+void
+Slice::Gen::DispatcherVisitor::visitModuleEnd(const ModulePtr&)
+{
+ _out << eb;
+}
+
+bool
+Slice::Gen::DispatcherVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ if(p->isLocal() || !p->isInterface())
+ {
+ return false;
+ }
+
+ string name = p->name();
+
+ _out << sp << nl << "public abstract class " << name << "Disp_ : Ice.ObjectImpl, " << fixId(name);
+ _out << sb;
+
+ OperationList ops = p->operations();
+ if(!ops.empty())
+ {
+ _out << sp << nl << "#region Slice operations";
+ for(OperationList::const_iterator op = ops.begin(); op != ops.end(); ++op)
+ {
+ string opname = (*op)->name();
+ vector<string> params = getParams(*op);
+ vector<string> args = getArgs(*op);
+ TypePtr ret = (*op)->returnType();
+
+ opname = fixId(opname, DotNet::ICloneable, true);
+
+ _out << sp << nl << "public abstract " << typeToString(ret) << " "
+ << opname << spar << params << epar << ';';
+ }
+ _out << sp << nl << "#endregion"; // Slice operations
+ }
+
+ writeInheritedOperations(p);
+
+ writeDispatchAndMarshalling(p);
+
+ _out << eb;
+
+ return true;
+}
+
+Slice::Gen::AsyncVisitor::AsyncVisitor(::IceUtil::Output &out)
+ : CsVisitor(out)
+{
+}
+
+bool
+Slice::Gen::AsyncVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!p->hasAsyncOps())
+ {
+ return false;
+ }
+
+ _out << sp << nl << "namespace " << fixId(p->name());
+ _out << sb;
+ return true;
+}
+
+void
+Slice::Gen::AsyncVisitor::visitModuleEnd(const ModulePtr&)
+{
+ _out << eb;
+}
+
+bool
+Slice::Gen::AsyncVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ return true;
+}
+
+void
+Slice::Gen::AsyncVisitor::visitClassDefEnd(const ClassDefPtr&)
+{
+}
+
+void
+Slice::Gen::AsyncVisitor::visitOperation(const OperationPtr& p)
+{
+ ContainerPtr container = p->container();
+ ClassDefPtr cl = ClassDefPtr::dynamicCast(container);
+
+ if(cl->isLocal())
+ {
+ return;
+ }
+
+ string name = p->name();
+
+ if(cl->hasMetaData("ami") || p->hasMetaData("ami"))
+ {
+
+ TypePtr ret = p->returnType();
+ string retS = typeToString(ret);
+
+ TypeStringList inParams;
+ TypeStringList outParams;
+ ParamDeclList paramList = p->parameters();
+ for(ParamDeclList::const_iterator pli = paramList.begin(); pli != paramList.end(); ++pli)
+ {
+ if((*pli)->isOutParam())
+ {
+ outParams.push_back(make_pair((*pli)->type(), (*pli)->name()));
+ }
+ else
+ {
+ inParams.push_back(make_pair((*pli)->type(), (*pli)->name()));
+ }
+ }
+
+ ExceptionList throws = p->throws();
+ throws.sort();
+ throws.unique();
+
+ //
+ // Arrange exceptions into most-derived to least-derived order. If we don't
+ // do this, a base exception handler can appear before a derived exception
+ // handler, causing compiler warnings and resulting in the base exception
+ // being marshaled instead of the derived exception.
+ //
+#if defined(__SUNPRO_CC)
+ throws.sort(Slice::derivedToBaseCompare);
+#else
+ throws.sort(Slice::DerivedToBaseCompare());
+#endif
+
+ TypeStringList::const_iterator q;
+
+ vector<string> params = getParamsAsyncCB(p);
+ vector<string> args = getArgsAsyncCB(p);
+
+ vector<string> paramsInvoke = getParamsAsync(p, false);
+
+ _out << sp << nl << "public abstract class AMI_" << cl->name() << '_'
+ << name << " : IceInternal.OutgoingAsync";
+ _out << sb;
+ _out << sp;
+ _out << nl << "public abstract void ice_response" << spar << params << epar << ';';
+
+ _out << sp << nl << "public void invoke__" << spar << "Ice.ObjectPrx prx__"
+ << paramsInvoke << "_System.Collections.Generic.Dictionary<string, string> ctx__" << epar;
+ _out << sb;
+ _out << nl << "try";
+ _out << sb;
+ _out << nl << "prepare__(prx__, \"" << name << "\", " << sliceModeToIceMode(p->sendMode())
+ << ", ctx__);";
+ for(q = inParams.begin(); q != inParams.end(); ++q)
+ {
+ string typeS = typeToString(q->first);
+ writeMarshalUnmarshalCode(_out, q->first, fixId(q->second), true, false, false);
+ }
+ if(p->sendsClasses())
+ {
+ _out << nl << "os__.writePendingObjects();";
+ }
+ _out << nl << "os__.endWriteEncaps();";
+ _out << eb;
+ _out << nl << "catch(Ice.LocalException ex__)";
+ _out << sb;
+ _out << nl << "finished__(ex__);";
+ _out << nl << "return;";
+ _out << eb;
+ _out << nl << "send__();";
+ _out << eb;
+
+ _out << sp << nl << "protected override void response__(bool ok__)";
+ _out << sb;
+ for(q = outParams.begin(); q != outParams.end(); ++q)
+ {
+ string param = fixId(q->second);
+ string typeS = typeToString(q->first);
+ _out << nl << typeS << ' ' << param << ';';
+ }
+ if(ret)
+ {
+ _out << nl << retS << " ret__;";
+ }
+ _out << nl << "try";
+ _out << sb;
+ _out << nl << "if(!ok__)";
+ _out << sb;
+ _out << nl << "try";
+ _out << sb;
+ _out << nl << "is__.throwException();";
+ _out << eb;
+ for(ExceptionList::const_iterator r = throws.begin(); r != throws.end(); ++r)
+ {
+ _out << nl << "catch(" << fixId((*r)->scoped()) << ')';
+ _out << sb;
+ _out << nl << "throw;";
+ _out << eb;
+ }
+ _out << nl << "catch(Ice.UserException ex)";
+ _out << sb;
+ _out << nl << "throw new Ice.UnknownUserException(ex);";
+ _out << eb;
+ _out << eb;
+ for(q = outParams.begin(); q != outParams.end(); ++q)
+ {
+ string param = fixId(q->second);
+ StructPtr st = StructPtr::dynamicCast(q->first);
+ if(st)
+ if(isValueType(st))
+ {
+ _out << nl << param << " = new " << typeToString(q->first) << "();";
+ }
+ else
+ {
+ _out << nl << param << " = null;";
+ }
+ writeMarshalUnmarshalCode(_out, q->first, fixId(q->second), false, false, true);
+ }
+ if(ret)
+ {
+ StructPtr st = StructPtr::dynamicCast(ret);
+ if(st)
+ {
+ if(isValueType(ret))
+ {
+ _out << nl << "ret__ = new " << retS << "();";
+ }
+ else
+ {
+ _out << nl << "ret__ = null;";
+ }
+ }
+ writeMarshalUnmarshalCode(_out, ret, "ret__", false, false, true);
+ }
+ if(p->returnsClasses())
+ {
+ _out << nl << "is__.readPendingObjects();";
+ }
+ for(q = outParams.begin(); q != outParams.end(); ++q)
+ {
+ string param = fixId(q->second);
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(q->first);
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(q->first))
+ {
+ string type = typeToString(q->first);
+ _out << nl << param << " = (" << type << ")" << param << "_PP.value;";
+ }
+ }
+ if(ret)
+ {
+ BuiltinPtr builtin = BuiltinPtr::dynamicCast(ret);
+ if((builtin && builtin->kind() == Builtin::KindObject) || ClassDeclPtr::dynamicCast(ret))
+ {
+ string type = typeToString(ret);
+ _out << nl << "ret__ = (" << retS << ")ret___PP.value;";
+ }
+ }
+ _out << eb;
+ _out << nl << "catch(Ice.LocalException ex__)";
+ _out << sb;
+ _out << nl << "finished__(ex__);";
+ _out << nl << "return;";
+ _out << eb;
+ if(!throws.empty())
+ {
+ _out << nl << "catch(Ice.UserException ex__)";
+ _out << sb;
+ _out << nl << "ice_exception(ex__);";
+ _out << nl << "return;";
+ _out << eb;
+ }
+ _out << nl << "ice_response" << spar << args << epar << ';';
+ _out << eb;
+ _out << eb;
+ }
+}
diff --git a/cpp/src/slice2sl/Gen.h b/cpp/src/slice2sl/Gen.h
new file mode 100644
index 00000000000..8d16880ba56
--- /dev/null
+++ b/cpp/src/slice2sl/Gen.h
@@ -0,0 +1,260 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2007 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#ifndef GEN_H
+#define GEN_H
+
+#include <Slice/CsUtil.h>
+
+namespace Slice
+{
+
+
+class CsVisitor : public CsGenerator, public ParserVisitor
+{
+public:
+
+ CsVisitor(::IceUtil::Output&);
+ virtual ~CsVisitor();
+
+protected:
+
+ virtual void writeInheritedOperations(const ClassDefPtr&);
+ virtual void writeDispatchAndMarshalling(const ClassDefPtr&);
+ virtual std::vector<std::string> getParams(const OperationPtr&);
+ virtual std::vector<std::string> getParamsAsync(const OperationPtr&, bool);
+ virtual std::vector<std::string> getParamsAsyncCB(const OperationPtr&);
+ virtual std::vector<std::string> getArgs(const OperationPtr&);
+ virtual std::vector<std::string> getArgsAsync(const OperationPtr&);
+ virtual std::vector<std::string> getArgsAsyncCB(const OperationPtr&);
+
+ void emitAttributes(const ContainedPtr&);
+ ::std::string getParamAttributes(const ParamDeclPtr&);
+
+ ::IceUtil::Output& _out;
+};
+
+class Gen : private ::IceUtil::noncopyable
+{
+public:
+
+ Gen(const std::string&, const std::string&, const std::vector<std::string>&, const std::string&);
+ ~Gen();
+
+ bool operator!() const; // Returns true if there was a constructor error
+
+ void generate(const UnitPtr&);
+ void generateTie(const UnitPtr&);
+ void generateImpl(const UnitPtr&);
+ void generateImplTie(const UnitPtr&);
+
+private:
+
+ IceUtil::Output _out;
+ IceUtil::Output _impl;
+
+ std::vector<std::string> _includePaths;
+
+ void printHeader();
+
+ class UnitVisitor : public CsVisitor
+ {
+ public:
+
+ UnitVisitor(::IceUtil::Output&);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+
+ private:
+
+ bool _globalMetaDataDone;
+ };
+
+ class TypesVisitor : public CsVisitor
+ {
+ public:
+
+ TypesVisitor(::IceUtil::Output&);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual void visitOperation(const OperationPtr&);
+ virtual void visitClassDefEnd(const ClassDefPtr&);
+ virtual bool visitExceptionStart(const ExceptionPtr&);
+ virtual void visitExceptionEnd(const ExceptionPtr&);
+ virtual bool visitStructStart(const StructPtr&);
+ virtual void visitStructEnd(const StructPtr&);
+ virtual void visitSequence(const SequencePtr&);
+ virtual void visitDictionary(const DictionaryPtr&);
+ virtual void visitEnum(const EnumPtr&);
+ virtual void visitConst(const ConstPtr&);
+ virtual void visitDataMember(const DataMemberPtr&);
+ };
+
+ class ProxyVisitor : public CsVisitor
+ {
+ public:
+
+ ProxyVisitor(::IceUtil::Output&);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual void visitClassDefEnd(const ClassDefPtr&);
+ virtual void visitOperation(const OperationPtr&);
+ };
+
+ class OpsVisitor : public CsVisitor
+ {
+ public:
+
+ OpsVisitor(::IceUtil::Output&);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+
+ private:
+ void writeOperations(const ClassDefPtr&, bool);
+ };
+
+ class HelperVisitor : public CsVisitor
+ {
+ public:
+
+ HelperVisitor(::IceUtil::Output&);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual void visitClassDefEnd(const ClassDefPtr&);
+ virtual void visitSequence(const SequencePtr&);
+ virtual void visitDictionary(const DictionaryPtr&);
+ };
+
+ class DelegateVisitor : public CsVisitor
+ {
+ public:
+
+ DelegateVisitor(::IceUtil::Output&);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual void visitClassDefEnd(const ClassDefPtr&);
+ };
+
+ class DelegateMVisitor : public CsVisitor
+ {
+ public:
+
+ DelegateMVisitor(::IceUtil::Output&);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual void visitClassDefEnd(const ClassDefPtr&);
+ };
+
+ class DelegateDVisitor : public CsVisitor
+ {
+ public:
+
+ DelegateDVisitor(::IceUtil::Output&);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual void visitClassDefEnd(const ClassDefPtr&);
+ };
+
+ class DispatcherVisitor : public CsVisitor
+ {
+ public:
+
+ DispatcherVisitor(::IceUtil::Output&);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ };
+
+ class AsyncVisitor : public CsVisitor
+ {
+ public:
+
+ AsyncVisitor(::IceUtil::Output&);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual void visitClassDefEnd(const ClassDefPtr&);
+ virtual void visitOperation(const OperationPtr&);
+ };
+
+ class TieVisitor : public CsVisitor
+ {
+ public:
+
+ TieVisitor(::IceUtil::Output&);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual void visitClassDefEnd(const ClassDefPtr&);
+
+ private:
+
+ typedef ::std::set< ::std::string> NameSet;
+ void writeInheritedOperationsWithOpNames(const ClassDefPtr&, NameSet&);
+ };
+
+ class BaseImplVisitor : public CsVisitor
+ {
+ public:
+
+ BaseImplVisitor(::IceUtil::Output&);
+
+ protected:
+
+ void writeOperation(const OperationPtr&, bool, bool);
+
+ private:
+
+ ::std::string writeValue(const TypePtr&);
+ };
+
+ class ImplVisitor : public BaseImplVisitor
+ {
+ public:
+
+ ImplVisitor(::IceUtil::Output&);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ virtual void visitClassDefEnd(const ClassDefPtr&);
+ };
+
+ class ImplTieVisitor : public BaseImplVisitor
+ {
+ public:
+
+ ImplTieVisitor(::IceUtil::Output&);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+ virtual void visitModuleEnd(const ModulePtr&);
+ virtual bool visitClassDefStart(const ClassDefPtr&);
+ };
+};
+
+}
+
+#endif
diff --git a/cpp/src/slice2sl/Main.cpp b/cpp/src/slice2sl/Main.cpp
new file mode 100644
index 00000000000..fa86c17720e
--- /dev/null
+++ b/cpp/src/slice2sl/Main.cpp
@@ -0,0 +1,182 @@
+// **********************************************************************
+//
+// Copyright (c) 2003-2007 ZeroC, Inc. All rights reserved.
+//
+// This copy of Ice is licensed to you under the terms described in the
+// ICE_LICENSE file included in this distribution.
+//
+// **********************************************************************
+
+#include <IceUtil/Options.h>
+#include <Slice/Preprocessor.h>
+#include <Gen.h>
+
+using namespace std;
+using namespace Slice;
+
+void
+usage(const char* n)
+{
+ cerr << "Usage: " << n << " [options] slice-files...\n";
+ cerr <<
+ "Options:\n"
+ "-h, --help Show this message.\n"
+ "-v, --version Display the Ice version.\n"
+ "-DNAME Define NAME as 1.\n"
+ "-DNAME=DEF Define NAME as DEF.\n"
+ "-UNAME Remove any definition for NAME.\n"
+ "-IDIR Put DIR in the include file search path.\n"
+ "-E Print preprocessor output on stdout.\n"
+ "--output-dir DIR Create files in the directory DIR.\n"
+ "--depend Generate Makefile dependencies.\n"
+ "-d, --debug Print debug messages.\n"
+ "--ice Permit `Ice' prefix (for building Ice source code only)\n"
+ ;
+ // Note: --case-sensitive is intentionally not shown here!
+}
+
+int
+main(int argc, char* argv[])
+{
+ IceUtil::Options opts;
+ opts.addOpt("h", "help");
+ opts.addOpt("v", "version");
+ opts.addOpt("D", "", IceUtil::Options::NeedArg, "", IceUtil::Options::Repeat);
+ opts.addOpt("U", "", IceUtil::Options::NeedArg, "", IceUtil::Options::Repeat);
+ opts.addOpt("I", "", IceUtil::Options::NeedArg, "", IceUtil::Options::Repeat);
+ opts.addOpt("E");
+ opts.addOpt("", "output-dir", IceUtil::Options::NeedArg);
+ opts.addOpt("", "depend");
+ opts.addOpt("d", "debug");
+ opts.addOpt("", "ice");
+ opts.addOpt("", "case-sensitive");
+
+ vector<string> args;
+ try
+ {
+ args = opts.parse(argc, (const char**)argv);
+ }
+ catch(const IceUtil::BadOptException& e)
+ {
+ cerr << argv[0] << ": " << e.reason << endl;
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ if(opts.isSet("help"))
+ {
+ usage(argv[0]);
+ return EXIT_SUCCESS;
+ }
+
+ if(opts.isSet("version"))
+ {
+ cout << ICE_STRING_VERSION << endl;
+ return EXIT_SUCCESS;
+ }
+
+ string cppArgs;
+ vector<string> optargs = opts.argVec("D");
+ vector<string>::const_iterator i;
+ for(i = optargs.begin(); i != optargs.end(); ++i)
+ {
+ cppArgs += " -D" + Preprocessor::addQuotes(*i);
+ }
+
+ optargs = opts.argVec("U");
+ for(i = optargs.begin(); i != optargs.end(); ++i)
+ {
+ cppArgs += " -U" + Preprocessor::addQuotes(*i);
+ }
+
+ vector<string> includePaths = opts.argVec("I");
+ for(i = includePaths.begin(); i != includePaths.end(); ++i)
+ {
+ cppArgs += " -I" + Preprocessor::normalizeIncludePath(*i);
+ }
+
+ bool preprocess = opts.isSet("E");
+
+ string output = opts.optArg("output-dir");
+
+ bool depend = opts.isSet("depend");
+
+ bool debug = opts.isSet("debug");
+
+ bool ice = opts.isSet("ice");
+
+ bool caseSensitive = opts.isSet("case-sensitive");
+
+ if(args.empty())
+ {
+ cerr << argv[0] << ": no input file" << endl;
+ usage(argv[0]);
+ return EXIT_FAILURE;
+ }
+
+ int status = EXIT_SUCCESS;
+
+ for(i = args.begin(); i != args.end(); ++i)
+ {
+ if(depend)
+ {
+ Preprocessor icecpp(argv[0], *i, cppArgs);
+ icecpp.printMakefileDependencies(Preprocessor::CSharp);
+ }
+ else
+ {
+ Preprocessor icecpp(argv[0], *i, cppArgs);
+ FILE* cppHandle = icecpp.preprocess(false);
+
+ if(cppHandle == 0)
+ {
+ return EXIT_FAILURE;
+ }
+ if(preprocess)
+ {
+ char buf[4096];
+ while(fgets(buf, static_cast<int>(sizeof(buf)), cppHandle) != NULL)
+ {
+ if(fputs(buf, stdout) == EOF)
+ {
+ return EXIT_FAILURE;
+ }
+ }
+ if(!icecpp.close())
+ {
+ return EXIT_FAILURE;
+ }
+ }
+ else
+ {
+ UnitPtr p = Unit::createUnit(false, false, ice, caseSensitive);
+ int parseStatus = p->parse(cppHandle, debug);
+
+ if(!icecpp.close())
+ {
+ p->destroy();
+ return EXIT_FAILURE;
+ }
+
+ if(parseStatus == EXIT_FAILURE)
+ {
+ status = EXIT_FAILURE;
+ }
+ else
+ {
+ Gen gen(argv[0], icecpp.getBaseName(), includePaths, output);
+ if(!gen)
+ {
+ p->destroy();
+ return EXIT_FAILURE;
+ }
+ gen.generate(p);
+ }
+
+ p->destroy();
+ }
+ }
+ }
+
+ return status;
+}
diff --git a/cpp/src/slice2sl/Makefile b/cpp/src/slice2sl/Makefile
new file mode 100644
index 00000000000..3e2c3f48179
--- /dev/null
+++ b/cpp/src/slice2sl/Makefile
@@ -0,0 +1,32 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2007 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ../..
+
+NAME = $(top_srcdir)/bin/slice2sl
+
+TARGETS = $(NAME)
+
+OBJS = Gen.o \
+ Main.o
+
+SRCS = $(OBJS:.o=.cpp)
+
+include $(top_srcdir)/config/Make.rules
+
+CPPFLAGS := -I. $(CPPFLAGS)
+
+$(NAME): $(OBJS)
+ rm -f $@
+ $(CXX) $(LDFLAGS) -o $@ $(OBJS) -lSlice $(BASELIBS)
+
+install:: all
+ $(call installprogram,$(NAME),$(install_bindir))
+
+include .depend
diff --git a/cpp/src/slice2sl/Makefile.mak b/cpp/src/slice2sl/Makefile.mak
new file mode 100644
index 00000000000..d6f2b230401
--- /dev/null
+++ b/cpp/src/slice2sl/Makefile.mak
@@ -0,0 +1,56 @@
+# **********************************************************************
+#
+# Copyright (c) 2003-2007 ZeroC, Inc. All rights reserved.
+#
+# This copy of Ice is licensed to you under the terms described in the
+# ICE_LICENSE file included in this distribution.
+#
+# **********************************************************************
+
+top_srcdir = ..\..
+
+NAME = $(top_srcdir)\bin\slice2sl.exe
+
+TARGETS = $(NAME)
+
+OBJS = Gen.obj \
+ Main.obj
+
+SRCS = $(OBJS:.obj=.cpp)
+
+!include $(top_srcdir)/config/Make.rules.mak
+
+CPPFLAGS = -I. $(CPPFLAGS) -DWIN32_LEAN_AND_MEAN
+
+!if "$(CPP_COMPILER)" != "BCC2006" && "$(OPTIMIZE)" != "yes"
+PDBFLAGS = /pdb:$(NAME:.exe=.pdb)
+!endif
+
+$(NAME): $(OBJS)
+ $(LINK) $(LD_EXEFLAGS) $(PDBFLAGS) $(OBJS) $(SETARGV) $(PREOUT)$@ $(PRELIBS)slice$(LIBSUFFIX).lib $(BASELIBS)
+ @if exist $@.manifest echo ^ ^ ^ Embedding manifest using $(MT) && \
+ $(MT) -nologo -manifest $@.manifest -outputresource:$@;#1 && del /q $@.manifest
+
+clean::
+ del /q $(NAME:.exe=.*)
+
+install:: all
+ copy $(NAME) $(install_bindir)
+
+!if "$(OPTIMIZE)" != "yes"
+
+!if "$(CPP_COMPILER)" == "BCC2006"
+
+install:: all
+ copy $(NAME:.exe=.tds) $(install_bindir)
+
+!else
+
+install:: all
+ copy $(NAME:.exe=.pdb) $(install_bindir)
+
+!endif
+
+!endif
+
+!include .depend