You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

78 lines
2.8 KiB

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.CodeAnalysis;
namespace gaemstone.SourceGen.Structure;
public abstract class BaseEntityInfo : BaseInfo
{
public new TypeEntityInfo? Parent { get => (TypeEntityInfo?)base.Parent; set => base.Parent = value; }
public string? Path { get; }
// TODO: Rename this to something sensible, like [Symbol].
// public bool IsPublic { get; private set; }
// private bool IsPrivate { get; }
public List<INamedTypeSymbol> EntitiesToAdd { get; } = new();
public List<(INamedTypeSymbol, INamedTypeSymbol)> RelationsToAdd { get; } = new();
public bool HasEntitiesToAdd => (EntitiesToAdd.Count > 0) || (RelationsToAdd.Count > 0);
public BaseEntityInfo(ISymbol symbol)
: base(symbol)
{
Path = Get("Path")?.ConstructorArguments.FirstOrDefault().Value as string;
// IsPublic = Symbol.HasAttribute("gaemstone.ECS.PublicAttribute");
// IsPrivate = Symbol.HasAttribute("gaemstone.ECS.PrivateAttribute");
}
protected override IEnumerable<Diagnostic> ValidateSelf()
{
if (this is ModuleEntityInfo) {
// If this entity is a module, it must not be nested.
if (Symbol.ContainingType != null) yield return Diagnostic.Create(
Descriptors.ModuleMustNotBeNested, Location);
} else {
// Otherwise, it must occur within a module
if (Parent is not ModuleEntityInfo) yield return Diagnostic.Create(
Descriptors.EntityMustBeInModule, Location);
}
// var moduleIsPublic = (Parent?.IsPublic == true);
// var inheritsPublic = (this is MethodEntityInfo); // Observers and systems don't inherit [Public] from their module.
// IsPublic = IsPublic || (moduleIsPublic && inheritsPublic && !IsPrivate);
// Add entities and relationships specified using [Add<...>] attributes.
foreach (var attr in Symbol.GetAttributes()) {
for (var attrType = attr.AttributeClass; attrType != null; attrType = attrType.BaseType) {
if (RelevantSymbolReceiver.ToRelevantAttributeName(attrType) != "Add") continue;
var allTypeArgumentsValid = true;
for (var i = 0; i < attrType.TypeArguments.Length; i++) {
var arg = attrType.TypeArguments[i];
var param = attrType.TypeParameters[i];
if (arg is not INamedTypeSymbol) {
yield return Diagnostic.Create(
Descriptors.InvalidTypeArgument, param.Locations.Single());
allTypeArgumentsValid = false;
}
// TODO: Make sure entities being added have appropriate attributes as well.
}
if (allTypeArgumentsValid) {
switch (attrType.TypeArguments) {
case [ INamedTypeSymbol entity ]:
EntitiesToAdd.Add(entity);
break;
case [ INamedTypeSymbol relation, INamedTypeSymbol target ]:
RelationsToAdd.Add((relation, target));
break;
default: throw new InvalidOperationException(
"Type argument pattern matching failed");
}
}
}
}
}
}