/// <inheritdoc/>
        public void Load(ICSharpWorkspace cSharpWorkspace, ICSharpAssembly assembly)
        {
            if (assembly == null)
            {
                throw new ArgumentNullException(nameof(assembly), $"The argument {nameof(assembly)} was null.");
            }

            ((CSharpAssembly)assembly).Load();
        }
        public void BuildScaffoldingClass(ICSharpAssembly assembly)
        {
            this._assembly = assembly;
            if (!assembly.Namespaces.PathExists(this.Detail.Namespace))
            {
                assembly.Namespaces.Add(this.Detail.Namespace);
            }
            var ns = assembly.Namespaces[this.Detail.Namespace];

            this.VisitorResult             = ns.Parts.Add().Classes.Add(this.Detail.TargetContext);
            this.VisitorResult.AccessLevel = AccessLevelModifiers.Public;
        }
示例#3
0
        public void ScaffoldInterface(ICSharpAssembly assembly)
        {
            this._assembly = assembly;
            var namespaceNames = this._relevantTypes.Select(k => k.NamespaceName).Distinct().ToArray();
            /* We're going to throw-out cases where there's only one type, as it's likely a special case, not the standard. */
            var totalTypeCount        = this._relevantTypes.Count;
            var namespaceNamesTrimmed =
                (from name in namespaceNames
                 join type in this._relevantTypes on name equals type.NamespaceName into set
                 where (((float)set.Count()) / (float)totalTypeCount) * 100 > 20
                 select name).Distinct().ToArray();

            if (namespaceNamesTrimmed.Length > 0)
            {
                namespaceNames = namespaceNamesTrimmed;
            }
            var relativeRoot = namespaceNames.GetRelativeRoot(".");

            if (!assembly.Namespaces.PathExists(relativeRoot))
            {
                assembly.Namespaces.Add(relativeRoot);
            }
            var ns = assembly.Namespaces[relativeRoot];

            GenericParameterData[] gpData = new GenericParameterData[(this._detail.ContextualVisitor ? 1 : 0) + (this._detail.YieldingVisitor ? 1 : 0)];
            if (this._detail.YieldingVisitor)
            {
                gpData[0] = new GenericParameterData("TResult");
            }
            if (this._detail.ContextualVisitor)
            {
                gpData[this._detail.YieldingVisitor ? 1 : 0] = new GenericParameterData("TContext");
            }
            var nameParts = this._detail.TargetContext.TitleCaseIdentifierSplit();

            this.NameParts = nameParts;
            if (!this._detail.YieldingVisitor && this._detail.ContextualVisitor)
            {
                var npList = new List <string>(nameParts);
                npList.Insert(npList.Count - 1, "Contextual");
                nameParts = npList.ToArray();
            }

            var visitorInterface = ns.Parts.Add().Interfaces.Add(string.Format("I{0}", string.Join(string.Empty, nameParts)), gpData);

            this.VisitorInterface             = visitorInterface;
            this.VisitorInterface.AccessLevel = AccessLevelModifiers.Public;
        }
示例#4
0
        private static VisitorImplementationBuilder GetImplementationBuilder(ICSharpAssembly resultAssembly, VisitorModelCommonTypeContext attributeContext, VisitorImplementationTargetDetail implementation, IEnumerable <IGrouping <InheritanceDetailKey, VisitorBuilder> > visitorBuilderQuery, IAssembly assembly)
        {
            var result = new VisitorImplementationBuilder(
                new VisitorImplementationContext(
                    implementation,
                    attributeContext,
                    visitorBuilderQuery.Select(
                        v => new VisitorImplementationVariationContext(
                            v.ToArray(),
                            v.Key.TContext,
                            v.Key.TResult,
                            v.Key.TargetContext,
                            v.Key.TargetAbstract,
                            v.Key.VisitorBuilderHandler,
                            assembly)),
                    resultAssembly));

            foreach (var variation in result.Context.Variations)
            {
                variation.ImplementationBuilder = result;
            }
            return(result);
        }
