Exemple #1
0
        private static void AnalyzeCall(SyntaxNodeAnalysisContext context, ISymbol migratableAttributeType, ISymbol dataContractAttributeType, ISymbol dataMemberAttributeType)
        {
            var typeDecl      = (TypeDeclarationSyntax)context.Node;
            var semanticModel = context.SemanticModel;
            var ct            = context.CancellationToken;

            var isMigratable = MigrationHashHelper.HasAttribute(typeDecl, migratableAttributeType, semanticModel, ct);

            if (!isMigratable)
            {
                return;
            }

            if (dataContractAttributeType != null && dataMemberAttributeType != null)
            {
                var isDataContract = MigrationHashHelper.HasAttribute(typeDecl, dataContractAttributeType, semanticModel, ct);
                var hasDataMember  = MigrationHashHelper.GetDataMembers(typeDecl, ct, semanticModel, dataMemberAttributeType).Any();

                if (isDataContract && hasDataMember)
                {
                    return;
                }
            }

            var diagnostic = Diagnostic.Create(Rule, typeDecl.GetLocation(), typeDecl.Identifier.ToString());

            context.ReportDiagnostic(diagnostic);
        }
Exemple #2
0
        private static void AnalyzeCall(SyntaxNodeAnalysisContext context, ISymbol migratableAttributeType)
        {
            var ct = context.CancellationToken;
            var typeDeclaration = (TypeDeclarationSyntax)context.Node;
            var attribute       = MigrationHashHelper.GetAttribute(typeDeclaration, migratableAttributeType, context.SemanticModel, ct);

            if (attribute == null)
            {
                return;
            }

            var typeSymbol       = context.SemanticModel.GetDeclaredSymbol(typeDeclaration, ct);
            var verifier         = new MigrationMethodVerifier(CanAssign(context));
            var migrationMethods = MigrationHashHelper.GetMigrationMethods(typeSymbol);

            var invalidMethods = verifier.VerifyMigrationMethods(migrationMethods)
                                 .Where(x => x.Result != VerificationResultEnum.Ok);

            foreach (var x in invalidMethods)
            {
                var method = typeSymbol.GetMembers()
                             .First(sy => sy.Name == x.Method.Name);
                Debug.Assert(method.Locations.Length == 1, "Method has multiple locations.");
                var diagnostic = Diagnostic.Create(Rule, method.Locations[0], method.Name, typeSymbol.Name, x.Result);
                context.ReportDiagnostic(diagnostic);
            }
        }
        private static async Task <Document> FixMigrationHash(Document document, TypeDeclarationSyntax typeDecl, CancellationToken ct)
        {
            var semanticModel = await document.GetSemanticModelAsync(ct);

            var newTypeDecl = MigrationHashHelper.UpdateMigrationHash(typeDecl, ct, semanticModel);

            var root = await document.GetSyntaxRootAsync(ct);

            var newRoot = root.ReplaceNode(typeDecl, newTypeDecl);

            return(document.WithSyntaxRoot(newRoot));
        }
Exemple #4
0
        private static async Task <Document> AddMigrationMethod(Document document, TypeDeclarationSyntax typeDecl, CancellationToken ct)
        {
            var semanticModel = await document.GetSemanticModelAsync(ct);

            var typeSymbol            = semanticModel.GetDeclaredSymbol(typeDecl, ct);
            var latestMigrationMethod = MigrationHashHelper.GetMigrationMethods(typeSymbol).LastOrDefault();

            var latestVersion        = latestMigrationMethod?.ToVersion ?? 0;
            var dataArgumentTypeName = latestMigrationMethod?.ReturnType.Name ?? "JToken";
            var method = GetMigrationMethod(latestVersion + 1, dataArgumentTypeName, ct);
            var typeDeclWithUpdatedMigrationHash = MigrationHashHelper.UpdateMigrationHash(typeDecl, ct, semanticModel);
            var typeDeclWithAddedMigrationMethod = AddMember(typeDeclWithUpdatedMigrationHash, method);

            var root = (CompilationUnitSyntax)await document.GetSyntaxRootAsync(ct);

            var rootWithNewTypeDecl = root.ReplaceNode(typeDecl, typeDeclWithAddedMigrationMethod);

            return(document.WithSyntaxRoot(rootWithNewTypeDecl));
        }
Exemple #5
0
        private static void AnalyzeCall(SyntaxNodeAnalysisContext context, ISymbol migratableAttributeType, ISymbol dataMemberAttributeType)
        {
            var ct = context.CancellationToken;
            var typeDeclaration = (TypeDeclarationSyntax)context.Node;
            var attribute       = MigrationHashHelper.GetAttribute(typeDeclaration, migratableAttributeType, context.SemanticModel, ct);

            if (attribute == null)
            {
                return;
            }

            var attributeHash = GetAttributeHash(attribute, context.SemanticModel, ct);
            var computedHash  = MigrationHashHelper.GetMigrationHashFromType(typeDeclaration, ct, context.SemanticModel, dataMemberAttributeType);

            if (attributeHash != computedHash)
            {
                var diagnostic = Diagnostic.Create(Rule, typeDeclaration.GetLocation(), typeDeclaration.Identifier.ToString(), computedHash, attributeHash);
                context.ReportDiagnostic(diagnostic);
            }
        }
        public void ShouldGetAllDataMembers()
        {
            var tree = SyntaxFactory.ParseSyntaxTree(@"using System.Runtime.Serialization;

public class A
{
    public string PropertyA { get; }
    [DataMember] public string PropertyB { get; }
    public int FieldA { get; }
    [DataMember] public int FieldB { get; }
}");

            var compilation = CSharpCompilation.Create(
                "MyCompilation",
                syntaxTrees: new[] { tree },
                references: new[]
            {
                MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
                MetadataReference.CreateFromFile(typeof(DataMemberAttribute).Assembly.Location)
            });
            var model = compilation.GetSemanticModel(tree);

            var typeDecl = tree
                           .GetRoot()
                           .ChildNodes()
                           .OfType <TypeDeclarationSyntax>()
                           .Single();

            var dataMemberAttributeType = compilation.GetTypeByMetadataName(Constants.DataMemberAttributeMetadataName);

            var dataMembers = MigrationHashHelper.GetDataMembers(typeDecl, CancellationToken.None, model, dataMemberAttributeType);

            dataMembers.Count.Should().Be(2);
            dataMembers[0].Identifier.Should().Be("FieldB");
            dataMembers[0].Type.Should().Be("int");
            dataMembers[1].Identifier.Should().Be("PropertyB");
            dataMembers[1].Type.Should().Be("string");
        }