Beispiel #1
0
        public void ScaffoldInterface(IIntermediateAssembly 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;
        }
 IIntermediateGenericParameter IIntermediateGenericParameterDictionary.Add(GenericParameterData genericParameterData)
 {
     return(this.Add(genericParameterData));
 }
        public TIntermediateGenericParameter Add(GenericParameterData genericParameterData)
        {
            if (this.Locked)
            {
                throw new InvalidOperationException(Resources.ObjectStateThrowMessage);
            }
            if (string.IsNullOrEmpty(genericParameterData.Name))
            {
                throw new ArgumentException("genericParameterData");
            }
            int index          = this.Count;
            var defaultParamId = TypeSystemIdentifiers.GetGenericParameterIdentifier(index, this.Parent is IType);
            var result         = this.GetNew(genericParameterData.Name);

            if (this.ContainsKey(defaultParamId))
            {
                throw new ArgumentException("genericParameterData");
            }
            foreach (var ctorSig in genericParameterData.Constructors.Signatures)
            {
                result.Constructors.Add(TransposeTypedNames(ctorSig.Parameters.ToSeries(), result));
            }
            var disambiguatedEvents = TransposeTypedNames(genericParameterData.Events, result);

            foreach (var eventGroup in disambiguatedEvents)
            {
                result.Events.Add(eventGroup);
            }
            IControlledTypeCollection typeParameters       = null;
            IControlledTypeCollection methodTypeParameters = null;

            foreach (var constraint in genericParameterData.Constraints)
            {
                if (constraint.ContainsSymbols())
                {
                    if (constraint.ContainsGenericParameters())
                    {
                        result.Constraints.Add(Disambiguate(constraint).SimpleSymbolDisambiguation(result));
                    }
                    else
                    {
                        result.Constraints.Add(constraint.SimpleSymbolDisambiguation(result));
                    }
                }
                else if (constraint.ContainsGenericParameters())
                {
                    result.Constraints.Add(Disambiguate(constraint));
                }
                else
                {
                    result.Constraints.Add(constraint);
                }
            }
            result.SpecialConstraint = genericParameterData.SpecialConstraint;
            //foreach (var propertyGroup in genericParameterData.Properties)
            //result.Properties.Add
            foreach (var method in genericParameterData.Methods.Signatures)
            {
                result.Methods.Add(new TypedName(method.Name, method.ReturnType), method.Parameters.ToSeries());
            }
            this._Add(defaultParamId, result);
            this.Keys[index] = result.UniqueIdentifier;
            return(result);
        }
