Fix categorization of generated vs. non-generated nodes.

This commit is contained in:
Kuba Ober 2019-08-30 11:16:02 -04:00
parent c296c0f63a
commit 024ecbbced
7 changed files with 40 additions and 28 deletions

View File

@ -5,6 +5,7 @@ namespace CapnpC.Model
class Annotation : IDefinition class Annotation : IDefinition
{ {
public ulong Id { get; } public ulong Id { get; }
public bool IsGenerated { get; }
public TypeTag Tag { get => TypeTag.Annotation; } public TypeTag Tag { get => TypeTag.Annotation; }
public IHasNestedDefinitions DeclaringElement { get; } public IHasNestedDefinitions DeclaringElement { get; }
@ -14,6 +15,7 @@ namespace CapnpC.Model
{ {
Trace.Assert(parent != null); Trace.Assert(parent != null);
Id = id; Id = id;
IsGenerated = (parent as IDefinition).IsGenerated;
DeclaringElement = parent; DeclaringElement = parent;
parent.NestedDefinitions.Add(this); parent.NestedDefinitions.Add(this);
} }

View File

@ -5,6 +5,7 @@ namespace CapnpC.Model
class Constant : IDefinition class Constant : IDefinition
{ {
public ulong Id { get; } public ulong Id { get; }
public bool IsGenerated { get; }
public TypeTag Tag { get => TypeTag.Const; } public TypeTag Tag { get => TypeTag.Const; }
public IHasNestedDefinitions DeclaringElement { get; } public IHasNestedDefinitions DeclaringElement { get; }
@ -14,6 +15,7 @@ namespace CapnpC.Model
{ {
Trace.Assert(parent != null); Trace.Assert(parent != null);
Id = id; Id = id;
IsGenerated = (parent as IDefinition).IsGenerated;
DeclaringElement = parent; DeclaringElement = parent;
parent.NestedDefinitions.Add(this); parent.NestedDefinitions.Add(this);
} }

View File

@ -8,8 +8,8 @@ namespace CapnpC.Model
{ {
readonly Dictionary<ulong, IDefinition> _id2def = new Dictionary<ulong, IDefinition>(); readonly Dictionary<ulong, IDefinition> _id2def = new Dictionary<ulong, IDefinition>();
public GenFile CreateFile(ulong id) public GenFile CreateFile(ulong id, bool isGenerated)
=> CreateId<GenFile>(id, () => new GenFile(id)); => CreateId<GenFile>(id, () => new GenFile(id, isGenerated));
public GenFile GetExistingFile(ulong id) public GenFile GetExistingFile(ulong id)
=> GetId<GenFile>(id, TypeTag.File); => GetId<GenFile>(id, TypeTag.File);

View File

@ -5,6 +5,7 @@ namespace CapnpC.Model
class GenFile: IDefinition, IHasNestedDefinitions class GenFile: IDefinition, IHasNestedDefinitions
{ {
public ulong Id { get; } public ulong Id { get; }
public bool IsGenerated { get; }
public TypeTag Tag { get => TypeTag.File; } public TypeTag Tag { get => TypeTag.File; }
public IHasNestedDefinitions DeclaringElement { get => null; } public IHasNestedDefinitions DeclaringElement { get => null; }
@ -15,9 +16,10 @@ namespace CapnpC.Model
public ICollection<IDefinition> NestedDefinitions { get; } = new List<IDefinition>(); public ICollection<IDefinition> NestedDefinitions { get; } = new List<IDefinition>();
public ICollection<Constant> Constants { get; } = new List<Constant>(); public ICollection<Constant> Constants { get; } = new List<Constant>();
public GenFile(ulong id) public GenFile(ulong id, bool isGenerated)
{ {
Id = id; Id = id;
IsGenerated = isGenerated;
} }
} }
} }

View File

@ -4,6 +4,7 @@ namespace CapnpC.Model
interface IDefinition interface IDefinition
{ {
ulong Id { get; } ulong Id { get; }
bool IsGenerated { get; }
TypeTag Tag { get; } TypeTag Tag { get; }
IHasNestedDefinitions DeclaringElement { get; } IHasNestedDefinitions DeclaringElement { get; }
} }

View File

@ -61,7 +61,6 @@ namespace CapnpC.Model
struct Pass1State struct Pass1State
{ {
public HashSet<ulong> unprocessedNodes; public HashSet<ulong> unprocessedNodes;
public bool isGenerated;
public IHasNestedDefinitions parent; public IHasNestedDefinitions parent;
} }
@ -74,17 +73,11 @@ namespace CapnpC.Model
foreach (var node in _id2node.Values.Where(n => n.IsFile)) foreach (var node in _id2node.Values.Where(n => n.IsFile))
{ {
GenFile file; GenFile file;
state.isGenerated = requestedFiles.TryGetValue(node.Id, out var req); bool isGenerated = requestedFiles.TryGetValue(node.Id, out var req);
state.parent = null; var filename = isGenerated ? req.Filename : node.DisplayName;
if (state.isGenerated) file = ProcessFilePass1(node.Id, filename, state, isGenerated);
{ if (isGenerated)
file = (GenFile)ProcessNodePass1(node.Id, req.Filename, state);
_generatedFiles.Add(file); _generatedFiles.Add(file);
}
else
{
file = (GenFile)ProcessNodePass1(node.Id, node.DisplayName, state);
}
} }
if (state.unprocessedNodes.Count != 0) if (state.unprocessedNodes.Count != 0)
{ {
@ -92,9 +85,20 @@ namespace CapnpC.Model
} }
} }
GenFile ProcessFilePass1(ulong id, string name, Pass1State state, bool isGenerated)
{
var file = _typeDefMgr.CreateFile(id, isGenerated);
var node = IdToNode(id);
state.parent = null;
file.Namespace = GetNamespaceAnnotation(node);
file.Name = name;
return ProcessNodePass1(id, name, state) as GenFile;
}
IDefinition ProcessNodePass1(ulong id, string name, Pass1State state) IDefinition ProcessNodePass1(ulong id, string name, Pass1State state)
{ {
if (!(IdToNode(id, state.isGenerated) is Schema.Node.Reader node)) bool mustExist = state.parent == null || (state.parent as IDefinition).IsGenerated;
if (!(IdToNode(id, mustExist) is Schema.Node.Reader node))
return null; return null;
if (!state.unprocessedNodes.Remove(id)) if (!state.unprocessedNodes.Remove(id))
return null; return null;
@ -112,10 +116,11 @@ namespace CapnpC.Model
return _typeDefMgr.CreateConstant(id, state.parent); return _typeDefMgr.CreateConstant(id, state.parent);
case NodeKind.File: case NodeKind.File:
if (state.parent != null) if (state.parent != null)
throw new InvalidSchemaException("Did not expect file nodes to appear as nested nodes"); throw new InvalidSchemaException($"Did not expect a file node {node.StrId()} to be a nested node.");
var file = _typeDefMgr.CreateFile(id); var file = _typeDefMgr.GetExistingFile(id);
file.Namespace = GetNamespaceAnnotation(node); file.Namespace = GetNamespaceAnnotation(node);
file.Name = name; file.Name = name;
state.parent = file;
def = file; def = file;
processNestedNodes = true; processNestedNodes = true;
break; break;
@ -140,9 +145,9 @@ namespace CapnpC.Model
Trace.Assert(state.parent != null, $"The {node.GetTypeTag().ToString()} node {node.StrId()} was expected to have a parent."); Trace.Assert(state.parent != null, $"The {node.GetTypeTag().ToString()} node {node.StrId()} was expected to have a parent.");
var typeDef = _typeDefMgr.CreateTypeDef(id, node.GetTypeTag(), state.parent); var typeDef = _typeDefMgr.CreateTypeDef(id, node.GetTypeTag(), state.parent);
typeDef.Name = name; typeDef.Name = name;
state.parent = typeDef;
def = typeDef; def = typeDef;
} }
state.parent = def as IHasNestedDefinitions;
if (processNestedNodes && node.NestedNodes != null) if (processNestedNodes && node.NestedNodes != null)
foreach (var nested in node.NestedNodes) foreach (var nested in node.NestedNodes)
@ -187,7 +192,6 @@ namespace CapnpC.Model
struct Pass2State struct Pass2State
{ {
public Method currentMethod; public Method currentMethod;
public bool isGenerated;
public HashSet<ulong> processedNodes; public HashSet<ulong> processedNodes;
} }
@ -197,16 +201,15 @@ namespace CapnpC.Model
foreach (var file in _typeDefMgr.Files) foreach (var file in _typeDefMgr.Files)
{ {
var node = IdToNode(file.Id); var node = IdToNode(file.Id);
state.isGenerated = requestedFiles.ContainsKey(file.Id); ProcessNestedNodes(node.NestedNodes, state, file.IsGenerated);
ProcessNestedNodes(node.NestedNodes, state);
} }
} }
void ProcessNestedNodes(IEnumerable<Schema.Node.NestedNode.Reader> nestedNodes, Pass2State state) void ProcessNestedNodes(IEnumerable<Schema.Node.NestedNode.Reader> nestedNodes, Pass2State state, bool mustExist)
{ {
foreach (var nestedNode in nestedNodes) foreach (var nestedNode in nestedNodes)
{ {
ProcessNode(nestedNode.Id, state); ProcessNode(nestedNode.Id, state, mustExist);
} }
} }
@ -534,7 +537,7 @@ namespace CapnpC.Model
} }
} }
ProcessNestedNodes(reader.NestedNodes, state); ProcessNestedNodes(reader.NestedNodes, state, def.File.IsGenerated);
ProcessFields(reader, def, def.Fields, state); ProcessFields(reader, def, def.Fields, state);
@ -683,7 +686,7 @@ namespace CapnpC.Model
TypeDefinition ProcessTypeDef(ulong id, Pass2State state, TypeTag tag = default) TypeDefinition ProcessTypeDef(ulong id, Pass2State state, TypeTag tag = default)
{ {
var def = ProcessNode(id, state, tag); var def = ProcessNode(id, state, true, tag);
var typeDef = def as TypeDefinition; var typeDef = def as TypeDefinition;
if (def == null) if (def == null)
throw new ArgumentException( throw new ArgumentException(
@ -692,9 +695,9 @@ namespace CapnpC.Model
return typeDef; return typeDef;
} }
IDefinition ProcessNode(ulong id, Pass2State state, TypeTag tag = default) IDefinition ProcessNode(ulong id, Pass2State state, bool mustExist, TypeTag tag = default)
{ {
if (!(IdToNode(id, state.isGenerated) is Schema.Node.Reader node)) return null; if (!(IdToNode(id, mustExist) is Schema.Node.Reader node)) return null;
var kind = node.GetKind(); var kind = node.GetKind();
if (tag == TypeTag.Unknown) tag = kind.GetTypeTag(); if (tag == TypeTag.Unknown) tag = kind.GetTypeTag();
var def = _typeDefMgr.GetExistingDef(id, tag); var def = _typeDefMgr.GetExistingDef(id, tag);

View File

@ -22,6 +22,7 @@ namespace CapnpC.Model
Trace.Assert(parent != null); Trace.Assert(parent != null);
Tag = tag; Tag = tag;
Id = id; Id = id;
IsGenerated = (parent as IDefinition).IsGenerated;
DeclaringElement = parent; DeclaringElement = parent;
if (tag == TypeTag.Group) if (tag == TypeTag.Group)
((TypeDefinition)parent).NestedGroups.Add(this); ((TypeDefinition)parent).NestedGroups.Add(this);
@ -30,6 +31,7 @@ namespace CapnpC.Model
} }
public ulong Id { get; } public ulong Id { get; }
public bool IsGenerated { get; }
public IHasNestedDefinitions DeclaringElement { get; } public IHasNestedDefinitions DeclaringElement { get; }
public Method UsingMethod { get; set; } public Method UsingMethod { get; set; }