< Summary

Class:NanoCLang.Entities.PointerReadExpression
Assembly:NanoCLang
File(s):C:\GitLab-Runner\builds\JxAESPd8\0\chenmichael\nanoc\src\NanoCLang\Entities\Expression\PointerReadExpression.cs
Covered lines:45
Uncovered lines:5
Coverable lines:50
Total lines:105
Line coverage:90% (45 of 50)
Covered branches:22
Total branches:28
Branch coverage:78.5% (22 of 28)

Metrics

MethodBranch coverage Cyclomatic complexity Line coverage
.ctor(...)100%1100%
get_Pointer()100%1100%
get_BaseRead()100%10%
GetPointerValueType(...)85.71%1494.73%
DoInferWorld(...)100%1100%
Tokens()75%4100%
Tokens()75%8100%
RequiredFunctions()100%1100%
Equals(...)100%1100%
Equals(...)50%2100%
GetHashCode()100%10%
op_Equality(...)100%10%
op_Inequality(...)100%10%

File(s)

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

#LineLine coverage
 1using NanoCLang.Environemnts;
 2using System;
 3using System.Collections.Generic;
 4
 5namespace NanoCLang.Entities {
 6    /// <summary>
 7    /// Provide an abstract base class for all reading expressions.
 8    /// </summary>
 9    public abstract class ReadExpression : Expression {
 10        /// <summary>
 11        /// Equivalent read expression that is fixed during type inference.
 12        /// </summary>
 13        public virtual PointerReadExpression? BaseRead { get; protected set; }
 14        /// <inheritdoc/>
 15        public override IEnumerable<StringFormatterToken> Tokens(CSourceFormat args)
 16            => (BaseRead ?? throw new InvalidOperationException("Read Expression must be fixed when translating!"))
 17            .Tokens(args);
 18    }
 19    /// <summary>
 20    /// Provides a class for pointer read expressions.
 21    /// </summary>
 22    public class PointerReadExpression : ReadExpression, IEquatable<PointerReadExpression?> {
 23        /// <summary>
 24        /// Creates a new instance of a pointer read expression that reads the value of the <paramref name="pointer"/>.
 25        /// </summary>
 26        /// <param name="pointer">Pointer to write to.</param>
 4627        public PointerReadExpression(PureExpression pointer) {
 2328            Pointer = pointer;
 2329        }
 30        /// <summary>
 31        /// Pointer that is read from.
 32        /// </summary>
 3433        public PureExpression Pointer { get; }
 34        /// <inheritdoc/>
 035        public override PointerReadExpression? BaseRead { get => this; protected set => throw new InvalidOperationExcept
 36        /// <summary>
 37        /// Gets the type that the pointer points to if it is well-formed.
 38        /// Additionally checks if the type that is bound at the index in the heap is safe within bounds of the allocati
 39        /// </summary>
 40        /// <param name="ptrType">(Refined) type of the pointer expression.</param>
 41        /// <param name="gamma">Local environment to check the pointer with.</param>
 42        /// <param name="heap">Heap that contains (if well-formed) the appointed location.</param>
 43        /// <returns>Type of the value the pointer points to.</returns>
 3744        public static Type GetPointerValueType(Type ptrType, LocalEnvironment gamma, Heap heap) {
 3745            if (!(ptrType.BaseType is ReferenceType ptrRef))
 346                throw new IllFormedException(ptrType, $"Cannot read from non-reference of type {ptrType.BaseType}");
 3447            if (ptrRef.Abstract)
 048                throw new IllFormedException(ptrType, "Cannot read from abstract reference!");
 3449            var loc = ptrRef.Location;
 3450            var bindings = heap.TryGetBinding(loc, out var tmp) ? tmp
 3451                : throw new IllFormedException(ptrType, $"Cannot access pointer to location {loc} if the location is not
 52
 3453            Type? bound = null;
 22254            foreach (var block in bindings) if (ptrRef.Offsets <= block.Index) {
 3355                    bound = block.Type;
 3356                    break;
 57                }
 58
 3459            if (bound is null)
 160                throw new IllFormedException(ptrRef.Offsets, $"Heap location {loc} does not contain a binding at offset 
 61
 3362            if (!ptrType.SubType(gamma, new RefinedType(ptrRef,
 6663                v => new UninterpretedApplicationExpression("SafeN", v, new IntegerConstant(bound.Size, 4)))))
 264                throw new IllFormedException(ptrType, $"Pointer is not safe and can not be read from!");
 3165            return bound;
 3166        }
 67        /// <inheritdoc/>
 1968        protected override World DoInferWorld(GlobalEnvironment phi, LocalEnvironment gamma, Heap heap) {
 1969            VerbConsole.WriteLine(VerbosityLevel.Default, "T-Read");
 1970            var ptrType = Pointer.InferType(gamma);
 1971            return new World(GetPointerValueType(ptrType, gamma, heap), heap);
 1472        }
 73        /// <inheritdoc/>
 274        public override IEnumerable<StringFormatterToken> Tokens(NanoCSourceFormat args) {
 275            yield return "*";
 276            if (args.SpaceAfterDerefOperator) yield return " ";
 3677            foreach (var tk in Pointer.Tokens(args)) yield return tk;
 278        }
 79        /// <inheritdoc/>
 780        public override IEnumerable<StringFormatterToken> Tokens(CSourceFormat args) {
 781            if (FixedWorld is null) throw new InvalidOperationException("Expression must have fixed world when translati
 782            yield return "*";
 783            if (args.SpaceAfterDerefOperator) yield return " ";
 784            yield return "((";
 5185            foreach (var tk in FixedWorld.Type.Tokens(args)) yield return tk;
 786            yield return "*)";
 25287            foreach (var tk in Pointer.Tokens(args)) yield return tk;
 788            yield return ")";
 789        }
 90        /// <inheritdoc/>
 291        public override IEnumerable<string> RequiredFunctions() { yield break; }
 92        #region Equality checks
 93        /// <inheritdoc/>
 394        public override bool Equals(object? obj) => Equals(obj as PointerReadExpression);
 95        /// <inheritdoc/>
 396        public bool Equals(PointerReadExpression? other) => !(other is null) && EqualityComparer<PureExpression>.Default
 97        /// <inheritdoc/>
 098        public override int GetHashCode() => HashCode.Combine(Pointer);
 99        /// <inheritdoc/>
 0100        public static bool operator ==(PointerReadExpression? left, PointerReadExpression? right) => EqualityComparer<Po
 101        /// <inheritdoc/>
 0102        public static bool operator !=(PointerReadExpression? left, PointerReadExpression? right) => !(left == right);
 103        #endregion
 104    }
 105}