@@ -396,7 +396,6 @@ public async Task<ValueTuple<bool, List<RestoreTargetGraph>, RuntimeGraph>> Reso
396396 }
397397
398398 LibraryDependencyIndex childLibraryDependencyIndex = resolvedDependencyGraphItem . GetDependencyIndexForDependencyAt ( i ) ;
399- LibraryRangeIndex currentRangeIndex = resolvedDependencyGraphItem . GetRangeIndexForDependencyAt ( i ) ;
400399
401400 if ( ! resolvedDependencyGraphItems . TryGetValue ( childLibraryDependencyIndex , out ResolvedDependencyGraphItem ? childResolvedDependencyGraphItem ) )
402401 {
@@ -410,6 +409,8 @@ public async Task<ValueTuple<bool, List<RestoreTargetGraph>, RuntimeGraph>> Reso
410409 // Determine if this dependency has already been visited
411410 if ( ! visitedItems . Add ( childLibraryDependencyIndex ) )
412411 {
412+ LibraryRangeIndex currentRangeIndex = resolvedDependencyGraphItem . GetRangeIndexForDependencyAt ( i ) ;
413+
413414 if ( resolvedDependencyGraphItem . Path . Contains ( currentRangeIndex ) )
414415 {
415416 // If the dependency exists in the its own path, then a cycle exists
@@ -512,27 +513,10 @@ public async Task<ValueTuple<bool, List<RestoreTargetGraph>, RuntimeGraph>> Reso
512513 continue ;
513514 }
514515
515- if ( TryDetectVersionConflict (
516- currentGraphNode ,
517- childResolvedDependencyGraphItem ,
518- versionConflicts ,
519- downgrades ,
520- childLibraryDependency ,
521- currentRangeIndex ,
522- childResolvedLibraryRangeIndex ,
523- out GraphNode < RemoteResolveResult > ? nodeWithConflict ) )
524- {
525- currentGraphNode . InnerNodes . Add ( nodeWithConflict ) ;
526-
527- nodesById . Add ( currentRangeIndex , nodeWithConflict ) ;
528-
529- continue ;
530- }
531-
532516 // If it wasn't a downgrade, then it was a version conflict like A -> B [1.0.0] but B 1.0.0 was not in the resolved graph
533517 if ( versionConflicts . ContainsKey ( childResolvedLibraryRangeIndex ) && ! nodesById . ContainsKey ( currentRangeIndex ) )
534518 {
535- nodeWithConflict = new ( childResolvedLibraryDependency . LibraryRange )
519+ GraphNode < RemoteResolveResult > nodeWithConflict = new ( childResolvedLibraryDependency . LibraryRange )
536520 {
537521 Item = childResolvedDependencyGraphItem . Item ,
538522 Disposition = Disposition . Acceptable ,
@@ -597,26 +581,43 @@ public async Task<ValueTuple<bool, List<RestoreTargetGraph>, RuntimeGraph>> Reso
597581 ) ) ;
598582 }
599583
600- if ( TryDetectVersionConflict (
601- currentGraphNode ,
602- childResolvedDependencyGraphItem ,
603- versionConflicts , downgrades ,
604- childLibraryDependency ,
605- currentRangeIndex ,
606- childResolvedLibraryRangeIndex ,
607- out GraphNode < RemoteResolveResult > ? conflictingNode ) )
584+ // This is a version conflict if:
585+ // 1. The node is not a project and isn't unresolved
586+ // 2. The conflict has not already been detected
587+ // 3. The dependency is transitive and doesn't have PrivateAssets=All
588+ // 4. The dependency has a version specified
589+ // 5. The version range is not satisfied by the resolved version
590+ // 6. A corresponding downgrade was not detected
591+ if ( newGraphNode . Item . Key . Type != LibraryType . Project
592+ && newGraphNode . Item . Key . Type != LibraryType . ExternalProject
593+ && newGraphNode . Item . Key . Type != LibraryType . Unresolved
594+ && ! versionConflicts . ContainsKey ( childResolvedLibraryRangeIndex )
595+ && childLibraryDependency . SuppressParent != LibraryIncludeFlags . All
596+ && childLibraryDependency . LibraryRange . VersionRange != null
597+ && ! childLibraryDependency . LibraryRange . VersionRange ! . Satisfies ( newGraphNode . Item . Key . Version )
598+ && ! downgrades . ContainsKey ( childResolvedLibraryRangeIndex ) )
608599 {
609600 // Remove the existing node so it can be replaced with a node representing the conflict
610601 currentGraphNode . InnerNodes . Remove ( newGraphNode ) ;
611602
603+ GraphNode < RemoteResolveResult > conflictingNode = new ( childLibraryDependency . LibraryRange )
604+ {
605+ Disposition = Disposition . Acceptable ,
606+ Item = new GraphItem < RemoteResolveResult > (
607+ new LibraryIdentity (
608+ childLibraryDependency . Name ,
609+ childLibraryDependency . LibraryRange . VersionRange . MinVersion ! ,
610+ LibraryType . Package ) ) ,
611+ OuterNode = currentGraphNode ,
612+ } ;
613+
612614 // Add the conflict node to the parent
613615 currentGraphNode . InnerNodes . Add ( conflictingNode ) ;
614616
615- nodesById . Add ( currentRangeIndex , conflictingNode ) ;
616-
617- // This node conflicts and won't be included in the final graph
618- visitedItems . Remove ( childLibraryDependencyIndex ) ;
617+ // Track the version conflict for later
618+ versionConflicts . Add ( childResolvedLibraryRangeIndex , conflictingNode ) ;
619619
620+ // Process the next child
620621 continue ;
621622 }
622623
@@ -751,59 +752,6 @@ public async Task<ValueTuple<bool, List<RestoreTargetGraph>, RuntimeGraph>> Reso
751752 resolvedDependencies : resolvedPackages ) ;
752753
753754 return ( success , restoreTargetGraph ) ;
754-
755- static bool TryDetectVersionConflict (
756- GraphNode < RemoteResolveResult > currentGraphNode ,
757- ResolvedDependencyGraphItem resolvedDependencyGraphItem ,
758- Dictionary < LibraryRangeIndex , GraphNode < RemoteResolveResult > > versionConflicts ,
759- Dictionary < LibraryRangeIndex , ( LibraryRangeIndex FromParentLibraryRangeIndex , LibraryDependency FromLibraryDependency , LibraryRangeIndex ToParentLibraryRangeIndex , LibraryDependencyIndex ToLibraryDependencyIndex , bool IsCentralTransitive ) > downgrades ,
760- LibraryDependency childLibraryDependency ,
761- LibraryRangeIndex childLibraryDependencyIndex ,
762- LibraryRangeIndex childResolvedLibraryRangeIndex ,
763- [ NotNullWhen ( true ) ] out GraphNode < RemoteResolveResult > ? conflictingNode )
764- {
765- conflictingNode = null ;
766-
767- if ( resolvedDependencyGraphItem . IsRootPackageReference )
768- {
769- return false ;
770- }
771-
772- // This is a version conflict if:
773- // 1. The node is not a project and isn't unresolved
774- // 2. The conflict has not already been detected
775- // 3. The dependency is transitive and doesn't have PrivateAssets=All
776- // 4. The dependency has a version specified
777- // 5. The version range is not satisfied by the resolved version
778- // 6. A corresponding downgrade was not detected
779- if ( resolvedDependencyGraphItem . Item . Key . Type != LibraryType . Project
780- && resolvedDependencyGraphItem . Item . Key . Type != LibraryType . ExternalProject
781- && resolvedDependencyGraphItem . Item . Key . Type != LibraryType . Unresolved
782- && ! versionConflicts . ContainsKey ( childResolvedLibraryRangeIndex )
783- && childLibraryDependency . SuppressParent != LibraryIncludeFlags . All
784- && childLibraryDependency . LibraryRange . VersionRange != null
785- && ! childLibraryDependency . LibraryRange . VersionRange ! . Satisfies ( resolvedDependencyGraphItem . Item . Key . Version )
786- && ! downgrades . ContainsKey ( childResolvedLibraryRangeIndex ) )
787- {
788- conflictingNode = new ( childLibraryDependency . LibraryRange )
789- {
790- Disposition = Disposition . Rejected ,
791- Item = new GraphItem < RemoteResolveResult > (
792- new LibraryIdentity (
793- childLibraryDependency . Name ,
794- childLibraryDependency . LibraryRange . VersionRange . MinVersion ! ,
795- LibraryType . Package ) ) ,
796- OuterNode = currentGraphNode ,
797- } ;
798-
799- // Track the version conflict for later
800- versionConflicts . Add ( childResolvedLibraryRangeIndex , conflictingNode ) ;
801-
802- return true ;
803- }
804-
805- return false ;
806- }
807755 }
808756
809757 private static bool EvaluateRuntimeDependencies ( ref LibraryDependency libraryDependency , RuntimeGraph ? runtimeGraph , string ? runtimeIdentifier , ref HashSet < LibraryDependency > ? runtimeDependencies )
0 commit comments