Files
Flee/ExpressionElements/MemberElements/InvocationList.cs

122 lines
3.8 KiB
C#

using System;
using System.Collections;
using Flee.ExpressionElements.Base;
using Flee.InternalTypes;
using Flee.PublicTypes;
using Flee.Resources;
namespace Flee.ExpressionElements.MemberElements
{
internal class InvocationListElement : ExpressionElement
{
private readonly MemberElement _myTail;
public InvocationListElement(IList elements, IServiceProvider services)
{
this.HandleFirstElement(elements, services);
LinkElements(elements);
Resolve(elements, services);
_myTail = (MemberElement)elements[elements.Count - 1];
}
/// <summary>
/// Arrange elements as a linked list
/// </summary>
/// <param name="elements"></param>
private static void LinkElements(IList elements)
{
for (int i = 0; i <= elements.Count - 1; i++)
{
MemberElement current = (MemberElement)elements[i];
MemberElement nextElement = null;
if (i + 1 < elements.Count)
{
nextElement = (MemberElement)elements[i + 1];
}
current.Link(nextElement);
}
}
private void HandleFirstElement(IList elements, IServiceProvider services)
{
ExpressionElement first = (ExpressionElement)elements[0];
// If the first element is not a member element, then we assume it is an expression and replace it with the correct member element
if (!(first is MemberElement))
{
ExpressionMemberElement actualFirst = new ExpressionMemberElement(first);
elements[0] = actualFirst;
}
else
{
this.ResolveNamespaces(elements, services);
}
}
private void ResolveNamespaces(IList elements, IServiceProvider services)
{
ExpressionContext context = (ExpressionContext)services.GetService(typeof(ExpressionContext));
ImportBase currentImport = context.Imports.RootImport;
while (true)
{
string name = GetName(elements);
if (name == null)
{
break; // TODO: might not be correct. Was : Exit While
}
ImportBase import = currentImport.FindImport(name);
if (import == null)
{
break; // TODO: might not be correct. Was : Exit While
}
currentImport = import;
elements.RemoveAt(0);
if (elements.Count > 0)
{
MemberElement newFirst = (MemberElement)elements[0];
newFirst.SetImport(currentImport);
}
}
if (elements.Count == 0)
{
base.ThrowCompileException(CompileErrorResourceKeys.NamespaceCannotBeUsedAsType, CompileExceptionReason.TypeMismatch, currentImport.Name);
}
}
private static string GetName(IList elements)
{
if (elements.Count == 0)
{
return null;
}
// Is the first member a field/property element?
var fpe = elements[0] as IdentifierElement;
return fpe?.MemberName;
}
private static void Resolve(IList elements, IServiceProvider services)
{
foreach (MemberElement element in elements)
{
element.Resolve(services);
}
}
public override void Emit(FleeILGenerator ilg, IServiceProvider services)
{
_myTail.Emit(ilg, services);
}
public override System.Type ResultType => _myTail.ResultType;
}
}