bool FreezeScript::TransformVisitor::checkClasses(const Slice::ClassDeclPtr& dest, const Slice::ClassDeclPtr& src) { // // Here are the rules for verifying class compatibility: // // 1. If the type ids are the same, assume they are compatible. // 2. If the source type has been renamed, then check its equivalent new definition for compatibility. // 3. Otherwise, the types are only compatible if they are defined in the same Slice unit, and if the // destination type is a base type of the source type. // string s1 = dest->scoped(); string s2 = src->scoped(); if(s1 == s2) { return true; } else { Slice::TypePtr t = _info->getRenamedType(src); Slice::ClassDeclPtr s = Slice::ClassDeclPtr::dynamicCast(t); if(s) { return checkClasses(dest, s); } if(dest->unit().get() != src->unit().get()) { Slice::TypeList l = dest->unit()->lookupTypeNoBuiltin(s2, false); if(l.empty()) { _info->getErrorReporter()->error("class " + s2 + " not found in new Slice definitions"); } s = Slice::ClassDeclPtr::dynamicCast(l.front()); } else { s = src; } if(s) { Slice::ClassDefPtr def = s->definition(); if(!def) { _info->getErrorReporter()->error("class " + s2 + " declared but not defined"); } return def->isA(s1); } } return false; }
bool FreezeScript::AssignVisitor::checkClasses(const Slice::ClassDeclPtr& dest, const Slice::ClassDeclPtr& src) { string s1 = dest->scoped(); string s2 = src->scoped(); if(s1 == s2) { return true; } else { Slice::ClassDefPtr def = src->definition(); if(!def) { error("class " + s2 + " declared but not defined"); } return def->isA(s1); } return false; }
bool FreezeScript::invokeMemberFunction(const string& name, const DataPtr& target, const DataList& args, DataPtr& result, const DataFactoryPtr& factory, const ErrorReporterPtr& errorReporter) { // // string // StringDataPtr targetStr = StringDataPtr::dynamicCast(target); if(targetStr) { if(name == "find") { StringDataPtr argData; IntegerDataPtr startData; if(args.size() > 0) { argData = StringDataPtr::dynamicCast(args[0]); } if(args.size() > 1) { startData = IntegerDataPtr::dynamicCast(args[1]); } if(args.size() == 0 || args.size() > 2 || !argData || (args.size() == 2 && !startData)) { errorReporter->error("invalid arguments to find(string str[, int len])"); } string targ = targetStr->stringValue(); string arg = argData->stringValue(); string::size_type pos; if(startData) { string::size_type start = static_cast<string::size_type>(startData->integerValue()); pos = targ.find(arg, start); } else { pos = targ.find(arg); } result = factory->createInteger(pos == string::npos ? -1 : static_cast<Ice::Long>(pos), false); return true; } else if(name == "substr") { IntegerDataPtr startData; IntegerDataPtr lenData; if(args.size() > 0) { startData = IntegerDataPtr::dynamicCast(args[0]); } if(args.size() > 1) { lenData = IntegerDataPtr::dynamicCast(args[1]); } if(args.size() == 0 || args.size() > 2 || !startData || (args.size() == 2 && !lenData)) { errorReporter->error("invalid arguments to substr(int start[, int len])"); } string targ = targetStr->stringValue(); string::size_type start = static_cast<string::size_type>(startData->integerValue()); string::size_type len = string::npos; if(lenData) { len = static_cast<string::size_type>(lenData->integerValue()); } if(start > targ.size()) { ostringstream ostr; ostr << "substr() starting position (" << start << ") is greater than string length (" << targ.size() << ")"; errorReporter->error(ostr.str()); } result = factory->createString(targ.substr(start, len), false); return true; } else if(name == "replace") { IntegerDataPtr startData; IntegerDataPtr lenData; StringDataPtr strData; if(args.size() == 3) { startData = IntegerDataPtr::dynamicCast(args[0]); lenData = IntegerDataPtr::dynamicCast(args[1]); strData = StringDataPtr::dynamicCast(args[2]); } if(args.size() != 3 || !startData || !lenData || !strData) { errorReporter->error("invalid arguments to replace(int start, int len, string val)"); } string targ = targetStr->stringValue(); string::size_type start = static_cast<string::size_type>(startData->integerValue()); string::size_type len = static_cast<string::size_type>(lenData->integerValue()); string str = strData->stringValue(); if(start > targ.size()) { ostringstream ostr; ostr << "replace() starting position (" << start << ") is greater than string length (" << targ.size() << ")"; errorReporter->error(ostr.str()); } result = factory->createString(targ.replace(start, len, str), false); return true; } return false; } // // Object // ObjectRefPtr targetObj = ObjectRefPtr::dynamicCast(target); if(targetObj) { if(name == "ice_isA") { ObjectDataPtr value = targetObj->getValue(); if(!value) { errorReporter->error("ice_isA() invoked on nil object"); } StringDataPtr str; if(args.size() > 0) { str = StringDataPtr::dynamicCast(args.front()); } if(args.size() != 1 || !str) { errorReporter->error("invalid arguments to ice_isA(string id)"); } string id = str->stringValue(); if(id == "::Ice::Object") { result = factory->createBoolean(true, false); return true; } Slice::ClassDeclPtr decl = Slice::ClassDeclPtr::dynamicCast(value->getType()); if(!decl) { // // Ice::Object // result = factory->createBoolean(false, false); return true; } Slice::ClassDefPtr def = decl->definition(); assert(def); result = factory->createBoolean(def->isA(id), false); return true; } return false; } return false; }