summaryrefslogtreecommitdiff
path: root/cpp/src/Slice/CsUtil.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/Slice/CsUtil.cpp')
-rwxr-xr-xcpp/src/Slice/CsUtil.cpp146
1 files changed, 100 insertions, 46 deletions
diff --git a/cpp/src/Slice/CsUtil.cpp b/cpp/src/Slice/CsUtil.cpp
index ad546d3b0b6..0abaea9d9fe 100755
--- a/cpp/src/Slice/CsUtil.cpp
+++ b/cpp/src/Slice/CsUtil.cpp
@@ -165,11 +165,34 @@ Slice::CsGenerator::typeToString(const TypePtr& type)
}
SequencePtr seq = SequencePtr::dynamicCast(type);
- if(seq && !seq->hasMetaData("clr:collection"))
+ if(seq)
{
+ if(seq->hasMetaData("clr:collection"))
+ {
+ return fixId(seq->scoped());
+ }
+
+ string prefix = "clr:generic:";
+ string meta;
+ if(seq->findMetaData(prefix, meta))
+ {
+ string type = meta.substr(prefix.size());
+ return "_System.Collections.Generic." + type + "<" + typeToString(seq->type()) + ">";
+ }
+
return typeToString(seq->type()) + "[]";
}
+ DictionaryPtr d = DictionaryPtr::dynamicCast(type);
+ if(d)
+ {
+ if(!d->hasMetaData("clr:collection"))
+ {
+ return "_System.Collections.Generic.Dictionary<"
+ + typeToString(d->keyType()) + ", " + typeToString(d->valueType()) + ">";
+ }
+ }
+
ContainedPtr contained = ContainedPtr::dynamicCast(type);
if(contained)
{
@@ -529,7 +552,23 @@ Slice::CsGenerator::writeMarshalUnmarshalCode(Output &out,
}
assert(ConstructedPtr::dynamicCast(type));
- string typeS = typeToString(type);
+ string typeS;
+ DictionaryPtr d = DictionaryPtr::dynamicCast(type);
+ if(d)
+ {
+ if(!d->hasMetaData("clr:collection"))
+ {
+ typeS = fixId(d->scoped());
+ }
+ else
+ {
+ typeS = typeToString(type);
+ }
+ }
+ else
+ {
+ typeS = typeToString(type);
+ }
if(marshal)
{
out << nl << typeS << "Helper.write(" << stream << ", " << param << ");";
@@ -560,7 +599,14 @@ Slice::CsGenerator::writeSequenceMarshalUnmarshalCode(Output& out,
TypePtr type = seq->type();
string typeS = typeToString(type);
- bool isArray = !seq->hasMetaData("clr:collection");
+ string genericPrefix = "clr:generic:";
+ string genericType;
+ bool isGeneric = seq->findMetaData(genericPrefix, genericType);
+ if(isGeneric)
+ {
+ genericType = genericType.substr(genericPrefix.size());
+ }
+ bool isArray = !isGeneric && !seq->hasMetaData("clr:collection");
string limitID = isArray ? "Length" : "Count";
BuiltinPtr builtin = BuiltinPtr::dynamicCast(type);
@@ -621,7 +667,8 @@ Slice::CsGenerator::writeSequenceMarshalUnmarshalCode(Output& out,
{
out << "(ReadObjectCallback)";
}
- out << "new IceInternal.SequencePatcher(" << param << ", typeof(Ice.Object), ix__));";
+ out << "new IceInternal.SequencePatcher<" << typeS << ">(" << param
+ << ", typeof(Ice.Object), ix__));";
}
else
{
@@ -664,23 +711,42 @@ Slice::CsGenerator::writeSequenceMarshalUnmarshalCode(Output& out,
typeS[0] = toupper(typeS[0]);
if(marshal)
{
- out << nl << stream << ".write" << typeS << "Seq(" << param;
- if(!isArray)
+ out << nl << stream << ".write" << typeS << "Seq(";
+ if(isGeneric)
{
- out << " == null ? null : " << param << ".ToArray()";
+ switch(builtin->kind())
+ {
+ case Builtin::KindByte:
+ case Builtin::KindBool:
+ out << param << ");";
+ break;
+ default:
+ out << param << ".Count, " << param << ");";
+ }
+ }
+ else if(!isArray)
+ {
+ out << param << " == null ? null : " << param << ".ToArray());";
+ }
+ else
+ {
+ out << param << ");";
}
- out << ");";
}
else
{
- if(!isArray)
+ if(isArray)
{
- out << nl << param << " = new " << fixId(seq->scoped())
- << '(' << stream << ".read" << typeS << "Seq());";
+ out << nl << param << " = " << stream << ".read" << typeS << "Seq();";
+ }
+ else if(isGeneric)
+ {
+ out << nl << stream << ".read" << typeS << "Seq(out " << param << ");";
}
else
{
- out << nl << param << " = " << stream << ".read" << typeS << "Seq();";
+ out << nl << param << " = new " << fixId(seq->scoped())
+ << '(' << stream << ".read" << typeS << "Seq());";
}
}
break;
@@ -734,8 +800,8 @@ Slice::CsGenerator::writeSequenceMarshalUnmarshalCode(Output& out,
out << ';';
out << nl << "for(int ix__ = 0; ix__ < szx__; ++ix__)";
out << sb;
- out << nl << "IceInternal.SequencePatcher spx = new IceInternal.SequencePatcher("
- << param << ", " << "typeof(" << typeS << "), ix__);";
+ out << nl << "IceInternal.SequencePatcher<" << typeS << "> spx = new IceInternal.SequencePatcher<"
+ << typeS << ">(" << param << ", " << "typeof(" << typeS << "), ix__);";
out << nl << stream << ".readObject(";
if(streamingAPI)
{
@@ -960,6 +1026,10 @@ Slice::CsGenerator::writeSequenceMarshalUnmarshalCode(Output& out,
{
out << toArrayAlloc(typeS + "[]", "szx__");
}
+ else if(isGeneric)
+ {
+ out << "_System.Collections.Generic." << genericType << "<" << typeS << ">()";
+ }
else
{
out << fixId(seq->scoped()) << "(szx__)";
@@ -1162,36 +1232,6 @@ Slice::CsGenerator::MetaDataVisitor::validate(const ContainedPtr& cont)
{
string s = *p;
- if(s.find("cs:") == 0) // TODO: remove this statement once "cs:" is a hard error.
- {
- if(SequencePtr::dynamicCast(cont))
- {
- if(s.substr(3) == "collection")
- {
- cout << file << ":" << cont->line() << ": warning: `cs:' metadata prefix is deprecated; "
- << "use `clr:' instead" << endl;
- cont->addMetaData("clr:collection");
- }
- }
- else if(StructPtr::dynamicCast(cont))
- {
- if(s.substr(3) == "class")
- {
- cout << file << ":" << cont->line() << ": warning: `cs:' metadata prefix is deprecated; "
- << "use `clr:' instead" << endl;
- 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)
{
@@ -1203,8 +1243,15 @@ Slice::CsGenerator::MetaDataVisitor::validate(const ContainedPtr& cont)
{
continue;
}
+ if(s.substr(prefix.size(), 8) == "generic:")
+ {
+ if(!s.substr(prefix.size() + 8).empty())
+ {
+ continue;
+ }
+ }
}
- if(StructPtr::dynamicCast(cont))
+ else if(StructPtr::dynamicCast(cont))
{
if(s.substr(prefix.size()) == "class")
{
@@ -1215,13 +1262,20 @@ Slice::CsGenerator::MetaDataVisitor::validate(const ContainedPtr& cont)
continue;
}
}
- if(ClassDefPtr::dynamicCast(cont))
+ else if(ClassDefPtr::dynamicCast(cont))
{
if(s.substr(prefix.size()) == "property")
{
continue;
}
}
+ else if(DictionaryPtr::dynamicCast(cont))
+ {
+ if(s.substr(prefix.size()) == "collection")
+ {
+ continue;
+ }
+ }
cout << file << ":" << cont->line() << ": warning: ignoring invalid metadata `" << s << "'" << endl;
}
_history.insert(s);