Esempio n. 1
0
        internal async Task Parse()
        {
            if (isParsed)
            {
                return;
            }
            isParsed = true;

            // gather references
            var references = new List <Project>();
            var sln        = roslynProject.Solution;

            foreach (var reference in roslynProject.AllProjectReferences)
            {
                var project = solution.projects.FirstOrDefault(x => x.roslynProject.Id == reference.ProjectId);
                if (project == null)
                {
                    throw new Exception("Project reference not found in solution: " + reference.ProjectId);
                }
                references.Add(project);
                await project.Parse();
            }

            this.references = references;

            // init main objects
            classTypes     = new List <INamedTypeSymbol>();
            structTypes    = new List <INamedTypeSymbol>();
            interfaceTypes = new List <INamedTypeSymbol>();
            enumTypes      = new List <INamedTypeSymbol>();

            typeClassMethods = new HashSet <InvocationExpressionSyntax>();
            genericMethods   = new HashSet <IMethodSymbol>();
            genericTypes     = new HashSet <INamedTypeSymbol>();
            arrayTypes       = new HashSet <IArrayTypeSymbol>();
            pointerTypes     = new HashSet <IPointerTypeSymbol>();

            // parse normal members
            compilation = (CSharpCompilation)await roslynProject.GetCompilationAsync();

            ParseNamespace(compilation.Assembly.GlobalNamespace);

            // get special types
            foreach (var syntaxTree in compilation.SyntaxTrees)
            {
                ParseSpecialMembers(compilation, syntaxTree.GetRoot());
            }

            // merge all types in one list
            var allTypesList = new List <INamedTypeSymbol>();

            allTypesList.AddRange(classTypes);
            allTypesList.AddRange(structTypes);
            allTypesList.AddRange(interfaceTypes);
            allTypesList.AddRange(enumTypes);

            // dependency sort all types
            var allTypesDependencyOrderedList = new List <INamedTypeSymbol>();

            foreach (var type in allTypesList)
            {
                int index = -1, i = 0;
                foreach (var orderedType in allTypesDependencyOrderedList)
                {
                    if (type.IsValueType)
                    {
                        foreach (var member in orderedType.GetMembers())
                        {
                            if (member.Kind != SymbolKind.Field)
                            {
                                continue;
                            }
                            var field = (IFieldSymbol)member;
                            if (field.Type.FullName() == type.FullName())
                            {
                                index = i;
                                break;
                            }
                        }
                        if (index != -1)
                        {
                            break;
                        }
                    }
                    ++i;
                }

                if (index == -1)
                {
                    allTypesDependencyOrderedList.Add(type);
                }
                else
                {
                    allTypesDependencyOrderedList.Insert(index, type);
                }
            }
            allTypes = allTypesDependencyOrderedList;

            // validate basic syntax rules
            foreach (var type in allTypes)
            {
                ValidateType(type);
            }
        }