private void AnalyzeSimpleBaseType(
            SyntaxNodeAnalysisContext context,
            IImmutableSet <INamedTypeSymbol> disallowedTypes
            )
        {
            SimpleBaseTypeSyntax baseTypeSyntax = (SimpleBaseTypeSyntax)context.Node;
            SymbolInfo           baseTypeSymbol = context.SemanticModel.GetSymbolInfo(baseTypeSyntax.Type);

            INamedTypeSymbol baseSymbol = (baseTypeSymbol.Symbol as INamedTypeSymbol);

            if (baseSymbol.IsNullOrErrorType())
            {
                return;
            }

            if (!disallowedTypes.Contains(baseSymbol))
            {
                return;
            }

            Diagnostic diagnostic = Diagnostic.Create(
                Diagnostics.EventHandlerDisallowed,
                baseTypeSyntax.GetLocation(),
                baseSymbol.ToDisplayString()
                );

            context.ReportDiagnostic(diagnostic);
        }
        /// <summary>
        /// Checks if symbol under carret is object mapper interface.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="context">The context.</param>
        private static void CheckForObjectMapperBaseInterface(SimpleBaseTypeSyntax node, SyntaxNodeAnalysisContext context)
        {
            SimpleNameSyntax sns = (node.Type as SimpleNameSyntax) ?? (node.Type as QualifiedNameSyntax).Right;
            var className = sns?.Identifier.Text;
            if (className != "IObjectMapper" && className != "IObjectMapperAdapter")
            {
                return;
            }
            var symbol = context.SemanticModel.GetSymbolInfo(sns).Symbol as INamedTypeSymbol;
            if (symbol == null || symbol.TypeKind != TypeKind.Interface || !symbol.IsGenericType)
            {
                return;
            }

            var fullSymbolName = symbol.OriginalDefinition.ToDisplayString();
            if (fullSymbolName != "ObjectMapper.Framework.IObjectMapper<T>" && fullSymbolName != "ObjectMapper.Framework.IObjectMapperAdapter<T, U>")
            {
                return;
            }

            if (!FrameworkHelpers.IsObjectMapperFrameworkAssembly(symbol.OriginalDefinition.ContainingAssembly))
            {
                return;
            }

            var diagnostic = Diagnostic.Create(Rule, node.GetLocation());
            context.ReportDiagnostic(diagnostic);
        }
        private void AnalyzeNode(SyntaxNodeAnalysisContext context)
        {
            var classDeclarationNode = (ClassDeclarationSyntax)context.Node;

            if (classDeclarationNode == null)
            {
                return;
            }

            string className = classDeclarationNode.Identifier.ValueText;

            if (classDeclarationNode != null && !className.EndsWith("ViewModel") && classDeclarationNode.BaseList != null)
            {
                foreach (SyntaxNode node in classDeclarationNode.BaseList.Types)
                {
                    SimpleBaseTypeSyntax baseTypeNode = node as SimpleBaseTypeSyntax;
                    if (baseTypeNode != null && ((IdentifierNameSyntax)baseTypeNode.Type).Identifier.ValueText == "BaseViewModel")
                    {
                        // For all such symbols, produce a diagnostic.
                        var diagnostic = Diagnostic.Create(Rule, classDeclarationNode.GetLocation(), classDeclarationNode.Identifier.ValueText);

                        context.ReportDiagnostic(diagnostic);
                    }
                }
            }
        }
Example #4
0
        private void AnalyzeClassDeclaration(SyntaxNodeAnalysisContext context)
        {
            var classDeclarationNode = (ClassDeclarationSyntax)context.Node;

            if (classDeclarationNode == null)
            {
                return;
            }

            string className = classDeclarationNode.Identifier.ValueText;

            if (className != "BaseViewModel" && className.EndsWith("ViewModel"))
            {
                bool baseViewModelBaseTypeFound = false;
                if (classDeclarationNode.BaseList != null)
                {
                    foreach (SyntaxNode node in classDeclarationNode.BaseList.Types)
                    {
                        SimpleBaseTypeSyntax baseTypeNode = node as SimpleBaseTypeSyntax;
                        if (baseTypeNode != null &&
                            baseTypeNode.Type is IdentifierNameSyntax &&
                            ((IdentifierNameSyntax)baseTypeNode.Type).Identifier.ValueText == "BaseViewModel")
                        {
                            baseViewModelBaseTypeFound = true;
                        }
                    }
                }

                if (!baseViewModelBaseTypeFound)
                {
                    var diagnostic = Diagnostic.Create(Rule, classDeclarationNode.GetLocation(), classDeclarationNode.Identifier.ValueText);
                    context.ReportDiagnostic(diagnostic);
                }
            }
        }
        /// <summary>
        /// Checks if symbol under carret is object mapper interface.
        /// </summary>
        /// <param name="node">The node.</param>
        /// <param name="context">The context.</param>
        private static void CheckForObjectMapperBaseInterface(SimpleBaseTypeSyntax node, SyntaxNodeAnalysisContext context)
        {
            SimpleNameSyntax sns = (node.Type as SimpleNameSyntax) ?? (node.Type as QualifiedNameSyntax).Right;
            var className        = sns?.Identifier.Text;

            if (className != "IObjectMapper" && className != "IObjectMapperAdapter")
            {
                return;
            }
            var symbol = context.SemanticModel.GetSymbolInfo(sns).Symbol as INamedTypeSymbol;

            if (symbol == null || symbol.TypeKind != TypeKind.Interface || !symbol.IsGenericType)
            {
                return;
            }

            var fullSymbolName = symbol.OriginalDefinition.ToDisplayString();

            if (fullSymbolName != "ObjectMapper.Framework.IObjectMapper<T>" && fullSymbolName != "ObjectMapper.Framework.IObjectMapperAdapter<T, U>")
            {
                return;
            }

            if (!FrameworkHelpers.IsObjectMapperFrameworkAssembly(symbol.OriginalDefinition.ContainingAssembly))
            {
                return;
            }

            var diagnostic = Diagnostic.Create(Rule, node.GetLocation());

            context.ReportDiagnostic(diagnostic);
        }
