/// <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; }
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; }
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); }
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); }
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()); }
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); } }
public static VisitorBuilder GetVisitorFrom(VisitorTargetDetail detail, IEnumerable <IType> types, ICSharpAssembly assembly) { var builder = new VisitorBuilder(detail, types.ToList()); builder.ScaffoldInterface(assembly); return(builder); }