< Summary

Class:NanoCLang.Entities.FunctionCallExpression
Assembly:NanoCLang
File(s):C:\GitLab-Runner\builds\JxAESPd8\0\chenmichael\nanoc\src\NanoCLang\Entities\Expression\FunctionCallExpression.cs
Covered lines:96
Uncovered lines:6
Coverable lines:102
Total lines:150
Line coverage:94.1% (96 of 102)
Covered branches:39
Total branches:54
Branch coverage:72.2% (39 of 54)

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
.ctor(...)100%1100%
get_Name()100%1100%
get_Locations()100%1100%
get_Parameters()100%1100%
get_Arity()100%10%
DoInferWorld(...)50%488.23%
GetBindings(...)87.5%894.44%
CheckParameterSubtyping(...)100%2100%
GetSubstitutions(...)100%1100%
VariableSubstitution(...)50%2100%
LocationSubstitution(...)50%2100%
Tokens()66.66%12100%
Tokens()75%12100%
RequiredFunctions()100%1100%
Equals(...)100%1100%
Equals(...)50%6100%
GetHashCode()100%4100%
Replace(...)100%2100%
op_Equality(...)100%10%
op_Inequality(...)100%10%

File(s)

C:\GitLab-Runner\builds\JxAESPd8\0\chenmichael\nanoc\src\NanoCLang\Entities\Expression\FunctionCallExpression.cs

