Exemplo n.º 1
0
        internal static string GetValue(this GraphNodeId id, GraphNodeIdName idPartName)
        {
            if (idPartName == CodeGraphNodeIdName.Assembly || idPartName == CodeGraphNodeIdName.File)
            {
                try
                {
                    Uri value = id.GetNestedValueByName <Uri>(idPartName);

                    // for idPartName == CodeGraphNodeIdName.File it can be null, avoid unnecessary exception
                    if (value == null)
                    {
                        return(null);
                    }

                    // Assembly and File are represented by a Uri, extract LocalPath string from Uri
                    return((value.IsAbsoluteUri ? value.LocalPath : value.ToString()).Trim('/'));
                }
                catch
                {
                    // for some node ids Uri might throw format exception, thus try to get string at least
                    return(id.GetNestedValueByName <string>(idPartName));
                }
            }
            else
            {
                return(id.GetNestedValueByName <string>(idPartName));
            }
        }
Exemplo n.º 2
0
        private static async Task <GraphNodeId> GetPartialForArrayTypeAsync(
            IArrayTypeSymbol arrayType,
            GraphNodeIdName nodeName,
            Solution solution,
            CancellationToken cancellationToken
            )
        {
            var partials = new List <GraphNodeId>();

            var underlyingType = ChaseToUnderlyingType(arrayType);

            if (underlyingType.TypeKind == TypeKind.Dynamic)
            {
                partials.Add(GraphNodeId.GetPartial(CodeQualifiedName.Name, "Object"));
            }
            else if (underlyingType.TypeKind != TypeKind.TypeParameter)
            {
                partials.Add(GraphNodeId.GetPartial(CodeQualifiedName.Name, underlyingType.Name));
            }

            partials.Add(
                GraphNodeId.GetPartial(CodeQualifiedName.ArrayRank, arrayType.Rank.ToString())
                );
            partials.Add(
                await GetPartialForTypeAsync(
                    arrayType.ElementType,
                    CodeGraphNodeIdName.ParentType,
                    solution,
                    cancellationToken
                    )
                .ConfigureAwait(false)
                );

            return(GraphNodeId.GetPartial(nodeName, MakeCollectionIfNecessary(partials.ToArray())));
        }
Exemplo n.º 3
0
        private static async Task <GraphNodeId> GetPartialForTypeAsync(
            ITypeSymbol symbol,
            GraphNodeIdName nodeName,
            Solution solution,
            CancellationToken cancellationToken,
            bool isInGenericArguments = false
            )
        {
            if (symbol is IArrayTypeSymbol arrayType)
            {
                return(await GetPartialForArrayTypeAsync(
                           arrayType,
                           nodeName,
                           solution,
                           cancellationToken
                           )
                       .ConfigureAwait(false));
            }
            else if (symbol is INamedTypeSymbol namedType)
            {
                return(await GetPartialForNamedTypeAsync(
                           namedType,
                           nodeName,
                           solution,
                           cancellationToken,
                           isInGenericArguments
                           )
                       .ConfigureAwait(false));
            }
            else if (symbol is IPointerTypeSymbol pointerType)
            {
                return(await GetPartialForPointerTypeAsync(
                           pointerType,
                           nodeName,
                           solution,
                           cancellationToken
                           )
                       .ConfigureAwait(false));
            }
            else if (symbol is ITypeParameterSymbol typeParameter)
            {
                return(await GetPartialForTypeParameterSymbolAsync(
                           typeParameter,
                           nodeName,
                           solution,
                           cancellationToken
                           )
                       .ConfigureAwait(false));
            }
            else if (symbol is IDynamicTypeSymbol)
            {
                return(GetPartialForDynamicType(nodeName));
            }

            throw ExceptionUtilities.Unreachable;
        }