Example #6
0
        public override void VisitSimpleBaseType(SimpleBaseTypeSyntax node)
        {
            Information.Add(InfoExtractor.Info.TYPE, node);

            node.Type?.Accept(this);

            base.VisitSimpleBaseType(node);
        }
        private static StructDeclarationSyntax AddInterfaceToBaseList(StructDeclarationSyntax structDeclaration, INamedTypeSymbol structType)
        {
            TypeSyntax           interfaceTypeNode           = ParseTypeName($"System.IEquatable<{structType.ToDisplayString()}>").WithAdditionalAnnotations(Simplifier.Annotation);
            SimpleBaseTypeSyntax interfaceImplementationNode = SimpleBaseType(interfaceTypeNode);

            structDeclaration = structDeclaration.AddBaseListTypes(interfaceImplementationNode);
            return(structDeclaration);
        }
Example #8
0
 public override void VisitSimpleBaseType(
     SimpleBaseTypeSyntax node)
 {
     if (ItsFromSameMember(node))
     {
         IncrementsRelationsFromExpressionAndCheckGenerics(
             node.Type, RelationType.Inheritance);
     }
 }
        public MixinReference Create(SimpleBaseTypeSyntax typeOfMixinNode)
        {
            var typeOfMixin = _semantic.GetTypeInfo(typeOfMixinNode.Type).Type;
            // type could not be resolved => return here
            if (typeOfMixin.TypeKind == TypeKind.Error)
                return null;

            var mixinClass = new ClassFactory(_semantic).Create(typeOfMixin);
            var mixinName = mixinClass.Name.ConvertTypeNameToFieldName();
            return new MixinReference(mixinName, mixinClass);
        }
Example #10
0
 public override void VisitSimpleBaseType(SimpleBaseTypeSyntax node)
 {
     //Jumping the gun here. Instead of going down further, we simply do the
     //processing here and add the base classes.
     if (node == null)
     {
         throw new InvalidOperationException("Simple Base Type node is null!");
     }
     ((m_currentParent as InheritableUserDefinedType)).AddBaseClassOrInterface(node.ChildNodes().First().GetText().ToString());
     base.VisitSimpleBaseType(node);
 }
 public override void VisitSimpleBaseType(SimpleBaseTypeSyntax node)
 {
     var baseClassType = node.Type;
     var baseClassSymbolInfo = _semantic.GetSymbolInfo(baseClassType);
     if (baseClassSymbolInfo.Symbol != null)
     {
         var baseClassTypeSymbol = (ITypeSymbol)baseClassSymbolInfo.Symbol;
         // this time, only check for interfaces
         if (baseClassTypeSymbol.TypeKind == TypeKind.Interface)
             _interfaces.AddInterface(
                 new Interface(baseClassTypeSymbol));
     }
 }
Example #12
0
        public override void VisitSimpleBaseType(SimpleBaseTypeSyntax node)
        {
            if (!PreVisit(node))
            {
                return;
            }

            node.Type?.Accept(this);

            base.VisitSimpleBaseType(node);

            PostVisit(node);
        }
        private void AnalyzeSimpleBaseType(
            SyntaxNodeAnalysisContext context,
            INamedTypeSymbol featureDefinitionType
            )
        {
            SimpleBaseTypeSyntax baseTypeSyntax = (SimpleBaseTypeSyntax)context.Node;
            SymbolInfo           baseTypeSymbol = context.SemanticModel.GetSymbolInfo(baseTypeSyntax.Type);

            INamedTypeSymbol baseSymbol = (baseTypeSymbol.Symbol as INamedTypeSymbol);

            if (baseSymbol.IsNullOrErrorType())
            {
                return;
            }

            ISymbol originalSymbol = baseSymbol.OriginalDefinition;

            if (originalSymbol.IsNullOrErrorType())
            {
                return;
            }

            if (!originalSymbol.Equals(featureDefinitionType, SymbolEqualityComparer.Default))
            {
                return;
            }

            ISymbol valueTypeSymbol = baseSymbol.TypeArguments[0];

            if (valueTypeSymbol.IsNullOrErrorType())
            {
                return;
            }

            string valueType = valueTypeSymbol.ToDisplayString();

            if (ValidTypes.Contains(valueType))
            {
                return;
            }

            Diagnostic diagnostic = Diagnostic.Create(
                Diagnostics.InvalidLaunchDarklyFeatureDefinition,
                baseTypeSyntax.GetLocation(),
                valueType
                );

            context.ReportDiagnostic(diagnostic);
        }
 public override void VisitSimpleBaseType(SimpleBaseTypeSyntax node)
 {
     var baseClassType = node.Type;
     var baseClassSymbolInfo = _semantic.GetSymbolInfo(baseClassType);
     if (baseClassSymbolInfo.Symbol != null)
     {
         var baseClassTypeSymbol = (ITypeSymbol)baseClassSymbolInfo.Symbol;
         // skip interfaces as base types (since they do not have an implementation
         // their methods will always be overridden by the mixins)
         if (baseClassTypeSymbol.TypeKind == TypeKind.Interface)
             return;
         var classFactory = new ClassFactory(_semantic);
         _subClass.BaseClass = classFactory.Create(baseClassTypeSymbol);
     }
 }
        private async Task <Document> AddMissingHandler(Document document, ClassDeclarationSyntax classExpr, string messageType, CancellationToken cancellationToken)
        {
            if (classExpr.BaseList == null)
            {
                return(document);
            }
            var genericBases = classExpr.BaseList.ChildNodes()
                               .Where(x => x is SimpleBaseTypeSyntax)
                               .Select(x => x.ChildNodes().FirstOrDefault(g => g is GenericNameSyntax))
                               .Where(x => x != null)
                               .Cast <GenericNameSyntax>();

            if (!genericBases.Any())
            {
                return(document);
            }

            SyntaxTriviaList     trailingWhiteSpace = new SyntaxTriviaList().Add(SyntaxFactory.EndOfLine(Environment.NewLine));
            SimpleBaseTypeSyntax newInterface       = null;

            if (genericBases.Any(x => x.Identifier.ValueText.Equals(MachineClassName)))
            {
                newInterface = SyntaxFactory.SimpleBaseType(SyntaxFactory.ParseTypeName($"IMachineMessageHandler<{messageType}>")).WithTrailingTrivia(trailingWhiteSpace);
            }
            else if (genericBases.Any(x => x.Identifier.ValueText.Equals(SagaClassName)))
            {
                newInterface = SyntaxFactory.SimpleBaseType(SyntaxFactory.ParseTypeName($"IMessageHandler<{messageType}>")).WithTrailingTrivia(trailingWhiteSpace);
            }
            else
            {
                return(document);
            }

            ClassDeclarationSyntax newClassExpr = classExpr.AddBaseListTypes(newInterface);

            var lastComma = newClassExpr.BaseList.DescendantTokens().LastOrDefault(x => x.IsKind(SyntaxKind.CommaToken));

            if (lastComma != null)
            {
                newClassExpr = newClassExpr.ReplaceToken(lastComma, lastComma.WithTrailingTrivia(trailingWhiteSpace));
            }

            var oldRoot = await document.GetSyntaxRootAsync(cancellationToken);

            var newRoot = oldRoot.ReplaceNode(classExpr, newClassExpr);

            return(document.WithSyntaxRoot(newRoot));
        }
