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); } } }