Exemplo n.º 4
0
        private static async Task <GraphNodeId> GetPartialForPointerTypeAsync(
            IPointerTypeSymbol pointerType,
            GraphNodeIdName nodeName,
            Solution solution,
            CancellationToken cancellationToken
            )
        {
            var indirection = 1;

            while (pointerType.PointedAtType.TypeKind == TypeKind.Pointer)
            {
                indirection++;
                pointerType = (IPointerTypeSymbol)pointerType.PointedAtType;
            }

            var partials = new List <GraphNodeId>();

            partials.Add(
                GraphNodeId.GetPartial(CodeQualifiedName.Name, pointerType.PointedAtType.Name)
                );
            partials.Add(
                GraphNodeId.GetPartial(CodeQualifiedName.Indirection, indirection.ToString())
                );

            if (pointerType.PointedAtType.ContainingType != null)
            {
                partials.Add(
                    await GetPartialForTypeAsync(
                        pointerType.PointedAtType.ContainingType,
                        CodeGraphNodeIdName.ParentType,
                        solution,
                        cancellationToken
                        )
                    .ConfigureAwait(false)
                    );
            }

            return(GraphNodeId.GetPartial(nodeName, MakeCollectionIfNecessary(partials.ToArray())));
        }
        private string GetPartialValueFromGraphNodeId(GraphNodeId id, GraphNodeIdName idPartName)
        {
            if (idPartName == CodeGraphNodeIdName.Assembly || idPartName == CodeGraphNodeIdName.File)
            {
                try
                {
                    var value = id.GetNestedValueByName <Uri>(idPartName);

                    // Assembly and File are represented by a Uri, extract LocalPath string from Uri
                    return((value.IsAbsoluteUri ? value.LocalPath : value.ToString()).Trim('/'));
                }
                catch
                {
                    // for some node ids Uri might throw format exception, thus try to get string at least
                    return(id.GetNestedValueByName <string>(idPartName));
                }
            }
            else
            {
                return(id.GetNestedValueByName <string>(idPartName));
            }
        }
Exemplo n.º 6
0
        private static async Task <GraphNodeId> GetPartialForTypeParameterSymbolAsync(
            ITypeParameterSymbol typeParameterSymbol,
            GraphNodeIdName nodeName,
            Solution solution,
            CancellationToken cancellationToken
            )
        {
            if (typeParameterSymbol.TypeParameterKind == TypeParameterKind.Method)
            {
                return(GraphNodeId.GetPartial(
                           nodeName,
                           new GraphNodeIdCollection(
                               false,
                               GraphNodeId.GetPartial(
                                   CodeGraphNodeIdName.Parameter,
                                   typeParameterSymbol.Ordinal.ToString()
                                   )
                               )
                           ));
            }
            else
            {
                var nodes = await GetPartialsForNamespaceAndTypeAsync(
                    typeParameterSymbol,
                    false,
                    solution,
                    cancellationToken
                    )
                            .ConfigureAwait(false);

                return(GraphNodeId.GetPartial(
                           nodeName,
                           new GraphNodeIdCollection(false, nodes.ToArray())
                           ));
            }
        }
Exemplo n.º 7
0
        private static async Task <GraphNodeId> GetPartialForNamedTypeAsync(INamedTypeSymbol namedType, GraphNodeIdName nodeName, Solution solution, CancellationToken cancellationToken, bool isInGenericArguments = false)
        {
            // If this is a simple type, then we don't have much to do
            if (namedType.ContainingType == null && namedType.ConstructedFrom == namedType && namedType.Arity == 0)
            {
                return(GraphNodeId.GetPartial(nodeName, namedType.Name));
            }
            else
            {
                // For a generic type, we need to populate "type" property with the following form:
                //
                //      Type = (Name =...GenericParameterCount = GenericArguments =...ParentType =...)
                //
                //  where "Name" contains a symbol name
                //    and "GenericParameterCount" contains the number of type parameters,
                //    and "GenericArguments" contains its type parameters' node information.
                //    and "ParentType" contains its containing type's node information.

                var partials = new List <GraphNodeId>();

                partials.Add(GraphNodeId.GetPartial(CodeQualifiedName.Name, namedType.Name));

                if (namedType.Arity > 0)
                {
                    partials.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.GenericParameterCountIdentifier, namedType.Arity.ToString()));
                }

                // For the property "GenericArguments", we only populate them
                // when type parameters are constructed using instance types (i.e., namedType.ConstructedFrom != namedType).
                // However, there is a case where we need to populate "GenericArguments" even though arguments are not marked as "constructed"
                // because a symbol is not marked as "constructed" when a type is constructed using its own type parameters.
                // To distinguish this case, we use "isInGenericArguments" flag which we pass either to populate arguments recursively or to populate "ParentType".

                bool hasGenericArguments = (namedType.ConstructedFrom != namedType || isInGenericArguments) && namedType.TypeArguments != null && namedType.TypeArguments.Any();

                if (hasGenericArguments)
                {
                    var genericArguments = new List <GraphNodeId>();
                    foreach (var arg in namedType.TypeArguments)
                    {
                        var nodes = await GetPartialsForNamespaceAndTypeAsync(arg, includeNamespace : true, solution : solution, cancellationToken : cancellationToken, isInGenericArguments : true).ConfigureAwait(false);

                        genericArguments.Add(GraphNodeId.GetNested(nodes.ToArray()));
                    }

                    partials.Add(GraphNodeId.GetArray(
                                     CodeGraphNodeIdName.GenericArgumentsIdentifier,
                                     genericArguments.ToArray()));
                }

                if (namedType.ContainingType != null)
                {
                    partials.Add(await GetPartialForTypeAsync(namedType.ContainingType, CodeGraphNodeIdName.ParentType, solution, cancellationToken, hasGenericArguments).ConfigureAwait(false));
                }

                return(GraphNodeId.GetPartial(nodeName, MakeCollectionIfNecessary(false, partials.ToArray())));
            }
        }
