private void CalculateReachableSerializedObjects(object obj, HashSet<object> reachableObjects)
{
if (obj == null || !reachableObjects.Add(obj))
return;
CalculateReachableSerializedObjects(obj.GetType(), reachableObjects);
if (obj is bool || obj is string)
{
// nothing more to do
return;
}
else
{
IToken token = obj as IToken;
if (token != null)
{
// nothing else to do
return;
}
Type type = obj as Type;
if (type != null)
{
// nothing else to do
return;
}
if (obj.GetType() == typeof(CompiledTemplate))
{
CompiledTemplate compiledTemplate = (CompiledTemplate)obj;
CalculateReachableSerializedObjects(compiledTemplate.NativeGroup, reachableObjects);
CalculateReachableSerializedObjects(compiledTemplate.TemplateDefStartToken, reachableObjects);
if (compiledTemplate.FormalArguments != null)
{
foreach (var argument in compiledTemplate.FormalArguments)
CalculateReachableSerializedObjects(argument, reachableObjects);
}
if (compiledTemplate.ImplicitlyDefinedTemplates != null)
{
foreach (var template in compiledTemplate.ImplicitlyDefinedTemplates)
CalculateReachableSerializedObjects(template, reachableObjects);
}
}
else if (obj.GetType() == typeof(FormalArgument))
{
FormalArgument formalArgument = (FormalArgument)obj;
CalculateReachableSerializedObjects(formalArgument.DefaultValueToken, reachableObjects);
CalculateReachableSerializedObjects(formalArgument.DefaultValue, reachableObjects);
CalculateReachableSerializedObjects(formalArgument.CompiledDefaultValue, reachableObjects);
}
else if (obj.GetType() == typeof(Template))
{
Template template = (Template)obj;
CalculateReachableSerializedObjects(template.impl, reachableObjects);
if (template.locals != null)
{
foreach (var local in template.locals)
CalculateReachableSerializedObjects(local, reachableObjects);
}
CalculateReachableSerializedObjects(template.Group, reachableObjects);
}
else if (obj.GetType() == typeof(TemplateGroupFile) || obj == TemplateGroup.DefaultGroup)
{
// these are the only supported groups for now
if (obj != this && obj != TemplateGroup.DefaultGroup)
throw new NotSupportedException();
return;
}
else
{
throw new NotImplementedException();
}
}
}