示例#5
0
        private static Dictionary <Tuple <string, bool, bool>, VisitorBuilder> BuildInheritedVisitors(Dictionary <VisitorTargetDetail, List <IType> > visitorContextualDetail, Dictionary <VisitorTargetDetail, VisitorBuilder> builders, ICSharpAssembly assembly)
        {
            var derivedContextDetail = new MultikeyedDictionary <string, VisitorTargetDetail, List <IType> >();
            var derivedDetail        = visitorContextualDetail.Keys.Where(k => !string.IsNullOrEmpty(k.DerivedThroughInheriting)).ToArray();

            foreach (var contextKey in derivedDetail)
            {
                derivedContextDetail.Add(contextKey.TargetContext, contextKey, visitorContextualDetail[contextKey]);
            }
            var inheritanceTree = (from ksvp in derivedContextDetail
                                   orderby ksvp.Keys.Key1, ksvp.Keys.Key2.DerivedThroughInheriting
                                   group ksvp.Keys.Key2.DerivedThroughInheriting by Tuple.Create(ksvp.Keys.Key1, ksvp.Keys.Key2.ContextualVisitor, ksvp.Keys.Key2.YieldingVisitor))
                                  .ToDictionary(
                k => k.Key,
                v => v.Distinct()
                .ToArray());
            var typelessVisitors = new Dictionary <Tuple <string, bool, bool>, VisitorBuilder>();

            foreach (var hierarchyKey in inheritanceTree.Keys)
            {
                bool addedBuilder      = false;
                var  inheritanceDetail = inheritanceTree[hierarchyKey];
                var  firstContext      = visitorContextualDetail.Keys.FirstOrDefault(k => k.ContextualVisitor == hierarchyKey.Item2 && k.YieldingVisitor == hierarchyKey.Item3 && k.TargetContext == hierarchyKey.Item1 && string.IsNullOrEmpty(k.DerivedThroughInheriting));
                if (firstContext == null)
                {
                    var builder = GetVisitorBuilderWith(hierarchyKey);
                    firstContext = builder.Detail;
                    typelessVisitors.Add(hierarchyKey, builder);
                    addedBuilder = true;
                }
                var children =
                    (from child in inheritanceDetail.Select(k => Tuple.Create(k, hierarchyKey.Item2, hierarchyKey.Item3))
                     let childContext = visitorContextualDetail.Keys.FirstOrDefault(k => k.ContextualVisitor == child.Item2 && k.YieldingVisitor == child.Item3 && k.TargetContext == child.Item1)
                                        let actualChildContext =
                         childContext == null
                         ? GetVisitorBuilderWith(child)
                         : builders.ContainsKey(childContext)
                           ? builders[childContext]
                           : typelessVisitors[new Tuple <string, bool, bool>(childContext.TargetContext, childContext.ContextualVisitor, childContext.YieldingVisitor)]
                         select actualChildContext).ToArray();
                foreach (var childBuilder in children.Where(actualChildContext => actualChildContext.VisitorInterface == null).Select(childBuilder => new { Builder = childBuilder, Key = Tuple.Create(childBuilder.Detail.TargetContext, childBuilder.Detail.ContextualVisitor, childBuilder.Detail.YieldingVisitor) }).Where(x => !typelessVisitors.ContainsKey(x.Key)))
                {
                    typelessVisitors.Add(childBuilder.Key, childBuilder.Builder);
                    childBuilder.Builder.ScaffoldInterface(assembly);
                }

                if (addedBuilder)
                {
                    var currentBuilder = typelessVisitors[hierarchyKey];
                    if (currentBuilder.VisitorInterface == null)
                    {
                        currentBuilder.SkippedTypes      =
                            currentBuilder.RelevantTypes =
                                children
                                .Select(k => k.RelevantTypes)
                                .SelectMany(k => k)
                                .Distinct()
                                .ToList();
                        currentBuilder.ScaffoldInterface(assembly);
                        foreach (var childBuilder in children)
                        {
                            currentBuilder.VisitorInterface.ImplementedInterfaces.Add(childBuilder.VisitorInterface);
                        }
                        currentBuilder.ChildBuilders = children;
                    }
                }
                else
                {
                    var currentBuilder = builders[firstContext];
                    currentBuilder.ChildBuilders = children;
                    foreach (var childBuilder in children)
                    {
                        currentBuilder.VisitorInterface.ImplementedInterfaces.Add(childBuilder.VisitorInterface);
                    }
                }
            }
            return(typelessVisitors);
        }
