summaryrefslogtreecommitdiff
path: root/cpp/src
diff options
context:
space:
mode:
authorMichi Henning <michi@zeroc.com>2005-09-14 05:53:59 +0000
committerMichi Henning <michi@zeroc.com>2005-09-14 05:53:59 +0000
commitdc121bb2cb79a3c72f51d8ac965a9a789e4f6f06 (patch)
tree94b8b02cea437b976d9bd242408d35b561319015 /cpp/src
parenthttp://bugzilla.zeroc.com/bugzilla/show_bug.cgi?id=459 (diff)
downloadice-dc121bb2cb79a3c72f51d8ac965a9a789e4f6f06.tar.bz2
ice-dc121bb2cb79a3c72f51d8ac965a9a789e4f6f06.tar.xz
ice-dc121bb2cb79a3c72f51d8ac965a9a789e4f6f06.zip
Bug 454.
Diffstat (limited to 'cpp/src')
-rwxr-xr-xcpp/src/Slice/CsUtil.cpp75
-rw-r--r--cpp/src/Slice/Grammar.y6
-rwxr-xr-xcpp/src/Slice/VbUtil.cpp73
-rwxr-xr-xcpp/src/slice2cs/Gen.cpp128
-rw-r--r--cpp/src/slice2cs/Gen.h18
-rwxr-xr-xcpp/src/slice2vb/Gen.cpp134
-rw-r--r--cpp/src/slice2vb/Gen.h17
7 files changed, 374 insertions, 77 deletions
diff --git a/cpp/src/Slice/CsUtil.cpp b/cpp/src/Slice/CsUtil.cpp
index 8edd505d628..2aa48cb64b9 100755
--- a/cpp/src/Slice/CsUtil.cpp
+++ b/cpp/src/Slice/CsUtil.cpp
@@ -963,13 +963,46 @@ void
Slice::CsGenerator::validateMetaData(const UnitPtr& unit)
{
MetaDataVisitor visitor;
- unit->visit(&visitor, false);
+ unit->visit(&visitor, true);
+}
+
+Slice::CsGenerator::MetaDataVisitor::MetaDataVisitor()
+ : _globalMetaDataDone(false)
+{
}
bool
Slice::CsGenerator::MetaDataVisitor::visitModuleStart(const ModulePtr& p)
{
- validate(p);
+ if(!_globalMetaDataDone)
+ {
+ //
+ // Validate global metadata.
+ //
+ DefinitionContextPtr dc = p->definitionContext();
+ assert(dc);
+ StringList globalMetaData = dc->getMetaData();
+ string file = dc->filename();
+ static const string prefix = "cs:";
+ for(StringList::const_iterator q = globalMetaData.begin(); q != globalMetaData.end(); ++q)
+ {
+ string s = *q;
+ if(_history.count(s) == 0)
+ {
+ if(s.find(prefix) == 0)
+ {
+ static const string attributePrefix = "cs:attribute:";
+ if(s.find(attributePrefix) != 0 || s.size() == attributePrefix.size())
+ {
+ cout << file << ": warning: ignoring invalid global metadata `" << s << "'" << endl;
+ }
+ }
+ _history.insert(s);
+ }
+ }
+ _globalMetaDataDone = true;
+ validate(p);
+ }
return true;
}
@@ -1067,30 +1100,16 @@ Slice::CsGenerator::MetaDataVisitor::validate(const ContainedPtr& cont)
{
DefinitionContextPtr dc = cont->definitionContext();
assert(dc);
- StringList globalMetaData = dc->getMetaData();
string file = dc->filename();
StringList localMetaData = cont->getMetaData();
StringList::const_iterator p;
- static const string prefix = "clr:";
-
- for(p = globalMetaData.begin(); p != globalMetaData.end(); ++p)
- {
- string s = *p;
- if(_history.count(s) == 0)
- {
- if(s.find(prefix) == 0)
- {
- cout << file << ": warning: ignoring invalid global metadata `" << s << "'" << endl;
- }
- _history.insert(s);
- }
- }
for(p = localMetaData.begin(); p != localMetaData.end(); ++p)
{
string s = *p;
+
if(s.find("cs:") == 0) // TODO: remove this statement once "cs:" is a hard error.
{
if(SequencePtr::dynamicCast(cont))
@@ -1108,14 +1127,20 @@ Slice::CsGenerator::MetaDataVisitor::validate(const ContainedPtr& cont)
{
cout << file << ":" << cont->line() << ": warning: `cs:' metadata prefix is deprecated; "
<< "use `clr:' instead" << endl;
+ cont->addMetaData("clr:class");
}
- cont->addMetaData("clr:class");
+ }
+ else if(s.find("cs:attribute:") == 0)
+ {
+ ; // Do nothing, "cs:attribute:" is OK
}
else
{
cout << file << ":" << cont->line() << ": warning: ignoring invalid metadata `" << s << "'" << endl;
}
} // End TODO
+
+ string prefix = "clr:";
if(_history.count(s) == 0)
{
if(s.find(prefix) == 0)
@@ -1138,5 +1163,19 @@ Slice::CsGenerator::MetaDataVisitor::validate(const ContainedPtr& cont)
}
_history.insert(s);
}
+
+ prefix = "cs:";
+ if(_history.count(s) == 0)
+ {
+ if(s.find(prefix) == 0)
+ {
+ if(s.substr(prefix.size()) == "attribute:")
+ {
+ continue;
+ }
+ cout << file << ":" << cont->line() << ": warning: ignoring invalid metadata `" << s << "'" << endl;
+ }
+ _history.insert(s);
+ }
}
}
diff --git a/cpp/src/Slice/Grammar.y b/cpp/src/Slice/Grammar.y
index b0340cd4aca..a10760ec2d9 100644
--- a/cpp/src/Slice/Grammar.y
+++ b/cpp/src/Slice/Grammar.y
@@ -1510,10 +1510,10 @@ string_literal
// ----------------------------------------------------------------------
string_list
// ----------------------------------------------------------------------
-: string_literal ',' string_list
+: string_list ',' string_literal
{
- StringTokPtr str = StringTokPtr::dynamicCast($1);
- StringListTokPtr stringList = StringListTokPtr::dynamicCast($3);
+ StringTokPtr str = StringTokPtr::dynamicCast($3);
+ StringListTokPtr stringList = StringListTokPtr::dynamicCast($1);
stringList->v.push_back(str->v);
$$ = stringList;
}
diff --git a/cpp/src/Slice/VbUtil.cpp b/cpp/src/Slice/VbUtil.cpp
index 30c5342eff0..528d393c7c9 100755
--- a/cpp/src/Slice/VbUtil.cpp
+++ b/cpp/src/Slice/VbUtil.cpp
@@ -1015,10 +1015,43 @@ Slice::VbGenerator::validateMetaData(const UnitPtr& unit)
unit->visit(&visitor, false);
}
+Slice::VbGenerator::MetaDataVisitor::MetaDataVisitor()
+ : _globalMetaDataDone(false)
+{
+}
+
bool
Slice::VbGenerator::MetaDataVisitor::visitModuleStart(const ModulePtr& p)
{
- validate(p);
+ if(!_globalMetaDataDone)
+ {
+ //
+ // Validate global metadata.
+ //
+ DefinitionContextPtr dc = p->definitionContext();
+ assert(dc);
+ StringList globalMetaData = dc->getMetaData();
+ string file = dc->filename();
+ static const string prefix = "vb:";
+ for(StringList::const_iterator q = globalMetaData.begin(); q != globalMetaData.end(); ++q)
+ {
+ string s = *q;
+ if(_history.count(s) == 0)
+ {
+ if(s.find(prefix) == 0)
+ {
+ static const string attributePrefix = "vb:attribute:";
+ if(s.find(attributePrefix) != 0 || s.size() == attributePrefix.size())
+ {
+ cout << file << ": warning: ignoring invalid global metadata `" << s << "'" << endl;
+ }
+ }
+ _history.insert(s);
+ }
+ }
+ _globalMetaDataDone = true;
+ validate(p);
+ }
return true;
}
@@ -1116,30 +1149,16 @@ Slice::VbGenerator::MetaDataVisitor::validate(const ContainedPtr& cont)
{
DefinitionContextPtr dc = cont->definitionContext();
assert(dc);
- StringList globalMetaData = dc->getMetaData();
string file = dc->filename();
StringList localMetaData = cont->getMetaData();
StringList::const_iterator p;
- static const string prefix = "clr:";
-
- for(p = globalMetaData.begin(); p != globalMetaData.end(); ++p)
- {
- string s = *p;
- if(_history.count(s) == 0)
- {
- if(s.find(prefix) == 0)
- {
- cout << file << ": warning: ignoring invalid global metadata `" << s << "'" << endl;
- }
- _history.insert(s);
- }
- }
for(p = localMetaData.begin(); p != localMetaData.end(); ++p)
{
string s = *p;
+
if(s.find("vb:") == 0) // TODO: remove this statement once "vb:" is a hard error.
{
if(SequencePtr::dynamicCast(cont))
@@ -1157,14 +1176,20 @@ Slice::VbGenerator::MetaDataVisitor::validate(const ContainedPtr& cont)
{
cout << file << ":" << cont->line() << ": warning: `vb:' metadata prefix is deprecated; "
<< "use `clr:' instead" << endl;
+ cont->addMetaData("clr:class");
}
- cont->addMetaData("clr:class");
+ }
+ else if(s.find("vb:attribute:") == 0)
+ {
+ ; // Do nothing, "vb:attribute:" is OK
}
else
{
cout << file << ":" << cont->line() << ": warning: ignoring invalid metadata `" << s << "'" << endl;
}
} // End TODO
+
+ string prefix = "clr";
if(_history.count(s) == 0)
{
if(s.find(prefix) == 0)
@@ -1187,5 +1212,19 @@ Slice::VbGenerator::MetaDataVisitor::validate(const ContainedPtr& cont)
}
_history.insert(s);
}
+
+ prefix = "vb:";
+ if(_history.count(s) == 0)
+ {
+ if(s.find(prefix) == 0)
+ {
+ if(s.substr(prefix.size()) == "attribute:")
+ {
+ continue;
+ }
+ cout << file << ":" << cont->line() << ": warning: ignoring invalid metadata `" << s << "'" << endl;
+ }
+ _history.insert(s);
+ }
}
}
diff --git a/cpp/src/slice2cs/Gen.cpp b/cpp/src/slice2cs/Gen.cpp
index fafd2010610..bd9132b0fe2 100755
--- a/cpp/src/slice2cs/Gen.cpp
+++ b/cpp/src/slice2cs/Gen.cpp
@@ -714,6 +714,22 @@ Slice::CsVisitor::writeDispatch(const ClassDefPtr& p)
}
}
+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)
{
@@ -721,11 +737,12 @@ Slice::CsVisitor::getParams(const OperationPtr& op)
ParamDeclList paramList = op->parameters();
for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
{
- string param = typeToString((*q)->type()) + " " + fixId((*q)->name());
+ string param = getParamAttributes(*q);
if((*q)->isOutParam())
{
- param = "out " + param;
+ param += "out ";
}
+ param += typeToString((*q)->type()) + " " + fixId((*q)->name());
params.push_back(param);
}
return params;
@@ -747,7 +764,7 @@ Slice::CsVisitor::getParamsAsync(const OperationPtr& op, bool amd)
{
if(!(*q)->isOutParam())
{
- params.push_back(typeToString((*q)->type()) + " " + fixId((*q)->name()));
+ params.push_back(getParamAttributes(*q) + typeToString((*q)->type()) + " " + fixId((*q)->name()));
}
}
return params;
@@ -769,7 +786,7 @@ Slice::CsVisitor::getParamsAsyncCB(const OperationPtr& op)
{
if((*q)->isOutParam())
{
- params.push_back(typeToString((*q)->type()) + ' ' + fixId((*q)->name()));
+ params.push_back(getParamAttributes(*q) + typeToString((*q)->type()) + ' ' + fixId((*q)->name()));
}
}
@@ -834,6 +851,20 @@ Slice::CsVisitor::getArgsAsyncCB(const OperationPtr& op)
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 << '[' << i->substr(prefix.size()) << ']' << nl;
+ }
+ }
+}
+
Slice::Gen::Gen(const string& name, const string& base, const vector<string>& includePaths, const string& dir,
bool impl, bool implTie, bool stream)
: _base(base),
@@ -937,6 +968,9 @@ Slice::Gen::generate(const UnitPtr& p)
CsGenerator::validateMetaData(p);
+ UnitVisitor unitVisitor(_out, _stream);
+ p->visit(&unitVisitor, false);
+
TypesVisitor typesVisitor(_out, _stream);
p->visit(&typesVisitor, false);
@@ -1047,9 +1081,37 @@ Slice::Gen::printHeader()
_out << "\n// Ice version " << ICE_STRING_VERSION;
}
-Slice::Gen::OpsVisitor::OpsVisitor(IceUtil::Output& out)
- : CsVisitor(out)
+Slice::Gen::UnitVisitor::UnitVisitor(IceUtil::Output& out, bool stream)
+ : CsVisitor(out), _stream(stream), _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, bool stream)
@@ -1060,8 +1122,11 @@ Slice::Gen::TypesVisitor::TypesVisitor(IceUtil::Output& out, bool stream)
bool
Slice::Gen::TypesVisitor::visitModuleStart(const ModulePtr& p)
{
+
string name = fixId(p->name());
- _out << sp << nl << "namespace " << name;
+ _out << sp << nl;
+ emitAttributes(p);
+ _out << "namespace " << name;
_out << sb;
@@ -1117,9 +1182,11 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p)
_out << eb;
}
+ _out << sp << nl;
+ emitAttributes(p);
if(p->isInterface())
{
- _out << sp << nl << "public interface " << fixId(name) << " : ";
+ _out << "public interface " << fixId(name) << " : ";
if(p->isLocal())
{
_out << "Ice.LocalObject";
@@ -1146,7 +1213,7 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p)
}
else
{
- _out << sp << nl << "public ";
+ _out << "public ";
if(p->isAbstract())
{
_out << "abstract ";
@@ -1508,7 +1575,9 @@ Slice::Gen::TypesVisitor::visitOperation(const OperationPtr& p)
name = name + "_async";
}
- _out << sp << nl << "public ";
+ _out << sp << nl;
+ emitAttributes(p);
+ _out << "public ";
if(isLocal)
{
_out << "abstract ";
@@ -1552,7 +1621,9 @@ Slice::Gen::TypesVisitor::visitSequence(const SequencePtr& p)
string s = typeToString(p->type());
bool isValue = isValueType(p->type());
- _out << sp << nl << "public class " << name
+ _out << sp << nl;
+ emitAttributes(p);
+ _out << "public class " << name
<< " : _System.Collections.CollectionBase, _System.ICloneable";
_out << sb;
@@ -1793,7 +1864,9 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
string name = fixId(p->name());
ExceptionPtr base = p->base();
- _out << sp << nl << "public class " << name << " : ";
+ _out << sp << nl;
+ emitAttributes(p);
+ _out << "public class " << name << " : ";
if(base)
{
_out << fixId(base->scoped());
@@ -2150,13 +2223,15 @@ Slice::Gen::TypesVisitor::visitStructStart(const StructPtr& p)
_out << eb;
}
+ _out << sp << nl;
+ emitAttributes(p);
if(p->hasMetaData("clr:class"))
{
- _out << sp << nl << "public class " << name << " : _System.ICloneable";
+ _out << "public class " << name << " : _System.ICloneable";
}
else
{
- _out << sp << nl << "public struct " << name;
+ _out << "public struct " << name;
}
_out << sb;
@@ -2501,7 +2576,9 @@ Slice::Gen::TypesVisitor::visitDictionary(const DictionaryPtr& p)
string vs = typeToString(p->valueType());
bool valueIsValue = isValueType(p->valueType());
- _out << sp << nl << "public class " << name
+ _out << sp << nl;
+ emitAttributes(p);
+ _out << "public class " << name
<< " : _System.Collections.DictionaryBase, _System.ICloneable";
_out << sb;
@@ -2742,7 +2819,9 @@ Slice::Gen::TypesVisitor::visitEnum(const EnumPtr& p)
string name = fixId(p->name());
string scoped = fixId(p->scoped());
EnumeratorList enumerators = p->getEnumerators();
- _out << sp << nl << "public enum " << name;
+ _out << sp << nl;
+ emitAttributes(p);
+ _out << "public enum " << name;
_out << sb;
EnumeratorList::const_iterator en = enumerators.begin();
while(en != enumerators.end())
@@ -2780,7 +2859,9 @@ void
Slice::Gen::TypesVisitor::visitConst(const ConstPtr& p)
{
string name = fixId(p->name());
- _out << sp << nl << "public abstract class " << name;
+ _out << sp << nl;
+ emitAttributes(p);
+ _out << "public abstract class " << name;
_out << sb;
_out << sp << nl << "public const " << typeToString(p->type()) << " value = ";
BuiltinPtr bp = BuiltinPtr::dynamicCast(p->type());
@@ -2864,7 +2945,9 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p)
baseTypes = DotNet::ICloneable;
isClass = true;
}
- _out << sp << nl << "public " << typeToString(p->type()) << " " << fixId(p->name(), baseTypes, isClass) << ";";
+ _out << sp << nl;
+ emitAttributes(p);
+ _out << "public " << typeToString(p->type()) << " " << fixId(p->name(), baseTypes, isClass) << ";";
}
Slice::Gen::ProxyVisitor::ProxyVisitor(IceUtil::Output& out)
@@ -2957,6 +3040,11 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p)
}
}
+Slice::Gen::OpsVisitor::OpsVisitor(IceUtil::Output& out)
+ : CsVisitor(out)
+{
+}
+
bool
Slice::Gen::OpsVisitor::visitModuleStart(const ModulePtr& p)
{
@@ -3066,7 +3154,9 @@ Slice::Gen::OpsVisitor::writeOperations(const ClassDefPtr& p, bool noCurrent)
string retS = typeToString(ret);
- _out << sp << nl << retS << ' ' << name << spar << params;
+ _out << sp << nl;
+ emitAttributes(op);
+ _out << retS << ' ' << name << spar << params;
if(!noCurrent && !p->isLocal())
{
_out << "Ice.Current __current";
diff --git a/cpp/src/slice2cs/Gen.h b/cpp/src/slice2cs/Gen.h
index 4ac46477ce7..568c8bc6350 100644
--- a/cpp/src/slice2cs/Gen.h
+++ b/cpp/src/slice2cs/Gen.h
@@ -15,6 +15,7 @@
namespace Slice
{
+
class CsVisitor : public CsGenerator, public ParserVisitor
{
public:
@@ -33,6 +34,9 @@ protected:
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;
};
@@ -69,6 +73,20 @@ private:
void printHeader();
+ class UnitVisitor : public CsVisitor
+ {
+ public:
+
+ UnitVisitor(::IceUtil::Output&, bool);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+
+ private:
+
+ bool _stream;
+ bool _globalMetaDataDone;
+ };
+
class TypesVisitor : public CsVisitor
{
public:
diff --git a/cpp/src/slice2vb/Gen.cpp b/cpp/src/slice2vb/Gen.cpp
index fc8bc3ba589..504c461932e 100755
--- a/cpp/src/slice2vb/Gen.cpp
+++ b/cpp/src/slice2vb/Gen.cpp
@@ -699,6 +699,22 @@ Slice::VbVisitor::writeDispatch(const ClassDefPtr& p)
}
}
+string
+Slice::VbVisitor::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 = "vb:attribute:";
+ if(i->find(prefix) == 0)
+ {
+ result += "<" + i->substr(prefix.size()) + "> ";
+ }
+ }
+ return result;
+}
+
vector<string>
Slice::VbVisitor::getParams(const OperationPtr& op)
{
@@ -706,8 +722,9 @@ Slice::VbVisitor::getParams(const OperationPtr& op)
ParamDeclList paramList = op->parameters();
for(ParamDeclList::const_iterator q = paramList.begin(); q != paramList.end(); ++q)
{
- string param = ((*q)->isOutParam() ? "<_System.Runtime.InteropServices.Out()> ByRef " : "ByVal ")
- + fixId((*q)->name()) + " As " + typeToString((*q)->type());
+ string param = getParamAttributes(*q);
+ param += ((*q)->isOutParam() ? "<_System.Runtime.InteropServices.Out()> ByRef " : "ByVal ")
+ + fixId((*q)->name()) + " As " + typeToString((*q)->type());
params.push_back(param);
}
return params;
@@ -731,7 +748,8 @@ Slice::VbVisitor::getParamsAsync(const OperationPtr& op, bool amd)
{
if(!(*q)->isOutParam())
{
- params.push_back("ByVal " + fixId((*q)->name()) + " As " + typeToString((*q)->type()));
+ params.push_back(getParamAttributes(*q) + "ByVal " + fixId((*q)->name()) + " As "
+ + typeToString((*q)->type()));
}
}
return params;
@@ -753,7 +771,8 @@ Slice::VbVisitor::getParamsAsyncCB(const OperationPtr& op)
{
if((*q)->isOutParam())
{
- params.push_back("ByVal " + fixId((*q)->name()) + " As " + typeToString((*q)->type()));
+ params.push_back(getParamAttributes(*q) + "ByVal " + fixId((*q)->name()) + " As "
+ + typeToString((*q)->type()));
}
}
@@ -814,6 +833,20 @@ Slice::VbVisitor::getArgsAsyncCB(const OperationPtr& op)
return args;
}
+void
+Slice::VbVisitor::emitAttributes(const ContainedPtr& p)
+{
+ StringList metaData = p->getMetaData();
+ for(StringList::const_iterator i = metaData.begin(); i != metaData.end(); ++i)
+ {
+ static const string prefix = "vb:attribute:";
+ if(i->find(prefix) == 0)
+ {
+ _out << '<' << i->substr(prefix.size()) << '>' << nl;
+ }
+ }
+}
+
Slice::Gen::Gen(const string& name, const string& base, const vector<string>& includePaths, const string& dir,
bool impl, bool implTie, bool stream)
: _base(base),
@@ -917,6 +950,9 @@ Slice::Gen::generate(const UnitPtr& p)
VbGenerator::validateMetaData(p);
+ UnitVisitor unitVisitor(_out, _stream);
+ p->visit(&unitVisitor, false);
+
TypesVisitor typesVisitor(_out, _stream);
p->visit(&typesVisitor, false);
@@ -1032,11 +1068,39 @@ Slice::Gen::printHeader()
_out << "\n' Ice version " << ICE_STRING_VERSION;
}
-Slice::Gen::OpsVisitor::OpsVisitor(IceUtil::Output& out)
- : VbVisitor(out)
+Slice::Gen::UnitVisitor::UnitVisitor(IceUtil::Output& out, bool stream)
+ : VbVisitor(out), _stream(stream), _globalMetaDataDone(false)
{
}
+bool
+Slice::Gen::UnitVisitor::visitModuleStart(const ModulePtr& p)
+{
+ if(!_globalMetaDataDone)
+ {
+ DefinitionContextPtr dc = p->definitionContext();
+ StringList globalMetaData = dc->getMetaData();
+
+ static const string attributePrefix = "vb: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, bool stream)
: VbVisitor(out),
_stream(stream)
@@ -1047,7 +1111,9 @@ bool
Slice::Gen::TypesVisitor::visitModuleStart(const ModulePtr& p)
{
string name = fixId(p->name());
- _out << sp << nl << "Namespace " << name;
+ _out << sp << nl;
+ emitAttributes(p);
+ _out << "Namespace " << name;
_out.inc();
@@ -1110,9 +1176,12 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p)
_out.dec();
_out << nl << "End Class";
}
+
+ _out << sp << nl;
+ emitAttributes(p);
if(p->isInterface())
{
- _out << sp << nl << "Public Interface " << name;
+ _out << "Public Interface " << name;
_out.inc();
if(p->isLocal())
{
@@ -1140,7 +1209,7 @@ Slice::Gen::TypesVisitor::visitClassDefStart(const ClassDefPtr& p)
}
else
{
- _out << sp << nl << "Public ";
+ _out << "Public ";
if(p->isAbstract())
{
_out << "MustInherit ";
@@ -1529,7 +1598,9 @@ Slice::Gen::TypesVisitor::visitOperation(const OperationPtr& p)
string vbOp = ret ? "Function" : "Sub";
- _out << sp << nl << "Public ";
+ _out << sp << nl;
+ emitAttributes(p);
+ _out << "Public ";
if(isLocal)
{
_out << "MustOverride ";
@@ -1580,7 +1651,9 @@ Slice::Gen::TypesVisitor::visitSequence(const SequencePtr& p)
string s = typeToString(p->type());
bool isValue = isValueType(p->type());
- _out << sp << nl << "Public Class " << name;
+ _out << sp << nl;
+ emitAttributes(p);
+ _out << "Public Class " << name;
_out.inc();
_out << nl << "Inherits _System.Collections.CollectionBase";
_out << nl << "Implements _System.ICloneable";
@@ -1880,7 +1953,9 @@ Slice::Gen::TypesVisitor::visitExceptionStart(const ExceptionPtr& p)
string name = fixId(p->name());
ExceptionPtr base = p->base();
- _out << sp << nl << "Public Class " << name;
+ _out << sp << nl;
+ emitAttributes(p);
+ _out << "Public Class " << name;
_out.inc();
if(base)
{
@@ -2314,13 +2389,15 @@ Slice::Gen::TypesVisitor::visitStructStart(const StructPtr& p)
_out << nl << "End Class";
}
+ _out << sp << nl;
+ emitAttributes(p);
if(p->hasMetaData("clr:class"))
{
- _out << sp << nl << "Public Class " << name << " Implements _System.ICloneable";
+ _out << "Public Class " << name << " Implements _System.ICloneable";
}
else
{
- _out << sp << nl << "Public Structure " << name;
+ _out << "Public Structure " << name;
}
_out.inc();
@@ -2743,7 +2820,9 @@ Slice::Gen::TypesVisitor::visitDictionary(const DictionaryPtr& p)
string vs = typeToString(p->valueType());
bool valueIsValue = isValueType(p->valueType());
- _out << sp << nl << "Public Class " << name;
+ _out << sp << nl;
+ emitAttributes(p);
+ _out << "Public Class " << name;
_out.inc();
_out << nl << "Inherits _System.Collections.DictionaryBase";
_out << nl << "Implements _System.ICloneable";
@@ -3049,7 +3128,9 @@ Slice::Gen::TypesVisitor::visitEnum(const EnumPtr& p)
{
string name = fixId(p->name());
string scoped = fixId(p->scoped());
- _out << sp << nl << "Public Enum " << name;
+ _out << sp << nl;
+ emitAttributes(p);
+ _out << "Public Enum " << name;
_out.inc();
EnumeratorList enumerators = p->getEnumerators();
for(EnumeratorList::const_iterator en = enumerators.begin(); en != enumerators.end(); ++en)
@@ -3087,7 +3168,9 @@ void
Slice::Gen::TypesVisitor::visitConst(const ConstPtr& p)
{
string name = fixId(p->name());
- _out << sp << nl << "Public NotInheritable Class " << name;
+ _out << sp << nl;
+ emitAttributes(p);
+ _out << "Public NotInheritable Class " << name;
_out.inc();
_out << nl << "Public Const value As " << typeToString(p->type()) << " = ";
BuiltinPtr bp = BuiltinPtr::dynamicCast(p->type());
@@ -3220,7 +3303,9 @@ Slice::Gen::TypesVisitor::visitDataMember(const DataMemberPtr& p)
baseTypes = DotNet::ICloneable;
isClass = true;
}
- _out << sp << nl << "Public " << fixId(p->name(), baseTypes, isClass) << " As " << typeToString(p->type());
+ _out << sp << nl;
+ emitAttributes(p);
+ _out << "Public " << fixId(p->name(), baseTypes, isClass) << " As " << typeToString(p->type());
}
Slice::Gen::ProxyVisitor::ProxyVisitor(IceUtil::Output& out)
@@ -3236,7 +3321,9 @@ Slice::Gen::ProxyVisitor::visitModuleStart(const ModulePtr& p)
return false;
}
- _out << sp << nl << "Namespace " << fixId(p->name());
+ _out << sp << nl;
+ emitAttributes(p);
+ _out << "Namespace " << fixId(p->name());
_out.inc();
return true;
}
@@ -3326,6 +3413,11 @@ Slice::Gen::ProxyVisitor::visitOperation(const OperationPtr& p)
}
}
+Slice::Gen::OpsVisitor::OpsVisitor(IceUtil::Output& out)
+ : VbVisitor(out)
+{
+}
+
bool
Slice::Gen::OpsVisitor::visitModuleStart(const ModulePtr& p)
{
@@ -3435,7 +3527,9 @@ Slice::Gen::OpsVisitor::writeOperations(const ClassDefPtr& p, bool noCurrent)
string vbOp = ret ? "Function" : "Sub";
- _out << sp << nl << vbOp << ' ' << name << spar << params;
+ _out << sp << nl;
+ emitAttributes(op);
+ _out << vbOp << ' ' << name << spar << params;
if(!noCurrent && !p->isLocal())
{
_out << "ByVal __current As Ice.Current";
diff --git a/cpp/src/slice2vb/Gen.h b/cpp/src/slice2vb/Gen.h
index a1cfe9ef60d..76b7fb58da1 100644
--- a/cpp/src/slice2vb/Gen.h
+++ b/cpp/src/slice2vb/Gen.h
@@ -33,6 +33,9 @@ protected:
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;
};
@@ -69,6 +72,20 @@ private:
void printHeader();
+ class UnitVisitor : public VbVisitor
+ {
+ public:
+
+ UnitVisitor(::IceUtil::Output&, bool);
+
+ virtual bool visitModuleStart(const ModulePtr&);
+
+ private:
+
+ bool _stream;
+ bool _globalMetaDataDone;
+ };
+
class TypesVisitor : public VbVisitor
{
public: