Esempio n. 1
0
        private TypeName(string s, ref int index)
        {
            try
            {
                var startIndex = index;

                var nameStartIndex = startIndex;
                var nameEndIndex   = (int?)null;

                var assemblyDescriptionStartIndex = (int?)null;
                var assemblyDescriptionEndIndex   = (int?)null;

                var hasGroupingBracket = false;

                var state = State.Name;

                for (; index < s.Length; ++index)
                {
                    var currentCharacter = s[index];
                    var nextCharacter    = index + 1 < s.Length ? s[index + 1] : (char?)null;

                    if (state == State.Name)
                    {
                        if (currentCharacter == '[')
                        {
                            if (index == startIndex)
                            {
                                // Skip type grouping bracket
                                hasGroupingBracket = true;
                                nameStartIndex++;
                            }
                            else if (nextCharacter == ']' || nextCharacter == ',')
                            {
                                // Square bracket delimits an array
                                state = State.Array;
                            }
                            else
                            {
                                // Square bracket delimits the generic argument list
                                nameEndIndex = index;
                                state        = State.Generics;
                            }
                        }
                        else if (currentCharacter == ']')
                        {
                            if (hasGroupingBracket)
                            {
                                // We finished the current grouping, break out
                                break;
                            }
                        }
                        else if (currentCharacter == ',')
                        {
                            // We're entering assembly description

                            state = State.Assembly;

                            assemblyDescriptionStartIndex = index + 1;

                            if (nameEndIndex == null)
                            {
                                nameEndIndex = index;
                            }
                        }
                    }
                    else if (state == State.Array)
                    {
                        if (currentCharacter == ']')
                        {
                            state = State.Name;
                        }
                    }
                    else if (state == State.Generics)
                    {
                        if (currentCharacter == ']')
                        {
                            state = State.Name;
                        }
                        else if (currentCharacter == ',' || currentCharacter == ' ')
                        {
                            // Generic delimiters
                        }
                        else
                        {
                            GenericParameters.Add(new TypeName(s, ref index));
                        }
                    }
                    else if (state == State.Assembly)
                    {
                        if (currentCharacter == ']')
                        {
                            if (hasGroupingBracket)
                            {
                                // We finished the current grouping, break out
                                assemblyDescriptionEndIndex = index;
                                break;
                            }
                        }
                    }
                }

                if (nameEndIndex == null)
                {
                    nameEndIndex = s.Length;
                }

                if (assemblyDescriptionEndIndex == null)
                {
                    assemblyDescriptionEndIndex = s.Length;
                }

                Name = s.Substring(nameStartIndex, nameEndIndex.Value - nameStartIndex);

                if (Name.Contains('+'))
                {
                    var nestedNames = Name.Split('+');

                    foreach (var nestedName in nestedNames)
                    {
                        nestedName.PartsAround('`', out var name, out var genericarity);

                        names.Add(name);

                        if (genericarity != null)
                        {
                            genericarities.Add(int.Parse(genericarity));
                        }
                        else
                        {
                            genericarities.Add(0);
                        }
                    }
                }
                else
                {
                    Name.PartsAround('`', out var name, out var genericarity);

                    names.Add(name);

                    if (genericarity != null)
                    {
                        genericarities.Add(int.Parse(genericarity));
                    }
                    else
                    {
                        genericarities.Add(0);
                    }
                }

                if (assemblyDescriptionStartIndex != null)
                {
                    AssemblyDescription = s.Substring(assemblyDescriptionStartIndex.Value, assemblyDescriptionEndIndex.Value - assemblyDescriptionStartIndex.Value);

                    var parts = AssemblyDescription.Split(',')
                                .Select(x => x.Trim())
                                .ToList();

                    AssemblyVersion        = LookForPairThenRemove(parts, "Version");
                    AssemblyCulture        = LookForPairThenRemove(parts, "Culture");
                    AssemblyPublicKeyToken = LookForPairThenRemove(parts, "PublicKeyToken");

                    if (parts.Count > 0)
                    {
                        AssemblyName = parts[0];
                    }
                }
            }
            catch (Exception ex)
            {
                throw new FormatException($"Failed to parse type name: {s}", ex);
            }
        }
        public ParsedAssemblyQualifiedName(string AssemblyQualifiedName)
        {
            var typeNameLength         = AssemblyQualifiedName.Length;
            var hasAssemblyDescription = false;

            var rootBlock = new Block();

            {
                var depth        = 0;
                var currentBlock = rootBlock;

                for (var index = 0; index < AssemblyQualifiedName.Length; ++index)
                {
                    var c = AssemblyQualifiedName[index];

                    if (c == '[')
                    {
                        if (AssemblyQualifiedName[index + 1] == ']') // Array type // TODO (LAZLO): This won't detect multidimensional array, but FS can't handle them anyway
                        {
                            index++;
                        }
                        else
                        {
                            if (depth == 0)
                            {
                                typeNameLength = index;
                            }

                            ++depth;

                            var innerBlock = new Block
                            {
                                startIndex  = index + 1,
                                level       = depth,
                                parentBlock = currentBlock
                            };

                            currentBlock.innerBlocks.Add(innerBlock);

                            currentBlock = innerBlock;
                        }
                    }
                    else if (c == ']')
                    {
                        currentBlock.endIndex = index - 1;

                        if (AssemblyQualifiedName[currentBlock.startIndex] != '[')
                        {
                            currentBlock.parsedAssemblyQualifiedName = new ParsedAssemblyQualifiedName(AssemblyQualifiedName.Substring(currentBlock.startIndex, index - currentBlock.startIndex));

                            if (depth == 2)
                            {
                                GenericParameters.Add(currentBlock.parsedAssemblyQualifiedName);
                            }
                        }

                        currentBlock = currentBlock.parentBlock;
                        --depth;
                    }
                    else if (depth == 0 && c == ',')
                    {
                        typeNameLength         = index;
                        hasAssemblyDescription = true;

                        break;
                    }
                }
            }

            TypeName = AssemblyQualifiedName.Substring(0, typeNameLength);

            var tickIndex = TypeName.IndexOf('`');

            if (tickIndex >= 0)
            {
                GenericParameterCount = int.Parse(TypeName.Substring(tickIndex + 1));
                TypeName = TypeName.Substring(0, tickIndex);
            }

            if (hasAssemblyDescription)
            {
                AssemblyDescriptionString = AssemblyQualifiedName.Substring(typeNameLength + 2);

                var parts = AssemblyDescriptionString.Split(',')
                            .Select(x => x.Trim())
                            .ToList();

                Version        = LookForPairThenRemove(parts, "Version");
                Culture        = LookForPairThenRemove(parts, "Culture");
                PublicKeyToken = LookForPairThenRemove(parts, "PublicKeyToken");

                if (parts.Count > 0)
                {
                    ShortAssemblyName = parts[0];
                }
            }
        }