Ejemplo n.º 1
0
        public static ICodeSource MakeFromConstructor(XUnitTypeName unit,
                                                      IReadOnlyList <ValueOfSomeTypeExpression> arguments, bool dependsOnLeftArgument)
        {
            var call = "new " + unit.GetTypename();
            var ar   = arguments.Select(a => (ICodeSource1)a.Expression).ToArray();

            return(new MethodCallCodeSource(call, ar, dependsOnLeftArgument));
        }
        private void Scan(ValueOfSomeTypeExpressionRoot root, XUnitTypeName x, Kind2 kind, ExpressionPath path = null)
        {
            if (!_resolver.TryGetValue(x.GetTypename(), out var type))
            {
                throw new NotImplementedException();
            }
            var info1 = new ValueOfSomeTypeExpression(root, type, new TreeExpression(path, null, kind), kind);

            _sink.Add(info1);
            if (kind != Kind2.Property)
            {
                return;
            }
            foreach (var propInfo in type.GetProperties())
            {
                var attribute = propInfo.GetCustomAttribute <RelatedUnitSourceAttribute>();
                if (attribute != null && attribute.Usage == RelatedUnitSourceUsage.DoNotUse)
                {
                    continue;
                }
                var pt = propInfo.PropertyType;
                if (!pt.Implements <IUnit>())
                {
                    continue;
                }
                Scan(root, new XUnitTypeName(propInfo.PropertyType.Name), kind, path + propInfo.Name);
            }

            foreach (var methodInfo in type.GetMethods(BindingFlags.Instance | BindingFlags.Public))
            {
                var at = methodInfo.GetCustomAttribute <RelatedUnitSourceAttribute>();
                if (at is null || (at.Usage & RelatedUnitSourceUsage.ProvidesRelatedUnit) == 0)
                {
                    continue;
                }
                var returnType = methodInfo.ReturnType;
                if (!returnType.Implements <IUnit>())
                {
                    throw new Exception("Should return IUnit");
                }
                if (methodInfo.GetParameters().Length != 0)
                {
                    throw new Exception("Should be parameterles");
                }
                Scan(root, new XUnitTypeName(returnType.Name), Kind2.Method, path + $"{methodInfo.Name}");
            }
        }
        private ICodeSource Construct(XUnitTypeName unit)
        {
            if (!_resolver.TryGetValue(unit.GetTypename(), out var type1))
            {
                throw new NotImplementedException();
            }


            ValueOfSomeTypeExpression[] sources;

            var constr = type1.GetConstructors()
                         .Where(a =>
            {
                var pa = a.GetParameters();
                foreach (var info in pa)
                {
                    if (!info.ParameterType.Implements <IUnit>())
                    {
                        return(false);
                    }
                }
                return(true);
            })
                         .OrderByDescending(a => a.GetParameters().Length)
                         .ToArray();
            var typesDict = TypeFinder.Make(_sink);

            if (constr.Length == 0)
            {
                sources = typesDict.GetTypeSources(type1);
                if (sources.Any())
                {
                    var src = sources[0];
                    return(new ExpressionCodeSource(src.Expression,
                                                    src.Root == ValueOfSomeTypeExpressionRoot.Left));
                }

                return(null);
            }

            var ccc = constr[0];


            var list = typesDict.FindParameters(ccc, t => Construct(new XUnitTypeName(t.Name)), out var hasLeft);

            // var hasLeft = list.Any(q => q.Root == ValueOfSomeTypeExpressionRoot.Left);
            if (!hasLeft)
            {
                sources = typesDict.GetTypeSources(type1);
                if (sources.Any())
                {
                    var src = sources[0];
                    return(new ExpressionCodeSource(src.Expression,
                                                    src.Root == ValueOfSomeTypeExpressionRoot.Left));
                }

                throw new NotImplementedException();
            }

            return(MethodCallCodeSource.MakeFromConstructor(unit, list, true));
        }