summaryrefslogtreecommitdiff
path: root/cpp/src/Slice/PythonUtil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/Slice/PythonUtil.cpp')
-rw-r--r--cpp/src/Slice/PythonUtil.cpp1215
1 files changed, 558 insertions, 657 deletions
diff --git a/cpp/src/Slice/PythonUtil.cpp b/cpp/src/Slice/PythonUtil.cpp
index 8fe29955ed6..05c928c0e7d 100644
--- a/cpp/src/Slice/PythonUtil.cpp
+++ b/cpp/src/Slice/PythonUtil.cpp
@@ -12,8 +12,6 @@
#include <Slice/Util.h>
#include <IceUtil/IceUtil.h>
#include <IceUtil/StringUtil.h>
-#include <IceUtil/InputUtil.h>
-#include <IceUtil/Unicode.h>
#include <climits>
#include <iterator>
@@ -22,6 +20,27 @@ using namespace Slice;
using namespace IceUtil;
using namespace IceUtilInternal;
+namespace
+{
+
+string
+getEscapedParamName(const OperationPtr& p, const string& name)
+{
+ ParamDeclList params = p->parameters();
+
+ for(ParamDeclList::const_iterator i = params.begin(); i != params.end(); ++i)
+ {
+ if((*i)->name() == name)
+ {
+ return name + "_";
+ }
+ }
+ return name;
+}
+
+}
+
+
namespace Slice
{
namespace Python
@@ -49,7 +68,7 @@ private:
//
// Validates sequence metadata.
//
- void validateSequence(const string&, const string&, const TypePtr&, const StringList&);
+ StringList validateSequence(const string&, const string&, const TypePtr&, const StringList&);
//
// Checks a definition that doesn't currently support Python metadata.
@@ -105,9 +124,14 @@ public:
private:
//
+ // Emit Python code for the class operations
+ //
+ void writeOperations(const ClassDefPtr&);
+
+ //
// Return a Python symbol for the given parser element.
//
- string getSymbol(const ContainedPtr&, const string& = string());
+ string getSymbol(const ContainedPtr&, const string& = "", const string& = "");
//
// Emit Python code to assign the given symbol in the current module.
@@ -183,7 +207,7 @@ private:
};
bool parseOpComment(const string&, OpComment&);
- enum DocstringMode { DocSync, DocAsyncBegin, DocAsyncEnd, DocDispatch, DocAsyncDispatch };
+ enum DocstringMode { DocSync, DocAsync, DocAsyncBegin, DocAsyncEnd, DocDispatch, DocAsyncDispatch };
void writeDocstring(const OperationPtr&, DocstringMode, bool);
@@ -196,44 +220,6 @@ private:
}
}
-string
-u32CodePoint(unsigned int value)
-{
- ostringstream s;
- s << "\\U";
- s << hex;
- s.width(8);
- s.fill('0');
- s << value;
- return s.str();
-}
-
-void
-writeU8Buffer(const vector<unsigned char>& u8buffer, ostringstream& out)
-{
- vector<unsigned int> u32buffer;
- IceUtilInternal::ConversionResult result = convertUTF8ToUTF32(u8buffer, u32buffer, IceUtil::lenientConversion);
- switch(result)
- {
- case conversionOK:
- break;
- case sourceExhausted:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source exhausted");
- case sourceIllegal:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source illegal");
- default:
- {
- assert(0);
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__);
- }
- }
-
- for(vector<unsigned int>::const_iterator c = u32buffer.begin(); c != u32buffer.end(); ++c)
- {
- out << u32CodePoint(*c);
- }
-}
-
static string
lookupKwd(const string& name)
{
@@ -288,7 +274,7 @@ splitScopedName(const string& scoped)
}
static string
-getDictLookup(const ContainedPtr& cont, const string& suffix = string())
+getDictLookup(const ContainedPtr& cont, const string& suffix = "", const string& prefix = "")
{
string scope = Slice::Python::scopedToName(cont->scope());
assert(!scope.empty());
@@ -299,7 +285,7 @@ getDictLookup(const ContainedPtr& cont, const string& suffix = string())
scope = package + "." + scope;
}
- return "'" + suffix + Slice::Python::fixIdent(cont->name()) + "' not in _M_" + scope + "__dict__";
+ return "'" + suffix + Slice::Python::fixIdent(cont->name() + prefix) + "' not in _M_" + scope + "__dict__";
}
//
@@ -356,7 +342,8 @@ Slice::Python::ModuleVisitor::visitModuleStart(const ModulePtr& p)
// CodeVisitor implementation.
//
Slice::Python::CodeVisitor::CodeVisitor(Output& out, set<string>& moduleHistory) :
- _out(out), _moduleHistory(moduleHistory)
+ _out(out),
+ _moduleHistory(moduleHistory)
{
}
@@ -440,10 +427,15 @@ Slice::Python::CodeVisitor::visitClassDecl(const ClassDeclPtr& p)
{
_out << sp << nl << "if " << getDictLookup(p) << ':';
_out.inc();
- string type = getAbsolute(p, "_t_");
- _out << nl << "_M_" << type << " = IcePy.declareClass('" << scoped << "')";
- if(!p->isLocal())
+
+ if(!p->isInterface() || p->isLocal())
{
+ _out << nl << "_M_" << getAbsolute(p, "_t_") << " = IcePy.declareValue('" << scoped << "')";
+ }
+
+ if(!p->isLocal() && (p->isInterface() || p->definition()->allOperations().size()))
+ {
+ _out << nl << "_M_" << getAbsolute(p, "_t_", "Disp") << " = IcePy.declareClass('" << scoped << "')";
_out << nl << "_M_" << getAbsolute(p, "_t_", "Prx") << " = IcePy.declareProxy('" << scoped << "')";
}
_out.dec();
@@ -451,150 +443,10 @@ Slice::Python::CodeVisitor::visitClassDecl(const ClassDeclPtr& p)
}
}
-bool
-Slice::Python::CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
+void
+Slice::Python::CodeVisitor::writeOperations(const ClassDefPtr& p)
{
- string scoped = p->scoped();
- string type = getAbsolute(p, "_t_");
- string abs = getAbsolute(p);
- string name = fixIdent(p->name());
- string prxAbs = getAbsolute(p, "", "Prx");
- string prxName = fixIdent(p->name() + "Prx");
- string prxType = getAbsolute(p, "_t_", "Prx");
- ClassList bases = p->bases();
- ClassDefPtr base;
OperationList ops = p->operations();
- bool isAbstract = p->isInterface() || p->allOperations().size() > 0; // Don't use isAbstract() - see bug 3739
-
- //
- // Define the class.
- //
- _out << sp << nl << "if " << getDictLookup(p) << ':';
- _out.inc();
- _out << nl << "_M_" << abs << " = Ice.createTempClass()";
- _out << nl << "class " << name << '(';
- if(bases.empty())
- {
- if(p->isLocal())
- {
- _out << "object";
- }
- else
- {
- _out << "Ice.Object";
- }
- }
- else
- {
- for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q)
- {
- if(q != bases.begin())
- {
- _out << ", ";
- }
- _out << getSymbol(*q);
- }
- if(!bases.front()->isInterface())
- {
- base = bases.front();
- }
- }
- _out << "):";
-
- _out.inc();
-
- writeDocstring(p->comment(), p->dataMembers());
-
- //
- // __init__
- //
- _out << nl << "def __init__(self";
- MemberInfoList allMembers;
- collectClassMembers(p, allMembers, false);
- writeConstructorParams(allMembers);
- _out << "):";
- _out.inc();
- if(!base && !p->hasDataMembers() && !isAbstract)
- {
- _out << nl << "pass";
- }
- else
- {
- if(isAbstract)
- {
- _out << nl << "if Ice.getType(self) == _M_" << abs << ':';
- _out.inc();
- _out << nl << "raise RuntimeError('" << abs << " is an abstract class')";
- _out.dec();
- }
- if(base)
- {
- _out << nl << getSymbol(base) << ".__init__(self";
- for(MemberInfoList::iterator q = allMembers.begin(); q != allMembers.end(); ++q)
- {
- if(q->inherited)
- {
- _out << ", " << q->fixedName;
- }
- }
- _out << ')';
- }
- for(MemberInfoList::iterator q = allMembers.begin(); q != allMembers.end(); ++q)
- {
- if(!q->inherited)
- {
- writeAssign(*q);
- }
- }
- }
- _out.dec();
-
- if(!p->isLocal())
- {
- //
- // ice_ids
- //
- ClassList allBases = p->allBases();
- StringList ids;
- transform(allBases.begin(), allBases.end(), back_inserter(ids), IceUtil::constMemFun(&Contained::scoped));
- StringList other;
- other.push_back(scoped);
- other.push_back("::Ice::Object");
- other.sort();
- ids.merge(other);
- ids.unique();
- _out << sp << nl << "def ice_ids(self, current=None):";
- _out.inc();
- _out << nl << "return (";
- for(StringList::iterator q = ids.begin(); q != ids.end(); ++q)
- {
- if(q != ids.begin())
- {
- _out << ", ";
- }
- _out << "'" << *q << "'";
- }
- _out << ')';
- _out.dec();
-
- //
- // ice_id
- //
- _out << sp << nl << "def ice_id(self, current=None):";
- _out.inc();
- _out << nl << "return '" << scoped << "'";
- _out.dec();
-
- //
- // ice_staticId
- //
- _out << sp << nl << "def ice_staticId():";
- _out.inc();
- _out << nl << "return '" << scoped << "'";
- _out.dec();
- _out << nl << "ice_staticId = staticmethod(ice_staticId)";
- }
-
if(!ops.empty())
{
//
@@ -603,9 +455,9 @@ Slice::Python::CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
for(OperationList::iterator oli = ops.begin(); oli != ops.end(); ++oli)
{
string fixedOpName = fixIdent((*oli)->name());
- if(!p->isLocal() && (p->hasMetaData("amd") || (*oli)->hasMetaData("amd")))
+ if(!p->isLocal())
{
- _out << sp << nl << "def " << (*oli)->name() << "_async(self, _cb";
+ _out << sp << nl << "def " << fixedOpName << "(self";
ParamDeclList params = (*oli)->parameters();
@@ -616,9 +468,11 @@ Slice::Python::CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
_out << ", " << fixIdent((*pli)->name());
}
}
+
if(!p->isLocal())
{
- _out << ", current=None";
+ const string currentParamName = getEscapedParamName(*oli, "current");
+ _out << ", " << currentParamName << "=None";
}
_out << "):";
_out.inc();
@@ -643,7 +497,8 @@ Slice::Python::CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
}
if(!p->isLocal())
{
- _out << ", current=None";
+ const string currentParamName = getEscapedParamName(*oli, "current");
+ _out << ", " << currentParamName << "=None";
}
_out << "):";
_out.inc();
@@ -653,44 +508,276 @@ Slice::Python::CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
}
}
}
+}
- //
- // __str__
- //
- _out << sp << nl << "def __str__(self):";
- _out.inc();
- _out << nl << "return IcePy.stringify(self, _M_" << getAbsolute(p, "_t_") << ")";
- _out.dec();
- _out << sp << nl << "__repr__ = __str__";
+bool
+Slice::Python::CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
+{
+ bool isLocal = p->isLocal();
+ bool isInterface = p->isInterface();
+ bool isAbstract = isInterface || p->allOperations().size() > 0; // Don't use isAbstract() - see bug 3739
- _out.dec();
+ string scoped = p->scoped();
+ string type = getAbsolute(p, "_t_");
+ string classType = getAbsolute(p, "_t_", "Disp");
+ string abs = getAbsolute(p);
+ string className = isLocal ? fixIdent(p->name()) : isAbstract ? fixIdent("_" + p->name() + "Disp") : "None";
+ string classAbs = getAbsolute(p, "_", "Disp");
+ string valueName = (isInterface && !isLocal) ? "Ice.Value" : fixIdent(p->name());
+ string prxAbs = getAbsolute(p, "", "Prx");
+ string prxName = fixIdent(p->name() + "Prx");
+ string prxType = getAbsolute(p, "_t_", "Prx");
+ ClassList bases = p->bases();
+ ClassDefPtr base;
+
+ if(!bases.empty() && !bases.front()->isInterface())
+ {
+ base = bases.front();
+ }
//
- // Define the proxy class.
+ // Define a class type for Value types or local classes.
//
- if(!p->isLocal())
+ if(isLocal || !isInterface)
{
- _out << sp << nl << "_M_" << prxAbs << " = Ice.createTempClass()";
- _out << nl << "class " << prxName << "(";
- if(bases.empty())
+ _out << sp << nl << "if " << getDictLookup(p) << ':';
+ _out.inc();
+ _out << nl << "_M_" << abs << " = Ice.createTempClass()";
+ _out << nl << "class " << valueName << '(';
+ if(isLocal)
{
- _out << "Ice.ObjectPrx";
+ if(bases.empty())
+ {
+ _out << "object";
+ }
+ else
+ {
+ for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q)
+ {
+ if(q != bases.begin())
+ {
+ _out << ", ";
+ }
+ _out << getSymbol(*q);
+ }
+ }
}
else
{
- ClassList::const_iterator q = bases.begin();
- while(q != bases.end())
+ if(bases.empty() || bases.front()->isInterface())
{
- _out << getSymbol(*q, "Prx");
- if(++q != bases.end())
+ _out << "Ice.Value";
+ }
+ else
+ {
+ _out << getSymbol(bases.front());
+ }
+ }
+ _out << "):";
+
+ _out.inc();
+
+ writeDocstring(p->comment(), p->dataMembers());
+
+ //
+ // __init__
+ //
+ _out << nl << "def __init__(self";
+ MemberInfoList allMembers;
+ collectClassMembers(p, allMembers, false);
+ writeConstructorParams(allMembers);
+ _out << "):";
+ _out.inc();
+ if(!base && !p->hasDataMembers() && (!isAbstract || !isLocal))
+ {
+ _out << nl << "pass";
+ }
+ else
+ {
+ if(isAbstract && isLocal)
+ {
+ _out << nl << "if Ice.getType(self) == _M_" << abs << ':';
+ _out.inc();
+ _out << nl << "raise RuntimeError('" << abs << " is an abstract class')";
+ _out.dec();
+ }
+ if(base)
+ {
+ _out << nl << getSymbol(base) << ".__init__(self";
+ for(MemberInfoList::iterator q = allMembers.begin(); q != allMembers.end(); ++q)
{
- _out << ", ";
+ if(q->inherited)
+ {
+ _out << ", " << q->fixedName;
+ }
+ }
+ _out << ')';
+ }
+ for(MemberInfoList::iterator q = allMembers.begin(); q != allMembers.end(); ++q)
+ {
+ if(!q->inherited)
+ {
+ writeAssign(*q);
+ }
+ }
+ }
+ _out.dec();
+
+ if(!isLocal)
+ {
+ //
+ // ice_id
+ //
+ _out << sp << nl << "def ice_id(self):";
+ _out.inc();
+ _out << nl << "return '" << scoped << "'";
+ _out.dec();
+
+ //
+ // ice_staticId
+ //
+ _out << sp << nl << "@staticmethod";
+ _out << nl << "def ice_staticId():";
+ _out.inc();
+ _out << nl << "return '" << scoped << "'";
+ _out.dec();
+ }
+ else
+ {
+ writeOperations(p);
+ }
+
+ //
+ // __str__
+ //
+ _out << sp << nl << "def __str__(self):";
+ _out.inc();
+ _out << nl << "return IcePy.stringify(self, _M_" << type << ")";
+ _out.dec();
+ _out << sp << nl << "__repr__ = __str__";
+
+ _out.dec();
+
+ if(_classHistory.count(scoped) == 0 && p->canBeCyclic())
+ {
+ //
+ // Emit a forward declaration for the class in case a data member refers to this type.
+ //
+ _out << sp << nl << "_M_" << type << " = IcePy.declareValue('" << scoped << "')";
+ }
+ DataMemberList members = p->dataMembers();
+ _out << sp << nl << "_M_" << type << " = IcePy.defineValue('" << scoped << "', " << valueName
+ << ", " << p->compactId() << ", ";
+ writeMetaData(p->getMetaData());
+ const bool preserved = p->hasMetaData("preserve-slice") || p->inheritsMetaData("preserve-slice");
+ _out << ", " << (preserved ? "True" : "False") << ", " << (isInterface ? "True" : "False") << ", ";
+ if(!base)
+ {
+ _out << "None";
+ }
+ else
+ {
+ _out << "_M_" << getAbsolute(base, "_t_");
+ }
+ _out << ", (";
+ //
+ // Members
+ //
+ // Data members are represented as a tuple:
+ //
+ // ('MemberName', MemberMetaData, MemberType, Optional, Tag)
+ //
+ // where MemberType is either a primitive type constant (T_INT, etc.) or the id of a constructed type.
+ //
+ if(members.size() > 1)
+ {
+ _out.inc();
+ _out << nl;
+ }
+ bool isProtected = p->hasMetaData("protected");
+ for(DataMemberList::iterator r = members.begin(); r != members.end(); ++r)
+ {
+ if(r != members.begin())
+ {
+ _out << ',' << nl;
+ }
+ _out << "('";
+ if(isProtected || (*r)->hasMetaData("protected"))
+ {
+ _out << '_';
+ }
+ _out << fixIdent((*r)->name()) << "', ";
+ writeMetaData((*r)->getMetaData());
+ _out << ", ";
+ writeType((*r)->type());
+ _out << ", " << ((*r)->optional() ? "True" : "False") << ", "
+ << ((*r)->optional() ? (*r)->tag() : 0) << ')';
+ }
+ if(members.size() == 1)
+ {
+ _out << ',';
+ }
+ else if(members.size() > 1)
+ {
+ _out.dec();
+ _out << nl;
+ }
+ _out << "))";
+ _out << nl << valueName << "._ice_type = _M_" << type;
+
+ registerName(valueName);
+
+ _out.dec();
+ }
+ else if(!isLocal && isInterface)
+ {
+ _out << sp << nl << "_M_" << type << " = IcePy.defineValue('" << scoped << "', Ice.Value, -1, ";
+ writeMetaData(p->getMetaData());
+ _out << ", False, True, None, ())";
+ }
+
+ if(!isLocal && isAbstract)
+ {
+ _out << sp << nl << "if " << getDictLookup(p, "", "Prx") << ':';
+ _out.inc();
+
+ // Define the proxy class
+ _out << nl << "_M_" << prxAbs << " = Ice.createTempClass()";
+ _out << nl << "class " << prxName << '(';
+
+ {
+ vector<string> baseClasses;
+ for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q)
+ {
+ ClassDefPtr d = *q;
+ if(d->isInterface() || d->allOperations().size() > 0)
+ {
+ baseClasses.push_back(getSymbol(*q, "", "Prx"));
+ }
+ }
+
+ if(baseClasses.empty())
+ {
+ _out << "Ice.ObjectPrx";
+ }
+ else
+ {
+ vector<string>::const_iterator q = baseClasses.begin();
+ while(q != baseClasses.end())
+ {
+ _out << *q;
+
+ if(++q != baseClasses.end())
+ {
+ _out << ", ";
+ }
}
}
}
_out << "):";
_out.inc();
+ OperationList ops = p->operations();
for(OperationList::iterator oli = ops.begin(); oli != ops.end(); ++oli)
{
string fixedOpName = fixIdent((*oli)->name());
@@ -721,170 +808,227 @@ Slice::Python::CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
{
_out << ", " << inParams;
}
- _out << ", _ctx=None):";
+ const string contextParamName = getEscapedParamName(*oli, "context");
+ _out << ", " << contextParamName << "=None):";
_out.inc();
- _out << nl << "return _M_" << abs << "._op_" << (*oli)->name() << ".invoke(self, ((" << inParams;
+ _out << nl << "return _M_" << classAbs << "._op_" << (*oli)->name() << ".invoke(self, ((" << inParams;
if(!inParams.empty() && inParams.find(',') == string::npos)
{
_out << ", ";
}
- _out << "), _ctx))";
+ _out << "), " << contextParamName << "))";
_out.dec();
//
// Async operations.
//
_out << sp;
+ writeDocstring(*oli, DocAsync, false);
+ _out << nl << "def " << (*oli)->name() << "Async(self";
+ if(!inParams.empty())
+ {
+ _out << ", " << inParams;
+ }
+ _out << ", " << contextParamName << "=None):";
+ _out.inc();
+ _out << nl << "return _M_" << classAbs << "._op_" << (*oli)->name() << ".invokeAsync(self, ((" << inParams;
+ if(!inParams.empty() && inParams.find(',') == string::npos)
+ {
+ _out << ", ";
+ }
+ _out << "), " << contextParamName << "))";
+ _out.dec();
+
+ _out << sp;
writeDocstring(*oli, DocAsyncBegin, false);
_out << nl << "def begin_" << (*oli)->name() << "(self";
if(!inParams.empty())
{
_out << ", " << inParams;
}
- _out << ", _response=None, _ex=None, _sent=None, _ctx=None):";
+ _out << ", _response=None, _ex=None, _sent=None, " << contextParamName << "=None):";
_out.inc();
- _out << nl << "return _M_" << abs << "._op_" << (*oli)->name() << ".begin(self, ((" << inParams;
+ _out << nl << "return _M_" << classAbs << "._op_" << (*oli)->name() << ".begin(self, ((" << inParams;
if(!inParams.empty() && inParams.find(',') == string::npos)
{
_out << ", ";
}
- _out << "), _response, _ex, _sent, _ctx))";
+ _out << "), _response, _ex, _sent, " << contextParamName << "))";
_out.dec();
_out << sp;
writeDocstring(*oli, DocAsyncEnd, false);
_out << nl << "def end_" << (*oli)->name() << "(self, _r):";
_out.inc();
- _out << nl << "return _M_" << abs << "._op_" << (*oli)->name() << ".end(self, _r)";
+ _out << nl << "return _M_" << classAbs << "._op_" << (*oli)->name() << ".end(self, _r)";
_out.dec();
}
- _out << sp << nl << "def checkedCast(proxy, facetOrCtx=None, _ctx=None):";
+ _out << sp << nl << "@staticmethod";
+ _out << nl << "def checkedCast(proxy, facetOrContext=None, context=None):";
_out.inc();
- _out << nl << "return _M_" << prxAbs << ".ice_checkedCast(proxy, '" << scoped << "', facetOrCtx, _ctx)";
+ _out << nl << "return _M_" << prxAbs << ".ice_checkedCast(proxy, '" << scoped << "', facetOrContext, context)";
_out.dec();
- _out << nl << "checkedCast = staticmethod(checkedCast)";
- _out << sp << nl << "def uncheckedCast(proxy, facet=None):";
+ _out << sp << nl << "@staticmethod";
+ _out << nl << "def uncheckedCast(proxy, facet=None):";
_out.inc();
_out << nl << "return _M_" << prxAbs << ".ice_uncheckedCast(proxy, facet)";
_out.dec();
- _out << nl << "uncheckedCast = staticmethod(uncheckedCast)";
- //
+ //
// ice_staticId
//
- _out << sp << nl << "def ice_staticId():";
+ _out << sp << nl << "@staticmethod";
+ _out << nl << "def ice_staticId():";
_out.inc();
_out << nl << "return '" << scoped << "'";
_out.dec();
- _out << nl << "ice_staticId = staticmethod(ice_staticId)";
- _out.dec();
+ _out.dec(); // end prx class
- _out << sp << nl << "_M_" << prxType << " = IcePy.defineProxy('" << scoped << "', " << prxName << ")";
- }
+ _out << nl << "_M_" << prxType << " = IcePy.defineProxy('" << scoped << "', " << prxName << ")";
+
+ registerName(prxName);
+
+ // Define the servant class
+ _out << sp << nl << "_M_" << classAbs << " = Ice.createTempClass()";
+ _out << nl << "class " << className << '(';
+ {
+ vector<string> baseClasses;
+ for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q)
+ {
+ ClassDefPtr d = *q;
+ if(d->isInterface() || d->allOperations().size() > 0)
+ {
+ baseClasses.push_back(getSymbol(*q, "_", "Disp"));
+ }
+ }
+
+ if(baseClasses.empty())
+ {
+ _out << "Ice.Object";
+ }
+ else
+ {
+ vector<string>::const_iterator q = baseClasses.begin();
+ while(q != baseClasses.end())
+ {
+ _out << *q;
+
+ if(++q != baseClasses.end())
+ {
+ _out << ", ";
+ }
+ }
+ }
+ }
+ _out << "):";
+
+ _out.inc();
- if(_classHistory.count(scoped) == 0 && p->canBeCyclic())
- {
//
- // Emit a forward declaration for the class in case a data member refers to this type.
+ // ice_ids
//
- _out << sp << nl << "_M_" << type << " = IcePy.declareClass('" << scoped << "')";
- }
-
- DataMemberList members = p->dataMembers();
- _out << sp << nl << "_M_" << type << " = IcePy.defineClass('" << scoped << "', " << name << ", " << p->compactId()
- << ", ";
- writeMetaData(p->getMetaData());
- const bool preserved = p->hasMetaData("preserve-slice") || p->inheritsMetaData("preserve-slice");
- _out << ", " << (isAbstract ? "True" : "False") << ", " << (preserved ? "True" : "False") << ", ";
- if(!base)
- {
- _out << "None";
- }
- else
- {
- _out << "_M_" << getAbsolute(base, "_t_");
- }
- _out << ", (";
- //
- // Interfaces
- //
- int interfaceCount = 0;
- for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q)
- {
- if((*q)->isInterface())
+ ClassList allBases = p->allBases();
+ StringList ids;
+ transform(allBases.begin(), allBases.end(), back_inserter(ids), IceUtil::constMemFun(&Contained::scoped));
+ StringList other;
+ other.push_back(scoped);
+ other.push_back("::Ice::Object");
+ other.sort();
+ ids.merge(other);
+ ids.unique();
+ _out << sp << nl << "def ice_ids(self, current=None):";
+ _out.inc();
+ _out << nl << "return (";
+ for(StringList::iterator q = ids.begin(); q != ids.end(); ++q)
{
- if(interfaceCount > 0)
+ if(q != ids.begin())
{
_out << ", ";
}
- _out << "_M_" << getAbsolute(*q, "_t_");
- ++interfaceCount;
+ _out << "'" << *q << "'";
}
- }
- if(interfaceCount == 1)
- {
- _out << ',';
- }
- //
- // Members
- //
- // Data members are represented as a tuple:
- //
- // ('MemberName', MemberMetaData, MemberType, Optional, Tag)
- //
- // where MemberType is either a primitive type constant (T_INT, etc.) or the id of a constructed type.
- //
- _out << "), (";
- if(members.size() > 1)
- {
+ _out << ')';
+ _out.dec();
+
+ //
+ // ice_id
+ //
+ _out << sp << nl << "def ice_id(self, current=None):";
_out.inc();
- _out << nl;
- }
- bool isProtected = p->hasMetaData("protected");
- for(DataMemberList::iterator r = members.begin(); r != members.end(); ++r)
- {
- if(r != members.begin())
+ _out << nl << "return '" << scoped << "'";
+ _out.dec();
+
+ //
+ // ice_staticId
+ //
+ _out << sp << nl << "@staticmethod";
+ _out << nl << "def ice_staticId():";
+ _out.inc();
+ _out << nl << "return '" << scoped << "'";
+ _out.dec();
+
+ writeOperations(p);
+
+ //
+ // __str__
+ //
+ _out << sp << nl << "def __str__(self):";
+ _out.inc();
+ _out << nl << "return IcePy.stringify(self, _M_" << getAbsolute(p, "_t_", "Disp") << ")";
+ _out.dec();
+ _out << sp << nl << "__repr__ = __str__";
+
+ _out.dec();
+
+ _out << sp << nl << "_M_" << classType << " = IcePy.defineClass('" << scoped << "', " << className
+ << ", ";
+ writeMetaData(p->getMetaData());
+ _out << ", ";
+ if(!base || (!base->isInterface() && base->allOperations().size() == 0))
{
- _out << ',' << nl;
+ _out << "None";
}
- _out << "('";
- if(isProtected || (*r)->hasMetaData("protected"))
+ else
{
- _out << '_';
+ _out << "_M_" << getAbsolute(base, "_t_", "Disp");
}
- _out << fixIdent((*r)->name()) << "', ";
- writeMetaData((*r)->getMetaData());
- _out << ", ";
- writeType((*r)->type());
- _out << ", " << ((*r)->optional() ? "True" : "False") << ", "
- << ((*r)->optional() ? (*r)->tag() : 0) << ')';
- }
- if(members.size() == 1)
- {
- _out << ',';
- }
- else if(members.size() > 1)
- {
- _out.dec();
- _out << nl;
- }
- _out << "))";
- _out << nl << name << "._ice_type = _M_" << type;
+ _out << ", (";
+ //
+ // Interfaces
+ //
+ int interfaceCount = 0;
+ for(ClassList::const_iterator q = bases.begin(); q != bases.end(); ++q)
+ {
+ if((*q)->isInterface())
+ {
+ if(interfaceCount > 0)
+ {
+ _out << ", ";
+ }
+ _out << "_M_" << getAbsolute(*q, "_t_", "Disp");
+ ++interfaceCount;
+ }
+ }
+ if(interfaceCount == 1)
+ {
+ _out << ',';
+ }
+ _out << "))";
+ _out << nl << className << "._ice_type = _M_" << classType;
- //
- // Define each operation. The arguments to the IcePy.Operation constructor are:
- //
- // 'opName', Mode, SendMode, AMD, Format, MetaData, (InParams), (OutParams), ReturnParam, (Exceptions)
- //
- // where InParams and OutParams are tuples of type descriptions, and Exceptions
- // is a tuple of exception type ids.
- //
- if(!p->isLocal())
- {
+
+ //
+ // Define each operation. The arguments to the IcePy.Operation constructor are:
+ //
+ // 'opName', Mode, SendMode, AMD, Format, MetaData, (InParams), (OutParams), ReturnParam, (Exceptions)
+ //
+ // where InParams and OutParams are tuples of type descriptions, and Exceptions
+ // is a tuple of exception type ids.
+ //
if(!ops.empty())
{
_out << sp;
@@ -908,10 +1052,10 @@ Slice::Python::CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
break;
}
- _out << nl << name << "._op_" << (*s)->name() << " = IcePy.Operation('" << (*s)->name() << "', "
- << getOperationMode((*s)->mode()) << ", " << getOperationMode((*s)->sendMode()) << ", "
- << ((p->hasMetaData("amd") || (*s)->hasMetaData("amd")) ? "True" : "False") << ", "
- << format << ", ";
+ _out << nl << className << "._op_" << (*s)->name() << " = IcePy.Operation('" << (*s)->name() << "', "
+ << getOperationMode((*s)->mode()) << ", " << getOperationMode((*s)->sendMode()) << ", "
+ << ((p->hasMetaData("amd") || (*s)->hasMetaData("amd")) ? "True" : "False") << ", "
+ << format << ", ";
writeMetaData((*s)->getMetaData());
_out << ", (";
for(t = params.begin(), count = 0; t != params.end(); ++t)
@@ -949,7 +1093,7 @@ Slice::Python::CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
_out << ", ";
writeType((*t)->type());
_out << ", " << ((*t)->optional() ? "True" : "False") << ", "
- << ((*t)->optional() ? (*t)->tag() : 0) << ')';
+ << ((*t)->optional() ? (*t)->tag() : 0) << ')';
++count;
}
}
@@ -1000,20 +1144,14 @@ Slice::Python::CodeVisitor::visitClassDefStart(const ClassDefPtr& p)
{
msg = deprecateMetadata.substr(pos + 1);
}
- _out << nl << name << "._op_" << (*s)->name() << ".deprecate(\"" << msg << "\")";
+ _out << nl << className << "._op_" << (*s)->name() << ".deprecate(\"" << msg << "\")";
}
}
- }
- registerName(name);
-
- if(!p->isLocal())
- {
- registerName(prxName);
+ registerName(className);
+ _out.dec();
}
- _out.dec();
-
if(_classHistory.count(scoped) == 0)
{
_classHistory.insert(scoped); // Avoid redundant declarations.
@@ -1102,9 +1240,9 @@ Slice::Python::CodeVisitor::visitExceptionStart(const ExceptionPtr& p)
_out << sp << nl << "__repr__ = __str__";
//
- // _ice_name
+ // _ice_id
//
- _out << sp << nl << "_ice_name = '" << scoped.substr(2) << "'";
+ _out << sp << nl << "_ice_id = '" << scoped << "'";
_out.dec();
@@ -1515,7 +1653,7 @@ Slice::Python::CodeVisitor::visitEnum(const EnumPtr& p)
string scoped = p->scoped();
string abs = getAbsolute(p);
string name = fixIdent(p->name());
- EnumeratorList enums = p->getEnumerators();
+ EnumeratorList enums = p->enumerators();
EnumeratorList::iterator q;
_out << sp << nl << "if " << getDictLookup(p) << ':';
@@ -1586,12 +1724,12 @@ Slice::Python::CodeVisitor::visitConst(const ConstPtr& p)
}
string
-Slice::Python::CodeVisitor::getSymbol(const ContainedPtr& p, const string& nameSuffix)
+Slice::Python::CodeVisitor::getSymbol(const ContainedPtr& p, const string& prefix, const string& suffix)
{
//
// An explicit reference to another type must always be prefixed with "_M_".
//
- return "_M_" + getAbsolute(p, "", nameSuffix);
+ return "_M_" + getAbsolute(p, prefix, suffix);
}
void
@@ -1651,8 +1789,9 @@ Slice::Python::CodeVisitor::writeType(const TypePtr& p)
break;
}
case Builtin::KindObject:
+ case Builtin::KindValue:
{
- _out << "IcePy._t_Object";
+ _out << "IcePy._t_Value";
break;
}
case Builtin::KindObjectProxy:
@@ -1672,7 +1811,15 @@ Slice::Python::CodeVisitor::writeType(const TypePtr& p)
ProxyPtr prx = ProxyPtr::dynamicCast(p);
if(prx)
{
- _out << "_M_" << getAbsolute(prx->_class(), "_t_", "Prx");
+ ClassDefPtr def = prx->_class()->definition();
+ if(def->isInterface() || def->allOperations().size() > 0)
+ {
+ _out << "_M_" << getAbsolute(prx->_class(), "_t_", "Prx");
+ }
+ else
+ {
+ _out << "IcePy._t_ObjectPrx";
+ }
return;
}
@@ -1714,6 +1861,7 @@ Slice::Python::CodeVisitor::writeInitializer(const DataMemberPtr& m)
_out << "''";
break;
}
+ case Builtin::KindValue:
case Builtin::KindObject:
case Builtin::KindObjectProxy:
case Builtin::KindLocalObject:
@@ -1728,7 +1876,7 @@ Slice::Python::CodeVisitor::writeInitializer(const DataMemberPtr& m)
EnumPtr en = EnumPtr::dynamicCast(p);
if(en)
{
- EnumeratorList enums = en->getEnumerators();
+ EnumeratorList enums = en->enumerators();
_out << getSymbol(en) << "." << fixIdent(enums.front()->name());
return;
}
@@ -1875,274 +2023,17 @@ Slice::Python::CodeVisitor::writeConstantValue(const TypePtr& type, const Syntax
}
case Slice::Builtin::KindString:
{
- ostringstream sv2;
- ostringstream sv3;
-
- //
- // 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());
+ string sv2 = toStringLiteral(value, "\a\b\f\n\r\t\v", "", Octal, 0);
+ string sv3 = toStringLiteral(value, "\a\b\f\n\r\t\v", "", UCN, 0);
- for(size_t i = 0; i < value.size();)
+ _out << "\"" << sv2<< "\"";
+ if(sv2 != sv3)
{
- char c = value[i];
- switch(c)
- {
- case '"':
- {
- sv2 << "\\\"";
- break;
- }
- case '\\':
- {
- string s = "\\";
- size_t j = i + 1;
- for(; j < value.size(); ++j)
- {
- if(value[j] != '\\')
- {
- break;
- }
- s += "\\";
- }
-
- //
- // An even number of slash \ will escape the backslash and
- // the codepoint will be interpreted as its charaters
- //
- // \\u00000041 - ['\\', 'u', '0', '0', '0', '0', '0', '0', '4', '1']
- // \\\u00000041 - ['\\', 'A'] (41 is the codepoint for 'A')
- //
- if(s.size() % 2 != 0 && (value[j] == 'U' || value[j] == 'u'))
- {
- //
- // Convert codepoint to UTF8 bytes and write the escaped bytes
- //
- sv2 << s.substr(0, s.size() - 1);
-
- size_t sz = value[j] == 'U' ? 8 : 4;
- string codepoint = value.substr(j + 1, sz);
- assert(codepoint.size() == sz);
-
- IceUtil::Int64 v = IceUtilInternal::strToInt64(codepoint.c_str(), 0, 16);
-
- vector<unsigned int> u32buffer;
- u32buffer.push_back(static_cast<unsigned int>(v));
-
- vector<unsigned char> u8buffer;
- IceUtilInternal::ConversionResult result = convertUTF32ToUTF8(u32buffer, u8buffer, IceUtil::lenientConversion);
- switch(result)
- {
- case conversionOK:
- break;
- case sourceExhausted:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source exhausted");
- case sourceIllegal:
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__, "string source illegal");
- default:
- {
- assert(0);
- throw IceUtil::IllegalConversionException(__FILE__, __LINE__);
- }
- }
-
- ostringstream s;
- for(vector<unsigned char>::const_iterator q = u8buffer.begin(); q != u8buffer.end(); ++q)
- {
- s << "\\";
- s.fill('0');
- s.width(3);
- s << oct;
- s << static_cast<unsigned int>(*q);
- }
- sv2 << s.str();
-
- i = j + 1 + sz;
- }
- else
- {
- sv2 << s;
- i = j;
- }
- continue;
- }
- case '\r':
- {
- sv2 << "\\r";
- break;
- }
- case '\n':
- {
- sv2 << "\\n";
- break;
- }
- case '\t':
- {
- sv2 << "\\t";
- break;
- }
- case '\b':
- {
- sv2 << "\\b";
- break;
- }
- case '\f':
- {
- sv2 << "\\f";
- break;
- }
- default:
- {
- if(charSet.find(c) == charSet.end())
- {
- unsigned char uc = c; // Char may be signed, so make it positive.
- stringstream s;
- s << "\\"; // Print as octal if not in basic source character set.
- s.flags(ios_base::oct);
- s.width(3);
- s.fill('0');
- s << static_cast<unsigned>(uc);
- sv2 << s.str();
- }
- else
- {
- sv2 << c; // Print normally if in basic source character set.
- }
- break;
- }
- }
- ++i;
- }
-
- vector<unsigned char> u8buffer; // Buffer to convert multibyte characters
-
- for(size_t i = 0; i < value.size();)
- {
- if(charSet.find(value[i]) == charSet.end())
- {
- char c = value[i];
- if(static_cast<unsigned char>(c) < 128) // Single byte character
- {
- //
- // Print as unicode if not in basic source character set
- //
- switch(c)
- {
- //
- // Don't encode this special characters as universal characters
- //
- case '\r':
- {
- sv3 << "\\r";
- break;
- }
- case '\n':
- {
- sv3 << "\\n";
- break;
- }
- case '\\':
- {
- sv3 << "\\";
- break;
- }
- default:
- {
- sv3 << u32CodePoint(c);
- break;
- }
- }
- }
- else
- {
- u8buffer.push_back(value[i]);
- }
- }
- else
- {
- //
- // Write any pedding characters in the utf8 buffer
- //
- if(!u8buffer.empty())
- {
- writeU8Buffer(u8buffer, sv3);
- u8buffer.clear();
- }
- switch(value[i])
- {
- case '\\':
- {
- string s = "\\";
- size_t j = i + 1;
- for(; j < value.size(); ++j)
- {
- if(value[j] != '\\')
- {
- break;
- }
- s += "\\";
- }
-
- //
- // An even number of slash \ will escape the backslash and
- // the codepoint will be interpreted as its charaters
- //
- // \\U00000041 - ['\\', 'U', '0', '0', '0', '0', '0', '0', '4', '1']
- // \\\U00000041 - ['\\', 'A'] (41 is the codepoint for 'A')
- //
- if(s.size() % 2 != 0 && (value[j] == 'U' || value[j] == 'u'))
- {
- size_t sz = value[j] == 'U' ? 8 : 4;
- sv3 << s.substr(0, s.size() - 1);
- i = j + 1;
-
- string codepoint = value.substr(j + 1, sz);
- assert(codepoint.size() == sz);
-
- IceUtil::Int64 v = IceUtilInternal::strToInt64(codepoint.c_str(), 0, 16);
- sv3 << u32CodePoint(static_cast<unsigned int>(v));
- i = j + 1 + sz;
- }
- else
- {
- sv3 << s;
- i = j;
- }
- continue;
- }
- case '"':
- {
- sv3 << "\\";
- break;
- }
- }
- sv3 << value[i]; // Print normally if in basic source character set
- }
- i++;
- }
-
- //
- // Write any pedding characters in the utf8 buffer
- //
- if(!u8buffer.empty())
- {
- writeU8Buffer(u8buffer, sv3);
- u8buffer.clear();
- }
-
-
- _out << "\"" << sv2.str() << "\"";
- if(sv2.str() != sv3.str())
- {
- _out << " if _version_info_[0] < 3 else \"" << sv3.str() << "\"";
+ _out << " if _version_info_[0] < 3 else \"" << sv3 << "\"";
}
break;
}
+ case Slice::Builtin::KindValue:
case Slice::Builtin::KindObject:
case Slice::Builtin::KindObjectProxy:
case Slice::Builtin::KindLocalObject:
@@ -2151,18 +2042,9 @@ Slice::Python::CodeVisitor::writeConstantValue(const TypePtr& type, const Syntax
}
else if(en)
{
- string enumName = getSymbol(en);
- string::size_type colon = value.rfind(':');
- string enumerator;
- if(colon != string::npos)
- {
- enumerator = fixIdent(value.substr(colon + 1));
- }
- else
- {
- enumerator = fixIdent(value);
- }
- _out << enumName << '.' << enumerator;
+ EnumeratorPtr lte = EnumeratorPtr::dynamicCast(valueType);
+ assert(lte);
+ _out << getSymbol(lte);
}
else
{
@@ -2781,7 +2663,7 @@ Slice::Python::CodeVisitor::writeDocstring(const OperationPtr& op, DocstringMode
{
return;
}
- else if(mode == DocAsyncBegin && inParams.empty())
+ else if((mode == DocAsync || mode == DocAsyncBegin) && inParams.empty())
{
return;
}
@@ -2814,6 +2696,7 @@ Slice::Python::CodeVisitor::writeDocstring(const OperationPtr& op, DocstringMode
switch(mode)
{
case DocSync:
+ case DocAsync:
case DocAsyncBegin:
case DocDispatch:
needArgs = !local || !inParams.empty();
@@ -2827,10 +2710,6 @@ Slice::Python::CodeVisitor::writeDocstring(const OperationPtr& op, DocstringMode
if(needArgs)
{
_out << nl << "Arguments:";
- if(mode == DocAsyncDispatch)
- {
- _out << nl << "_cb -- The asynchronous callback object.";
- }
for(vector<string>::iterator q = inParams.begin(); q != inParams.end(); ++q)
{
string fixed = fixIdent(*q);
@@ -2851,13 +2730,15 @@ Slice::Python::CodeVisitor::writeDocstring(const OperationPtr& op, DocstringMode
<< nl << "_ex -- The asynchronous exception callback."
<< nl << "_sent -- The asynchronous sent callback.";
}
- if(!local && (mode == DocSync || mode == DocAsyncBegin))
+ if(!local && (mode == DocSync || mode == DocAsync || mode == DocAsyncBegin))
{
- _out << nl << "_ctx -- The request context for the invocation.";
+ const string contextParamName = getEscapedParamName(op, "context");
+ _out << nl << contextParamName << " -- The request context for the invocation.";
}
if(!local && (mode == DocDispatch || mode == DocAsyncDispatch))
{
- _out << nl << "current -- The Current object for the invocation.";
+ const string currentParamName = getEscapedParamName(op, "current");
+ _out << nl << currentParamName << " -- The Current object for the invocation.";
}
}
else if(mode == DocAsyncEnd)
@@ -2869,6 +2750,10 @@ Slice::Python::CodeVisitor::writeDocstring(const OperationPtr& op, DocstringMode
//
// Emit return value(s).
//
+ if(mode == DocAsync || mode == DocAsyncDispatch)
+ {
+ _out << nl << "Returns: A future object for the invocation.";
+ }
if(mode == DocAsyncBegin)
{
_out << nl << "Returns: An asynchronous result object for the invocation.";
@@ -2936,7 +2821,8 @@ Slice::Python::CodeVisitor::writeDocstring(const OperationPtr& op, DocstringMode
}
void
-Slice::Python::generate(const UnitPtr& un, bool all, bool checksum, const vector<string>& includePaths, Output& out)
+Slice::Python::generate(const UnitPtr& un, bool all, bool checksum, const vector<string>& includePaths,
+ Output& out)
{
Slice::Python::MetaDataVisitor visitor;
un->visit(&visitor, false);
@@ -3064,14 +2950,7 @@ Slice::Python::getAbsolute(const ContainedPtr& cont, const string& suffix, const
}
}
- if(suffix.empty())
- {
- return scope + fixIdent(cont->name() + nameSuffix);
- }
- else
- {
- return scope + suffix + fixIdent(cont->name() + nameSuffix);
- }
+ return scope + suffix + fixIdent(cont->name() + nameSuffix);
}
void
@@ -3103,30 +2982,28 @@ Slice::Python::MetaDataVisitor::visitUnitStart(const UnitPtr& p)
// Validate global metadata in the top-level file and all included files.
//
StringList files = p->allFiles();
-
for(StringList::iterator q = files.begin(); q != files.end(); ++q)
{
string file = *q;
DefinitionContextPtr dc = p->findDefinitionContext(file);
assert(dc);
StringList globalMetaData = dc->getMetaData();
- for(StringList::const_iterator r = globalMetaData.begin(); r != globalMetaData.end(); ++r)
+ for(StringList::const_iterator r = globalMetaData.begin(); r != globalMetaData.end();)
{
- string s = *r;
- if(_history.count(s) == 0)
+ string s = *r++;
+ if(s.find(prefix) == 0)
{
- _history.insert(s);
- if(s.find(prefix) == 0)
+ static const string packagePrefix = "python:package:";
+ if(s.find(packagePrefix) == 0 && s.size() > packagePrefix.size())
{
- static const string packagePrefix = "python:package:";
- if(s.find(packagePrefix) == 0 && s.size() > packagePrefix.size())
- {
- continue;
- }
- emitWarning(file, "", "ignoring invalid global metadata `" + s + "'");
+ continue;
}
+
+ dc->warning(InvalidMetaData, file, "", "ignoring invalid global metadata `" + s + "'");
+ globalMetaData.remove(s);
}
}
+ dc->setMetaData(globalMetaData);
}
return true;
}
@@ -3194,6 +3071,11 @@ Slice::Python::MetaDataVisitor::visitSequence(const SequencePtr& p)
StringList metaData = p->getMetaData();
const string file = p->file();
const string line = p->line();
+ StringList protobufMetaData;
+ const UnitPtr unit = p->unit();
+ const DefinitionContextPtr dc = unit->findDefinitionContext(file);
+ assert(dc);
+
for(StringList::const_iterator q = metaData.begin(); q != metaData.end(); )
{
string s = *q++;
@@ -3203,17 +3085,22 @@ Slice::Python::MetaDataVisitor::visitSequence(const SequencePtr& p)
// Remove from list so validateSequence does not try to handle as well.
//
metaData.remove(s);
-
BuiltinPtr builtin = BuiltinPtr::dynamicCast(p->type());
if(!builtin || builtin->kind() != Builtin::KindByte)
{
- emitWarning(file, line, "ignoring invalid metadata `" + s + ": " +
+ dc->warning(InvalidMetaData, file, line, "ignoring invalid metadata `" + s + ": " +
"`protobuf' encoding must be a byte sequence");
}
+ else
+ {
+ protobufMetaData.push_back(s);
+ }
}
}
- validateSequence(file, line, p, metaData);
+ metaData = validateSequence(file, line, p, metaData);
+ metaData.insert(metaData.end(), protobufMetaData.begin(), protobufMetaData.end());
+ p->setMetaData(metaData);
}
void
@@ -3234,15 +3121,19 @@ Slice::Python::MetaDataVisitor::visitConst(const ConstPtr& p)
reject(p);
}
-void
+StringList
Slice::Python::MetaDataVisitor::validateSequence(const string& file, const string& line,
- const TypePtr& type, const StringList& meta)
+ const TypePtr& type, const StringList& metaData)
{
- static const string prefix = "python:";
+ const UnitPtr unit = type->unit();
+ const DefinitionContextPtr dc = unit->findDefinitionContext(file);
+ assert(dc);
- for(StringList::const_iterator p = meta.begin(); p != meta.end(); ++p)
+ static const string prefix = "python:";
+ StringList newMetaData = metaData;
+ for(StringList::const_iterator p = newMetaData.begin(); p != newMetaData.end();)
{
- string s = *p;
+ string s = *p++;
if(s.find(prefix) == 0)
{
string::size_type pos = s.find(':', prefix.size());
@@ -3258,9 +3149,11 @@ Slice::Python::MetaDataVisitor::validateSequence(const string& file, const strin
}
}
}
- emitWarning(file, line, "ignoring invalid metadata `" + s + "'");
+ dc->warning(InvalidMetaData, file, line, "ignoring invalid metadata `" + s + "'");
+ newMetaData.remove(s);
}
}
+ return newMetaData;
}
void
@@ -3268,11 +3161,19 @@ Slice::Python::MetaDataVisitor::reject(const ContainedPtr& cont)
{
StringList localMetaData = cont->getMetaData();
static const string prefix = "python:";
- for(StringList::const_iterator p = localMetaData.begin(); p != localMetaData.end(); ++p)
+
+ const UnitPtr unit = cont->unit();
+ const DefinitionContextPtr dc = unit->findDefinitionContext(cont->file());
+ assert(dc);
+
+ for(StringList::const_iterator p = localMetaData.begin(); p != localMetaData.end();)
{
- if(p->find(prefix) == 0)
+ string s = *p++;
+ if(s.find(prefix) == 0)
{
- emitWarning(cont->file(), cont->line(), "ignoring invalid metadata `" + *p + "'");
+ dc->warning(InvalidMetaData, cont->file(), cont->line(), "ignoring invalid metadata `" + s + "'");
+ localMetaData.remove(s);
}
}
+ cont->setMetaData(localMetaData);
}