Example #16
0
        public override void VisitSimpleBaseType(SimpleBaseTypeSyntax node)
        {
            if (debug)
            {
                Console.WriteLine(node.ToFullString());
            }
            var nl = OurLine.NewLine(LineKind.Decl, "SimpleBaseType");

            OurLine.AddEssentialInfo(ref nl, "type:" + node.Type.ToString());
            nl.Source     = node.ToFullString();
            nl.ParentKind = node.Parent.RawKind;
            nl.RawKind    = node.RawKind;
            LogCommand(nl);

            base.VisitSimpleBaseType(node);
        }
        private void AnalyzeSimpleBaseType(
            SyntaxNodeAnalysisContext context,
            INamedTypeSymbol featureInterfaceSymbol
            )
        {
            SimpleBaseTypeSyntax baseTypeSyntax = (SimpleBaseTypeSyntax)context.Node;
            SymbolInfo           baseTypeSymbol = context.SemanticModel.GetSymbolInfo(baseTypeSyntax.Type);

            ISymbol baseSymbol = baseTypeSymbol.Symbol;

            if (baseSymbol.IsNullOrErrorType())
            {
                return;
            }

            if (!baseSymbol.Equals(featureInterfaceSymbol))
            {
                return;
            }

            SyntaxNode classNode = baseTypeSyntax.Parent.Parent;

            ISymbol featureSymbol = context.SemanticModel.GetDeclaredSymbol(classNode);

            if (featureSymbol.IsNullOrErrorType())
            {
                return;
            }

            string featureName = featureSymbol.ToDisplayString();

            if (LegacyFeatureTypes.Types.Contains(featureName))
            {
                return;
            }

            Diagnostic diagnostic = Diagnostic.Create(
                Diagnostics.ObsoleteLaunchDarklyFramework,
                baseTypeSyntax.GetLocation()
                );

            context.ReportDiagnostic(diagnostic);
        }
        private static Task <Document> RefactorAsync(
            Document document,
            StructDeclarationSyntax structDeclaration,
            INamedTypeSymbol typeSymbol,
            INamedTypeSymbol equatableSymbol,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            int position = structDeclaration.SpanStart;

            SimpleBaseTypeSyntax baseType = SimpleBaseType(equatableSymbol.ToMinimalTypeSyntax(semanticModel, position));

            StructDeclarationSyntax newNode = AddBaseType(structDeclaration, baseType);

            TypeSyntax classType = typeSymbol.ToMinimalTypeSyntax(semanticModel, position);

            newNode = MemberDeclarationInserter.Default.Insert(newNode, CreateEqualsMethod(classType));

            return(document.ReplaceNodeAsync(structDeclaration, newNode, cancellationToken));
        }
Example #19
0
        public sealed override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            SyntaxNode root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

            SimpleBaseTypeSyntax baseType = root
                                            .FindNode(context.Span, getInnermostNodeForTie: true)?
                                            .FirstAncestorOrSelf <SimpleBaseTypeSyntax>();

            if (baseType == null)
            {
                return;
            }

            CodeAction codeAction = CodeAction.Create(
                "Remove default underlying type",
                cancellationToken => RemoveDefaultUnderlyingTypeAsync(context.Document, baseType, cancellationToken),
                DiagnosticIdentifiers.RemoveEnumDefaultUnderlyingType + EquivalenceKeySuffix);

            context.RegisterCodeFix(codeAction, context.Diagnostics);
        }
        private static Task <Document> RefactorAsync(
            Document document,
            ClassDeclarationSyntax classDeclaration,
            INamedTypeSymbol typeSymbol,
            INamedTypeSymbol equatableSymbol,
            SemanticModel semanticModel,
            CancellationToken cancellationToken)
        {
            int position = classDeclaration.SpanStart;

            SimpleBaseTypeSyntax baseType = SimpleBaseType(equatableSymbol.ToMinimalTypeSyntax(semanticModel, position));

            ClassDeclarationSyntax newNode = AddBaseType(classDeclaration, baseType);

            TypeSyntax classType = typeSymbol.ToMinimalTypeSyntax(semanticModel, position);

            newNode = newNode.InsertMember(CreateEqualsMethod(classType, semanticModel, position), MemberDeclarationComparer.ByKind);

            return(document.ReplaceNodeAsync(classDeclaration, newNode, cancellationToken));
        }
        public override async Task RegisterCodeFixesAsync(CodeFixContext context)
        {
            var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(false);

            var classNode = root.FindNode(context.Span).FirstAncestorOrSelf <ClassDeclarationSyntax>();

            if (classNode == null)
            {
                return;
            }

            var diagnostic = context.Diagnostics.FirstOrDefault(d => d.Id == Descriptors.PX1060_LegacyBqlField.Id);

            if (diagnostic == null)
            {
                return;
            }

            if (diagnostic.Properties == null ||
                !diagnostic.Properties.TryGetValue(LegacyBqlFieldAnalyzer.CorrespondingPropertyType, out string typeName) ||
                typeName.IsNullOrEmpty() ||
                context.CancellationToken.IsCancellationRequested)
            {
                return;
            }

            SimpleBaseTypeSyntax newBaseType = CreateBaseType(typeName, classNode.Identifier.Text);

            if (newBaseType == null)
            {
                return;
            }

            string title = nameof(Resources.PX1060Fix).GetLocalized().ToString();

            context.RegisterCodeFix(
                CodeAction.Create(title,
                                  c => Task.FromResult(GetDocumentWithUpdatedBqlField(context.Document, root, classNode, newBaseType)),
                                  equivalenceKey: title),
                context.Diagnostics);
        }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="node"></param>
 public override sealed void VisitSimpleBaseType(SimpleBaseTypeSyntax node)
 {
     this.OnNodeVisited(node, this.type.IsInstanceOfType(node));
     base.VisitSimpleBaseType(node);
 }