Beispiel #4
0
 public new IIntermediateDelegateTypeParameterType Add(GenericParameterData genericParameterData)
 {
     return((IIntermediateDelegateTypeParameterType)base.Add(genericParameterData));
 }
        public void BuildImplementation(IAssembly target)
        {
            if (IEnumerableOfT == null)
            {
                IEnumerableOfT = typeof(IEnumerable <>).GetTypeReference <IInterfaceType>(this._assembly.IdentityManager);
            }
            if (IControlledDictionaryOfTKeyTValue == null)
            {
                IControlledDictionaryOfTKeyTValue = typeof(IControlledDictionary <,>).GetTypeReference <IInterfaceType>(this._assembly.IdentityManager);
            }
            if (IntermediateDeclDict == null)
            {
                IntermediateDeclDict = typeof(IIntermediateDeclarationDictionary <, ,>).GetTypeReference <IInterfaceType>(this._assembly.IdentityManager);
            }
            IType ignoreAttr    = typeof(VisitorImplementationIgnorePropertyAttribute).GetTypeReference(this._assembly.IdentityManager);
            IType ignoreSetAttr = typeof(VisitorImplementationIgnoreLocalSetAttribute).GetTypeReference(this._assembly.IdentityManager);
            var   requireAttr   = typeof(VisitorPropertyRequirementAttribute).GetTypeReference(this._assembly.IdentityManager);
            bool  visitorsDoNotNeedConstraints = !string.IsNullOrEmpty(this.Detail.VisitRefactorName);
            var   builderInterfaces            = this._builders.SelectMany(k => k.RelevantTypes).Distinct().OfType <IInterfaceType>().ToArray();
            //var allEnumerables = builderInterfaces.Select(k => CreateEnumerableVariant(k)).ToArray();
            var distinctInterfaces =
                builderInterfaces.Concat(builderInterfaces.SelectMany(k => k.ImplementedInterfaces)).Distinct().ToArray();
            var interfaceProperties =
                (from iFace in distinctInterfaces.OfType <IInterfaceType>()
                 from prop in iFace.Properties.Values /*.Where(k => IsPropertyRelevant(ignoreAttr, builderInterfaces, k))*/.DefaultIfEmpty()
                 group prop by iFace).ToDictionary(k => k.Key, v => (v.First() == null ? (IEnumerable <IInterfacePropertyMember>) new IInterfacePropertyMember[0] : v).ToList());
            var interfacesWithAccept       = distinctInterfaces.OfType <IInterfaceType>().Where(k => k.Methods.Values.Any(j => j.Name == "Accept")).ToArray();
            var actionDetail               = typeof(VisitorImplementationActionDetailAttribute).GetTypeReference <IClassType>(this._assembly.IdentityManager);
            var relevantActionDetail       = target.Metadata.Where(k => k.Type == actionDetail && k.Parameters.GetIndexedParameter <string>(0).Item2 == this.Detail.TargetContext);
            var relevantActionDetailLookup = relevantActionDetail.ToDictionary(k => k.Parameters.GetIndexedParameter <IType>(1).Item2, v => VisitorImplementationActionDetail.DeriveFromMetadata(v));
            var relevantActionTypes        = relevantActionDetailLookup.Keys.ToArray();

            //foreach (var key in relevantActionTypes)
            //    foreach (var @interface in key.ImplementedInterfaces)
            //        if (!relevantActionDetailLookup.ContainsKey(@interface))
            //            relevantActionDetailLookup.Add(@interface, relevantActionDetailLookup[key]);
            builderInterfaces = builderInterfaces.Concat(interfacesWithAccept).Distinct().ToArray();
            var inheritanceDetail = (from iFace in builderInterfaces
                                     let baseTypes = iFace.ImplementedInterfaces.OfType <IInterfaceType>()
                                                     from iFace2 in new[] { iFace }.Concat(baseTypes).Distinct()
                                     group iFace2 by iFace).ToDictionary(k => k.Key, v => v.ToArray());

            bool isVoidReturn = !this.Detail.YieldingVisitor;

            if (visitorsDoNotNeedConstraints)
            {
                this.SecondaryResult = this.VisitorResult.Parts.Add();
                var relativeRoot = new string[] { this.VisitorResult.NamespaceName, this._assembly.DefaultNamespace.FullName }.GetRelativeRoot(".");
                if (!string.IsNullOrEmpty(relativeRoot))
                {
                    relativeRoot = this.VisitorResult.NamespaceName.Substring(relativeRoot.Length + 1);
                    relativeRoot = relativeRoot.Replace(".", @"\") + @"\";
                }

                this.SecondaryResult.Assembly.FileName = string.Format("{2}{0} ({1} Signatures)", this.Detail.TargetContext, this.Detail.VisitRefactorName, relativeRoot);
                this.VisitorResult.Assembly.FileName   = string.Format("{1}{0} (Visitor Signatures)", this.Detail.TargetContext, relativeRoot);
            }
            foreach (var builder in this._builders)
            {
                if (this.Detail.InheritedVisitors.Contains(builder.Detail.TargetContext))
                {
                    this.VisitorResult.ImplementedInterfaces.ImplementInterfaceQuick(builder.VisitorInterface);
                }
                foreach (var method in builder.VisitorInterface.Methods.Values)
                {
                    var gpData = new GenericParameterData[method.GenericParameters.Count];
                    if (method.TypeParameters.Count > 0)
                    {
                        for (int i = 0; i < method.TypeParameters.Count; i++)
                        {
                            var gParam = method.TypeParameters.Values[i];
                            gpData[i] = new GenericParameterData(gParam.Name);
                            if (!visitorsDoNotNeedConstraints)
                            {
                                gpData[i].Constraints.AddRange(gParam.Constraints.Select(k => k.TurnTypeParametersIntoSymbols()));
                                gpData[i].SpecialConstraint = gParam.SpecialConstraint;
                            }
                        }
                    }
                    var parameterData = new TypedNameSeries(method.Parameters.Values.Select(k => k.ParameterType.WithName(k.Name)));
                    var newMethod     = this.VisitorResult.Methods.Add(method.ReturnType.WithName(method.Name), parameterData, gpData);
                    if (visitorsDoNotNeedConstraints)
                    {
                        newMethod.Implementations.Add(builder.VisitorInterface);
                        foreach (var gpDetail in from gpDatum in gpData
                                 join genericParameter in method.TypeParameters.Values on gpDatum.Name equals genericParameter.Name
                                 select new { GenericParameterDatum = gpDatum, GenericParameter = genericParameter })
                        {
                            gpDetail.GenericParameterDatum.Constraints.AddRange(gpDetail.GenericParameter.Constraints.Select(k => k.TurnTypeParametersIntoSymbols()));
                            gpDetail.GenericParameterDatum.SpecialConstraint = gpDetail.GenericParameter.SpecialConstraint;
                        }
                        var secondNewMethod = this.SecondaryResult.Methods.Add(method.ReturnType.WithName(this.Detail.VisitRefactorName), parameterData, gpData);
                        secondNewMethod.AccessLevel = AccessLevelModifiers.Public;
                        if (this.Detail.VisitRefactorAbstract)
                        {
                            secondNewMethod.IsAbstract = true;
                        }
                        var paramRefs  = parameterData.Select(k => newMethod.Parameters[k.Name].GetReference()).ToArray();
                        var invocation = newMethod.IsGenericConstruct
                                         ? secondNewMethod.GetReference(null, newMethod.GenericParameters).Invoke(paramRefs)
                                         : secondNewMethod.GetReference(null).Invoke(paramRefs);
                        var firstParam     = newMethod.Parameters.Values[0];
                        var firstParamType = firstParam.ParameterType;
                        if (firstParamType is IInterfaceType)
                        {
                            foreach (var prop in EnumerateInterfaceProperties((IInterfaceType)firstParamType, ignoreAttr, inheritanceDetail, interfaceProperties))
                            {
                                var propertyRelevanceInfo        = IsPropertyRelevant(prop.Item1, builderInterfaces, ignoreAttr, relevantActionTypes);
                                var requirement                  = prop.Item1.Metadata[requireAttr];
                                IBlockStatementParent codeTarget = secondNewMethod;
                                if (propertyRelevanceInfo.Item2 != VisitorImplementationTypeRelevance.NotRelevant)
                                {
                                    if (requirement != null)
                                    {
                                        codeTarget = codeTarget.If(firstParam.GetReference().GetProperty(requirement.Parameters.GetIndexedParameter <string>(0).Item2));
                                    }
                                    else if (prop.Item1.PropertyType.Type == TypeKind.Interface || prop.Item1.PropertyType.Type == TypeKind.Class)
                                    {
                                        codeTarget = codeTarget.If(firstParam.GetReference().GetProperty(prop.Item1.Name).InequalTo(IntermediateGateway.NullValue));
                                    }
                                }
                                switch (propertyRelevanceInfo.Item2)
                                {
                                case VisitorImplementationTypeRelevance.AsItem:
                                    codeTarget.Call(firstParam.GetReference().GetProperty(prop.Item1.Name).GetMethod("Accept").Invoke(new IExpression[] { this.VisitorResult.GetThis() }.Concat(newMethod.Parameters.Values.Skip(1).Select(k => k.GetReference())).ToArray()));
                                    break;

                                case VisitorImplementationTypeRelevance.AsActionableItemSet:
                                    ProcessActionableSet(relevantActionDetailLookup, firstParam, prop, propertyRelevanceInfo, codeTarget, 0, null);
                                    break;

                                case VisitorImplementationTypeRelevance.AsActionableValueSet:
                                    ProcessActionableSet(relevantActionDetailLookup, firstParam, prop, propertyRelevanceInfo, codeTarget, 1, "Values");
                                    break;

                                case VisitorImplementationTypeRelevance.AsActionableDeclValueSet:
                                    ProcessActionableSet(relevantActionDetailLookup, firstParam, prop, propertyRelevanceInfo, codeTarget, 2, "Values");
                                    break;

                                case VisitorImplementationTypeRelevance.AsActionableItem:
                                    IType ratType = propertyRelevanceInfo.Item1;
                                    if (ratType.IsGenericTypeParameter)
                                    {
                                        var gpRat      = (IGenericParameter)(ratType);
                                        var interfaces = gpRat.Constraints.Concat(gpRat.Constraints.SelectMany(r => r.ImplementedInterfaces)).Distinct().ToArray();
                                        ratType = interfaces.FirstOrDefault(k => relevantActionDetailLookup.ContainsKey(k));
                                    }
                                    else if (!relevantActionDetailLookup.ContainsKey(ratType))
                                    {
                                        var interfaces = ratType.ImplementedInterfaces;
                                        ratType = interfaces.FirstOrDefault(k => relevantActionDetailLookup.ContainsKey(k));
                                    }
                                    var currentActionDetail = relevantActionDetailLookup[ratType];
                                    codeTarget.Call(
                                        this.VisitorResult
                                        .GetThis()
                                        .GetMethod(currentActionDetail.TargetAction)
                                        .Invoke(
                                            firstParam
                                            .GetReference()
                                            .GetProperty(prop.Item1.Name)));
                                    break;
                                //case VisitorImplementationTypeRelevance.AsActionableItemSet:
                                //    IType enumerableRatType = propertyRelevanceInfo.Item1;
                                //    var genericParam = ((IGenericType)(enumerableRatType)).GenericParameters.FirstOrDefault();
                                //    if (genericParam != null)
                                //    {
                                //        if (genericParam.IsGenericTypeParameter)
                                //        {
                                //            var gpRat = (IGenericParameter)(genericParam);
                                //            var interfaces = gpRat.Constraints.Concat(gpRat.Constraints.SelectMany(r => r.ImplementedInterfaces)).Distinct().ToArray();
                                //            genericParam = interfaces.FirstOrDefault(k => relevantActionDetailLookup.ContainsKey(k));
                                //        }
                                //        else if (!relevantActionDetailLookup.ContainsKey(genericParam))
                                //        {
                                //            var interfaces = genericParam.ImplementedInterfaces;
                                //            genericParam = interfaces.FirstOrDefault(k => relevantActionDetailLookup.ContainsKey(k));
                                //        }
                                //        var currentActionSetDetail = relevantActionDetailLookup[genericParam];
                                //        codeTarget.Call(this.VisitorResult.GetThis().GetMethod(currentActionSetDetail.TargetPluralAction).Invoke(firstParam.GetReference().GetProperty(prop.Item1.Name)));
                                //    }
                                //    break;

                                case VisitorImplementationTypeRelevance.AsValueSet:
                                case VisitorImplementationTypeRelevance.AsDeclValueSet:
                                    codeTarget.Call(this.VisitorResult.GetThis().GetMethod(this.Detail.VisitRefactorName ?? "Visit").Invoke(firstParam.GetReference().GetProperty(prop.Item1.Name).GetProperty("Values")));
                                    break;

                                case VisitorImplementationTypeRelevance.AsItemSet:
                                    codeTarget.Call(this.VisitorResult.GetThis().GetMethod(this.Detail.VisitRefactorName ?? "Visit").Invoke(firstParam.GetReference().GetProperty(prop.Item1.Name)));
                                    break;

                                default:
                                    break;
                                }
                            }
                            if (!firstParamType.Metadata.Contains(ignoreSetAttr))
                            {
                                var enAccess = IsTypeRelevantForEnumerableAccess(builderInterfaces, firstParamType, relevantActionTypes);
                                if (enAccess.Item2 == VisitorImplementationTypeRelevance.AsItemSet)
                                {
                                    secondNewMethod.Call(this.VisitorResult.GetThis().GetMethod(this.Detail.VisitRefactorName ?? "Visit").Invoke(firstParam.GetReference().Cast(enAccess.Item1)));
                                }
                            }
                        }
                        if (isVoidReturn)
                        {
                            newMethod.Call(invocation);
                        }
                        else
                        {
                            newMethod.Return(invocation);
                        }
                    }
                    else
                    {
                    }
                }
            }
        }