public bool ResolveBaseClass(
            StatTypeDefinition definition, StatDeclaration declaration,
            Dictionary <string, StatDeclaration> declarations,
            out StatDeclaration baseClassDeclaration)
        {
            var props = declaration.Properties;
            var name  = (string)props[definition.NameProperty];

            if (definition.BaseClassProperty != null && props.ContainsKey(definition.BaseClassProperty))
            {
                var baseClass = (string)props[definition.BaseClassProperty];

                if (declarations.TryGetValue(baseClass, out StatDeclaration baseDeclaration))
                {
                    baseClassDeclaration = baseDeclaration;
                    return(true);
                }
                else
                {
                    Context.LogError(DiagnosticCode.StatBaseClassNotKnown, $"Stat declaration '{name}' references nonexistent base class '{baseClass}'",
                                     declaration.Location.FileName, declaration.Location.StartLine, name);
                    baseClassDeclaration = null;
                    return(false);
                }
            }

            baseClassDeclaration = null;
            return(true);
        }
 private void PropagateInheritedProperties(StatDeclaration parent, StatDeclaration descendant)
 {
     foreach (var prop in parent.Properties)
     {
         if (!descendant.Properties.ContainsKey(prop.Key))
         {
             descendant.Properties[prop.Key]        = prop.Value;
             descendant.PropertyLocations[prop.Key] = parent.PropertyLocations[prop.Key];
         }
     }
 }
 private StatEntity InstantiateEntity(StatSubtypeDefinition subtype, string declarationName, StatDeclaration declaration)
 {
     return(InstantiateEntityInternal(subtype, declarationName, declaration.Location,
                                      declaration.Properties, declaration.PropertyLocations));
 }
        private StatSubtypeDefinition FindSubtype(StatTypeDefinition type, string declarationName, StatDeclaration declaration)
        {
            if (type.SubtypeProperty == null)
            {
                return(type.Subtypes.Values.First());
            }

            if (declaration.Properties.TryGetValue(type.SubtypeProperty, out object subtypeName))
            {
                var name = (string)subtypeName;
                if (type.Subtypes.TryGetValue(name, out StatSubtypeDefinition subtype))
                {
                    return(subtype);
                }
                else
                {
                    Context.LogError(DiagnosticCode.StatSubtypeMissing, $"Stat declaration '{declarationName}' references unknown subtype '{name}'",
                                     declaration.Location.FileName, declaration.Location.StartLine);
                    return(null);
                }
            }
            else
            {
                Context.LogError(DiagnosticCode.StatSubtypeMissing, $"Stat declaration '{declarationName}' is missing subtype property '{type.SubtypeProperty}'",
                                 declaration.Location.FileName, declaration.Location.StartLine);
                return(null);
            }
        }