summaryrefslogtreecommitdiff
path: root/cpp/src/FreezeScript/TransformVisitor.cpp
diff options
context:
space:
mode:
authorMark Spruiell <mes@zeroc.com>2014-04-18 16:23:03 -0700
committerMark Spruiell <mes@zeroc.com>2014-04-18 16:23:03 -0700
commit7f335ef52ae41c4227f24ae6db1dcf244353d36a (patch)
treea32a9dda20b9e1690d7eec6f04ec3fc464dbb89c /cpp/src/FreezeScript/TransformVisitor.cpp
parentFixed (ICE-5507) - Support Java 8 lambda expression (diff)
downloadice-7f335ef52ae41c4227f24ae6db1dcf244353d36a.tar.bz2
ice-7f335ef52ae41c4227f24ae6db1dcf244353d36a.tar.xz
ice-7f335ef52ae41c4227f24ae6db1dcf244353d36a.zip
ICE-5521 - first round of changes
Diffstat (limited to 'cpp/src/FreezeScript/TransformVisitor.cpp')
-rw-r--r--cpp/src/FreezeScript/TransformVisitor.cpp214
1 files changed, 154 insertions, 60 deletions
diff --git a/cpp/src/FreezeScript/TransformVisitor.cpp b/cpp/src/FreezeScript/TransformVisitor.cpp
index f2d88b882ac..c2e413b57d5 100644
--- a/cpp/src/FreezeScript/TransformVisitor.cpp
+++ b/cpp/src/FreezeScript/TransformVisitor.cpp
@@ -202,13 +202,17 @@ FreezeScript::TransformVisitor::visitStruct(const StructDataPtr& dest)
Slice::TypePtr type = dest->getType();
if(_info->doDefaultTransform(type))
{
+ //
+ // Support struct->struct and class->struct transforms.
+ //
StructDataPtr s = StructDataPtr::dynamicCast(_src);
- if(s && isCompatible(type, _src->getType()))
+ ObjectRefPtr obj = ObjectRefPtr::dynamicCast(_src);
+ if((s || obj) && isCompatible(type, _src->getType()))
{
//
// Transform members with the same name.
//
- DataMemberMap srcMap = s->getMembers();
+ DataMemberMap srcMap = s ? s->getMembers() : obj->getValue()->getMembers();
DataMemberMap destMap = dest->getMembers();
string typeName = typeToString(type);
for(DataMemberMap::iterator p = destMap.begin(); p != destMap.end(); ++p)
@@ -391,97 +395,172 @@ FreezeScript::TransformVisitor::visitDictionary(const DictionaryDataPtr& dest)
void
FreezeScript::TransformVisitor::visitObject(const ObjectRefPtr& dest)
{
+ //
+ // Support struct->class and class->class transforms.
+ //
Slice::TypePtr type = dest->getType();
ObjectRefPtr src = ObjectRefPtr::dynamicCast(_src);
- if(!src)
+ StructDataPtr s = StructDataPtr::dynamicCast(_src);
+ if(!src && !s)
{
typeMismatchError(type, _src->getType());
}
else if(_info->doDefaultTransform(type))
{
- ObjectDataPtr srcValue = src->getValue();
- Slice::TypePtr srcType = src->getType();
- if(!srcValue)
+ if(src)
{
//
- // Allow a nil value from type Object.
+ // class->class transform
//
- if(Slice::BuiltinPtr::dynamicCast(srcType) || isCompatible(type, srcType))
- {
- dest->setValue(0);
- }
- else
- {
- typeMismatchError(type, srcType);
- }
- }
- else
- {
- Slice::TypePtr srcValueType = srcValue->getType();
- if(isCompatible(type, srcValueType))
+ ObjectDataPtr srcValue = src->getValue();
+ Slice::TypePtr srcType = src->getType();
+ if(!srcValue)
{
//
- // If the types are in the same Slice unit, then we can simply
- // copy the reference. Otherwise, we check the object map to
- // see if an equivalent object has already been created, and
- // if not, then we have to create one.
+ // Allow a nil value from type Object.
//
- if(type->unit().get() == srcValueType->unit().get())
+ if(Slice::BuiltinPtr::dynamicCast(srcType) || isCompatible(type, srcType))
{
- dest->setValue(srcValue);
+ dest->setValue(0);
}
else
{
- ObjectDataMap& objectDataMap = _info->getObjectDataMap();
- ObjectDataMap::iterator p = objectDataMap.find(srcValue.get());
- if(p != objectDataMap.end() && p->second)
+ typeMismatchError(type, srcType);
+ }
+ }
+ else
+ {
+ Slice::TypePtr srcValueType = srcValue->getType();
+ if(isCompatible(type, srcValueType))
+ {
+ //
+ // If the types are in the same Slice unit, then we can simply
+ // copy the reference. Otherwise, we check the object map to
+ // see if an equivalent object has already been created, and
+ // if not, then we have to create one.
+ //
+ if(type->unit().get() == srcValueType->unit().get())
{
- dest->setValue(p->second);
+ dest->setValue(srcValue);
}
else
{
- //
- // If the type has been renamed, we need to get its equivalent
- // in the new Slice definitions.
- //
- Slice::TypePtr newType = _info->getRenamedType(srcValueType);
- if(!newType)
+ ObjectDataMap& objectDataMap = _info->getObjectDataMap();
+ ObjectDataMap::iterator p = objectDataMap.find(srcValue.get());
+ if(p != objectDataMap.end() && p->second)
{
- string name = typeToString(srcValueType);
- Slice::TypeList l = type->unit()->lookupType(name, false);
- if(l.empty())
+ dest->setValue(p->second);
+ }
+ else
+ {
+ //
+ // If the type has been renamed, we need to get its equivalent
+ // in the new Slice definitions.
+ //
+ Slice::TypePtr newType = _info->getRenamedType(srcValueType);
+ if(!newType)
{
- throw ClassNotFoundException(name);
+ string name = typeToString(srcValueType);
+ Slice::TypeList l = type->unit()->lookupType(name, false);
+ if(l.empty())
+ {
+ throw ClassNotFoundException(name);
+ }
+ newType = l.front();
}
- newType = l.front();
- }
- //
- // Use createObject() so that an initializer is invoked if necessary.
- //
- DataPtr newObj = _info->getDataFactory()->createObject(newType, false);
- ObjectRefPtr newRef = ObjectRefPtr::dynamicCast(newObj);
- assert(newRef);
+ //
+ // Use createObject() so that an initializer is invoked if necessary.
+ //
+ DataPtr newObj = _info->getDataFactory()->createObject(newType, false);
+ ObjectRefPtr newRef = ObjectRefPtr::dynamicCast(newObj);
+ assert(newRef);
- ObjectDataPtr newValue = newRef->getValue();
- try
- {
- transformObject(newValue, srcValue);
- }
- catch(...)
- {
+ ObjectDataPtr newValue = newRef->getValue();
+ try
+ {
+ transformObject(newValue, srcValue);
+ }
+ catch(...)
+ {
+ newObj->destroy();
+ throw;
+ }
+
+ dest->setValue(newValue);
newObj->destroy();
- throw;
}
+ }
+ }
+ else
+ {
+ typeMismatchError(type, srcValueType);
+ }
+ }
+ }
+ else
+ {
+ //
+ // struct->class transform
+ //
+ Slice::TypePtr srcType = _src->getType();
+ if(isCompatible(type, srcType))
+ {
+ //
+ // If the type has been renamed, we need to get its equivalent
+ // in the new Slice definitions.
+ //
+ Slice::TypePtr newType = _info->getRenamedType(srcType);
+ if(!newType)
+ {
+ string name = typeToString(srcType);
+ Slice::TypeList l = type->unit()->lookupType(name, false);
+ if(l.empty())
+ {
+ throw ClassNotFoundException(name);
+ }
+ newType = l.front();
+ }
+
+ //
+ // Use createObject() so that an initializer is invoked if necessary.
+ //
+ DataPtr newObj = _info->getDataFactory()->createObject(newType, false);
+ ObjectRefPtr newRef = ObjectRefPtr::dynamicCast(newObj);
+ assert(newRef);
- dest->setValue(newValue);
- newObj->destroy();
+ ObjectDataPtr newValue = newRef->getValue();
+ try
+ {
+ //
+ // Transform members with the same name.
+ //
+ DataMemberMap srcMap = s->getMembers();
+ DataMemberMap destMap = newValue->getMembers();
+ string typeName = typeToString(type);
+ for(DataMemberMap::iterator p = destMap.begin(); p != destMap.end(); ++p)
+ {
+ DataMemberMap::iterator q = srcMap.find(p->first);
+ if(q != srcMap.end())
+ {
+ string context = typeName + " member " + p->first + " value";
+ TransformVisitor v(q->second, _info, context);
+ p->second->visit(v);
+ }
}
}
+ catch(...)
+ {
+ newObj->destroy();
+ throw;
+ }
+
+ dest->setValue(newValue);
+ newObj->destroy();
}
else
{
- typeMismatchError(type, srcValueType);
+ typeMismatchError(type, srcType);
}
}
}
@@ -711,6 +790,20 @@ FreezeScript::TransformVisitor::isCompatible(const Slice::TypePtr& dest, const S
return true;
}
+ Slice::StructPtr s2 = Slice::StructPtr::dynamicCast(src);
+ if(s2)
+ {
+ if(checkRename(dest, src))
+ {
+ return true;
+ }
+
+ if(s2 && cl1->scoped() == s2->scoped())
+ {
+ return true;
+ }
+ }
+
return false;
}
@@ -723,7 +816,8 @@ FreezeScript::TransformVisitor::isCompatible(const Slice::TypePtr& dest, const S
}
Slice::StructPtr s2 = Slice::StructPtr::dynamicCast(src);
- if(s2 && s1->scoped() == s2->scoped())
+ Slice::ClassDeclPtr cl2 = Slice::ClassDeclPtr::dynamicCast(src);
+ if((s2 && s1->scoped() == s2->scoped()) || (cl2 && s1->scoped() == cl2->scoped()))
{
return true;
}