diff --git a/M6502/M6502.Symbols/IdentifiableSection.cs b/M6502/M6502.Symbols/IdentifiableSection.cs index c8f3d46..0dad750 100644 --- a/M6502/M6502.Symbols/IdentifiableSection.cs +++ b/M6502/M6502.Symbols/IdentifiableSection.cs @@ -45,6 +45,18 @@ return available; } + protected bool MaybeExtractCompoundInteger(string key, out List value) + { + var available = this.MaybeExtractFromParsed(key, out var extracted); + if (!available) + { + value = []; + return false; + } + value = ExtractCompoundInteger(extracted); + return available; + } + private void SetProperty(string name, object obj) { var type = this.GetType(); @@ -54,6 +66,12 @@ } public void ExtractReferences() + { + this.ExtractReferenceProperties(); + this.ExtractReferencesProperties(); + } + + private void ExtractReferenceProperties() { foreach (var (entryName, connection) in this.SectionProperties.ReferenceAttributes) { @@ -61,12 +79,12 @@ if (hasID) { var (name, type, _) = connection; - this.ExtractReference(id, name, type); + this.ExtractReferenceProperty(id, name, type); } } } - private void ExtractReference(int id, string name, System.Type type) + private void ExtractReferenceProperty(int id, string name, System.Type type) { // The reference container in the parent class var referenceSectionProperties = GetSectionProperties(type); @@ -90,6 +108,45 @@ Debug.Assert(referencingObject != null); this.SetProperty(name, referencingObject); } + + private void ExtractReferencesProperties() + { + foreach (var (entryName, connection) in this.SectionProperties.ReferencesAttributes) + { + // this'll be a set of ids + var hasIDs = this.MaybeExtractCompoundInteger(entryName, out var ids); + if (hasIDs) + { + var (name, type, _) = connection; + this.ExtractReferencesProperty(ids, name, type); + } + } + } + + private void ExtractReferencesProperty(List ids, string name, System.Type type) + { + // The reference container in the parent class + //var referenceSectionProperties = GetSectionProperties(type); + //var referenceClassAttribute = referenceSectionProperties.ClassAttribute; + //Debug.Assert(referenceClassAttribute != null); + //var referencingContainer = referenceClassAttribute.Referencing; + + // Get the parent container field + //var containerType = this._container.GetType(); + //Debug.Assert(referencingContainer != null); + //var containerField = containerType.GetField(referencingContainer); + //Debug.Assert(containerField != null); + //var fieldValue = containerField.GetValue(this._container); + //var fieldList = fieldValue as IList; + + // Now get the referenced object from the parent container field (via ID as an index) + //Debug.Assert(fieldList != null); + //var referencingObject = fieldList[id]; + + //// Now set our reference field + //Debug.Assert(referencingObject != null); + //this.SetProperty(name, referencingObject); + } } } } diff --git a/M6502/M6502.Symbols/Parser.cs b/M6502/M6502.Symbols/Parser.cs index 459c80d..dd62ee9 100644 --- a/M6502/M6502.Symbols/Parser.cs +++ b/M6502/M6502.Symbols/Parser.cs @@ -375,12 +375,9 @@ { if (!this.Parsed.TryGetValue(key, out var section)) { - this.Parsed[key] = []; - section = this.Parsed[key]; + this.Parsed.Add(key, section = []); } - - var dictionary = BuildDictionary(parts); - section.Add(dictionary); + section.Add(BuildDictionary(parts)); } private static Dictionary BuildDictionary(string[] parts) @@ -396,7 +393,7 @@ var key = definition[0]; var value = definition[1]; - dictionary[key] = value; + dictionary.Add(key, value); } return dictionary; diff --git a/M6502/M6502.Symbols/ReflectedSectionProperties.cs b/M6502/M6502.Symbols/ReflectedSectionProperties.cs index ebe3553..7f5dcb3 100644 --- a/M6502/M6502.Symbols/ReflectedSectionProperties.cs +++ b/M6502/M6502.Symbols/ReflectedSectionProperties.cs @@ -22,7 +22,7 @@ public Dictionary Properties { get; } = []; - internal SectionAttribute? ClassAttribute { get; } + internal SectionAttribute? ClassAttribute { get; private set; } internal Dictionary> Attributes { get; } = []; @@ -30,7 +30,11 @@ internal Dictionary> ReferencesAttributes { get; } = []; - public ReflectedSectionProperties(System.Type type) + //public ReflectedSectionProperties() + //{ + //} + + public void Build(System.Type type) { var sectionAttributes = type.GetCustomAttributes(typeof(SectionAttribute), true); Debug.Assert(sectionAttributes != null, "No section attributes available"); @@ -93,8 +97,7 @@ if (attributes.Length > 0) { Debug.Assert(attributes.Length == 1, "Too many section property attributes"); - var succeeded = this.Properties.TryAdd(property.Name, property); - Debug.Assert(succeeded, $"Unable to add property lookup {property.Name}"); + this.Properties.Add(property.Name, property); this.ProcessSectionPropertyAttribute(property.PropertyType, property.Name, attributes[0]); } } @@ -157,22 +160,17 @@ { var key = attribute.Key; - if (!_entriesToProperties.TryAdd(key, name)) - { - throw new InvalidOperationException($"Entry {key} from attribute has already been added"); - } + this._entriesToProperties.Add(key, name); this.Attributes.Add(key, new Tuple(name, originalType, attribute)); Debug.Assert(this.Attributes.Count == this.Properties.Count); if (attribute is SectionReferenceAttribute referenceAttribute) { - var success = this.ReferenceAttributes.TryAdd(key, new Tuple(name, originalType, referenceAttribute)); - Debug.Assert(success); + this.ReferenceAttributes.Add(key, new Tuple(name, originalType, referenceAttribute)); } else if (attribute is SectionReferencesAttribute referencesAttribute) { - var success = this.ReferencesAttributes.TryAdd(key, new Tuple(name, originalType, referencesAttribute)); - Debug.Assert(success); + this.ReferencesAttributes.Add(key, new Tuple(name, originalType, referencesAttribute)); } var multiples = attribute.Many; diff --git a/M6502/M6502.Symbols/Section.cs b/M6502/M6502.Symbols/Section.cs index fec0cca..9949ce5 100644 --- a/M6502/M6502.Symbols/Section.cs +++ b/M6502/M6502.Symbols/Section.cs @@ -38,10 +38,11 @@ protected void ProcessAttributesOfProperties() { var type = this.GetType(); + var entry = new ReflectedSectionProperties(); Debug.Assert(_sectionPropertiesCache != null); - if (!_sectionPropertiesCache.ContainsKey(type)) + if (_sectionPropertiesCache.TryAdd(type, entry)) { - _sectionPropertiesCache.Add(type, new ReflectedSectionProperties(type)); + entry.Build(type); } } @@ -82,15 +83,15 @@ { if (reference) { - this._references[key] = ExtractInteger(value); + this._references.Add(key, ExtractInteger(value)); } else if (references) { - this._multipleReferences[key] = ExtractCompoundInteger(value); + this._multipleReferences.Add(key, ExtractCompoundInteger(value)); } else { - throw new InvalidOperationException("Getting here should be impossible! Lazy, but not a reference"); + throw new InvalidOperationException($"Getting here should be impossible! Key {key} is lazy, but not a reference"); } return; }