void FreezeScript::AssignVisitor::visitObject(const ObjectRefPtr& dest) { Slice::TypePtr type = dest->getType(); ObjectRefPtr src = ObjectRefPtr::dynamicCast(_src); if(!src) { typeMismatchError(type, _src->getType()); } ObjectDataPtr srcValue = src->getValue(); Slice::TypePtr srcType = src->getType(); if(!srcValue) { // // Allow a nil value from type Object. // 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)) { dest->setValue(srcValue); } else { typeMismatchError(type, srcValueType); } } }
void FreezeScript::TransformVisitor::visitObject(const ObjectRefPtr& dest) { Slice::TypePtr type = dest->getType(); ObjectRefPtr src = ObjectRefPtr::dynamicCast(_src); if(!src) { typeMismatchError(type, _src->getType()); } else if(_info->doDefaultTransform(type)) { ObjectDataPtr srcValue = src->getValue(); Slice::TypePtr srcType = src->getType(); if(!srcValue) { // // Allow a nil value from type Object. // 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)) { // // 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(srcValue); } else { ObjectDataMap& objectDataMap = _info->getObjectDataMap(); ObjectDataMap::iterator p = objectDataMap.find(srcValue.get()); if(p != objectDataMap.end() && p->second) { 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) { string name = typeToString(srcValueType); 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); ObjectDataPtr newValue = newRef->getValue(); try { transformObject(newValue, srcValue); } catch(...) { newObj->destroy(); throw; } dest->setValue(newValue); newObj->destroy(); } } } else { typeMismatchError(type, srcValueType); } } } _info->executeCustomTransform(dest, _src); }