Example #23
0
 public override void VisitSimpleBaseType(SimpleBaseTypeSyntax node)
 {
     UpdateSyntaxNode(node);
     Visit(node.Type);
 }
Example #24
0
 public override void VisitSimpleBaseType(SimpleBaseTypeSyntax node)
 {
 }
 public override LuaSyntaxNode VisitSimpleBaseType(SimpleBaseTypeSyntax node)
 {
     return(node.Type.Accept(this));
 }
 public override void VisitSimpleBaseType(SimpleBaseTypeSyntax node)
 {
     Debug.Fail(node.ToString());
     base.VisitSimpleBaseType(node);
 }
Example #27
0
 public static string SimpleBaseType(SimpleBaseTypeSyntax typedSyntax)
 {
     return(SyntaxNode(typedSyntax.Type));
 }
 public SimpleBaseTypeTranslation(SimpleBaseTypeSyntax syntax, SyntaxTranslation parent) : base(syntax, parent)
 {
     this.Syntax = syntax;
 }
Example #29
0
 public TameSimpleBaseTypeSyntax(SimpleBaseTypeSyntax node)
 {
     Node = node;
     AddChildren();
 }
        private static async Task<Document> GenerateInterfaceImplementationAsync(Document document, SimpleBaseTypeSyntax baseTypeSyntax, CancellationToken cancellationToken)
        {
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken);

            SimpleNameSyntax sns = (baseTypeSyntax.Type as SimpleNameSyntax) ?? (baseTypeSyntax.Type as QualifiedNameSyntax).Right;
            var interfaceSymbol = semanticModel.GetSymbolInfo(sns).Symbol as INamedTypeSymbol;
            if (interfaceSymbol == null || interfaceSymbol.TypeKind != TypeKind.Interface) return document;

            var originalClassDefinitionSyntax = (ClassDeclarationSyntax)baseTypeSyntax.Parent.Parent;
            ClassDeclarationSyntax modifiedClassDefinitionSyntax = null;
            if (interfaceSymbol.Name == "IObjectMapper" && interfaceSymbol.TypeArguments.Length == 1)
            {
                var sourceClassSymbol = semanticModel.GetDeclaredSymbol(originalClassDefinitionSyntax);
                var targetClassSymbol = interfaceSymbol.TypeArguments[0].OriginalDefinition as INamedTypeSymbol;
                if (sourceClassSymbol == null || targetClassSymbol == null) return document;

                var matchedProperties = RetrieveMatchedProperties(sourceClassSymbol, targetClassSymbol);

                var updatedMethods = new Dictionary<MethodDeclarationSyntax, MethodDeclarationSyntax>();
                var addedMethods = new List<MethodDeclarationSyntax>();

                foreach (IMethodSymbol member in interfaceSymbol.GetMembers().Where(x => x.Kind == SymbolKind.Method))
                {
                    var method = sourceClassSymbol.FindImplementationForInterfaceMember(member) as IMethodSymbol;
                    MethodDeclarationSyntax methodSyntax = null;
                    if (method != null)
                    {
                        methodSyntax = await method.DeclaringSyntaxReferences[0].GetSyntaxAsync(cancellationToken) as MethodDeclarationSyntax;
                        var newMethodSyntax = methodSyntax.WithBody(GenerateMethodBody(member, matchedProperties, semanticModel, originalClassDefinitionSyntax.Span.End - 1));
                        updatedMethods.Add(methodSyntax, newMethodSyntax);
                    }
                    else
                    {
                        methodSyntax = GenerateMethodImplementation(member, semanticModel, originalClassDefinitionSyntax.Span.End - 1).
                            WithBody(GenerateMethodBody(member, matchedProperties, semanticModel, originalClassDefinitionSyntax.Span.End - 1));
                        addedMethods.Add(methodSyntax);
                    }
                }

                modifiedClassDefinitionSyntax = originalClassDefinitionSyntax.ReplaceNodes(updatedMethods.Keys.AsEnumerable(), (n1, n2) => updatedMethods[n1]).AddMembers(addedMethods.ToArray());
            } 
            else if (interfaceSymbol.Name == "IObjectMapperAdapter" && interfaceSymbol.TypeArguments.Length == 2)
            {
                var adapterClassSymbol = semanticModel.GetDeclaredSymbol(originalClassDefinitionSyntax);
                var sourceClassSymbol = interfaceSymbol.TypeArguments[0].OriginalDefinition as INamedTypeSymbol;
                var targetClassSymbol = interfaceSymbol.TypeArguments[1].OriginalDefinition as INamedTypeSymbol;
                if (sourceClassSymbol == null || targetClassSymbol == null) return document;

                var matchedProperties = RetrieveMatchedProperties(sourceClassSymbol, targetClassSymbol);

                var updatedMethods = new Dictionary<MethodDeclarationSyntax, MethodDeclarationSyntax>();
                var addedMethods = new List<MethodDeclarationSyntax>();

                foreach (IMethodSymbol member in interfaceSymbol.GetMembers().Where(x => x.Kind == SymbolKind.Method))
                {
                    var matchingPropertyList = matchedProperties;
                    // check if we have to switch matched properties
                    if (member.Parameters.Length == 2 && !interfaceSymbol.TypeArguments[0].Equals(member.Parameters[0].Type))
                    {
                        matchingPropertyList = matchingPropertyList.Select(x => new MatchedPropertySymbols { Source = x.Target, Target = x.Source });
                    }

                    var method = adapterClassSymbol.FindImplementationForInterfaceMember(member) as IMethodSymbol;
                    MethodDeclarationSyntax methodSyntax = null;
                    if (method != null)
                    {
                        methodSyntax = await method.DeclaringSyntaxReferences[0].GetSyntaxAsync(cancellationToken) as MethodDeclarationSyntax;
                        var newMethodSyntax = methodSyntax.WithBody(GenerateMethodBody(member, matchingPropertyList, semanticModel, originalClassDefinitionSyntax.Span.End - 1));
                        updatedMethods.Add(methodSyntax, newMethodSyntax);
                    }
                    else
                    {
                        methodSyntax = GenerateMethodImplementation(member, semanticModel, originalClassDefinitionSyntax.Span.End - 1).
                            WithBody(GenerateMethodBody(member, matchingPropertyList, semanticModel, originalClassDefinitionSyntax.Span.End - 1));
                        addedMethods.Add(methodSyntax);
                    }
                }

                modifiedClassDefinitionSyntax = originalClassDefinitionSyntax.ReplaceNodes(updatedMethods.Keys.AsEnumerable(), (n1, n2) => updatedMethods[n1]).AddMembers(addedMethods.ToArray());
            }

            if (modifiedClassDefinitionSyntax == null)
            {
                return document;
            }

            // replace root and return modified document
            var root = await document.GetSyntaxRootAsync(cancellationToken);
            var newRoot = root.ReplaceNode(originalClassDefinitionSyntax, modifiedClassDefinitionSyntax);
            var newDocument = document.WithSyntaxRoot(newRoot);
            return newDocument;
        }
        private async Task <Document> ConvertToAsyncPackageAsync(CodeFixContext context, Diagnostic diagnostic, CancellationToken cancellationToken)
        {
            SemanticModel semanticModel = await context.Document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

            Compilation?compilation = await context.Document.Project.GetCompilationAsync(cancellationToken).ConfigureAwait(false);

            Assumes.NotNull(compilation);
            SyntaxNode root = await context.Document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);

            BaseTypeSyntax          baseTypeSyntax         = root.FindNode(diagnostic.Location.SourceSpan).FirstAncestorOrSelf <BaseTypeSyntax>();
            ClassDeclarationSyntax  classDeclarationSyntax = baseTypeSyntax.FirstAncestorOrSelf <ClassDeclarationSyntax>();
            MethodDeclarationSyntax initializeMethodSyntax = classDeclarationSyntax.DescendantNodes()
                                                             .OfType <MethodDeclarationSyntax>()
                                                             .FirstOrDefault(method => method.Modifiers.Any(modifier => modifier.IsKind(SyntaxKind.OverrideKeyword)) && method.Identifier.Text == Types.Package.Initialize);
            InvocationExpressionSyntax?baseInitializeInvocationSyntax = initializeMethodSyntax?.Body?.DescendantNodes()
                                                                        .OfType <InvocationExpressionSyntax>()
                                                                        .FirstOrDefault(ies => ies.Expression is MemberAccessExpressionSyntax memberAccess && memberAccess.Name?.Identifier.Text == Types.Package.Initialize && memberAccess.Expression is BaseExpressionSyntax);
            var             getServiceInvocationsSyntax = new List <InvocationExpressionSyntax>();
            AttributeSyntax?packageRegistrationSyntax   = null;

            {
                INamedTypeSymbol userClassSymbol             = semanticModel.GetDeclaredSymbol(classDeclarationSyntax, context.CancellationToken);
                INamedTypeSymbol packageRegistrationType     = compilation.GetTypeByMetadataName(Types.PackageRegistrationAttribute.FullName);
                AttributeData?   packageRegistrationInstance = userClassSymbol?.GetAttributes().FirstOrDefault(a => Equals(a.AttributeClass, packageRegistrationType));
                if (packageRegistrationInstance?.ApplicationSyntaxReference != null)
                {
                    packageRegistrationSyntax = (AttributeSyntax)await packageRegistrationInstance.ApplicationSyntaxReference.GetSyntaxAsync(cancellationToken).ConfigureAwait(false);
                }
            }

            if (initializeMethodSyntax != null)
            {
                getServiceInvocationsSyntax.AddRange(
                    from invocation in initializeMethodSyntax.DescendantNodes().OfType <InvocationExpressionSyntax>()
                    let memberBinding = invocation.Expression as MemberAccessExpressionSyntax
                                        let identifierName = invocation.Expression as IdentifierNameSyntax
                                                             where identifierName?.Identifier.Text == Types.Package.GetService ||
                                                             (memberBinding.Name.Identifier.Text == Types.Package.GetService && memberBinding.Expression.IsKind(SyntaxKind.ThisExpression))
                                                             select invocation);
            }

            // Make it easier to track nodes across changes.
            var nodesToTrack = new List <SyntaxNode?>
            {
                baseTypeSyntax,
                initializeMethodSyntax,
                baseInitializeInvocationSyntax,
                packageRegistrationSyntax,
            };

            nodesToTrack.AddRange(getServiceInvocationsSyntax);
            nodesToTrack.RemoveAll(n => n == null);
            SyntaxNode updatedRoot = root.TrackNodes(nodesToTrack);

            // Replace the Package base type with AsyncPackage
            baseTypeSyntax = updatedRoot.GetCurrentNode(baseTypeSyntax);
            SimpleBaseTypeSyntax asyncPackageBaseTypeSyntax = SyntaxFactory.SimpleBaseType(Types.AsyncPackage.TypeSyntax.WithAdditionalAnnotations(Simplifier.Annotation))
                                                              .WithLeadingTrivia(baseTypeSyntax.GetLeadingTrivia())
                                                              .WithTrailingTrivia(baseTypeSyntax.GetTrailingTrivia());

            updatedRoot = updatedRoot.ReplaceNode(baseTypeSyntax, asyncPackageBaseTypeSyntax);

            // Update the PackageRegistration attribute
            if (packageRegistrationSyntax != null)
            {
                LiteralExpressionSyntax trueExpression = SyntaxFactory.LiteralExpression(SyntaxKind.TrueLiteralExpression);
                packageRegistrationSyntax = updatedRoot.GetCurrentNode(packageRegistrationSyntax);
                AttributeArgumentSyntax allowsBackgroundLoadingSyntax = packageRegistrationSyntax.ArgumentList.Arguments.FirstOrDefault(a => a.NameEquals?.Name?.Identifier.Text == Types.PackageRegistrationAttribute.AllowsBackgroundLoading);
                if (allowsBackgroundLoadingSyntax != null)
                {
                    updatedRoot = updatedRoot.ReplaceNode(
                        allowsBackgroundLoadingSyntax,
                        allowsBackgroundLoadingSyntax.WithExpression(trueExpression));
                }
                else
                {
                    updatedRoot = updatedRoot.ReplaceNode(
                        packageRegistrationSyntax,
                        packageRegistrationSyntax.AddArgumentListArguments(
                            SyntaxFactory.AttributeArgument(trueExpression).WithNameEquals(SyntaxFactory.NameEquals(Types.PackageRegistrationAttribute.AllowsBackgroundLoading))));
                }
            }

            // Find the Initialize override, if present, and update it to InitializeAsync
            if (initializeMethodSyntax != null)
            {
                IdentifierNameSyntax cancellationTokenLocalVarName = SyntaxFactory.IdentifierName("cancellationToken");
                IdentifierNameSyntax progressLocalVarName          = SyntaxFactory.IdentifierName("progress");
                initializeMethodSyntax = updatedRoot.GetCurrentNode(initializeMethodSyntax);
                BlockSyntax newBody = initializeMethodSyntax.Body;

                SyntaxTriviaList leadingTrivia = SyntaxFactory.TriviaList(
                    SyntaxFactory.Comment(@"// When initialized asynchronously, we *may* be on a background thread at this point."),
                    SyntaxFactory.CarriageReturnLineFeed,
                    SyntaxFactory.Comment(@"// Do any initialization that requires the UI thread after switching to the UI thread."),
                    SyntaxFactory.CarriageReturnLineFeed,
                    SyntaxFactory.Comment(@"// Otherwise, remove the switch to the UI thread if you don't need it."),
                    SyntaxFactory.CarriageReturnLineFeed);

                ExpressionStatementSyntax switchToMainThreadStatement = SyntaxFactory.ExpressionStatement(
                    SyntaxFactory.AwaitExpression(
                        SyntaxFactory.InvocationExpression(
                            SyntaxFactory.MemberAccessExpression(
                                SyntaxKind.SimpleMemberAccessExpression,
                                SyntaxFactory.MemberAccessExpression(
                                    SyntaxKind.SimpleMemberAccessExpression,
                                    SyntaxFactory.ThisExpression(),
                                    SyntaxFactory.IdentifierName(Types.ThreadHelper.JoinableTaskFactory)),
                                SyntaxFactory.IdentifierName(Types.JoinableTaskFactory.SwitchToMainThreadAsync)))
                        .AddArgumentListArguments(SyntaxFactory.Argument(cancellationTokenLocalVarName))))
                                                                        .WithLeadingTrivia(leadingTrivia)
                                                                        .WithTrailingTrivia(SyntaxFactory.CarriageReturnLineFeed);

                if (baseInitializeInvocationSyntax != null)
                {
                    var baseInitializeAsyncInvocationBookmark = new SyntaxAnnotation();
                    AwaitExpressionSyntax baseInitializeAsyncInvocationSyntax = SyntaxFactory.AwaitExpression(
                        baseInitializeInvocationSyntax
                        .WithLeadingTrivia()
                        .WithExpression(
                            SyntaxFactory.MemberAccessExpression(
                                SyntaxKind.SimpleMemberAccessExpression,
                                SyntaxFactory.BaseExpression(),
                                SyntaxFactory.IdentifierName(Types.AsyncPackage.InitializeAsync)))
                        .AddArgumentListArguments(
                            SyntaxFactory.Argument(cancellationTokenLocalVarName),
                            SyntaxFactory.Argument(progressLocalVarName)))
                                                                                .WithLeadingTrivia(baseInitializeInvocationSyntax.GetLeadingTrivia())
                                                                                .WithAdditionalAnnotations(baseInitializeAsyncInvocationBookmark);
                    newBody = newBody.ReplaceNode(initializeMethodSyntax.GetCurrentNode(baseInitializeInvocationSyntax), baseInitializeAsyncInvocationSyntax);
                    StatementSyntax baseInvocationStatement = newBody.GetAnnotatedNodes(baseInitializeAsyncInvocationBookmark).First().FirstAncestorOrSelf <StatementSyntax>();

                    newBody = newBody.InsertNodesAfter(
                        baseInvocationStatement,
                        new[] { switchToMainThreadStatement.WithLeadingTrivia(switchToMainThreadStatement.GetLeadingTrivia().Insert(0, SyntaxFactory.LineFeed)) });
                }
                else
                {
                    newBody = newBody.WithStatements(
                        newBody.Statements.Insert(0, switchToMainThreadStatement));
                }

                MethodDeclarationSyntax initializeAsyncMethodSyntax = initializeMethodSyntax
                                                                      .WithIdentifier(SyntaxFactory.Identifier(Types.AsyncPackage.InitializeAsync))
                                                                      .WithReturnType(Types.Task.TypeSyntax.WithAdditionalAnnotations(Simplifier.Annotation))
                                                                      .AddModifiers(SyntaxFactory.Token(SyntaxKind.AsyncKeyword))
                                                                      .AddParameterListParameters(
                    SyntaxFactory.Parameter(cancellationTokenLocalVarName.Identifier).WithType(Types.CancellationToken.TypeSyntax.WithAdditionalAnnotations(Simplifier.Annotation)),
                    SyntaxFactory.Parameter(progressLocalVarName.Identifier).WithType(Types.IProgress.TypeSyntaxOf(Types.ServiceProgressData.TypeSyntax).WithAdditionalAnnotations(Simplifier.Annotation)))
                                                                      .WithBody(newBody);
                updatedRoot = updatedRoot.ReplaceNode(initializeMethodSyntax, initializeAsyncMethodSyntax);

                // Replace GetService calls with GetServiceAsync
                getServiceInvocationsSyntax = updatedRoot.GetCurrentNodes <InvocationExpressionSyntax>(getServiceInvocationsSyntax).ToList();
                updatedRoot = updatedRoot.ReplaceNodes(
                    getServiceInvocationsSyntax,
                    (orig, node) =>
                {
                    InvocationExpressionSyntax invocation = node;
                    if (invocation.Expression is IdentifierNameSyntax methodName)
                    {
                        invocation = invocation.WithExpression(SyntaxFactory.IdentifierName(Types.AsyncPackage.GetServiceAsync));
                    }
                    else if (invocation.Expression is MemberAccessExpressionSyntax memberAccess)
                    {
                        invocation = invocation.WithExpression(
                            memberAccess.WithName(SyntaxFactory.IdentifierName(Types.AsyncPackage.GetServiceAsync)));
                    }

                    return(SyntaxFactory.ParenthesizedExpression(SyntaxFactory.AwaitExpression(invocation))
                           .WithAdditionalAnnotations(Simplifier.Annotation));
                });

                updatedRoot = await Utils.AddUsingTaskEqualsDirectiveAsync(updatedRoot, cancellationToken);
            }

            Document newDocument = context.Document.WithSyntaxRoot(updatedRoot);

            newDocument = await ImportAdder.AddImportsAsync(newDocument, Simplifier.Annotation, cancellationToken : cancellationToken);

            return(newDocument);
        }
        private Document GetDocumentWithUpdatedBqlField(Document oldDocument, SyntaxNode root, ClassDeclarationSyntax classNode, SimpleBaseTypeSyntax newBaseType)
        {
            var newClassNode =
                classNode.WithBaseList(
                    BaseList(
                        SingletonSeparatedList <BaseTypeSyntax>(newBaseType)));
            var newRoot = root.ReplaceNode(classNode, newClassNode);

            return(oldDocument.WithSyntaxRoot(newRoot));
        }
 /// <summary>
 /// 
 /// </summary>
 /// <param name="node"></param>
 public override sealed void VisitSimpleBaseType(SimpleBaseTypeSyntax node)
 {
     this.OnNodeVisited(node);
     if (!this.traverseRootOnly) base.VisitSimpleBaseType(node);
 }
 public override SyntaxNode VisitSimpleBaseType(SimpleBaseTypeSyntax node)
 {
     node = (SimpleBaseTypeSyntax)base.VisitSimpleBaseType(node);
     Classes.Add(node);
     return(node);
 }