示例#6
0
        internal static IEnumerable <VisitorBuilder> GetVisitorContexts(IAssembly assembly, VisitorModelCommonTypeContext attributeContext, ICSharpAssembly resultAssembly, IIntermediateCliManager identityManager)
        {
            var visitorRelevantTypes = assembly.GetTypes().Where(t => t.Metadata.Contains(attributeContext.TargetAttribute)).ToArray();

            /* Using the metadata supplied on the relevant types, group them by their distinct visitor targets.
             * We'll use the distinct targets to generate concrete visitor interfaces.
             * The VisitorTargetAttribute allows multiple applications, so we may have multiple possible visitors for a single type. */
            var visitorContextualDetail = (from type in visitorRelevantTypes
                                           from metadatum in type.Metadata.Where(k => k.Type == attributeContext.TargetAttribute)
                                           let currentDetail = VisitorTargetDetail.DeriveFromMetadata(metadatum)
                                                               group type by currentDetail into distinctVisitorDetail
                                                               orderby distinctVisitorDetail.Key.TargetContext,
                                           string.IsNullOrEmpty(distinctVisitorDetail.Key.DerivedThroughInheriting)
                                                   ? string.Empty
                                                   : distinctVisitorDetail.Key.DerivedThroughInheriting,
                                           distinctVisitorDetail.Key.ContextualVisitor,
                                           distinctVisitorDetail.Key.YieldingVisitor
                                           select distinctVisitorDetail).ToDictionary(k => k.Key, v => new HashSet <IType>(v));

            /* Break the sets into two variations:
             * 1. Visitors which are derived from other visitors */
            var inheritanceBasedDetail =
                visitorContextualDetail.Keys.Where(k => !string.IsNullOrEmpty(k.DerivedThroughInheriting)).ToArray();
            /* 2. The concrete visitors which aren't representative of derivation.  There may be overlap. */
            var nonDerivedVisitors =
                visitorContextualDetail.Keys.Where(k => string.IsNullOrEmpty(k.DerivedThroughInheriting)).ToArray();

            var directVisitors = (from context in nonDerivedVisitors
                                  let builder = GetVisitorFrom(context, visitorContextualDetail[context], resultAssembly)
                                                select builder).ToDictionary(k => k.Detail, v => v);

            var inheritanceTree =
                (from detail in inheritanceBasedDetail
                 orderby detail.TargetContext, detail.DerivedThroughInheriting
                 /* We group by a *new* TargetVisitorDetail since we're not interested in the DerivedThroughInheriting, which would fragment the visitors. */
                 group detail.DerivedThroughInheriting by new VisitorTargetDetail {
                TargetContext = detail.TargetContext, ContextualVisitor = detail.ContextualVisitor, YieldingVisitor = detail.YieldingVisitor
            })
                .ToDictionary(k => k.Key, v => v.Distinct().ToArray());

            var inheritanceOnlyVisitors = new Dictionary <VisitorTargetDetail, VisitorBuilder>();

            foreach (var inheritanceKey in inheritanceTree.Keys)
            {
                var inheritedVisitorNames = inheritanceTree[inheritanceKey];
                var iovKey = new VisitorTargetDetail {
                    TargetContext = inheritanceKey.TargetContext, ContextualVisitor = inheritanceKey.ContextualVisitor, YieldingVisitor = inheritanceKey.YieldingVisitor
                };
                VisitorBuilder mainBuilder;
                if (!directVisitors.TryGetValue(inheritanceKey, out mainBuilder) && !inheritanceOnlyVisitors.TryGetValue(iovKey, out mainBuilder))
                {
                    inheritanceOnlyVisitors.Add(iovKey, mainBuilder = new VisitorBuilder(inheritanceKey));
                }

                var childBuilders =
                    (from childDetail in inheritedVisitorNames
                     .Select(k =>
                             GetRelevantDetail(nonDerivedVisitors, inheritanceKey, k))
                     select directVisitors.ContainsKey(childDetail)
                            ? directVisitors[childDetail]
                            : inheritanceOnlyVisitors.ContainsKey(childDetail)
                              ? inheritanceOnlyVisitors[childDetail]
                              : new VisitorBuilder(childDetail)).ToArray();
                foreach (var childBuilder in childBuilders.Where(childBuilder => childBuilder.VisitorInterface == null))
                {
                    inheritanceOnlyVisitors.Add(childBuilder.Detail, childBuilder);
                    childBuilder.ScaffoldInterface(resultAssembly);
                }
                if (mainBuilder.VisitorInterface == null)
                {
                    mainBuilder.SkippedTypes      =
                        mainBuilder.RelevantTypes =
                            childBuilders
                            .SelectMany(k => k.RelevantTypes)
                            .Distinct()
                            .ToList();
                    mainBuilder.ScaffoldInterface(resultAssembly);
                }
                mainBuilder.ChildBuilders = childBuilders;
                foreach (var childBuilder in childBuilders)
                {
                    mainBuilder.VisitorInterface.ImplementedInterfaces.Add(childBuilder.VisitorInterface);
                }
            }

            foreach (var builder in inheritanceOnlyVisitors.Values.Concat(directVisitors.Values))
            {
                builder.BuildVisitor();
            }

            return(inheritanceOnlyVisitors
                   .Values
                   .Concat(directVisitors.Values)
                   .OrderBy(k => k.Detail.TargetContext)
                   .ThenBy(k => k.Detail.ContextualVisitor)
                   .ThenBy(k => k.Detail.YieldingVisitor)
                   .ThenBy(k => string.IsNullOrEmpty(k.Detail.DerivedThroughInheriting) ? string.Empty : k.Detail.DerivedThroughInheriting)
                   .ToArray());
        }
