예제 #1
0
        private static ITypeSymbol GetGenericType(SyntaxNode node, GenRef genRef, SemanticModel semanticModel)
        {
            if (node is InvocationExpressionSyntax)
            {
                ISymbol invokedSymbol = semanticModel.GetSymbolInfo(node).Symbol;

                // if is generic method
                if (genRef.Methods.Contains(invokedSymbol.OriginalDefinition))
                {
                    return ((IMethodSymbol)invokedSymbol).ReturnType;
                }
            }
            else if ((node is MemberAccessExpressionSyntax) && !(node.Parent is AssignmentExpressionSyntax))
            {
                ISymbol invokedSymbol = semanticModel.GetSymbolInfo(node).Symbol;

                // if is generic property
                if (genRef.Properties.Contains(invokedSymbol.OriginalDefinition))
                {
                    return ((IPropertySymbol)invokedSymbol).Type;
                }
            }

            return null;
        }
예제 #2
0
        private static GenRef FindGenericClassMembers(IEnumerable<SemanticModel> semanticModels)
        {
            // FIND
            // 1. Generic properties symbols
            // 2. Generic method symbols
            // =============================

            var genericPropertiesList = new List<IPropertySymbol>();
            var genericMethodsList = new List<IMethodSymbol>();

            foreach (var semanticModel in semanticModels)
            {
                var tree = semanticModel.SyntaxTree;

                // Find generic classes
                var genericClassFinder = new GenericClassFinder(tree, semanticModel);
                var classDeclarations = genericClassFinder.Get().ToArray();

                SyntaxNode newTree = tree.GetRoot();

                // methods symbols
                var methodsToCast = classDeclarations
                    .SelectMany(x => x.Members)
                    .OfType<BaseMethodDeclarationSyntax>()
                    .Select(x => (IMethodSymbol)semanticModel.GetDeclaredSymbol(x));

                genericMethodsList.AddRange(methodsToCast);

                // properties symbols
                var propertiesToCast = classDeclarations
                    .SelectMany(x => x.Members)
                    .OfType<BasePropertyDeclarationSyntax>()
                    .Select(x => (IPropertySymbol)semanticModel.GetDeclaredSymbol(x));

                genericPropertiesList.AddRange(propertiesToCast);
            }

            var genRefs = new GenRef(genericMethodsList, genericPropertiesList);
            return genRefs;
        }
예제 #3
0
        private static SyntaxNode CastResursiveMethod(SyntaxNode tree, SemanticModel semanticModel, GenRef genRef, Dictionary<SyntaxNode, SyntaxNode> castChanges)
        {
            var change = new Dictionary<SyntaxNode, SyntaxNode>();

            foreach (var node in tree.ChildNodes())
            {
                // recurse for changed node
                var casted = CastResursiveMethod(node, semanticModel, genRef, castChanges);

                var ts = GetGenericType(node, genRef, semanticModel);

                if (ts != null)
                {
                    casted = Helpers.CastTo((ExpressionSyntax)casted, ts);

                    if (node.Parent is MemberAccessExpressionSyntax)
                        casted = ((ExpressionSyntax)casted).Parenthesize();

                    castChanges.Add(node, casted);
                }

                if (node != casted)
                    change.Add(node, casted);
            }

            if (change.Any())
                tree = tree.ReplaceNodes(change.Keys, (x, y) => change[x]);

            return tree;
        }