diff options
author | Benoit Foucher <benoit@zeroc.com> | 2009-03-24 11:45:18 +0100 |
---|---|---|
committer | Benoit Foucher <benoit@zeroc.com> | 2009-03-24 11:45:18 +0100 |
commit | 06a08ecf28e205277336a97a6173db7ccbed1adc (patch) | |
tree | a369a5044a63f8cdba9e7c0a461e24ae344486b4 /cpp/src/Slice/PythonUtil.cpp | |
parent | Merge branch 'R3_3_branch' (diff) | |
parent | Bug 3924: slice2py missing from VC60 installer (diff) | |
download | ice-06a08ecf28e205277336a97a6173db7ccbed1adc.tar.bz2 ice-06a08ecf28e205277336a97a6173db7ccbed1adc.tar.xz ice-06a08ecf28e205277336a97a6173db7ccbed1adc.zip |
Merge commit 'origin/R3_3_branch'
Conflicts:
CHANGES
cpp/demo/Freeze/backup/.depend
cpp/demo/Freeze/bench/.depend
cpp/demo/Freeze/casino/.depend
cpp/demo/Freeze/customEvictor/.depend
cpp/demo/Freeze/library/.depend
cpp/demo/Freeze/phonebook/.depend
cpp/demo/Freeze/transform/.depend
cpp/demo/Glacier2/callback/.depend
cpp/demo/Glacier2/chat/.depend
cpp/demo/Ice/async/.depend
cpp/demo/Ice/bidir/.depend
cpp/demo/Ice/callback/.depend
cpp/demo/Ice/converter/.depend
cpp/demo/Ice/hello/.depend
cpp/demo/Ice/invoke/.depend
cpp/demo/Ice/latency/.depend
cpp/demo/Ice/minimal/.depend
cpp/demo/Ice/multicast/.depend
cpp/demo/Ice/nested/.depend
cpp/demo/Ice/nrvo/.depend
cpp/demo/Ice/session/.depend
cpp/demo/Ice/throughput/.depend
cpp/demo/Ice/value/.depend
cpp/demo/IceBox/hello/.depend
cpp/demo/IceGrid/allocate/.depend
cpp/demo/IceGrid/icebox/.depend
cpp/demo/IceGrid/replication/.depend
cpp/demo/IceGrid/sessionActivation/.depend
cpp/demo/IceGrid/simple/.depend
cpp/demo/IceStorm/clock/.depend
cpp/demo/IceStorm/counter/.depend
cpp/demo/IceStorm/replicated/.depend
cpp/demo/IceStorm/replicated2/.depend
cpp/demo/book/freeze_filesystem/.depend
cpp/demo/book/lifecycle/.depend
cpp/demo/book/printer/.depend
cpp/demo/book/simple_filesystem/.depend
cpp/src/Freeze/.depend
cpp/src/FreezeScript/.depend
cpp/src/Ice/.depend
cpp/src/Ice/UdpTransceiver.cpp
cpp/src/Ice/UdpTransceiver.h
cpp/src/IceBox/.depend
cpp/src/IceGrid/.depend
cpp/src/IceGridLib/.depend
cpp/src/IcePatch2/.depend
cpp/src/IceStorm/.depend
cpp/src/slice2freeze/.depend
cpp/test/Freeze/complex/.depend
cpp/test/Freeze/dbmap/.depend
cpp/test/Freeze/evictor/.depend
cpp/test/Freeze/oldevictor/.depend
cpp/test/FreezeScript/dbmap/.depend
cpp/test/FreezeScript/evictor/.depend
cpp/test/Glacier2/attack/.depend
cpp/test/Glacier2/dynamicFiltering/.depend
cpp/test/Glacier2/router/.depend
cpp/test/Glacier2/sessionControl/.depend
cpp/test/Glacier2/ssl/.depend
cpp/test/Glacier2/staticFiltering/.depend
cpp/test/Ice/adapterDeactivation/.depend
cpp/test/Ice/background/.depend
cpp/test/Ice/binding/.depend
cpp/test/Ice/checksum/.depend
cpp/test/Ice/checksum/server/.depend
cpp/test/Ice/custom/.depend
cpp/test/Ice/exceptions/.depend
cpp/test/Ice/facets/.depend
cpp/test/Ice/faultTolerance/.depend
cpp/test/Ice/gc/.depend
cpp/test/Ice/hold/.depend
cpp/test/Ice/inheritance/.depend
cpp/test/Ice/interceptor/.depend
cpp/test/Ice/location/.depend
cpp/test/Ice/objects/.depend
cpp/test/Ice/operations/.depend
cpp/test/Ice/proxy/.depend
cpp/test/Ice/retry/.depend
cpp/test/Ice/servantLocator/.depend
cpp/test/Ice/slicing/exceptions/.depend
cpp/test/Ice/slicing/objects/.depend
cpp/test/Ice/stream/.depend
cpp/test/Ice/stringConverter/.depend
cpp/test/Ice/timeout/.depend
cpp/test/Ice/udp/.depend
cpp/test/IceBox/configuration/.depend
cpp/test/IceGrid/activation/.depend
cpp/test/IceGrid/allocation/.depend
cpp/test/IceGrid/deployer/.depend
cpp/test/IceGrid/distribution/.depend
cpp/test/IceGrid/replicaGroup/.depend
cpp/test/IceGrid/replication/.depend
cpp/test/IceGrid/session/.depend
cpp/test/IceGrid/simple/.depend
cpp/test/IceGrid/update/.depend
cpp/test/IceSSL/configuration/.depend
cpp/test/IceStorm/federation/.depend
cpp/test/IceStorm/federation2/.depend
cpp/test/IceStorm/rep1/.depend
cpp/test/IceStorm/repgrid/.depend
cpp/test/IceStorm/repstress/.depend
cpp/test/IceStorm/single/.depend
cpp/test/IceStorm/stress/.depend
cpp/test/Slice/keyword/.depend
cs/src/Ice/Instance.cs
cs/src/IceSSL/ConnectorI.cs
java/demo/book/simple_filesystem/Filesystem/DirectoryI.java
java/demo/book/simple_filesystem/Filesystem/FileI.java
java/src/IceInternal/TcpConnector.java
java/src/IceSSL/ConnectorI.java
py/modules/IcePy/.depend
rb/src/IceRuby/.depend
Diffstat (limited to 'cpp/src/Slice/PythonUtil.cpp')
-rw-r--r-- | cpp/src/Slice/PythonUtil.cpp | 229 |
1 files changed, 160 insertions, 69 deletions
diff --git a/cpp/src/Slice/PythonUtil.cpp b/cpp/src/Slice/PythonUtil.cpp index cb9e024717a..34fb3bd9654 100644 --- a/cpp/src/Slice/PythonUtil.cpp +++ b/cpp/src/Slice/PythonUtil.cpp @@ -32,6 +32,7 @@ class MetaDataVisitor : public ParserVisitor { public: + virtual bool visitUnitStart(const UnitPtr&); virtual bool visitModuleStart(const ModulePtr&); virtual void visitClassDecl(const ClassDeclPtr&); virtual bool visitClassDefStart(const ClassDefPtr&); @@ -47,14 +48,9 @@ public: private: // - // Validates global metadata. - // - void validateGlobal(const DefinitionContextPtr&); - - // // Validates sequence metadata. // - void validateSequence(const DefinitionContextPtr&, const string&, const TypePtr&, const StringList&); + void validateSequence(const string&, const string&, const TypePtr&, const StringList&); // // Checks a definition that doesn't currently support Python metadata. @@ -153,6 +149,11 @@ private: }; typedef list<MemberInfo> MemberInfoList; + // + // Write a member assignment statement for a constructor. + // + void writeAssign(const MemberInfo&); + void collectClassMembers(const ClassDefPtr&, MemberInfoList&, bool); void collectExceptionMembers(const ExceptionPtr&, MemberInfoList&, bool); @@ -476,7 +477,7 @@ Slice::Python::CodeVisitor::visitClassDefStart(const ClassDefPtr& p) { if(!q->inherited) { - _out << nl << "self." << q->fixedName << " = " << q->fixedName;; + writeAssign(*q); } } } @@ -982,7 +983,7 @@ Slice::Python::CodeVisitor::visitExceptionStart(const ExceptionPtr& p) { if(!q->inherited) { - _out << nl << "self." << q->fixedName << " = " << q->fixedName;; + writeAssign(*q); } } } @@ -1101,7 +1102,7 @@ Slice::Python::CodeVisitor::visitStructStart(const StructPtr& p) _out.inc(); for(r = memberList.begin(); r != memberList.end(); ++r) { - _out << nl << "self." << r->fixedName << " = " << r->fixedName; + writeAssign(*r); } _out.dec(); @@ -1199,17 +1200,46 @@ Slice::Python::CodeVisitor::visitStructStart(const StructPtr& p) void Slice::Python::CodeVisitor::visitSequence(const SequencePtr& p) { + static const string protobuf = "python:protobuf:"; + StringList metaData = p->getMetaData(); + bool isCustom = false; + string customType; + for(StringList::const_iterator q = metaData.begin(); q != metaData.end(); ++q) + { + if(q->find(protobuf) == 0) + { + BuiltinPtr builtin = BuiltinPtr::dynamicCast(p->type()); + if(!builtin || builtin->kind() != Builtin::KindByte) + { + continue; + } + isCustom = true; + customType = q->substr(protobuf.size()); + break; + } + } + // // Emit the type information. // string scoped = p->scoped(); _out << sp << nl << "if not " << getDictLookup(p, "_t_") << ':'; _out.inc(); - _out << nl << "_M_" << getAbsolute(p, "_t_") << " = IcePy.defineSequence('" << scoped << "', "; - writeMetaData(p->getMetaData()); - _out << ", "; - writeType(p->type()); - _out << ")"; + if(isCustom) + { + string package = customType.substr(0, customType.find('.')); + _out << nl << "import " << package; + _out << nl << "_M_" << getAbsolute(p, "_t_") + << " = IcePy.defineCustom('" << scoped << "', " << customType << ")"; + } + else + { + _out << nl << "_M_" << getAbsolute(p, "_t_") << " = IcePy.defineSequence('" << scoped << "', "; + writeMetaData(metaData); + _out << ", "; + writeType(p->type()); + _out << ")"; + } _out.dec(); } @@ -1629,7 +1659,13 @@ Slice::Python::CodeVisitor::writeDefaultValue(const TypePtr& p) StructPtr st = StructPtr::dynamicCast(p); if(st) { - _out << getSymbol(st) << "()"; + // + // We cannot emit a call to the struct's constructor here because Python + // only evaluates this expression once (see bug 3676). Instead, we emit + // a marker that allows us to determine whether the application has + // supplied a value. + // + _out << "Ice._struct_marker"; return; } @@ -1701,6 +1737,30 @@ Slice::Python::CodeVisitor::writeMetaData(const StringList& meta) _out << ')'; } +void +Slice::Python::CodeVisitor::writeAssign(const MemberInfo& info) +{ + // + // Structures are treated differently (see bug 3676). + // + StructPtr st = StructPtr::dynamicCast(info.type); + if(st) + { + _out << nl << "if " << info.fixedName << " is Ice._struct_marker:"; + _out.inc(); + _out << nl << "self." << info.fixedName << " = " << getSymbol(st) << "()"; + _out.dec(); + _out << nl << "else:"; + _out.inc(); + _out << nl << "self." << info.fixedName << " = " << info.fixedName; + _out.dec(); + } + else + { + _out << nl << "self." << info.fixedName << " = " << info.fixedName; + } +} + string Slice::Python::CodeVisitor::getOperationMode(Slice::Operation::Mode mode) { @@ -1779,6 +1839,16 @@ Slice::Python::generate(const UnitPtr& un, bool all, bool checksum, const vector out << nl << "import Ice, IcePy, __builtin__"; + // + // For backward-compatibility with generated code from Ice 3.3.0, we add a definition + // of _struct_marker to the Ice module if necessary. + // + out << nl; + out << nl << "if not Ice.__dict__.has_key(\"_struct_marker\"):"; + out.inc(); + out << nl << "Ice._struct_marker = object()"; + out.dec(); + if(!all) { vector<string> paths = includePaths; @@ -1866,20 +1936,19 @@ Slice::Python::fixIdent(const string& ident) string Slice::Python::getPackageMetadata(const ContainedPtr& cont) { - string package; + UnitPtr unit = cont->container()->unit(); + string file = cont->file(); + assert(!file.empty()); - DefinitionContextPtr dc = cont->definitionContext(); - if(dc) + static const string prefix = "python:package:"; + DefinitionContextPtr dc = unit->findDefinitionContext(file); + assert(dc); + string q = dc->findMetaData(prefix); + if(!q.empty()) { - static const string prefix = "python:package:"; - string metadata = dc->findMetaData(prefix); - if(!metadata.empty()) - { - package = metadata.substr(prefix.size()); - } + q = q.substr(prefix.size()); } - - return package; + return q; } string @@ -1929,15 +1998,44 @@ Slice::Python::printHeader(IceUtilInternal::Output& out) } bool -Slice::Python::MetaDataVisitor::visitModuleStart(const ModulePtr& p) +Slice::Python::MetaDataVisitor::visitUnitStart(const UnitPtr& p) { - if(!ModulePtr::dynamicCast(p->container())) + static const string prefix = "python:"; + + // + // 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) { - // - // We only need to validate global metadata for top-level modules. - // - validateGlobal(p->definitionContext()); + 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) + { + string s = *r; + if(_history.count(s) == 0) + { + if(s.find(prefix) == 0) + { + static const string packagePrefix = "python:package:"; + if(s.find(packagePrefix) != 0 || s.size() == packagePrefix.size()) + { + emitWarning(file, "", "ignoring invalid global metadata `" + s + "'"); + } + } + _history.insert(s); + } + } } + return true; +} + +bool +Slice::Python::MetaDataVisitor::visitModuleStart(const ModulePtr& p) +{ reject(p); return true; } @@ -1972,32 +2070,52 @@ Slice::Python::MetaDataVisitor::visitStructStart(const StructPtr& p) void Slice::Python::MetaDataVisitor::visitOperation(const OperationPtr& p) { - DefinitionContextPtr dc = p->definitionContext(); - assert(dc); - TypePtr ret = p->returnType(); if(ret) { - validateSequence(dc, p->line(), ret, p->getMetaData()); + validateSequence(p->file(), p->line(), ret, p->getMetaData()); } ParamDeclList params = p->parameters(); for(ParamDeclList::iterator q = params.begin(); q != params.end(); ++q) { - validateSequence(dc, (*q)->line(), (*q)->type(), (*q)->getMetaData()); + validateSequence(p->file(), (*q)->line(), (*q)->type(), (*q)->getMetaData()); } } void Slice::Python::MetaDataVisitor::visitDataMember(const DataMemberPtr& p) { - validateSequence(p->definitionContext(), p->line(), p->type(), p->getMetaData()); + validateSequence(p->file(), p->line(), p->type(), p->getMetaData()); } void Slice::Python::MetaDataVisitor::visitSequence(const SequencePtr& p) { - validateSequence(p->definitionContext(), p->line(), p, p->getMetaData()); + static const string protobuf = "python:protobuf:"; + StringList metaData = p->getMetaData(); + const string file = p->file(); + const string line = p->line(); + for(StringList::const_iterator q = metaData.begin(); q != metaData.end(); ) + { + string s = *q++; + if(s.find(protobuf) == 0) + { + // + // 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 + ": " + + "`protobuf' encoding must be a byte sequence"); + } + } + } + + validateSequence(file, line, p, metaData); } void @@ -2019,32 +2137,7 @@ Slice::Python::MetaDataVisitor::visitConst(const ConstPtr& p) } void -Slice::Python::MetaDataVisitor::validateGlobal(const DefinitionContextPtr& dc) -{ - StringList globalMetaData = dc->getMetaData(); - - static const string prefix = "python:"; - - for(StringList::const_iterator p = globalMetaData.begin(); p != globalMetaData.end(); ++p) - { - string s = *p; - if(_history.count(s) == 0) - { - if(s.find(prefix) == 0) - { - static const string packagePrefix = "python:package:"; - if(s.find(packagePrefix) != 0 || s.size() == packagePrefix.size()) - { - cerr << dc->filename() << ": warning: ignoring invalid global metadata `" << s << "'" << endl; - } - } - _history.insert(s); - } - } -} - -void -Slice::Python::MetaDataVisitor::validateSequence(const DefinitionContextPtr& dc, const string& line, +Slice::Python::MetaDataVisitor::validateSequence(const string& file, const string& line, const TypePtr& type, const StringList& meta) { static const string prefix = "python:"; @@ -2067,7 +2160,7 @@ Slice::Python::MetaDataVisitor::validateSequence(const DefinitionContextPtr& dc, } } } - cerr << dc->filename() << ":" << line << ": warning: ignoring metadata `" << s << "'" << endl; + emitWarning(file, line, "ignoring invalid metadata `" + s + "'"); } } } @@ -2083,9 +2176,7 @@ Slice::Python::MetaDataVisitor::reject(const ContainedPtr& cont) { if(p->find(prefix) == 0) { - DefinitionContextPtr dc = cont->definitionContext(); - assert(dc); - cerr << dc->filename() << ":" << cont->line() << ": warning: ignoring metadata `" << *p << "'" << endl; + emitWarning(cont->file(), cont->line(), "ignoring invalid metadata `" + *p + "'"); } } } |