Esempio n. 1
0
 public CompilationAnalyzer(IGeneratorExecutionContext context, WellKnownTypes wellKnownTypes, Compilation compilation)
 {
     this.context                            = context;
     this.wellKnownTypes                     = wellKnownTypes;
     this.serializableAttribute              = wellKnownTypes.SerializableAttribute;
     this.knownBaseTypeAttribute             = wellKnownTypes.KnownBaseTypeAttribute;
     this.knownAssemblyAttribute             = wellKnownTypes.KnownAssemblyAttribute;
     this.considerForCodeGenerationAttribute = wellKnownTypes.ConsiderForCodeGenerationAttribute;
     this.compilation                        = compilation;
 }
Esempio n. 2
0
        public CodeGenerator(IGeneratorExecutionContext context, CodeGeneratorOptions options)
        {
            this.context             = context;
            this.compilation         = context.Compilation;
            this.options             = options;
            this.wellKnownTypes      = new WellKnownTypes(compilation);
            this.compilationAnalyzer = new CompilationAnalyzer(context, this.wellKnownTypes, compilation);

            var firstSyntaxTree = compilation.SyntaxTrees.FirstOrDefault() ?? throw new InvalidOperationException("Compilation has no syntax trees.");

            this.semanticModelForAccessibility = compilation.GetSemanticModel(firstSyntaxTree);
            this.serializerTypeAnalyzer        = SerializerTypeAnalyzer.Create(this.wellKnownTypes);
            this.serializerGenerator           = new SerializerGenerator(this.options, this.wellKnownTypes);
            this.grainMethodInvokerGenerator   = new GrainMethodInvokerGenerator(this.options, this.wellKnownTypes);
            this.grainReferenceGenerator       = new GrainReferenceGenerator(this.options, this.wellKnownTypes);
        }
Esempio n. 3
0
        /// <summary>
        /// Generates the non serializer class for the provided grain types.
        /// </summary>
        internal (TypeDeclarationSyntax, TypeSyntax) GenerateClass(IGeneratorExecutionContext context, SemanticModel model, SerializerTypeDescription description)
        {
            var className    = GetGeneratedClassName(description.Target);
            var type         = description.Target;
            var genericTypes = type.GetHierarchyTypeParameters().Select(_ => TypeParameter(_.ToString())).ToArray();

            var attributes = new List <AttributeSyntax>
            {
                GeneratedCodeAttributeGenerator.GetGeneratedCodeAttributeSyntax(wellKnownTypes),
                Attribute(wellKnownTypes.ExcludeFromCodeCoverageAttribute.ToNameSyntax()),
                Attribute(wellKnownTypes.SerializerAttribute.ToNameSyntax())
                .AddArgumentListArguments(
                    AttributeArgument(TypeOfExpression(type.WithoutTypeParameters().ToTypeSyntax())))
            };

            var fields = GetFields(context, model, type);

            var members = new List <MemberDeclarationSyntax>(GenerateFields(fields))
            {
                GenerateConstructor(className, fields),
                GenerateDeepCopierMethod(type, fields, model),
                GenerateSerializerMethod(type, fields, model),
                GenerateDeserializerMethod(type, fields, model),
            };

            var classDeclaration =
                ClassDeclaration(className)
                .AddModifiers(Token(SyntaxKind.InternalKeyword))
                .AddModifiers(Token(SyntaxKind.SealedKeyword))
                .AddAttributeLists(AttributeList().AddAttributes(attributes.ToArray()))
                .AddMembers(members.ToArray())
                .AddConstraintClauses(type.GetTypeConstraintSyntax());

            if (genericTypes.Length > 0)
            {
                classDeclaration = classDeclaration.AddTypeParameterListParameters(genericTypes);
            }

            if (this.options.DebuggerStepThrough)
            {
                var debuggerStepThroughAttribute = Attribute(this.wellKnownTypes.DebuggerStepThroughAttribute.ToNameSyntax());
                classDeclaration = classDeclaration.AddAttributeLists(AttributeList().AddAttributes(debuggerStepThroughAttribute));
            }

            return(classDeclaration, ParseTypeName(type.GetParsableReplacementName(className)));
        }
Esempio n. 4
0
        /// <summary>
        /// Returns a sorted list of the fields of the provided type.
        /// </summary>
        private List <FieldInfoMember> GetFields(IGeneratorExecutionContext context, SemanticModel model, INamedTypeSymbol type)
        {
            var result = new List <FieldInfoMember>();

            foreach (var field in type.GetDeclaredInstanceMembers <IFieldSymbol>())
            {
                if (ShouldSerializeField(field))
                {
                    result.Add(new FieldInfoMember(this, model, type, field, result.Count));
                }
            }

            if (type.TypeKind == TypeKind.Class)
            {
                // Some reference assemblies are compiled without private fields.
                // Warn the user if they are inheriting from a type in one of these assemblies using a heuristic:
                // If the type inherits from a type in a reference assembly and there are no fields declared on those
                // base types, emit a warning.
                var hasUnsupportedRefAsmBase   = false;
                var referenceAssemblyHasFields = false;
                var baseType = type.BaseType;
                while (baseType != null &&
                       !SymbolEqualityComparer.Default.Equals(baseType, wellKnownTypes.Object) &&
                       !SymbolEqualityComparer.Default.Equals(baseType, wellKnownTypes.Attribute))
                {
                    if (!hasUnsupportedRefAsmBase &&
                        baseType.ContainingAssembly.HasAttribute("ReferenceAssemblyAttribute") &&
                        !IsSupportedRefAsmType(baseType))
                    {
                        hasUnsupportedRefAsmBase = true;
                    }
                    foreach (var field in baseType.GetDeclaredInstanceMembers <IFieldSymbol>())
                    {
                        if (hasUnsupportedRefAsmBase)
                        {
                            referenceAssemblyHasFields = true;
                        }
                        if (ShouldSerializeField(field))
                        {
                            result.Add(new FieldInfoMember(this, model, type, field, result.Count));
                        }
                    }

                    baseType = baseType.BaseType;
                }

                if (hasUnsupportedRefAsmBase && !referenceAssemblyHasFields)
                {
                    var declaration = type.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax() as TypeDeclarationSyntax;
                    context.ReportDiagnostic(RefAssemblyBaseTypeDiagnosticAnalyzer.CreateDiagnostic(declaration));
                }

                bool IsSupportedRefAsmType(INamedTypeSymbol t)
                {
                    INamedTypeSymbol baseDefinition;

                    if (t.IsGenericType && !t.IsUnboundGenericType)
                    {
                        baseDefinition = t.ConstructUnboundGenericType().OriginalDefinition;
                    }
                    else
                    {
                        baseDefinition = t.OriginalDefinition;
                    }

                    foreach (var refAsmType in wellKnownTypes.SupportedRefAsmBaseTypes)
                    {
                        if (SymbolEqualityComparer.Default.Equals(baseDefinition, refAsmType))
                        {
                            return(true);
                        }
                    }

                    return(false);
                }
            }

            result.Sort(FieldInfoMember.Comparer.Instance);
            return(result);
        }