示例#7
0
        public static IEnumerable <IVisitorImplementationBuilder> GetImplementationContext(IAssembly assembly, ICSharpAssembly resultAssembly, IIntermediateCliManager identityManager)
        {
            var attributeContext        = new VisitorModelCommonTypeContext(identityManager);
            var visitorBuilders         = GetVisitorContexts(assembly, attributeContext, resultAssembly, identityManager);
            var distinctImplementations = new HashSet <VisitorImplementationTargetDetail>(
                from metadatum in assembly.Metadata.Where(k => k.Type == attributeContext.ImplementationTargetAttribute)
                select VisitorImplementationTargetDetail.DeriveFromMetadata(metadatum));
            var inheritanceDetails =
                new HashSet <VisitorImplementationInheritanceDetail>(
                    assembly
                    .Metadata
                    .Where(k => k.Type == attributeContext.ImplementationInheritanceAttribute)
                    .Select(k => VisitorImplementationInheritanceDetail.DeriveFromMetadata(k)));
            var implementationDetail =
                (from inheritanceDetail in inheritanceDetails
                 orderby inheritanceDetail.TargetContext,
                 inheritanceDetail.VisitRefactorName,
                 inheritanceDetail.VisitRefactorAbstract,
                 inheritanceDetail.ContextualVisitor,
                 inheritanceDetail.YieldingVisitor
                 join implementation in distinctImplementations on inheritanceDetail.ImplementationDetailMatch equals implementation
                 group inheritanceDetail by implementation).ToDictionary(k => k.Key, v => v.ToArray());

            foreach (var detail in implementationDetail.Keys)
            {
                detail.InheritanceDetail = new ControlledCollection <VisitorImplementationInheritanceDetail>(implementationDetail[detail]);
            }
            var implementationBuilders =
                (from implementation in implementationDetail.Keys
                 let visitorBuilderQuery =
                     from inheritanceDetail in implementationDetail[implementation]
                     from visitorDetail in inheritanceDetail.VisitorTargets
                     join visitor in visitorBuilders on new { visitorDetail.TargetContext, visitorDetail.ContextualVisitor, visitorDetail.YieldingVisitor } equals new { visitor.Detail.TargetContext, visitor.Detail.ContextualVisitor, visitor.Detail.YieldingVisitor }
                 group visitor by GetInheritanceDetailKey(inheritanceDetail)
                 select GetImplementationBuilder(resultAssembly, attributeContext, implementation, visitorBuilderQuery, assembly))
                .ToArray();

            foreach (var builder in implementationBuilders)
            {
                yield return(builder);
            }
        }
示例#8
0
        public static VisitorBuilder GetVisitorFrom(VisitorTargetDetail detail, IEnumerable <IType> types, ICSharpAssembly assembly)
        {
            var builder = new VisitorBuilder(detail, types.ToList());

            builder.ScaffoldInterface(assembly);
            return(builder);
        }