Exemple #1
0
        public Expression GetConstructor(IConstructorResolver constructorResolver)
        {
            var ctor = constructorResolver.Resolve(InputParameter, OutputParameter);

            if (ctor == null)
            {
                throw new InvalidOperationException($"It was not possible determine a constructor to the type [{Output.FullName}].");
            }

            RemoveProcessedMembers(constructorResolver);
            return(ctor);
        }
        /// <inheritdoc/>
        protected override IAnalyticObject Construct(IAnalyticObject[] input)
        {
            #region Verify layout

            // First we need to verify that the objects match the layout
            switch (_construction.Configuration.LooseObjectsHolder.Layout)
            {
            // Two points should be always fine
            case LooseObjectLayout.LineSegment:
                break;

            // Make sure the points are not collinear
            case LooseObjectLayout.Triangle:

                // If yes, the construction shouldn't be possible
                if (AnalyticHelpers.AreCollinear((Point)input[0], (Point)input[1], (Point)input[2]))
                {
                    return(null);
                }

                break;

            // Make sure no three points are collinear
            case LooseObjectLayout.Quadrilateral:

                // Get the points
                var point1 = (Point)input[0];
                var point2 = (Point)input[1];
                var point3 = (Point)input[2];
                var point4 = (Point)input[3];

                // Verify any three of them
                if (AnalyticHelpers.AreCollinear(point1, point2, point3) ||
                    AnalyticHelpers.AreCollinear(point1, point2, point4) ||
                    AnalyticHelpers.AreCollinear(point1, point3, point4) ||
                    AnalyticHelpers.AreCollinear(point2, point3, point4))
                {
                    // If some three are collinear, the construction shouldn't be possible
                    return(null);
                }

                break;

            // Make sure the point doesn't lie on the line
            case LooseObjectLayout.LineAndPoint:

                // If yes, the construction shouldn't be possible
                if (((Line)input[0]).Contains((Point)input[1]))
                {
                    return(null);
                }

                break;

            // Make sure neither of the points lies on the line
            case LooseObjectLayout.LineAndTwoPoints:

                // Get the line
                var line = (Line)input[0];

                // If at least one point lies on the line, the construction
                // shouldn't be possible
                if (line.Contains((Point)input[1]) || line.Contains((Point)input[2]))
                {
                    return(null);
                }

                break;

            // Unhandled cases
            default:
                throw new ConstructorException($"Unhandled value of {nameof(LooseObjectLayout)}: {_construction.Configuration.LooseObjectsHolder.Layout}");
            }

            #endregion

            // Initialize an internal picture in which we're going to construct
            // the configuration that defines our composed construction
            var internalPicture = new Picture();

            // Add the loose objects to the picture
            _construction.Configuration.LooseObjects.Zip(input).ForEach(pair =>
            {
                // Safely try to add them
                internalPicture.TryAdd(pair.First, pair.Second, out var equalObject);

                // If there is an equal object, then we have a weird problem
                if (equalObject != default)
                {
                    throw new ConstructorException("The input for a composed construction doesn't contain distinct objects! This must be a bug...");
                }
            });

            // Add the constructed objects as well
            foreach (var constructedObject in _construction.Configuration.ConstructedObjects)
            {
                // For each one find the construction function
                var constructorFunction = _constructionResolver.Resolve(constructedObject.Construction).Construct(constructedObject);

                // Perform the construction
                var analyticObject = constructorFunction(internalPicture);

                // If it's not constructible, we can't do more
                if (analyticObject == null)
                {
                    return(null);
                }

                // Otherwise add the object to the picture
                internalPicture.TryAdd(constructedObject, analyticObject, out var equalObject);

                // If there is an equal object, we say the construction is incorrect as well
                if (equalObject != null)
                {
                    return(null);
                }
            }

            // If we are here, then the construction should be fine and the result
            // will be in the internal picture corresponding to the last object
            // of the configuration that defines our composed construction
            return(internalPicture.Get(_construction.Configuration.LastConstructedObject));
        }
        public static IMethodCompiler <TDelegate> ResolveConstructorTo <[DelegateConstraint] TDelegate>(IConstructorResolver constructorInfoResolver) where TDelegate : class
        {
            Func <TDelegate> resolved = constructorInfoResolver.Resolve <TDelegate>();

            return(new ConstructorExpressionizer <TDelegate>().From(resolved));
        }