Exemplo n.º 8
0
 private static GraphNodeId GetPartialForDynamicType(IDynamicTypeSymbol dt, GraphNodeIdName nodeName)
 {
     // We always consider this to be the "Object" type since Progression takes a very metadata-ish view of the type
     return(GraphNodeId.GetPartial(nodeName, "Object"));
 }
Exemplo n.º 9
0
 private static async Task<GraphNodeId> GetPartialForTypeParameterSymbolAsync(ITypeParameterSymbol typeParameterSymbol, GraphNodeIdName nodeName, Solution solution, CancellationToken cancellationToken)
 {
     if (typeParameterSymbol.TypeParameterKind == TypeParameterKind.Method)
     {
         return GraphNodeId.GetPartial(nodeName,
             new GraphNodeIdCollection(false,
                 GraphNodeId.GetPartial(CodeGraphNodeIdName.Parameter, typeParameterSymbol.Ordinal.ToString())));
     }
     else
     {
         var nodes = await GetPartialsForNamespaceAndTypeAsync(typeParameterSymbol, false, solution, cancellationToken).ConfigureAwait(false);
         return GraphNodeId.GetPartial(nodeName,
             new GraphNodeIdCollection(false, nodes.ToArray()));
     }
 }
Exemplo n.º 10
0
        private static async Task<GraphNodeId> GetPartialForArrayTypeAsync(IArrayTypeSymbol arrayType, GraphNodeIdName nodeName, Solution solution, CancellationToken cancellationToken)
        {
            var partials = new List<GraphNodeId>();

            var underlyingType = ChaseToUnderlyingType(arrayType);

            if (underlyingType.TypeKind == TypeKind.Dynamic)
            {
                partials.Add(GraphNodeId.GetPartial(CodeQualifiedName.Name, "Object"));
            }
            else if (underlyingType.TypeKind != TypeKind.TypeParameter)
            {
                partials.Add(GraphNodeId.GetPartial(CodeQualifiedName.Name, underlyingType.Name));
            }

            partials.Add(GraphNodeId.GetPartial(CodeQualifiedName.ArrayRank, arrayType.Rank.ToString()));
            partials.Add(await GetPartialForTypeAsync(arrayType.ElementType, CodeGraphNodeIdName.ParentType, solution, cancellationToken).ConfigureAwait(false));

            return GraphNodeId.GetPartial(nodeName, MakeCollectionIfNecessary(false, partials.ToArray()));
        }
Exemplo n.º 11
0
        private static async Task<GraphNodeId> GetPartialForPointerTypeAsync(IPointerTypeSymbol pointerType, GraphNodeIdName nodeName, Solution solution, CancellationToken cancellationToken)
        {
            var indirection = 1;

            while (pointerType.PointedAtType.TypeKind == TypeKind.Pointer)
            {
                indirection++;
                pointerType = (IPointerTypeSymbol)pointerType.PointedAtType;
            }

            var partials = new List<GraphNodeId>();

            partials.Add(GraphNodeId.GetPartial(CodeQualifiedName.Name, pointerType.PointedAtType.Name));
            partials.Add(GraphNodeId.GetPartial(CodeQualifiedName.Indirection, indirection.ToString()));

            if (pointerType.PointedAtType.ContainingType != null)
            {
                partials.Add(await GetPartialForTypeAsync(pointerType.PointedAtType.ContainingType, CodeGraphNodeIdName.ParentType, solution, cancellationToken).ConfigureAwait(false));
            }

            return GraphNodeId.GetPartial(nodeName, MakeCollectionIfNecessary(false, partials.ToArray()));
        }
