summaryrefslogtreecommitdiff
path: root/cpp/src/FreezeScript/TransformAnalyzer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'cpp/src/FreezeScript/TransformAnalyzer.cpp')
-rw-r--r--cpp/src/FreezeScript/TransformAnalyzer.cpp1236
1 files changed, 0 insertions, 1236 deletions
diff --git a/cpp/src/FreezeScript/TransformAnalyzer.cpp b/cpp/src/FreezeScript/TransformAnalyzer.cpp
deleted file mode 100644
index e1c9776e128..00000000000
--- a/cpp/src/FreezeScript/TransformAnalyzer.cpp
+++ /dev/null
@@ -1,1236 +0,0 @@
-// **********************************************************************
-//
-// Copyright (c) 2003-2015 ZeroC, Inc. All rights reserved.
-//
-// This copy of Ice is licensed to you under the terms described in the
-// ICE_LICENSE file included in this distribution.
-//
-// **********************************************************************
-
-#include <FreezeScript/TransformAnalyzer.h>
-#include <FreezeScript/Util.h>
-#include <IceUtil/OutputUtil.h>
-#include <map>
-
-using namespace std;
-using namespace Slice;
-using namespace IceUtil;
-using namespace IceUtilInternal;
-
-namespace FreezeScript
-{
-
-//
-// AnalyzeTransformVisitor visits the old definitions and compares them with
-// the new definitions.
-//
-class AnalyzeTransformVisitor : public ParserVisitor
-{
-public:
-
- AnalyzeTransformVisitor(XMLOutput&, const UnitPtr&, bool, vector<string>&, vector<string>&);
-
- void addDatabase(const string&, const TypePtr&, const TypePtr&, const TypePtr&, const TypePtr&);
-
- virtual bool visitClassDefStart(const ClassDefPtr&);
- virtual bool visitStructStart(const StructPtr&);
- virtual void visitSequence(const SequencePtr&);
- virtual void visitDictionary(const DictionaryPtr&);
- virtual void visitEnum(const EnumPtr&);
-
-private:
-
- void compareMembers(const DataMemberList&, const DataMemberList&);
- void compareTypes(const string&, const TypePtr&, const TypePtr&);
- void typeChange(const string&, const TypePtr&, const TypePtr&);
- bool checkClasses(const ClassDeclPtr&, const ClassDeclPtr&);
-
- XMLOutput& _out;
- UnitPtr _newUnit;
- bool _ignoreTypeChanges;
- vector<string>& _missingTypes;
- vector<string>& _errors;
-};
-
-//
-// InitVisitor visits the new definitions to find any that are not present
-// in the old definitions, and generates init elements for them.
-//
-class AnalyzeInitVisitor : public ParserVisitor
-{
-public:
-
- AnalyzeInitVisitor(XMLOutput&, const UnitPtr&);
-
- virtual bool visitClassDefStart(const ClassDefPtr&);
- virtual bool visitStructStart(const StructPtr&);
- virtual void visitSequence(const SequencePtr&);
- virtual void visitDictionary(const DictionaryPtr&);
- virtual void visitEnum(const EnumPtr&);
-
-private:
-
- void typeChange(const TypePtr&, const string&, const string&);
-
- XMLOutput& _out;
- UnitPtr _oldUnit;
-};
-
-}
-
-////////////////////////////////////
-// AnalyzeTransformVisitor
-////////////////////////////////////
-
-FreezeScript::AnalyzeTransformVisitor::AnalyzeTransformVisitor(XMLOutput& out, const UnitPtr& newUnit,
- bool ignoreTypeChanges, vector<string>& missingTypes,
- vector<string>& errors) :
- _out(out), _newUnit(newUnit), _ignoreTypeChanges(ignoreTypeChanges), _missingTypes(missingTypes), _errors(errors)
-{
-}
-
-void
-FreezeScript::AnalyzeTransformVisitor::addDatabase(const string& name, const TypePtr& oldKey, const TypePtr& newKey,
- const TypePtr& oldValue, const TypePtr& newValue)
-{
- _out << "\n";
- _out << se("database");
-
- if(!name.empty())
- {
- _out << attr("name", name);
- }
-
- string oldKeyName = oldKey ? typeToString(oldKey) : string("UNKNOWN");
- string newKeyName = newKey ? typeToString(newKey) : string("UNKNOWN");
- if(oldKeyName == newKeyName)
- {
- _out << attr("key", oldKeyName);
- }
- else
- {
- _out << attr("key", oldKeyName + "," + newKeyName);
- }
-
- string oldValueName = oldValue ? typeToString(oldValue) : string("UNKNOWN");
- string newValueName = newValue ? typeToString(newValue) : string("UNKNOWN");
- if(oldValueName == newValueName)
- {
- _out << attr("value", oldValueName);
- }
- else
- {
- _out << attr("value", oldValueName + "," + newValueName);
- }
-
- _out << se("record");
- if(oldKey && newKey)
- {
- compareTypes("database key", oldKey, newKey);
- }
- if(oldValue && newValue)
- {
- compareTypes("database value", oldValue, newValue);
- }
- _out << ee;
-
- _out << ee;
-}
-
-bool
-FreezeScript::AnalyzeTransformVisitor::visitClassDefStart(const ClassDefPtr& v)
-{
- if(v->isInterface() || v->isLocal())
- {
- return false;
- }
-
- string scoped = v->scoped();
- if(ignoreType(scoped))
- {
- return false;
- }
-
- TypeList l = _newUnit->lookupTypeNoBuiltin(scoped, false);
- if(l.empty())
- {
- _missingTypes.push_back(scoped);
- return false;
- }
-
- //
- // Allow transforming from class to struct.
- //
- ClassDeclPtr decl = ClassDeclPtr::dynamicCast(l.front());
- StructPtr newStruct = StructPtr::dynamicCast(l.front());
- if(!newStruct && (!decl || decl->isInterface()))
- {
- if(!_ignoreTypeChanges)
- {
- typeChange(scoped, v->declaration(), l.front());
- }
- return false;
- }
-
- ClassDefPtr newClass;
- if(decl)
- {
- newClass = decl->definition();
- if(!newClass)
- {
- _missingTypes.push_back(scoped);
- return false;
- }
- }
-
- DataMemberList oldMembers, newMembers;
-
- if(newClass)
- {
- oldMembers = v->dataMembers();
- newMembers = newClass->dataMembers();
- }
- else
- {
- oldMembers = v->allDataMembers();
- newMembers = newStruct->dataMembers();
- }
-
- _out.newline();
- _out.newline();
- if(newStruct)
- {
- _out << "<!-- struct " << scoped << " -->";
- }
- else
- {
- _out << "<!-- class " << scoped << " -->";
- }
- _out << se("transform") << attr("type", scoped);
-
- compareMembers(oldMembers, newMembers);
-
- _out << ee;
-
- return false;
-}
-
-bool
-FreezeScript::AnalyzeTransformVisitor::visitStructStart(const StructPtr& v)
-{
- if(v->isLocal())
- {
- return false;
- }
-
- string scoped = v->scoped();
- if(ignoreType(scoped))
- {
- return false;
- }
-
- TypeList l = _newUnit->lookupTypeNoBuiltin(scoped, false);
- if(l.empty())
- {
- _missingTypes.push_back(scoped);
- return false;
- }
-
- //
- // Allow transforming from struct to class.
- //
- StructPtr newStruct = StructPtr::dynamicCast(l.front());
- ClassDeclPtr decl = ClassDeclPtr::dynamicCast(l.front());
- ClassDefPtr newClass;
- if(decl)
- {
- newClass = decl->definition();
- if(!newClass)
- {
- _missingTypes.push_back(scoped);
- return false;
- }
- }
- else if(!newStruct)
- {
- if(!_ignoreTypeChanges)
- {
- typeChange(scoped, v, l.front());
- }
- return false;
- }
-
- _out.newline();
- _out.newline();
- if(newClass)
- {
- _out << "<!-- class " << scoped << " -->";
- }
- else
- {
- _out << "<!-- struct " << scoped << " -->";
- }
- _out << se("transform") << attr("type", scoped);
-
- DataMemberList oldMembers, newMembers;
-
- if(newClass)
- {
- oldMembers = v->dataMembers();
- newMembers = newClass->allDataMembers();
- }
- else
- {
- oldMembers = v->dataMembers();
- newMembers = newStruct->dataMembers();
- }
-
- compareMembers(oldMembers, newMembers);
-
- _out << ee;
-
- return false;
-}
-
-void
-FreezeScript::AnalyzeTransformVisitor::visitSequence(const SequencePtr& v)
-{
- if(v->isLocal())
- {
- return;
- }
-
- string scoped = v->scoped();
- if(ignoreType(scoped))
- {
- return;
- }
-
- TypeList l = _newUnit->lookupTypeNoBuiltin(scoped, false);
- if(l.empty())
- {
- _missingTypes.push_back(scoped);
- return;
- }
-
- SequencePtr newSeq = SequencePtr::dynamicCast(l.front());
- if(!newSeq)
- {
- if(!_ignoreTypeChanges)
- {
- typeChange(scoped, v, l.front());
- }
- return;
- }
-
- _out.newline();
- _out.newline();
- _out << "<!-- sequence " << scoped << " -->";
- _out << se("transform") << attr("type", scoped);
-
- compareTypes(scoped + " sequence type", v->type(), newSeq->type());
-
- _out << ee;
-}
-
-void
-FreezeScript::AnalyzeTransformVisitor::visitDictionary(const DictionaryPtr& v)
-{
- if(v->isLocal())
- {
- return;
- }
-
- string scoped = v->scoped();
- if(ignoreType(scoped))
- {
- return;
- }
-
- TypeList l = _newUnit->lookupTypeNoBuiltin(scoped, false);
- if(l.empty())
- {
- _missingTypes.push_back(scoped);
- return;
- }
-
- DictionaryPtr newDict = DictionaryPtr::dynamicCast(l.front());
- if(!newDict)
- {
- if(!_ignoreTypeChanges)
- {
- typeChange(scoped, v, l.front());
- }
- return;
- }
-
- _out.newline();
- _out.newline();
- _out << "<!-- dictionary " << scoped << " -->";
- _out << se("transform") << attr("type", scoped);
-
- compareTypes(scoped + " key type", v->keyType(), newDict->keyType());
- compareTypes(scoped + " value type", v->valueType(), newDict->valueType());
-
- _out << ee;
-}
-
-void
-FreezeScript::AnalyzeTransformVisitor::visitEnum(const EnumPtr& v)
-{
- if(v->isLocal())
- {
- return;
- }
-
- string scoped = v->scoped();
- if(ignoreType(scoped))
- {
- return;
- }
-
- TypeList l = _newUnit->lookupTypeNoBuiltin(scoped, false);
- if(l.empty())
- {
- _missingTypes.push_back(scoped);
- return;
- }
-
- EnumPtr newEnum = EnumPtr::dynamicCast(l.front());
- if(!newEnum)
- {
- if(!_ignoreTypeChanges)
- {
- typeChange(scoped, v, l.front());
- }
- return;
- }
-
- map<string, int> m;
- {
- Slice::EnumeratorList enumerators = newEnum->getEnumerators();
- int i = 0;
- for(Slice::EnumeratorList::iterator p = enumerators.begin(); p != enumerators.end(); ++p, ++i)
- {
- m.insert(map<string, int>::value_type((*p)->name(), i));
- }
- }
-
- _out.newline();
- _out.newline();
- _out << "<!-- enum " << scoped << " -->";
- _out << se("transform") << attr("type", scoped);
-
- Slice::EnumeratorList enumerators = v->getEnumerators();
- int i = 0;
- for(Slice::EnumeratorList::iterator p = enumerators.begin(); p != enumerators.end(); ++p, ++i)
- {
- map<string, int>::const_iterator q = m.find((*p)->name());
- if(q == m.end())
- {
- _out.newline();
- _out << "<!-- NOTICE: enumerator `" << (*p)->name() << "' has been removed -->";
- }
- else if(q->second != i)
- {
- _out.newline();
- _out << "<!-- NOTICE: enumerator `" << (*p)->name() << "' has changed position -->";
- }
- }
-
- _out << ee;
-}
-
-void
-FreezeScript::AnalyzeTransformVisitor::compareMembers(const DataMemberList& oldMembers,
- const DataMemberList& newMembers)
-{
- map<string, DataMemberPtr> oldMap, newMap;
-
- for(DataMemberList::const_iterator p = oldMembers.begin(); p != oldMembers.end(); ++p)
- {
- oldMap.insert(pair<string, DataMemberPtr>((*p)->name(), *p));
- }
-
- for(DataMemberList::const_iterator p = newMembers.begin(); p != newMembers.end(); ++p)
- {
- newMap.insert(pair<string, DataMemberPtr>((*p)->name(), *p));
- }
-
- for(DataMemberList::const_iterator p = oldMembers.begin(); p != oldMembers.end(); ++p)
- {
- string name = (*p)->name();
- map<string, DataMemberPtr>::iterator q = newMap.find(name);
- if(q == newMap.end())
- {
- _out.newline();
- _out << "<!-- NOTICE: " << name << " has been removed -->";
- }
- else
- {
- TypePtr oldType = (*p)->type();
- TypePtr newType = q->second->type();
- compareTypes(name, oldType, newType);
-
- //
- // Remove this entry from the map to indicate that we've
- // already seen it.
- //
- newMap.erase(q);
- }
- }
-
- //
- // Iterate over the remaining entries in newMap. These represent
- // members that were added in the new definition.
- //
- for(map<string, DataMemberPtr>::iterator q = newMap.begin(); q != newMap.end(); ++q)
- {
- _out.newline();
- _out << "<!-- NOTICE: " << q->first << " has been added -->";
- }
-}
-
-void
-FreezeScript::AnalyzeTransformVisitor::compareTypes(const string& desc, const TypePtr& oldType, const TypePtr& newType)
-{
- assert(!oldType->isLocal());
- if(newType->isLocal())
- {
- ostringstream ostr;
- ostr << desc << " has changed to a local type";
- _errors.push_back(ostr.str());
- return;
- }
-
- BuiltinPtr b = BuiltinPtr::dynamicCast(oldType);
- if(b)
- {
- BuiltinPtr newb = BuiltinPtr::dynamicCast(newType);
- switch(b->kind())
- {
- case Builtin::KindByte:
- {
- if(newb)
- {
- switch(newb->kind())
- {
- case Builtin::KindByte:
- case Builtin::KindShort:
- case Builtin::KindInt:
- case Builtin::KindLong:
- case Builtin::KindString:
- {
- return;
- }
- case Builtin::KindBool:
- case Builtin::KindFloat:
- case Builtin::KindDouble:
- case Builtin::KindObject:
- case Builtin::KindObjectProxy:
- case Builtin::KindLocalObject:
- {
- break;
- }
- }
- }
-
- break;
- }
- case Builtin::KindBool:
- {
- if(newb && (newb->kind() == Builtin::KindBool || newb->kind() == Builtin::KindString))
- {
- return;
- }
-
- break;
- }
- case Builtin::KindShort:
- {
- if(newb)
- {
- switch(newb->kind())
- {
- case Builtin::KindByte:
- case Builtin::KindShort:
- case Builtin::KindInt:
- case Builtin::KindLong:
- case Builtin::KindString:
- {
- return;
- }
- case Builtin::KindBool:
- case Builtin::KindFloat:
- case Builtin::KindDouble:
- case Builtin::KindObject:
- case Builtin::KindObjectProxy:
- case Builtin::KindLocalObject:
- {
- break;
- }
- }
- }
-
- break;
- }
- case Builtin::KindInt:
- {
- if(newb)
- {
- switch(newb->kind())
- {
- case Builtin::KindByte:
- case Builtin::KindShort:
- case Builtin::KindInt:
- case Builtin::KindLong:
- case Builtin::KindString:
- {
- return;
- }
- case Builtin::KindBool:
- case Builtin::KindFloat:
- case Builtin::KindDouble:
- case Builtin::KindObject:
- case Builtin::KindObjectProxy:
- case Builtin::KindLocalObject:
- {
- break;
- }
- }
- }
-
- break;
- }
- case Builtin::KindLong:
- {
- if(newb)
- {
- switch(newb->kind())
- {
- case Builtin::KindByte:
- case Builtin::KindShort:
- case Builtin::KindInt:
- case Builtin::KindLong:
- case Builtin::KindString:
- {
- return;
- }
- case Builtin::KindBool:
- case Builtin::KindFloat:
- case Builtin::KindDouble:
- case Builtin::KindObject:
- case Builtin::KindObjectProxy:
- case Builtin::KindLocalObject:
- {
- break;
- }
- }
- }
-
- break;
- }
- case Builtin::KindFloat:
- {
- if(newb)
- {
- switch(newb->kind())
- {
- case Builtin::KindFloat:
- case Builtin::KindDouble:
- case Builtin::KindString:
- {
- return;
- }
- case Builtin::KindByte:
- case Builtin::KindShort:
- case Builtin::KindInt:
- case Builtin::KindLong:
- case Builtin::KindBool:
- case Builtin::KindObject:
- case Builtin::KindObjectProxy:
- case Builtin::KindLocalObject:
- {
- break;
- }
- }
- }
-
- break;
- }
- case Builtin::KindDouble:
- {
- if(newb)
- {
- switch(newb->kind())
- {
- case Builtin::KindFloat:
- case Builtin::KindDouble:
- case Builtin::KindString:
- {
- return;
- }
- case Builtin::KindByte:
- case Builtin::KindShort:
- case Builtin::KindInt:
- case Builtin::KindLong:
- case Builtin::KindBool:
- case Builtin::KindObject:
- case Builtin::KindObjectProxy:
- case Builtin::KindLocalObject:
- {
- break;
- }
- }
- }
-
- break;
- }
- case Builtin::KindString:
- {
- if(newb)
- {
- switch(newb->kind())
- {
- case Builtin::KindByte:
- case Builtin::KindBool:
- case Builtin::KindShort:
- case Builtin::KindInt:
- case Builtin::KindLong:
- case Builtin::KindFloat:
- case Builtin::KindDouble:
- case Builtin::KindString:
- case Builtin::KindObjectProxy:
- {
- return;
- }
- case Builtin::KindObject:
- case Builtin::KindLocalObject:
- {
- break;
- }
- }
-
- break;
- }
-
- if(EnumPtr::dynamicCast(newType))
- {
- return;
- }
-
- if(ProxyPtr::dynamicCast(newType))
- {
- return;
- }
-
- break;
- }
- case Builtin::KindObject:
- {
- //
- // Allow change from Object to class. Validation has to
- // be done during transformation, when the actual type of
- // an instance can be compared for compatibility with the
- // new type.
- //
- ClassDeclPtr cl = ClassDeclPtr::dynamicCast(newType);
- if(cl || (newb && newb->kind() == Builtin::KindObject))
- {
- return;
- }
-
- break;
- }
- case Builtin::KindObjectProxy:
- {
- ProxyPtr p = ProxyPtr::dynamicCast(newType);
- if(p || (newb && newb->kind() == Builtin::KindObjectProxy) || (newb && newb->kind() == Builtin::KindString))
- {
- return;
- }
-
- break;
- }
- case Builtin::KindLocalObject:
- {
- assert(false);
- break;
- }
- }
-
- typeChange(desc, oldType, newType);
- return;
- }
-
- ClassDeclPtr cl = ClassDeclPtr::dynamicCast(oldType);
- if(cl)
- {
- if(!cl->definition())
- {
- _errors.push_back("class " + cl->scoped() + " declared but not defined");
- return;
- }
-
- //
- // Allow target type of Object.
- //
- BuiltinPtr newb = BuiltinPtr::dynamicCast(newType);
- if(newb && newb->kind() == Builtin::KindObject)
- {
- return;
- }
-
- //
- // Allow target type of struct.
- //
- if(StructPtr::dynamicCast(newType))
- {
- return;
- }
-
- ClassDeclPtr newcl = ClassDeclPtr::dynamicCast(newType);
- if(newcl)
- {
- if(!newcl->definition())
- {
- _errors.push_back("class " + newcl->scoped() + " declared but not defined");
- return;
- }
-
- if(checkClasses(cl, newcl))
- {
- return;
- }
- }
-
- typeChange(desc, oldType, newType);
- return;
- }
-
- StructPtr s = StructPtr::dynamicCast(oldType);
- if(s)
- {
- StructPtr news = StructPtr::dynamicCast(newType);
- if(news && s->scoped() == news->scoped())
- {
- return;
- }
-
- //
- // Allow target type of class.
- //
- if(ClassDeclPtr::dynamicCast(newType))
- {
- return;
- }
-
- typeChange(desc, oldType, newType);
- return;
- }
-
- ProxyPtr proxy = ProxyPtr::dynamicCast(oldType);
- if(proxy)
- {
- //
- // Allow target type of Object* and string.
- //
- BuiltinPtr newb = BuiltinPtr::dynamicCast(newType);
- if(newb && (newb->kind() == Builtin::KindObjectProxy || newb->kind() == Builtin::KindString))
- {
- return;
- }
-
- ProxyPtr newProxy = ProxyPtr::dynamicCast(newType);
- if(newProxy && checkClasses(proxy->_class(), newProxy->_class()))
- {
- return;
- }
-
- typeChange(desc, oldType, newType);
- return;
- }
-
- DictionaryPtr dict = DictionaryPtr::dynamicCast(oldType);
- if(dict)
- {
- DictionaryPtr newDict = DictionaryPtr::dynamicCast(newType);
- if(newDict && dict->scoped() == newDict->scoped())
- {
- return;
- }
-
- typeChange(desc, oldType, newType);
- return;
- }
-
- SequencePtr seq = SequencePtr::dynamicCast(oldType);
- if(seq)
- {
- SequencePtr newSeq = SequencePtr::dynamicCast(newType);
- if(newSeq && seq->scoped() == newSeq->scoped())
- {
- return;
- }
-
- typeChange(desc, oldType, newType);
- return;
- }
-
- EnumPtr en = EnumPtr::dynamicCast(oldType);
- if(en)
- {
- EnumPtr newen = EnumPtr::dynamicCast(newType);
- BuiltinPtr newb = BuiltinPtr::dynamicCast(newType);
- if((newen && en->scoped() == newen->scoped()) || (newb && newb->kind() == Builtin::KindString))
- {
- return;
- }
-
- typeChange(desc, oldType, newType);
- return;
- }
-
- assert(false);
-}
-
-void
-FreezeScript::AnalyzeTransformVisitor::typeChange(const string& desc, const TypePtr& t1, const TypePtr& t2)
-{
- BuiltinPtr b1 = BuiltinPtr::dynamicCast(t1);
- BuiltinPtr b2 = BuiltinPtr::dynamicCast(t2);
- ContainedPtr c1 = ContainedPtr::dynamicCast(t1);
- ContainedPtr c2 = ContainedPtr::dynamicCast(t2);
- ProxyPtr p1 = ProxyPtr::dynamicCast(t1);
- ProxyPtr p2 = ProxyPtr::dynamicCast(t2);
-
- if(_ignoreTypeChanges)
- {
- _out.newline();
- _out << "<!-- NOTICE: " << desc << " has changed from ";
- if(b1)
- {
- _out << b1->kindAsString();
- }
- else if(p1)
- {
- _out << p1->_class()->scoped() << '*';
- }
- else
- {
- assert(c1);
- _out << c1->kindOf() << ' ' << c1->scoped();
- }
- _out << " to ";
- if(b2)
- {
- _out << b2->kindAsString();
- }
- else if(p2)
- {
- _out << p2->_class()->scoped() << '*';
- }
- else
- {
- assert(c2);
- _out << c2->kindOf() << ' ' << c2->scoped();
- }
- _out << " -->";
- }
- else
- {
- ostringstream ostr;
- ostr << "unsupported type change in " << desc << " from ";
- if(b1)
- {
- ostr << b1->kindAsString();
- }
- else if(p1)
- {
- ostr << p1->_class()->scoped() << '*';
- }
- else
- {
- assert(c1);
- ostr << c1->kindOf() << ' ' << c1->scoped();
- }
- ostr << " to ";
- if(b2)
- {
- ostr << b2->kindAsString();
- }
- else if(p2)
- {
- ostr << p2->_class()->scoped() << '*';
- }
- else
- {
- assert(c2);
- ostr << c2->kindOf() << ' ' << c2->scoped();
- }
- _errors.push_back(ostr.str());
- }
-}
-
-bool
-FreezeScript::AnalyzeTransformVisitor::checkClasses(const ClassDeclPtr& from, const ClassDeclPtr& to)
-{
- string fromScoped = from->scoped();
- string toScoped = to->scoped();
-
- if(fromScoped == toScoped)
- {
- return true;
- }
-
- //
- // The types don't match, so check them for compatibility. Specifically,
- // look up the old type id in the new Slice and see if it has the target
- // type as a base class.
- //
- TypeList l = to->unit()->lookupTypeNoBuiltin(from->scoped(), false);
- if(!l.empty())
- {
- ClassDeclPtr decl = ClassDeclPtr::dynamicCast(l.front());
- if(decl)
- {
- ClassDefPtr def = decl->definition();
- if(def)
- {
- ClassList bases = def->allBases();
- for(ClassList::iterator p = bases.begin(); p != bases.end(); ++p)
- {
- if((*p)->scoped() == toScoped)
- {
- return true;
- }
- }
- }
- }
- }
-
- return false;
-}
-
-////////////////////////////////////
-// InitVisitor
-////////////////////////////////////
-
-FreezeScript::AnalyzeInitVisitor::AnalyzeInitVisitor(XMLOutput& out, const UnitPtr& oldUnit) :
- _out(out), _oldUnit(oldUnit)
-{
-}
-
-bool
-FreezeScript::AnalyzeInitVisitor::visitClassDefStart(const ClassDefPtr& v)
-{
- if(v->isInterface() || v->isLocal())
- {
- return false;
- }
-
- string scoped = v->scoped();
- TypeList l = _oldUnit->lookupTypeNoBuiltin(scoped, false);
- if(!l.empty())
- {
- ClassDeclPtr decl = ClassDeclPtr::dynamicCast(l.front());
- if(!decl || decl->isInterface())
- {
- typeChange(l.front(), scoped, "class");
- }
- else
- {
- return false;
- }
- }
-
- _out.newline();
- _out.newline();
- _out << "<!-- class " << scoped << " -->";
- _out << se("init") << attr("type", scoped);
- _out << ee;
-
- return false;
-}
-
-bool
-FreezeScript::AnalyzeInitVisitor::visitStructStart(const StructPtr& v)
-{
- if(v->isLocal())
- {
- return false;
- }
-
- string scoped = v->scoped();
- TypeList l = _oldUnit->lookupTypeNoBuiltin(scoped, false);
- if(!l.empty())
- {
- StructPtr s = StructPtr::dynamicCast(l.front());
- if(!s)
- {
- typeChange(l.front(), scoped, "struct");
- }
- else
- {
- return false;
- }
- }
-
- _out.newline();
- _out.newline();
- _out << "<!-- struct " << scoped << " -->";
- _out << se("init") << attr("type", scoped);
- _out << ee;
-
- return false;
-}
-
-void
-FreezeScript::AnalyzeInitVisitor::visitSequence(const SequencePtr& v)
-{
- if(v->isLocal())
- {
- return;
- }
-
- string scoped = v->scoped();
- TypeList l = _oldUnit->lookupTypeNoBuiltin(scoped, false);
- if(!l.empty())
- {
- SequencePtr s = SequencePtr::dynamicCast(l.front());
- if(!s)
- {
- typeChange(l.front(), scoped, "sequence");
- }
- else
- {
- return;
- }
- }
-
- _out.newline();
- _out.newline();
- _out << "<!-- sequence " << scoped << " -->";
- _out << se("init") << attr("type", scoped);
- _out << ee;
-}
-
-void
-FreezeScript::AnalyzeInitVisitor::visitDictionary(const DictionaryPtr& v)
-{
- if(v->isLocal())
- {
- return;
- }
-
- string scoped = v->scoped();
- TypeList l = _oldUnit->lookupTypeNoBuiltin(scoped, false);
- if(!l.empty())
- {
- DictionaryPtr d = DictionaryPtr::dynamicCast(l.front());
- if(!d)
- {
- typeChange(l.front(), scoped, "dictionary");
- }
- else
- {
- return;
- }
- }
-
- _out.newline();
- _out.newline();
- _out << "<!-- dictionary " << scoped << " -->";
- _out << se("init") << attr("type", scoped);
- _out << ee;
-}
-
-void
-FreezeScript::AnalyzeInitVisitor::visitEnum(const EnumPtr& v)
-{
- if(v->isLocal())
- {
- return;
- }
-
- string scoped = v->scoped();
- TypeList l = _oldUnit->lookupTypeNoBuiltin(scoped, false);
- if(!l.empty())
- {
- EnumPtr e = EnumPtr::dynamicCast(l.front());
- if(!e)
- {
- typeChange(l.front(), scoped, "enum");
- }
- else
- {
- return;
- }
- }
-
- _out.newline();
- _out.newline();
- _out << "<!-- enum " << scoped << " -->";
- _out << se("init") << attr("type", scoped);
- _out << ee;
-}
-
-
-void
-FreezeScript::AnalyzeInitVisitor::typeChange(const TypePtr& t, const string& scoped, const string& kind)
-{
- BuiltinPtr b = BuiltinPtr::dynamicCast(t);
- ContainedPtr c = ContainedPtr::dynamicCast(t);
- ProxyPtr p = ProxyPtr::dynamicCast(t);
-
- _out.newline();
- _out.newline();
- _out << "<!-- NOTICE: " << scoped << " has changed from ";
- if(b)
- {
- _out << b->kindAsString();
- }
- else if(p)
- {
- _out << "proxy";
- }
- else
- {
- assert(c);
- _out << c->kindOf();
- }
- _out << " to " << kind << " -->";
-}
-
-FreezeScript::TransformAnalyzer::TransformAnalyzer(const UnitPtr& oldUnit, const UnitPtr& newUnit,
- bool ignoreTypeChanges, ostream& os, vector<string>& missingTypes,
- vector<string>& errors) :
- _old(oldUnit), _new(newUnit), _out(os),
- _visitor(new AnalyzeTransformVisitor(_out, newUnit, ignoreTypeChanges, missingTypes, errors))
-{
- _out << se("transformdb");
-}
-
-FreezeScript::TransformAnalyzer::~TransformAnalyzer()
-{
- delete _visitor;
-}
-
-void
-FreezeScript::TransformAnalyzer::addDatabase(const string& name, const TypePtr& oldKey, const TypePtr& newKey,
- const TypePtr& oldValue, const TypePtr& newValue)
-{
- _visitor->addDatabase(name, oldKey, newKey, oldValue, newValue);
-}
-
-void
-FreezeScript::TransformAnalyzer::finish()
-{
- _old->visit(_visitor, false);
-
- AnalyzeInitVisitor initVisitor(_out, _old);
- _new->visit(&initVisitor, false);
-
- _out << ee;
- _out << '\n';
-}