diff --git a/cpp/src/ice2slice/Gen.cpp b/cpp/src/ice2slice/Gen.cpp index 699ed7e1f55..3df2889c690 100644 --- a/cpp/src/ice2slice/Gen.cpp +++ b/cpp/src/ice2slice/Gen.cpp @@ -5,7 +5,6 @@ #include "Gen.h" #include "../Slice/Util.h" -#include #include using namespace std; @@ -345,61 +344,61 @@ Gen::Gen(const std::string& fileBase) : _fileBase(fileBase) {} void Gen::generate(const UnitPtr& p) { - OutputVisitor outputVisitor; - p->visit(&outputVisitor); + OutputModulesVisitor outputModulesVisitor; + p->visit(&outputModulesVisitor); - TypesVisitor typesVisitor(_fileBase, outputVisitor.modules()); + TypesVisitor typesVisitor(_fileBase, outputModulesVisitor.modules()); p->visit(&typesVisitor); } bool -Gen::OutputVisitor::visitClassDefStart(const ClassDefPtr& p) +Gen::OutputModulesVisitor::visitClassDefStart(const ClassDefPtr& p) { _modules.insert(p->scope()); return false; } bool -Gen::OutputVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p) +Gen::OutputModulesVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p) { _modules.insert(p->scope()); return false; } bool -Gen::OutputVisitor::visitExceptionStart(const ExceptionPtr& p) +Gen::OutputModulesVisitor::visitExceptionStart(const ExceptionPtr& p) { _modules.insert(p->scope()); return false; } bool -Gen::OutputVisitor::visitStructStart(const StructPtr& p) +Gen::OutputModulesVisitor::visitStructStart(const StructPtr& p) { _modules.insert(p->scope()); return false; } void -Gen::OutputVisitor::visitSequence(const SequencePtr& p) +Gen::OutputModulesVisitor::visitSequence(const SequencePtr& p) { _modules.insert(p->scope()); } void -Gen::OutputVisitor::visitDictionary(const DictionaryPtr& p) +Gen::OutputModulesVisitor::visitDictionary(const DictionaryPtr& p) { _modules.insert(p->scope()); } void -Gen::OutputVisitor::visitEnum(const EnumPtr& p) +Gen::OutputModulesVisitor::visitEnum(const EnumPtr& p) { _modules.insert(p->scope()); } set -Gen::OutputVisitor::modules() const +Gen::OutputModulesVisitor::modules() const { return _modules; } @@ -410,6 +409,16 @@ Gen::TypesVisitor::TypesVisitor(const std::string& fileBase, const std::setscope(); Output& out = getOutput(p); + out << sp; writeComment(p, out); out << nl << "class " << p->name(); @@ -431,7 +441,6 @@ Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p) out.dec(); out << nl << "}"; - out << nl; return false; } @@ -442,6 +451,7 @@ Gen::TypesVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p) const string scope = p->scope(); Output& out = getOutput(p); + out << sp; writeComment(p, out); out << nl << "interface " << p->name(); if (bases.size() > 0) @@ -518,11 +528,10 @@ Gen::TypesVisitor::visitInterfaceDefStart(const InterfaceDefPtr& p) } out.dec(); out << nl << "}"; - out << sp; + out << sp; out << nl << "[cs::type(\"" << typeToCsString(p->declaration(), false) << "\")]"; out << nl << "custom " << p->name() << "Proxy"; - out << nl; return false; } @@ -531,6 +540,8 @@ Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) { const string scope = p->scope(); Output& out = getOutput(p); + + out << sp; writeComment(p, out); out << nl << "exception " << p->name(); if (ExceptionPtr base = p->base()) @@ -544,7 +555,6 @@ Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p) out.dec(); out << nl << "}"; - out << nl; return false; } @@ -553,6 +563,8 @@ Gen::TypesVisitor::visitStructStart(const StructPtr& p) { const string scope = p->scope(); Output& out = getOutput(p); + + out << sp; writeComment(p, out); out << nl << "compact struct " << p->name() << " {"; out.inc(); @@ -561,7 +573,6 @@ Gen::TypesVisitor::visitStructStart(const StructPtr& p) out.dec(); out << nl << "}"; - out << nl; return false; } @@ -571,6 +582,7 @@ Gen::TypesVisitor::visitSequence(const SequencePtr& p) const string scope = p->scope(); Output& out = getOutput(p); + out << sp; writeComment(p, out); out << nl << "typealias " << p->name() << " = "; @@ -601,7 +613,6 @@ Gen::TypesVisitor::visitSequence(const SequencePtr& p) } } out << " Sequence<" << typeToString(p->type(), p->scope(), false) << ">"; - out << nl; } void @@ -610,6 +621,7 @@ Gen::TypesVisitor::visitDictionary(const DictionaryPtr& p) const string scope = p->scope(); Output& out = getOutput(p); + out << sp; writeComment(p, out); out << nl << "typealias " << p->name() << " = "; @@ -626,7 +638,6 @@ Gen::TypesVisitor::visitDictionary(const DictionaryPtr& p) } out << " Dictionary<" << typeToString(p->keyType(), p->scope(), false) << ", " << typeToString(p->valueType(), p->scope(), false) << ">"; - out << nl; } void @@ -635,6 +646,7 @@ Gen::TypesVisitor::visitEnum(const EnumPtr& p) const string scope = p->scope(); Output& out = getOutput(p); + out << sp; writeComment(p, out); out << nl << "enum " << p->name() << " {"; out.inc(); @@ -649,7 +661,18 @@ Gen::TypesVisitor::visitEnum(const EnumPtr& p) } out.dec(); out << nl << "}"; - out << nl; +} + +void +Slice::Gen::TypesVisitor::visitConst(const ConstPtr& p) +{ + Output& out = getOutput(p); + out << sp; + out << nl << "// ice2slice could not convert:"; + out << nl << "// const " << p->type()->typeId() << " " << p->name() << " = " << p->value(); + + p->unit() + ->warning(p->file(), p->line(), WarningCategory::All, "ice2slice could not convert constant: " + p->name()); } // Get the output stream where to write the mapped Slice construct, creating a new output stream if necessary. The @@ -687,7 +710,6 @@ Gen::TypesVisitor::getOutput(const ContainedPtr& contained) string moduleName = scope.substr(2).substr(0, scope.size() - 4); *out << nl << "module " << moduleName; - *out << nl; auto inserted = _outputs.emplace(scope, std::move(out)); return *(inserted.first->second); } diff --git a/cpp/src/ice2slice/Gen.h b/cpp/src/ice2slice/Gen.h index da601db8088..b100fc84a17 100644 --- a/cpp/src/ice2slice/Gen.h +++ b/cpp/src/ice2slice/Gen.h @@ -22,35 +22,52 @@ namespace Slice private: std::string _fileBase; - class OutputVisitor : public ParserVisitor + /// The OutputModulesVisitor class gathers a list of modules requiring the generation of output `.slice` files. + /// Each `.ice` file may correspond to multiple `.slice` files, with one for each module that contains Slice + /// definitions. + class OutputModulesVisitor final : public ParserVisitor { public: - virtual bool visitClassDefStart(const ClassDefPtr&); - virtual bool visitInterfaceDefStart(const InterfaceDefPtr&); - virtual bool visitExceptionStart(const ExceptionPtr&); - virtual bool visitStructStart(const StructPtr&); - virtual void visitSequence(const SequencePtr&); - virtual void visitDictionary(const DictionaryPtr&); - virtual void visitEnum(const EnumPtr&); + bool visitClassDefStart(const ClassDefPtr&) final; + bool visitInterfaceDefStart(const InterfaceDefPtr&) final; + bool visitExceptionStart(const ExceptionPtr&) final; + bool visitStructStart(const StructPtr&) final; + void visitSequence(const SequencePtr&) final; + void visitDictionary(const DictionaryPtr&) final; + void visitEnum(const EnumPtr&) final; + /// After visiting all definitions, return the list of scopes corresponding to modules for which we need + /// to generate an output `.slice`. + /// @return The list of modules for which we need to generate an output `.slice`. std::set modules() const; private: std::set _modules; }; - class TypesVisitor : public ParserVisitor + /// The TypesVisitor class converts Slice definitions in `.ice` files to corresponding Slice definitions in + /// `.slice` files. + /// + /// If the `.ice` file contains a single module, the output is a single `.slice` file with the same base name, + /// replacing the `.ice` extension with `.slice`. + /// + /// If the `.ice` file contains multiple modules, it generates a `.slice` file for each module. Each file uses + /// the base name of the `.ice` file, appending the module scope with "::" replaced by "_" and the `.slice` + /// extension. + class TypesVisitor final : public ParserVisitor { public: - TypesVisitor(const std::string&, const std::set&); + TypesVisitor(const std::string& fileBase, const std::set& modules); - virtual bool visitClassDefStart(const ClassDefPtr&); - virtual bool visitInterfaceDefStart(const InterfaceDefPtr&); - virtual bool visitExceptionStart(const ExceptionPtr&); - virtual bool visitStructStart(const StructPtr&); - virtual void visitSequence(const SequencePtr&); - virtual void visitDictionary(const DictionaryPtr&); - virtual void visitEnum(const EnumPtr&); + void visitUnitEnd(const UnitPtr&) final; + bool visitClassDefStart(const ClassDefPtr&) final; + bool visitInterfaceDefStart(const InterfaceDefPtr&) final; + bool visitExceptionStart(const ExceptionPtr&) final; + bool visitStructStart(const StructPtr&) final; + void visitSequence(const SequencePtr&) final; + void visitDictionary(const DictionaryPtr&) final; + void visitEnum(const EnumPtr&) final; + void visitConst(const ConstPtr&) final; private: IceInternal::Output& getOutput(const ContainedPtr&);