public async Task <ProgramComposition> ProcessAsync(ProgramComposition composition, ProjectScriptInfo config) { _externallyReferencedTypes.Clear(); var usageAnalyzer = new UsageAnalyzer(); var typeUsages = await usageAnalyzer.FindUsagesAsync(composition, config); foreach (var typeUsage in typeUsages) { foreach (var part in typeUsage.Usage) { foreach (var location in part.Locations) { var node = composition.RootNode.FindNode(location.Location.SourceSpan); if (IsInProgram(node)) { _externallyReferencedTypes.Add(typeUsage.FullName); } } } } var root = composition.RootNode; root = Visit(root); return(await composition.WithNewDocumentRootAsync(root)); }
public async Task <ProgramComposition> ProcessAsync([NotNull] ProgramComposition composition, [NotNull] ProjectScriptInfo config) { if (composition == null) { throw new ArgumentNullException(nameof(composition)); } if (config == null) { throw new ArgumentNullException(nameof(config)); } var analyzer = new UsageAnalyzer(); while (true) { var symbolDefinitions = await analyzer.FindUsagesAsync(composition, config); var symbol = symbolDefinitions.FirstOrDefault(s => !s.IsProtected && s.SyntaxNode.IsTypeDeclaration() && HasNoUsage(s)); if (symbol == null) { break; } var rootNode = RemoveDefinition(composition.RootNode, symbol); composition = await composition.WithNewDocumentRootAsync(rootNode); } return(composition); }
public async Task <ProgramComposition> ProcessAsync(ProgramComposition composition, MDKProjectProperties config) { var newDocument = await Simplifier.ReduceAsync(composition.Document).ConfigureAwait(false); composition = await(composition.WithDocumentAsync(newDocument).ConfigureAwait(false)); _externallyReferencedMembers.Clear(); var usageAnalyzer = new UsageAnalyzer(); var typeUsages = await usageAnalyzer.FindUsagesAsync(composition, config); foreach (var typeUsage in typeUsages) { foreach (var part in typeUsage.Usage) { foreach (var location in part.Locations) { var node = composition.RootNode.FindNode(location.Location.SourceSpan); if (!IsInProgram(node)) { _externallyReferencedMembers.Add(typeUsage.FullName); } } } } var root = composition.RootNode; root = Visit(root); return(await composition.WithNewDocumentRootAsync(root)); }
public async Task <ProgramComposition> ProcessAsync([NotNull] ProgramComposition composition, [NotNull] ProjectScriptInfo config) { if (composition == null) { throw new ArgumentNullException(nameof(composition)); } if (config == null) { throw new ArgumentNullException(nameof(config)); } var nodes = new Dictionary <ISymbol, Node>(); var analyzer = new UsageAnalyzer(); var symbolDefinitions = await analyzer.FindUsagesAsync(composition, config); var symbolLookup = symbolDefinitions.GroupBy(d => d.Symbol).ToDictionary(g => g.Key, g => g.ToList()); var rootNode = composition.RootNode; foreach (var definition in symbolDefinitions) { if (!(definition.Symbol is ITypeSymbol typeSymbol)) { continue; } if (typeSymbol.TypeKind == TypeKind.TypeParameter) { continue; } if (!nodes.TryGetValue(definition.Symbol, out var node)) { nodes[definition.Symbol] = node = new Node(definition); } else { node.Definitions.Add(definition); } foreach (var usage in definition.Usage) { foreach (var location in usage.Locations) { var enclosingSymbol = await FindTypeSymbolAsync(rootNode, location); var enclosingSymbolDefinitions = symbolLookup[enclosingSymbol]; if (!nodes.TryGetValue(enclosingSymbol, out var referencingNode)) { nodes[enclosingSymbol] = referencingNode = new Node(enclosingSymbolDefinitions); } if (node != referencingNode) { referencingNode.References.Add(node); } } } } var program = symbolDefinitions.FirstOrDefault(d => d.FullName == "Program"); if (program == null || !nodes.TryGetValue(program.Symbol, out var programNode)) { throw new BuildException(string.Format(Text.TypeTrimmer_ProcessAsync_NoEntryPoint, composition.Document.Project.FilePath)); } var usedNodes = new List <Node>(); var queue = new Queue <Node>(); var visitedNodes = new HashSet <Node>(); queue.Enqueue(programNode); while (queue.Count > 0) { var node = queue.Dequeue(); if (!visitedNodes.Add(node)) { continue; } usedNodes.Add(node); foreach (var reference in node.References) { queue.Enqueue(reference); } } var usedSymbolDefinitions = usedNodes.SelectMany(n => n.Definitions).ToImmutableHashSet(); var unusedSymbolDefinitions = symbolDefinitions.Where(definition => IsEligibleForRemoval(definition) && !usedSymbolDefinitions.Contains(definition)).ToList(); var nodesToRemove = unusedSymbolDefinitions.Select(definition => definition.FullName).ToImmutableHashSet(); var walker = new RemovalWalker(nodesToRemove); rootNode = walker.Visit(rootNode); foreach (var symbol in unusedSymbolDefinitions) { rootNode = RemoveDefinition(rootNode, symbol); } return(await composition.WithNewDocumentRootAsync(rootNode)); }
static DataController() { usageAnalyzer = new UsageAnalyzer(GetUsageSettings(), UsageType.Display); }