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); }
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 { } } } }