Example #35
0
 public override void VisitSimpleBaseType(SimpleBaseTypeSyntax node)
 {
     throw new NotImplementedException();
 }
 public SimpleBaseTypeTranslation(SimpleBaseTypeSyntax syntax, SyntaxTranslation parent) : base(syntax, parent)
 {
     this.Syntax = syntax;
 }
Example #37
0
        private void ProcessEnum([NotNull] EnumDeclarationSyntax enumDecl, NamespaceDeclarationSyntax namespaceDecl = null)
        {
            if (enumDecl == null)
            {
                throw new ArgumentNullException(nameof(enumDecl));
            }

            ModelRoot modelRoot = Store.ModelRoot();
            string    enumName  = enumDecl.Identifier.Text;

            if (namespaceDecl == null && enumDecl.Parent is NamespaceDeclarationSyntax enumDeclParent)
            {
                namespaceDecl = enumDeclParent;
            }

            string namespaceName = namespaceDecl?.Name?.ToString() ?? modelRoot.Namespace;

            if (Store.Get <ModelClass>().Any(c => c.Name == enumName) || Store.Get <ModelEnum>().Any(c => c.Name == enumName))
            {
                ErrorDisplay.Show($"'{enumName}' already exists in model.");

                // ReSharper disable once ExpressionIsAlwaysNull
                return;
            }

            Transaction tx = Store.TransactionManager.CurrentTransaction == null
                             ? Store.TransactionManager.BeginTransaction()
                             : null;

            try
            {
                ModelEnum result = new ModelEnum(Store,
                                                 new PropertyAssignment(ModelEnum.NameDomainPropertyId, enumName))
                {
                    Namespace = namespaceName,
                    IsFlags   = enumDecl.HasAttribute("Flags")
                };

                SimpleBaseTypeSyntax baseTypeSyntax = enumDecl.DescendantNodes().OfType <SimpleBaseTypeSyntax>().FirstOrDefault();

                if (baseTypeSyntax != null)
                {
                    switch (baseTypeSyntax.Type.ToString())
                    {
                    case "Int16":
                    case "short":
                        result.ValueType = EnumValueType.Int16;

                        break;

                    case "Int32":
                    case "int":
                        result.ValueType = EnumValueType.Int32;

                        break;

                    case "Int64":
                    case "long":
                        result.ValueType = EnumValueType.Int64;

                        break;

                    default:
                        WarningDisplay.Show($"Could not resolve value type for '{enumName}'. The enum will default to an Int32 value type.");

                        break;
                    }
                }

                XMLDocumentation xmlDocumentation;

                foreach (EnumMemberDeclarationSyntax enumValueDecl in enumDecl.DescendantNodes().OfType <EnumMemberDeclarationSyntax>())
                {
                    ModelEnumValue          enumValue = new ModelEnumValue(Store, new PropertyAssignment(ModelEnumValue.NameDomainPropertyId, enumValueDecl.Identifier.ToString()));
                    EqualsValueClauseSyntax valueDecl = enumValueDecl.DescendantNodes().OfType <EqualsValueClauseSyntax>().FirstOrDefault();

                    if (valueDecl != null)
                    {
                        enumValue.Value = valueDecl.Value.ToString();
                    }

                    xmlDocumentation      = new XMLDocumentation(enumValueDecl);
                    enumValue.Summary     = xmlDocumentation.Summary;
                    enumValue.Description = xmlDocumentation.Description;

                    result.Values.Add(enumValue);
                }

                xmlDocumentation   = new XMLDocumentation(enumDecl);
                result.Summary     = xmlDocumentation.Summary;
                result.Description = xmlDocumentation.Description;

                modelRoot.Enums.Add(result);
            }
            catch
            {
                tx = null;

                throw;
            }
            finally
            {
                tx?.Commit();
            }
        }
        private static async Task <Document> GenerateInterfaceImplementationAsync(Document document, SimpleBaseTypeSyntax baseTypeSyntax, CancellationToken cancellationToken)
        {
            var semanticModel = await document.GetSemanticModelAsync(cancellationToken);

            SimpleNameSyntax sns = (baseTypeSyntax.Type as SimpleNameSyntax) ?? (baseTypeSyntax.Type as QualifiedNameSyntax).Right;
            var interfaceSymbol  = semanticModel.GetSymbolInfo(sns).Symbol as INamedTypeSymbol;

            if (interfaceSymbol == null || interfaceSymbol.TypeKind != TypeKind.Interface)
            {
                return(document);
            }

            var originalClassDefinitionSyntax = (ClassDeclarationSyntax)baseTypeSyntax.Parent.Parent;
            ClassDeclarationSyntax modifiedClassDefinitionSyntax = null;

            if (interfaceSymbol.Name == "IObjectMapper" && interfaceSymbol.TypeArguments.Length == 1)
            {
                var sourceClassSymbol = semanticModel.GetDeclaredSymbol(originalClassDefinitionSyntax);
                var targetClassSymbol = interfaceSymbol.TypeArguments[0].OriginalDefinition as INamedTypeSymbol;
                if (sourceClassSymbol == null || targetClassSymbol == null)
                {
                    return(document);
                }

                var matchedProperties = RetrieveMatchedProperties(sourceClassSymbol, targetClassSymbol);

                var updatedMethods = new Dictionary <MethodDeclarationSyntax, MethodDeclarationSyntax>();
                var addedMethods   = new List <MethodDeclarationSyntax>();

                foreach (IMethodSymbol member in interfaceSymbol.GetMembers().Where(x => x.Kind == SymbolKind.Method))
                {
                    var method = sourceClassSymbol.FindImplementationForInterfaceMember(member) as IMethodSymbol;
                    MethodDeclarationSyntax methodSyntax = null;
                    if (method != null)
                    {
                        methodSyntax = await method.DeclaringSyntaxReferences[0].GetSyntaxAsync(cancellationToken) as MethodDeclarationSyntax;
                        var newMethodSyntax = methodSyntax.WithBody(GenerateMethodBody(member, matchedProperties, semanticModel, originalClassDefinitionSyntax.Span.End - 1));
                        updatedMethods.Add(methodSyntax, newMethodSyntax);
                    }
                    else
                    {
                        methodSyntax = GenerateMethodImplementation(member, semanticModel, originalClassDefinitionSyntax.Span.End - 1).
                                       WithBody(GenerateMethodBody(member, matchedProperties, semanticModel, originalClassDefinitionSyntax.Span.End - 1));
                        addedMethods.Add(methodSyntax);
                    }
                }

                modifiedClassDefinitionSyntax = originalClassDefinitionSyntax.ReplaceNodes(updatedMethods.Keys.AsEnumerable(), (n1, n2) => updatedMethods[n1]).AddMembers(addedMethods.ToArray());
            }
            else if (interfaceSymbol.Name == "IObjectMapperAdapter" && interfaceSymbol.TypeArguments.Length == 2)
            {
                var adapterClassSymbol = semanticModel.GetDeclaredSymbol(originalClassDefinitionSyntax);
                var sourceClassSymbol  = interfaceSymbol.TypeArguments[0].OriginalDefinition as INamedTypeSymbol;
                var targetClassSymbol  = interfaceSymbol.TypeArguments[1].OriginalDefinition as INamedTypeSymbol;
                if (sourceClassSymbol == null || targetClassSymbol == null)
                {
                    return(document);
                }

                var matchedProperties = RetrieveMatchedProperties(sourceClassSymbol, targetClassSymbol);

                var updatedMethods = new Dictionary <MethodDeclarationSyntax, MethodDeclarationSyntax>();
                var addedMethods   = new List <MethodDeclarationSyntax>();

                foreach (IMethodSymbol member in interfaceSymbol.GetMembers().Where(x => x.Kind == SymbolKind.Method))
                {
                    var matchingPropertyList = matchedProperties;
                    // check if we have to switch matched properties
                    if (member.Parameters.Length == 2 && !interfaceSymbol.TypeArguments[0].Equals(member.Parameters[0].Type))
                    {
                        matchingPropertyList = matchingPropertyList.Select(x => new MatchedPropertySymbols {
                            Source = x.Target, Target = x.Source
                        });
                    }

                    var method = adapterClassSymbol.FindImplementationForInterfaceMember(member) as IMethodSymbol;
                    MethodDeclarationSyntax methodSyntax = null;
                    if (method != null)
                    {
                        methodSyntax = await method.DeclaringSyntaxReferences[0].GetSyntaxAsync(cancellationToken) as MethodDeclarationSyntax;
                        var newMethodSyntax = methodSyntax.WithBody(GenerateMethodBody(member, matchingPropertyList, semanticModel, originalClassDefinitionSyntax.Span.End - 1));
                        updatedMethods.Add(methodSyntax, newMethodSyntax);
                    }
                    else
                    {
                        methodSyntax = GenerateMethodImplementation(member, semanticModel, originalClassDefinitionSyntax.Span.End - 1).
                                       WithBody(GenerateMethodBody(member, matchingPropertyList, semanticModel, originalClassDefinitionSyntax.Span.End - 1));
                        addedMethods.Add(methodSyntax);
                    }
                }

                modifiedClassDefinitionSyntax = originalClassDefinitionSyntax.ReplaceNodes(updatedMethods.Keys.AsEnumerable(), (n1, n2) => updatedMethods[n1]).AddMembers(addedMethods.ToArray());
            }

            if (modifiedClassDefinitionSyntax == null)
            {
                return(document);
            }

            // replace root and return modified document
            var root = await document.GetSyntaxRootAsync(cancellationToken);

            var newRoot     = root.ReplaceNode(originalClassDefinitionSyntax, modifiedClassDefinitionSyntax);
            var newDocument = document.WithSyntaxRoot(newRoot);

            return(newDocument);
        }
 public CreateMixinFromInterfaceCommand(
     SimpleBaseTypeSyntax baseType,
     SemanticModel semantic):
     this(new MixinReferenceFactory(semantic).Create(baseType))
 {
 }