public void FullDependenciesWithIncrementalAnalysis() { MockTypeLib mainTypeLib1, mainTypeLib2, mainTypeLib3, dependencyTypeLib1, dependencyTypeLib2, dependencyTypeLib3; CreateTwoTypeLibs(out mainTypeLib1, out dependencyTypeLib1); CreateTwoTypeLibs(out mainTypeLib2, out dependencyTypeLib2); CreateTwoTypeLibs(out mainTypeLib3, out dependencyTypeLib3); mainTypeLib1.ContainedTypeInfos[0].DefinesVariable(dependencyTypeLib1.ContainedTypeInfos[0]); mainTypeLib2.ContainedTypeInfos[0].DefinesVariable(dependencyTypeLib1.ContainedTypeInfos[0]); mainTypeLib2.ContainedTypeInfos[0].DefinesVariable(dependencyTypeLib2.ContainedTypeInfos[0]); mainTypeLib3.ContainedTypeInfos[0].DefinesVariable(dependencyTypeLib1.ContainedTypeInfos[0]); mainTypeLib3.ContainedTypeInfos[0].DefinesVariable(dependencyTypeLib3.ContainedTypeInfos[0]); ComDependencyWalker walker = new ComDependencyWalker(MockReleaseComObject); walker.AnalyzeTypeLibrary(mainTypeLib1); TYPELIBATTR[] dependencies = walker.GetDependencies(); ICollection<string> analyzedTypes = walker.GetAnalyzedTypeNames(); AssertDependenciesContainTypeLib(dependencies, dependencyTypeLib1, true); AssertDependenciesContainTypeLib(dependencies, dependencyTypeLib2, false); AssertDependenciesContainTypeLib(dependencies, dependencyTypeLib3, false); Assert.Equal(2, analyzedTypes.Count); walker.ClearDependencyList(); walker.AnalyzeTypeLibrary(mainTypeLib2); dependencies = walker.GetDependencies(); analyzedTypes = walker.GetAnalyzedTypeNames(); AssertDependenciesContainTypeLib(dependencies, dependencyTypeLib1, true); AssertDependenciesContainTypeLib(dependencies, dependencyTypeLib2, true); AssertDependenciesContainTypeLib(dependencies, dependencyTypeLib3, false); Assert.Equal(4, analyzedTypes.Count); walker.ClearDependencyList(); walker.AnalyzeTypeLibrary(mainTypeLib3); dependencies = walker.GetDependencies(); analyzedTypes = walker.GetAnalyzedTypeNames(); AssertDependenciesContainTypeLib(dependencies, dependencyTypeLib1, true); AssertDependenciesContainTypeLib(dependencies, dependencyTypeLib2, false); AssertDependenciesContainTypeLib(dependencies, dependencyTypeLib3, true); Assert.Equal(6, analyzedTypes.Count); }
private List<string> ScanAndResolveAllDependencies(ComDependencyWalker dependencyWalker, ComReferenceInfo reference) { dependencyWalker.ClearDependencyList(); base.Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.ScanningDependencies", new object[] { reference.SourceItemSpec }); dependencyWalker.AnalyzeTypeLibrary(reference.typeLibPointer); foreach (Exception exception in dependencyWalker.EncounteredProblems) { base.Log.LogWarningWithCodeFromResources("ResolveComReference.FailedToScanDependencies", new object[] { reference.SourceItemSpec, exception.Message }); } dependencyWalker.EncounteredProblems.Clear(); HashSet<string> source = new HashSet<string>(); foreach (System.Runtime.InteropServices.ComTypes.TYPELIBATTR typelibattr in dependencyWalker.GetDependencies()) { if (!ComReference.AreTypeLibAttrEqual(typelibattr, reference.attr)) { ComReferenceInfo info; if (this.IsExistingProjectReference(typelibattr, null, out info)) { ITaskItem item; dependencyWalker.ClearAnalyzedTypeCache(); if (this.ResolveReference(dependencyWalker, info, this.WrapperOutputDirectory, out item)) { source.Add(item.ItemSpec); foreach (string str in info.dependentWrapperPaths) { source.Add(str); } } } else { ComReferenceWrapperInfo info2; base.Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.ResolvingDependency", new object[] { typelibattr.guid, typelibattr.wMajorVerNum, typelibattr.wMinorVerNum }); ((IComReferenceResolver) this).ResolveComClassicReference(typelibattr, this.WrapperOutputDirectory, null, null, out info2); base.Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.ResolvedDependentComReference", new object[] { typelibattr.guid, typelibattr.wMajorVerNum, typelibattr.wMinorVerNum, info2.path }); source.Add(info2.path); } } } return source.ToList<string>(); }
/// <summary> /// Scan all the dependencies of the main project references and preresolve them /// so that when we get asked about a previously unknown dependency in the form of a .NET assembly /// we know what to do with it. /// </summary> private List<string> ScanAndResolveAllDependencies(ComDependencyWalker dependencyWalker, ComReferenceInfo reference) { dependencyWalker.ClearDependencyList(); if (!Silent) { Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.ScanningDependencies", reference.SourceItemSpec); } dependencyWalker.AnalyzeTypeLibrary(reference.typeLibPointer); if (!Silent) { foreach (Exception ex in dependencyWalker.EncounteredProblems) { // A failure to resolve a reference due to something possibly being missing from disk is not // an error; the user may not be actually consuming types from it Log.LogWarningWithCodeFromResources("ResolveComReference.FailedToScanDependencies", reference.SourceItemSpec, ex.Message); } } dependencyWalker.EncounteredProblems.Clear(); HashSet<string> dependentPaths = new HashSet<string>(); TYPELIBATTR[] dependentAttrs = dependencyWalker.GetDependencies(); foreach (TYPELIBATTR dependencyTypeLibAttr in dependentAttrs) { // We don't need to even try to resolve if the dependency reference is ourselves. if (!ComReference.AreTypeLibAttrEqual(dependencyTypeLibAttr, reference.attr)) { ComReferenceInfo existingReference; if (IsExistingProjectReference(dependencyTypeLibAttr, null, out existingReference)) { ITaskItem resolvedItem; // If we're resolving another project reference, empty out the type cache -- if the dependencies are buried, // caching the analyzed types can make it so that we don't recognize our dependencies' dependencies. dependencyWalker.ClearAnalyzedTypeCache(); if (ResolveReference(dependencyWalker, existingReference, WrapperOutputDirectory, out resolvedItem)) { // Add the resolved dependency dependentPaths.Add(resolvedItem.ItemSpec); // and anything it depends on foreach (string dependentPath in existingReference.dependentWrapperPaths) { dependentPaths.Add(dependentPath); } } } else { if (!Silent) { Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.ResolvingDependency", dependencyTypeLibAttr.guid, dependencyTypeLibAttr.wMajorVerNum, dependencyTypeLibAttr.wMinorVerNum); } ComReferenceWrapperInfo wrapperInfo; ((IComReferenceResolver)this).ResolveComClassicReference(dependencyTypeLibAttr, WrapperOutputDirectory, null /* unknown wrapper type */, null /* unknown name */, out wrapperInfo); if (!Silent) { Log.LogMessageFromResources(MessageImportance.Low, "ResolveComReference.ResolvedDependentComReference", dependencyTypeLibAttr.guid, dependencyTypeLibAttr.wMajorVerNum, dependencyTypeLibAttr.wMinorVerNum, wrapperInfo.path); } dependentPaths.Add(wrapperInfo.path); } } } return dependentPaths.ToList<string>(); }