using System.Collections.Immutable; using System.Linq; using Upsilon.BaseTypes; using Upsilon.BoundTypes; namespace Upsilon.Binder.VariableSymbols { public class ScriptFunctionVariableSymbol : FunctionVariableSymbol { public ScriptFunctionVariableSymbol(string name, bool local, ImmutableArray parameters, Type resultType) : base(name, local, resultType) { FunctionOption.Add(new ScriptFunctionVariableOption(resultType, parameters)); } public override bool ValidateParameters(ImmutableArray callingParameters) { foreach (var functionVariableSymbolOption in FunctionOption) { if (!(functionVariableSymbolOption is ScriptFunctionVariableOption option)) continue; if (option.Parameters.Length != callingParameters.Length) continue; bool isValid = true; for (var i = 0; i < option.Parameters.Length; i++) { var functionParameter = option.Parameters[i]; var callingParameter = callingParameters[i]; if (functionParameter.TypeContainer == Type.Unknown || callingParameter.ValueType == Type.Unknown || callingParameter.ValueType == Type.Nil) continue; if (!functionParameter.TypeContainer.Type.HasFlag(callingParameter.ValueType)) { isValid = false; break; } if (functionParameter.TypeContainer.Type.HasFlag(Type.UserData)) { var variable = Binder.ResolveVariable(callingParameter, null); if (variable != null && variable.TypeContainer == Type.UserData) { var userData = functionParameter.TypeContainer.UserData; if (string.IsNullOrEmpty(userData)) continue; if (!string.Equals(userData, callingParameter.ValueType.UserData)) { isValid = false; break; } } } } if (!isValid) continue; return true; } return false; } } public class ScriptFunctionVariableOption : FunctionVariableSymbolOption { public ImmutableArray Parameters { get; } public bool IsBound { get; set; } public ScriptFunctionVariableOption(Type resultType, ImmutableArray parameters) : base(resultType) { Parameters = parameters; } public override TypeContainer[] GetParameterTypes() { return Parameters.Select(x => x.TypeContainer).ToArray(); } } }