private void AnalyzeDocumentData(DocumentData documentData)
        {
            foreach (var typeData in documentData.GetAllTypeDatas(o => o.Conversion != TypeConversion.Ignore))
            {
                // Ignore or copy properties of new types
                foreach (var property in typeData.Properties.Values)
                {
                    if (typeData.IsNewType)
                    {
                        property.Copy();                         // TODO: copy only if needed
                        SoftCopyAllDependencies(property.GetAccessorData);
                        SoftCopyAllDependencies(property.SetAccessorData);
                    }
                    // A type with Unknown conversion may be converted to a new type if one of its base classes
                    // is a new type and has at least one async member
                    else if (typeData.BaseTypes.All(o => o.Conversion != TypeConversion.NewType))
                    {
                        property.Conversion = PropertyConversion.Ignore;
                    }
                }

                foreach (var methodData in typeData.MethodsAndAccessors.Where(o => o.Conversion != MethodConversion.Ignore))
                {
                    foreach (var functionData in methodData.GetDescendantsChildFunctions(o => o.Conversion != MethodConversion.Ignore)
                             .OrderByDescending(o => o.GetNode().SpanStart))
                    {
                        AnalyzeAnonymousFunctionData(documentData, functionData);
                    }
                    AnalyzeMethodData(documentData, methodData);
                }
            }
        }
        private async Task ScanDocumentData(DocumentData documentData)
        {
            foreach (var typeData in documentData.GetAllTypeDatas(o => o.Conversion != TypeConversion.Ignore))
            {
                // If the type have to be defined as a new type then we need to find all references to that type
                if (typeData.Conversion == TypeConversion.NewType)
                {
                    await ScanForTypeReferences(typeData).ConfigureAwait(false);
                }

                if (_configuration.ScanForMissingAsyncMembers)
                {
                    ScanForTypeMissingAsyncMethods(typeData);
                }

                foreach (var methodData in typeData.Methods.Values
                         .Where(o => o.Conversion != MethodConversion.Ignore))
                {
                    await ScanMethodData(methodData);

                    foreach (var functionData in methodData.GetAllAnonymousFunctionData(o => o.Conversion != MethodConversion.Ignore))
                    {
                        // TODO: do we need something here?
                    }
                }
            }
        }
 private void AnalyzeDocumentData(DocumentData documentData)
 {
     foreach (var typeData in documentData.GetAllTypeDatas(o => o.Conversion != TypeConversion.Ignore))
     {
         foreach (var methodData in typeData.Methods.Values
                  .Where(o => o.Conversion != MethodConversion.Ignore))
         {
             AnalyzeMethodData(documentData, methodData);
             foreach (var functionData in methodData.GetAllAnonymousFunctionData(o => o.Conversion != MethodConversion.Ignore))
             {
                 AnalyzeAnonymousFunctionData(documentData, functionData);
             }
         }
     }
 }
        private async Task ScanDocumentData(DocumentData documentData, CancellationToken cancellationToken = default(CancellationToken))
        {
            if (cancellationToken.IsCancellationRequested)
            {
                cancellationToken.ThrowIfCancellationRequested();
            }
            foreach (var typeData in documentData.GetAllTypeDatas(o => o.Conversion != TypeConversion.Ignore))
            {
                // If the type have to be defined as a new type then we need to find all references to that type.
                // We must not scan for nested types as they will not be renamed
                if (typeData.Conversion == TypeConversion.NewType)
                {
                    await ScanForReferences(typeData, typeData.Symbol,
                                            (data, location, nameNode) => new TypeDataReference(data, location, nameNode, typeData.Symbol, typeData),
                                            cancellationToken)
                    .ConfigureAwait(false);
                }
                FillBaseTypes(typeData, documentData.ProjectData);

                if (_configuration.CanScanForMissingAsyncMembers != null && _configuration.CanScanForMissingAsyncMembers(typeData.Symbol))
                {
                    ScanForTypeMissingAsyncMethods(typeData);
                }
                // Scan also explicitly ignored methods in order to fix the conversion  if the user applies an invalid
                // conversion. (e.g. ignored a method that is used in a method that will be genereated)
                foreach (var methodOrAccessorData in typeData.MethodsAndAccessors
                         .Where(o => o.Conversion.HasAnyFlag(MethodConversion.ToAsync, MethodConversion.Smart) ||
                                o.IgnoredReason == IgnoreReason.AsyncCounterpartExists || // TODO: Should be configurable?
                                                                                          // TODO: Make configurable: Scan private methods in order to ignore them if they are not used
                                ((o.ExplicitlyIgnored /*|| o.IsPrivate*/) && o.TypeData.IsNewType)
                                )
                         )
                {
                    await ScanMethodData(methodOrAccessorData, 0, cancellationToken).ConfigureAwait(false);
                }
                foreach (var fieldVariableData in typeData.Fields.Values.SelectMany(o => o.Variables)
                         .Where(o => o.Conversion == FieldVariableConversion.Smart))
                {
                    await ScanForReferences(fieldVariableData, fieldVariableData.Symbol,
                                            (data, location, nameNode) =>
                                            new FieldVariableDataReference(data, location, nameNode, fieldVariableData.Symbol, fieldVariableData),
                                            cancellationToken)
                    .ConfigureAwait(false);
                }
            }
        }
        private void TryLinkToRealReference(ISymbol typeSymbol, DocumentData documentData, ReferenceLocation refLocation)
        {
            if (typeSymbol.Kind != SymbolKind.NamedType)
            {
                return;
            }
            // A cref/nameof can be on a method or type trivia but we get always the type symbol
            var typeData = documentData.GetAllTypeDatas(o => o.Symbol.Equals(typeSymbol)).FirstOrDefault();

            if (typeData == null)
            {
                return;
            }
            // Try to find the real node where the cref/nameof is located
            var referenceNameNode   = typeData.Node.GetSimpleName(refLocation.Location.SourceSpan, true);
            var referenceSymbolInfo = documentData.SemanticModel.GetSymbolInfo(referenceNameNode);
            var data = documentData.GetNearestNodeData(referenceNameNode.Parent, referenceNameNode.IsInsideCref());

            if (referenceSymbolInfo.Symbol is IMethodSymbol methodSymbol)
            {
                if (!referenceNameNode.IsInsideCref())
                {
                    return;
                }
                var referenceData = ProjectData.GetFunctionData(methodSymbol);
                var reference     = new CrefFunctionDataReference(data, refLocation, referenceNameNode, methodSymbol, referenceData, false);
                data.References.TryAdd(reference);
                referenceData?.SelfReferences.TryAdd(reference);
            }
            else if (referenceNameNode.IsInsideNameOf())            // GetSymbolInfo will never return a concrete symbol for nameof only candidates
            {
                var referencedFuncs = new Dictionary <IMethodSymbol, FunctionData>();
                foreach (var candidateSymbol in referenceSymbolInfo.CandidateSymbols.OfType <IMethodSymbol>())
                {
                    var nameofReferenceData = ProjectData.GetFunctionData(candidateSymbol);
                    referencedFuncs.Add(candidateSymbol, nameofReferenceData);
                }
                var nameofReference = new NameofFunctionDataReference(data, refLocation, referenceNameNode, referencedFuncs, false);
                data.References.TryAdd(nameofReference);
                foreach (var referencedFun in referencedFuncs.Values.Where(o => o != null))
                {
                    referencedFun.SelfReferences.TryAdd(nameofReference);
                }
            }
        }