コード例 #1
0
        public static (bool hasAttribute, ITypeSymbol?managedType, CustomTypeMarshallerData?kind) GetMarshallerShapeInfo(ITypeSymbol marshallerType)
        {
            var attr = marshallerType.GetAttributes().FirstOrDefault(attr => attr.AttributeClass.ToDisplayString() == TypeNames.CustomTypeMarshallerAttribute);

            if (attr is null)
            {
                return(false, null, null);
            }
            if (attr.ConstructorArguments.Length == 0)
            {
                return(true, null, null);
            }
            CustomTypeMarshallerKind kind = CustomTypeMarshallerKind.Value;
            ITypeSymbol?managedType       = attr.ConstructorArguments[0].Value as ITypeSymbol;

            if (attr.ConstructorArguments.Length > 1)
            {
                if (attr.ConstructorArguments[1].Value is not int i)
                {
                    return(true, managedType, null);
                }
                kind = (CustomTypeMarshallerKind)i;
            }
            var namedArguments = attr.NamedArguments.ToImmutableDictionary();
            int?bufferSize     = namedArguments.TryGetValue(CustomMarshallerAttributeFields.BufferSize, out TypedConstant bufferSizeConstant) ? bufferSizeConstant.Value as int? : null;
            CustomTypeMarshallerDirection direction = namedArguments.TryGetValue(CustomMarshallerAttributeFields.Direction, out TypedConstant directionConstant) ? (CustomTypeMarshallerDirection)directionConstant.Value : CustomTypeMarshallerDirection.Ref;
            CustomTypeMarshallerFeatures  features  = namedArguments.TryGetValue(CustomMarshallerAttributeFields.Features, out TypedConstant featuresConstant) ? (CustomTypeMarshallerFeatures)featuresConstant.Value : CustomTypeMarshallerFeatures.None;

            return(true, managedType, new CustomTypeMarshallerData(kind, direction, features, bufferSize));
        }
コード例 #2
0
        private static SyntaxNode AddMissingFeatures(string attributeName, AttributeData?customTypeMarshallerAttribute, CustomTypeMarshallerFeatures featuresToAdd, SyntaxGenerator gen)
        {
            SyntaxNode newAttributeSyntax = gen.Attribute(attributeName);

            newAttributeSyntax = gen.AddAttributeArguments(newAttributeSyntax, customTypeMarshallerAttribute.ConstructorArguments.Select(a => gen.AttributeArgument(gen.TypedConstantExpression(a))));

            CustomTypeMarshallerFeatures newFeaturesValue = featuresToAdd;
            int?featuresArgLocation = null;

            newAttributeSyntax = gen.AddAttributeArguments(newAttributeSyntax, customTypeMarshallerAttribute.NamedArguments
                                                           .Where((a, i) =>
            {
                if (a.Key == "Features")
                {
                    // Capture the original location of the 'Features' named argument so we can update it "in place".
                    featuresArgLocation = customTypeMarshallerAttribute.ConstructorArguments.Length + i;
                    newFeaturesValue   |= (CustomTypeMarshallerFeatures)a.Value.Value;
                    return(false);
                }
                return(true);
            })
                                                           .Select(a => gen.AttributeArgument(a.Key, gen.TypedConstantExpression(a.Value))));

            SyntaxNode featureAttributeArgument = gen.AttributeArgument("Features",
                                                                        gen.GetEnumValueAsFlagsExpression(
                                                                            customTypeMarshallerAttribute.AttributeClass.GetMembers(ManualTypeMarshallingHelper.CustomMarshallerAttributeFields.Features).OfType <IPropertySymbol>().First().Type,
                                                                            (int)newFeaturesValue,
                                                                            includeZeroValueFlags: false));

            newAttributeSyntax = featuresArgLocation is null
                ? gen.AddAttributeArguments(newAttributeSyntax, new[] { featureAttributeArgument })
                : gen.InsertAttributeArguments(newAttributeSyntax, featuresArgLocation.Value, new[] { featureAttributeArgument });

            return(newAttributeSyntax);
        }
コード例 #3
0
        private static (CustomTypeMarshallerFeatures featuresToAdd, List <Diagnostic> fixedDiagnostics) GetFeaturesToAdd(IEnumerable <Diagnostic> diagnostics)
        {
            List <Diagnostic>            featuresToAddDiagnostics = new();
            CustomTypeMarshallerFeatures featuresToAdd            = CustomTypeMarshallerFeatures.None;

            foreach (var diagnostic in diagnostics)
            {
                if (diagnostic.Id == AnalyzerDiagnostics.Ids.ProvidedMethodsNotSpecifiedInFeatures)
                {
                    featuresToAddDiagnostics.Add(diagnostic);
                    if (diagnostic.Properties.TryGetValue(CustomTypeMarshallerAnalyzer.MissingFeaturesKey, out string missingFeatures) &&
                        Enum.TryParse(missingFeatures, out CustomTypeMarshallerFeatures featuresValue))
                    {
                        featuresToAdd |= featuresValue;
                    }
                }
            }

            return(featuresToAdd, featuresToAddDiagnostics);
        }
コード例 #4
0
        private static async Task <Document> AddMissingFeatures(Document doc, SyntaxNode node, CustomTypeMarshallerFeatures featuresToAdd, CancellationToken ct)
        {
            var editor = await DocumentEditor.CreateAsync(doc, ct).ConfigureAwait(false);

            var gen = editor.Generator;

            ISymbol marshallerType = editor.SemanticModel.GetDeclaredSymbol(node, ct);

            AttributeData customTypeMarshallerAttribute = marshallerType.GetAttributes().FirstOrDefault(attr => attr.AttributeClass.ToDisplayString() == TypeNames.CustomTypeMarshallerAttribute);

            SyntaxNode attributeSyntax = await customTypeMarshallerAttribute.ApplicationSyntaxReference !.GetSyntaxAsync(ct).ConfigureAwait(false);

            SyntaxNode updatedDeclaration = AddMissingFeatures(gen.GetName(attributeSyntax), customTypeMarshallerAttribute, featuresToAdd, gen);

            editor.ReplaceNode(attributeSyntax, updatedDeclaration);

            return(editor.GetChangedDocument());
        }