#LineLine coverage
 1using NanoCLang.Environemnts;
 2using System;
 3using System.Collections.Generic;
 4using System.Linq;
 5
 6namespace NanoCLang.Entities {
 7    /// <summary>
 8    /// Provides a class for function call expressions.
 9    /// </summary>
 10    public class FunctionCallExpression : Expression, IEquatable<FunctionCallExpression?>, IHeapElement, ISubstitutable<
 11        /// <summary>
 12        /// Creates a new instance of a function call expression that calls the function with the given <paramref name="
 13        /// </summary>
 14        /// <param name="name">Name of the function to call.</param>
 15        /// <param name="locations">Locations that the function operates on.</param>
 16        /// <param name="parameters">Parameters that are passed to the function.</param>
 21817        public FunctionCallExpression(string name, string[] locations, params PureExpression[] parameters) {
 10918            Name = name;
 10919            Locations = locations;
 10920            Parameters = parameters;
 10921        }
 22        /// <summary>
 23        /// Name of the function to call.
 24        /// </summary>
 29525        public string Name { get; }
 26        /// <summary>
 27        /// Locations that the function operates on.
 28        /// </summary>
 34329        public string[] Locations { get; }
 30        /// <summary>
 31        /// Parameters that are passed to the function.
 32        /// </summary>
 32633        public PureExpression[] Parameters { get; }
 34        /// <summary>
 35        /// Gets the arity of the function call, being the number of supplied parameters.
 36        /// </summary>
 037        public int Arity => Parameters.Length;
 38        /// <inheritdoc/>
 1539        protected override World DoInferWorld(GlobalEnvironment phi, LocalEnvironment gamma, Heap heap) {
 1540            VerbConsole.WriteLine(VerbosityLevel.Default, "T-Call");
 1541            if (!phi.TryGetValue(Name, out var rawschema))
 042                throw new IllFormedException(this, $"No function named {Name} was declared in this environment!");
 1543            var schema = rawschema.Build(phi);
 1544            var theta = GetSubstitutions(schema);
 1545            CheckParameterSubtyping(gamma, schema, theta);
 1546            var usedLocs = new HashSet<string>(Locations);
 4747            var hm = heap.Filter(i => usedLocs.Contains(i.Name));
 4748            var hu = heap.Filter(i => !usedLocs.Contains(i.Name));
 49            // hu.WellFormed(gamma);
 1550            hm.WellFormed(gamma);
 1551            if (!hm.SubHeap(gamma, schema.Heap.Replace(theta)))
 052                throw new IllFormedException(this, "Heap is not compatible with function schema heap!");
 1553            var hout = hu * schema.World.Heap.Replace(theta);
 1554            hout.WellFormed(gamma);
 1555            return new World(schema.World.Type.Replace(theta), hout);
 1556        }
 57        /// <inheritdoc cref="IHeapElement.GetBindings(GlobalEnvironment, out IEnumerable{KeyValuePair{string, string}})
 5858        public IEnumerable<LocationBinding> GetBindings(GlobalEnvironment phi, out IEnumerable<KeyValuePair<string, stri
 5859            VerbConsole.WriteLine(VerbosityLevel.Default, "WF-StructCall");
 5860            if (Locations.Length < 1)
 061                throw new IllFormedException(this, "At least one location must be given. The first location sets the mai
 5862            var l = new Location(Locations[0], true);
 5863            if (!phi.TryGetStruct(Name, out var def))
 164                throw new IllFormedException(this, $"No structure named {Name} was declared in this environment!");
 5765            var linklist = new List<KeyValuePair<string, string>> { new KeyValuePair<string, string>(l.Name, Name) };
 5766            var bindings = new List<LocationBinding>();
 5767            var theta = GetSubstitutions(def);
 22768            foreach (var dep in def.Dependencies.Select(i => i.Replace(theta))) {
 1469                bindings.AddRange(dep.GetBindings(phi, out var newLinks));
 1470                linklist.AddRange(newLinks);
 1471            }
 12872            bindings.Add(new LocationBinding(l, def.Fields.Select(i => i.Binding.Replace(theta).Replace(def.GetSubstitut
 5773            links = linklist;
 5774            return bindings;
 5775        }
 76
 1577        private void CheckParameterSubtyping(LocalEnvironment gamma, FunctionSchema schema, Substitutor theta) {
 14778            for (var i = 0; i < Parameters.Length; i++) {
 3979                var param = Parameters[i];
 3980                var expParam = schema.Parameters[i];
 3981                param.CheckType(gamma, expParam.Type.Replace(theta));
 3982            }
 1583        }
 84
 7285        private Substitutor GetSubstitutions(ICallable callable) => new Substitutor() { Locations = LocationSubstitution
 86
 7287        private IDictionary<string, PureExpression> VariableSubstitution(Base entity, TypeParameter[] schemaparams, Pure
 7288            return schemaparams.Length != @params.Length
 7289                   ? throw new IllFormedException(entity, $"Parameter count mismatch! Expected {schemaparams.Length}, bu
 12590                         : new Dictionary<string, PureExpression>(schemaparams.Zip(@params, (a, b) => new KeyValuePair<s
 7291        }
 92
 7293        private static IDictionary<string, string> LocationSubstitution(Base entity, string[] schemalocations, string[] 
 7294            return schemalocations.Length != locations.Length
 7295                   ? throw new IllFormedException(entity, $"Location count mismatch! Expected {schemalocations.Length}, 
 25096                         : new Dictionary<string, string>(schemalocations.Zip(locations, (a, b) => new KeyValuePair<stri
 7297        }
 98        /// <inheritdoc/>
 3299        public override IEnumerable<StringFormatterToken> Tokens(NanoCSourceFormat args) {
 32100            yield return "[";
 252101            foreach (var tk in StringFormatterToken.Separated(Locations, args.ParameterListSeparator)) yield return tk;
 32102            yield return "]";
 32103            if (args.SpaceBetweenLocationsAndFunctionName) yield return " ";
 32104            yield return Name;
 32105            if (args.SpaceAfterFunctionName) yield return " ";
 32106            yield return "(";
 396107            foreach (var tk in StringFormatterToken.Separated(Parameters, args, args.ParameterListSeparator)) yield retu
 32108            if (args.SpaceInEmptyArgList && Parameters.Length == 0) yield return " ";
 32109            yield return ")";
 32110        }
 111        /// <inheritdoc/>
 21112        public override IEnumerable<StringFormatterToken> Tokens(CSourceFormat args) {
 21113            var requireReturn = args.PureRequiresReturn;
 25114            if (requireReturn) yield return "return ";
 21115            yield return Name;
 21116            if (args.SpaceAfterFunctionName) yield return " ";
 21117            yield return "(";
 21118            args.PureRequiresReturn = false;
 396119            foreach (var tk in StringFormatterToken.Separated(Parameters, args, args.ParameterListSeparator)) yield retu
 21120            if (args.SpaceInEmptyArgList && Parameters.Length == 0) yield return " ";
 21121            yield return ")";
 25122            if (requireReturn) yield return ";";
 21123            args.PureRequiresReturn = requireReturn;
 21124        }
 125        /// <inheritdoc/>
 9126        public override IEnumerable<string> RequiredFunctions() { yield return Name; }
 127        #region Equality checks
 128        /// <inheritdoc/>
 31129        public override bool Equals(object? obj) => Equals(obj as FunctionCallExpression);
 130        /// <inheritdoc/>
 33131        public bool Equals(FunctionCallExpression? other) => !(other is null) && Name == other.Name && Locations.Sequenc
 132        /// <inheritdoc/>
 28133        public override int GetHashCode() {
 28134            var hash = new HashCode();
 28135            hash.Add(Name);
 204136            foreach (var loc in Locations) hash.Add(loc);
 120137            foreach (var param in Parameters) hash.Add(param);
 28138            return hash.ToHashCode();
 28139        }
 140        /// <inheritdoc/>
 14141        public FunctionCallExpression Replace(Substitutor sub) => new FunctionCallExpression(Name,
 14142            Locations.Select(i => sub.Locations.TryGetValue(i, out var subs) ? subs : i).ToArray(),
 14143            Parameters.Select(i => i.Replace(sub)).ToArray());
 144        /// <inheritdoc/>
 0145        public static bool operator ==(FunctionCallExpression? left, FunctionCallExpression? right) => EqualityComparer<
 146        /// <inheritdoc/>
 0147        public static bool operator !=(FunctionCallExpression? left, FunctionCallExpression? right) => !(left == right);
 148        #endregion
 149    }
 150}