Exemplo n.º 12
0
        private static async Task<GraphNodeId> GetPartialForNamedTypeAsync(INamedTypeSymbol namedType, GraphNodeIdName nodeName, Solution solution, CancellationToken cancellationToken, bool isInGenericArguments = false)
        {
            // If this is a simple type, then we don't have much to do
            if (namedType.ContainingType == null && namedType.ConstructedFrom == namedType && namedType.Arity == 0)
            {
                return GraphNodeId.GetPartial(nodeName, namedType.Name);
            }
            else
            {
                // For a generic type, we need to populate "type" property with the following form:
                //
                //      Type = (Name =...GenericParameterCount = GenericArguments =...ParentType =...)
                //
                //  where "Name" contains a symbol name
                //    and "GenericParameterCount" contains the number of type parameters,
                //    and "GenericArguments" contains its type parameters' node information. 
                //    and "ParentType" contains its containing type's node information.

                var partials = new List<GraphNodeId>();

                partials.Add(GraphNodeId.GetPartial(CodeQualifiedName.Name, namedType.Name));

                if (namedType.Arity > 0)
                {
                    partials.Add(GraphNodeId.GetPartial(CodeGraphNodeIdName.GenericParameterCountIdentifier, namedType.Arity.ToString()));
                }

                // For the property "GenericArguments", we only populate them 
                // when type parameters are constructed using instance types (i.e., namedType.ConstructedFrom != namedType).
                // However, there is a case where we need to populate "GenericArguments" even though arguments are not marked as "constructed"
                // because a symbol is not marked as "constructed" when a type is constructed using its own type parameters.
                // To distinguish this case, we use "isInGenericArguments" flag which we pass either to populate arguments recursively or to populate "ParentType".

                bool hasGenericArguments = (namedType.ConstructedFrom != namedType || isInGenericArguments) && namedType.TypeArguments != null && namedType.TypeArguments.Any();

                if (hasGenericArguments)
                {
                    var genericArguments = new List<GraphNodeId>();
                    foreach (var arg in namedType.TypeArguments)
                    {
                        var nodes = await GetPartialsForNamespaceAndTypeAsync(arg, includeNamespace: true, solution: solution, cancellationToken: cancellationToken, isInGenericArguments: true).ConfigureAwait(false);
                        genericArguments.Add(GraphNodeId.GetNested(nodes.ToArray()));
                    }

                    partials.Add(GraphNodeId.GetArray(
                        CodeGraphNodeIdName.GenericArgumentsIdentifier,
                        genericArguments.ToArray()));
                }

                if (namedType.ContainingType != null)
                {
                    partials.Add(await GetPartialForTypeAsync(namedType.ContainingType, CodeGraphNodeIdName.ParentType, solution, cancellationToken, hasGenericArguments).ConfigureAwait(false));
                }

                return GraphNodeId.GetPartial(nodeName, MakeCollectionIfNecessary(false, partials.ToArray()));
            }
        }
Exemplo n.º 13
0
 private static GraphNodeId GetPartialForDynamicType(IDynamicTypeSymbol dt, GraphNodeIdName nodeName)
 {
     // We always consider this to be the "Object" type since Progression takes a very metadata-ish view of the type
     return GraphNodeId.GetPartial(nodeName, "Object");
 }
Exemplo n.º 14
0
        private static async Task<GraphNodeId> GetPartialForTypeAsync(ITypeSymbol symbol, GraphNodeIdName nodeName, Solution solution, CancellationToken cancellationToken, bool isInGenericArguments = false)
        {
            if (symbol is IArrayTypeSymbol)
            {
                return await GetPartialForArrayTypeAsync((IArrayTypeSymbol)symbol, nodeName, solution, cancellationToken).ConfigureAwait(false);
            }
            else if (symbol is INamedTypeSymbol)
            {
                return await GetPartialForNamedTypeAsync((INamedTypeSymbol)symbol, nodeName, solution, cancellationToken, isInGenericArguments).ConfigureAwait(false);
            }
            else if (symbol is IPointerTypeSymbol)
            {
                return await GetPartialForPointerTypeAsync((IPointerTypeSymbol)symbol, nodeName, solution, cancellationToken).ConfigureAwait(false);
            }
            else if (symbol is ITypeParameterSymbol)
            {
                return await GetPartialForTypeParameterSymbolAsync((ITypeParameterSymbol)symbol, nodeName, solution, cancellationToken).ConfigureAwait(false);
            }
            else if (symbol is IDynamicTypeSymbol)
            {
                return GetPartialForDynamicType((IDynamicTypeSymbol)symbol, nodeName);
            }

            throw ExceptionUtilities.Unreachable;
        }