private string ResolveMixinInstanceTypeFullName( MixinGenerationPlan mixinPlan) { if (!mixinPlan.ProtectedWrapperPlan.Members.Any() && ( !mixinPlan.AbstractWrapperPlan.Members.Any() || mixinPlan.MixinAttribute.ExplicitlyInitializeMixin )) { //Can just use mixin type return (mixinPlan.MixinAttribute.Mixin.GetOriginalFullNameWithGlobal()); } else if (mixinPlan.AbstractWrapperPlan.GenerateAbstractWrapperInExternalNamespace) { //External_Namespace.AbstractWrapper return (mixinPlan.ExternalMixinSpecificAutoGeneratedNamespaceName.EnsureEndsWith(".") + mixinPlan.AbstractWrapperPlan.AbstractWrapperClassName); } else { //Abstract warpper is in the same namespace return(mixinPlan.AbstractWrapperPlan.AbstractWrapperClassName); } }
private void ImplementIContainsMixin( CodeGeneratorProxy codeBehind, MixinGenerationPlan mgp) { var containMixinInterfaceName = string.Format( "global::{0}.{1}<{2}>", typeof(IContainMixin <>).Namespace, "IContainMixin", mgp.MixinAttribute.Mixin.GetOriginalFullNameWithGlobal()); codeBehind.ImplementInterface( containMixinInterfaceName); codeBehind.CreateProperty( modifier: //implement explicitly string.Empty, returnTypeFullName: mgp.MixinAttribute.Mixin.GetOriginalFullNameWithGlobal(), propertyName: containMixinInterfaceName + ".MixinInstance", getterMethodBody: string.Format( "get{{ return {0}.{1}; }}", mgp.MasterWrapperPlan.MasterWrapperInstanceNameAvailableFromTargetCodeBehind, MasterWrapperPlan.MixinInstanceDataMemberName), setterMethodBody: //no setter string.Empty ); }
private ImplicitConversionPlan CollectImplicitConversionOperator(MixinGenerationPlan mgp) { if (mgp.MixinAttribute.Mixin.GetDefinition().IsPublic) { return new ImplicitConversionPlan { MixinGenerationPlan = mgp, ConversionTargetType = mgp.MixinAttribute.Mixin, } } ; //fall back to the first base type in Mixin that is public //otherwise return null return(mgp.MixinAttribute.Mixin.GetDefinition() .GetAllBaseTypes() .Where( t => t.GetDefinition().IsPublic&& t.GetDefinition().FullName.ToLower() != "system.object") .Select( t => new ImplicitConversionPlan { MixinGenerationPlan = mgp, ConversionTargetType = t }) .FirstOrDefault()); } }
private string GetMasterWrapperFullTypeName(MixinGenerationPlan mixinPlan) { return (TargetCodeBehindPlan.GlobalAutoGeneratedContainerClassName .EnsureEndsWith(".") + mixinPlan.MixinLevelAutoGeneratedContainerClass .EnsureEndsWith(".") + mixinPlan.MasterWrapperPlan.MasterWrapperClassName); }
private IEnumerable <IMethod> GetConstructors(MixinGenerationPlan mixinPlan) { var wrapAllConstructors = mixinPlan.MixinAttribute.ExplicitlyInitializeMixin || !mixinPlan.MixinAttribute.Mixin.HasParameterlessConstructor(); return (mixinPlan.MixinAttribute.Mixin .GetConstructors() .Where(c => c.IsProtected || wrapAllConstructors)); }
//TODO: Document this logic better. Forget the need for edge cases private string CreateMixinInitializationStatement( MixinGenerationPlan mixinPlan, string mixinInstanceTypeFullName) { if (mixinPlan.MixinAttribute.ExplicitlyInitializeMixin) { //initialize by casting the 'target' constructor parameter //to IMixinConstructorRequirement and calling InitializeMixin return (string.Format( @"( (global::CopaceticSoftware.pMixins.Infrastructure. IMixinConstructorRequirement<{0}>) {1} ) .InitializeMixin();", mixinInstanceTypeFullName, MasterWrapperPlan.TargetInstanceConstructorParameterName)); } else if (mixinPlan.MixinAttribute.Mixin.GetDefinition().IsSealed) { return (string.Format("base.TryActivateMixin<{0}>();", mixinPlan.MixinAttribute.Mixin.GetOriginalFullNameWithGlobal())); } else if (mixinPlan.MixinAttribute.Mixin.GetDefinition().IsAbstract) { return (string.Format("base.TryActivateMixin<{0}>({1});", mixinInstanceTypeFullName, MasterWrapperPlan.TargetInstanceConstructorParameterName)); } else if (mixinPlan.AbstractWrapperPlan.GenerateAbstractWrapperInExternalNamespace) { return (string.Format("base.TryActivateMixin<{0}>({1});", mixinPlan.ExternalMixinSpecificAutoGeneratedNamespaceName .EnsureEndsWith(".") + mixinPlan.AbstractWrapperPlan.AbstractWrapperClassName, MasterWrapperPlan.TargetInstanceConstructorParameterName)); } else { return (string.Format("base.TryActivateMixin<{0}>({1});", mixinPlan.AbstractWrapperPlan.AbstractWrapperClassName, MasterWrapperPlan.TargetInstanceConstructorParameterName)); } }
private ProtectedWrapperPlan BuildPlan(MixinGenerationPlan mixinPlan) { return(new ProtectedWrapperPlan { GenrateProtectedWrapper = !mixinPlan.MixinAttribute.Mixin.IsStaticOrSealed(), Constructors = GetConstructors(mixinPlan), Members = mixinPlan.Members.Where(m => m.Member.IsProtected && !m.Member.IsAbstract), GenerateProtectedWrapperInExternalNamespace = !mixinPlan.MixinAttribute.Mixin.GetDefinition().IsPrivate, ProtectedWrapperClassName = mixinPlan.MixinAttribute.Mixin.GetNameAsIdentifier() + "ProtectedMembersWrapper" }); }
private AbstractWrapperPlan BuildPlan(MixinGenerationPlan mixinPlan) { return(new AbstractWrapperPlan { GenrateAbstractWrapper = !mixinPlan.MixinAttribute.Mixin.IsStaticOrSealed(), Members = mixinPlan.Members.Where( x => x.Member.IsAbstract && !x.ImplementationDetails.ImplementExplicitly), Constructors = GetConstructors(mixinPlan), GenerateAbstractWrapperInExternalNamespace = !mixinPlan.MixinAttribute.Mixin.GetDefinition().IsPrivate, AbstractWrapperClassName = mixinPlan.MixinAttribute.Mixin.GetNameAsIdentifier() + "AbstractWrapper" }); }
private void CreateActivateDependencyMethod(CodeGeneratorProxy codeGenerator, MixinGenerationPlan mixinPlan) { const string targetInstanceMethodParameterName = "target"; var methodBodyStatements = new StringBuilder(); foreach (var dependency in mixinPlan.MasterWrapperPlan.MixinDependencies) { methodBodyStatements.AppendFormat( @" (({0}){1}).Dependency = {2}; (({0}){1}).OnDependencySet();", dependency.GetOriginalFullNameWithGlobal(), MasterWrapperPlan.MixinInstanceDataMemberName, targetInstanceMethodParameterName); } codeGenerator.CreateMethod( modifier: "public", returnTypeFullName: "void", methodName: mixinPlan.CodeGenerationPlan.TargetCodeBehindPlan.MixinsActivateMixinDependenciesMethodName, parameters: new[] { new KeyValuePair <string, string>( mixinPlan.CodeGenerationPlan.SourceClass.GetFullTypeName(), targetInstanceMethodParameterName) }, methodBody: methodBodyStatements.ToString() //make sure method has at least an empty body .IfEmpty("{}")); }
private MasterWrapperPlan BuildPlan(MixinGenerationPlan mixinPlan) { var mixinInstanceTypeFullName = ResolveMixinInstanceTypeFullName(mixinPlan); return(new MasterWrapperPlan { MixinGenerationPlan = mixinPlan, MasterWrapperClassName = mixinPlan.MixinAttribute.Mixin.GetNameAsIdentifier() + "MasterWrapper", MasterWrapperInstanceNameInMixinsContainer = mixinPlan.MixinAttribute.Mixin.GetFullNameAsIdentifier(), MixinInstanceTypeFullName = mixinInstanceTypeFullName, MixinInstanceInitializationStatement = CreateMixinInitializationStatement(mixinPlan, mixinInstanceTypeFullName), MixinDependencies = mixinPlan.MixinAttribute.Mixin .GetAllBaseTypes() .Where(t => t.Kind == TypeKind.Interface && t.GetOriginalFullName().StartsWith( typeof(IMixinDependency <>).GetOriginalFullName() //This is hacky, but can't find a way to compare typeof(IMixinDependency<>) //to new IType(IMixinDependency<int>) .Replace("<>", ""))), ImplementExplicitlyMembers = mixinPlan.Members .Where(x => x.ImplementationDetails.ImplementExplicitly), ProtectedAbstractMembers = mixinPlan.Members .Where(m => (m.Member.IsAbstract || m.Member.IsOverride) && m.Member.IsProtected && !m.ImplementationDetails.ImplementExplicitly), RegularMembers = mixinPlan.Members .Where(m => !m.Member.IsStaticOrConst() && !(m.Member.IsAbstract && m.Member.IsProtected) && !m.Member.IsOverride && !m.Member.IsOverridable && !m.Member.IsVirtual && !m.ImplementationDetails.ImplementExplicitly), StaticMembers = mixinPlan.Members .Where(m => m.Member.IsStaticOrConst()), VirtualMembers = mixinPlan.Members .Where(m => !m.ImplementationDetails.ImplementExplicitly && (m.Member.IsVirtual || ( m.Member.IsOverride || m.Member.IsOverridable && !m.Member.IsProtected))), }); }