private void SetDetails( CodeGenerationPlan cgp, MemberImplementationDetails implDetails) { var member = implDetails.ParentMemberWrapper.Member; if (member.IsExplicitInterfaceImplementation) { implDetails.ExplicitInterfaceImplementationType = member.ImplementedInterfaceMembers.First().DeclaringType; } implDetails.ImplementInTargetAsAbstract = member.IsAbstract && implDetails.ParentMemberWrapper.MixinAttribute.KeepAbstractMembersAbstract; var sourceClassAlsoDefinesMember = cgp.SourceClassMembers.Contains(member, new MemberExtensions.MemberEqualityComparer()); implDetails.RequirementsInterfaceImplementationName = (member.IsAbstract && !sourceClassAlsoDefinesMember && !implDetails.ImplementInTargetAsAbstract) ? member.Name + "Implementation" : member.Name; if (member.IsAbstract && member.IsProtected) { implDetails.ProtectedAbstractMemberPromotedToPublicMemberName = member.Name + "_Public"; } }
private void AddLockDataMember(CodeGeneratorProxy mixinsClassCodeGenerator, CodeGenerationPlan codeGenerationPlan) { mixinsClassCodeGenerator.CreateDataMember( modifiers: "public static", dataMemberTypeFullName: "global::System.Object", dataMemberName: codeGenerationPlan.TargetCodeBehindPlan.MixinsLockVariableName, initializerExpression: "= new global::System.Object();"); }
private bool EnsureMixinDependenciesAreSatisfied( ICreateCodeGenerationPlanPipelineState manager, CodeGenerationPlan cgp) { var mixinBaseTypeMap = cgp.MixinGenerationPlans.Values .Select(mgp => mgp.MixinAttribute) .ToDictionary( x => x.Mixin.GetOriginalFullName(), x => x.Mixin.GetAllBaseTypes()); var allBaseTypes = mixinBaseTypeMap .SelectMany(x => x.Value) .Union( cgp.SourceClass.BaseTypes .Select(bt => manager.CommonState.Context.TypeResolver.Resolve(bt).Type)) .ToList(); var unsatisfiedDependencies = mixinBaseTypeMap //Take only Mixin base types .SelectMany(x => x.Value) //Get IMixinDependency .Where(bt => TypeIsIMixinDependency(bt)) //Cast in order to get generic parameter .OfType <ParameterizedType>() //Pull out generic param .Select(bt => bt.TypeArguments.First()) //Filter out .Where(md => !allBaseTypes.Contains(md)) .ToList(); //Add interface dependencies to Target cgp.TargetCodeBehindPlan.MixinInterfaces.AddRange( unsatisfiedDependencies .Where(md => md.Kind == TypeKind.Interface)); var unsatisfiedClassDependencies = unsatisfiedDependencies .Where(md => md.Kind != TypeKind.Interface) .ToList(); //Write out errors if (unsatisfiedClassDependencies.Count > 0) { foreach (var dep in unsatisfiedDependencies) { var mixin = cgp.MixinGenerationPlans.Values.Select(mgp => mgp.MixinAttribute) .First(mix => mix.Mixin.FullName == mixinBaseTypeMap .First(x => x.Value.OfType <ParameterizedType>() .Any(p => p.TypeArguments.First().Equals(dep))) .Key); manager.CommonState.CodeGenerationErrors.Add( new CodeGenerationError { Message = string.Format( Strings.ErrorMixinDependencyIsClassAndIsNotSatisified, mixin.Mixin.GetOriginalFullName(), cgp.SourceClass.Name, dep.GetOriginalFullName()), Line = (uint)cgp.SourceClass.GetRegion().BeginLine, Column = (uint)cgp.SourceClass.GetRegion().EndLine, Severity = CodeGenerationError.SeverityOptions.Error }); } return(false); } return(true); }