From 854940a4a20236ad31e433e4edbc2a6db9a4068a Mon Sep 17 00:00:00 2001 From: CyrusNajmabadi Date: Fri, 19 Feb 2016 11:56:37 -0800 Subject: [PATCH] Check each project independently to see if it denies the reference. --- .../VisualStudioWorkspaceImpl.cs | 62 ++++++++++++------- 1 file changed, 41 insertions(+), 21 deletions(-) diff --git a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioWorkspaceImpl.cs b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioWorkspaceImpl.cs index 6468954f0c8..40f40285d98 100644 --- a/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioWorkspaceImpl.cs +++ b/src/VisualStudio/Core/Def/Implementation/ProjectSystem/VisualStudioWorkspaceImpl.cs @@ -1056,55 +1056,75 @@ internal override bool CanAddProjectReference(ProjectId referencingProject, Proj if (!TryGetHierarchy(referencingProject, out referencingHierarchy) || !TryGetHierarchy(referencedProject, out referencedHierarchy)) { + // Couldn't even get a hierarchy for this project. So we have to assume + // that adding a reference is disallowed. return false; } - var referencingProjectFlavor3 = referencingHierarchy as IVsProjectFlavorReferences3; - var referencedProjectFlavor3 = referencedHierarchy as IVsProjectFlavorReferences3; + // First we have to see if either project disallows the reference being added. + const int ContextFlags = (int)__VSQUERYFLAVORREFERENCESCONTEXT.VSQUERYFLAVORREFERENCESCONTEXT_RefreshReference; - if (referencingProjectFlavor3 != null && referencedProjectFlavor3 != null) - { - const int ContextFlags = (int)__VSQUERYFLAVORREFERENCESCONTEXT.VSQUERYFLAVORREFERENCESCONTEXT_RefreshReference; + uint canAddProjectReference = (uint)__VSREFERENCEQUERYRESULT.REFERENCE_UNKNOWN; + uint canBeReferenced = (uint)__VSREFERENCEQUERYRESULT.REFERENCE_UNKNOWN; - uint canAddProjectReference; - uint canBeReferenced; + var referencingProjectFlavor3 = referencingHierarchy as IVsProjectFlavorReferences3; + if (referencingProjectFlavor3 != null) + { string unused; - if (ErrorHandler.Failed(referencingProjectFlavor3.QueryAddProjectReferenceEx(referencedHierarchy, ContextFlags, out canAddProjectReference, out unused)) || - ErrorHandler.Failed(referencedProjectFlavor3.QueryCanBeReferencedEx(referencingHierarchy, ContextFlags, out canBeReferenced, out unused))) + if (ErrorHandler.Failed(referencingProjectFlavor3.QueryAddProjectReferenceEx(referencedHierarchy, ContextFlags, out canAddProjectReference, out unused))) { // Something went wrong even trying to see if the reference would be allowed. // Assume it won't be allowed. return false; } - if (canAddProjectReference == (uint)__VSREFERENCEQUERYRESULT.REFERENCE_DENY || - canBeReferenced == (uint)__VSREFERENCEQUERYRESULT.REFERENCE_DENY) + if (canAddProjectReference == (uint)__VSREFERENCEQUERYRESULT.REFERENCE_DENY) { - // If either of them deny then add a project reference is not allowed. + // Adding this project reference is not allowed. return false; } + } - if (canAddProjectReference == (int)__VSREFERENCEQUERYRESULT.REFERENCE_ALLOW || - canBeReferenced == (int)__VSREFERENCEQUERYRESULT.REFERENCE_ALLOW) + var referencedProjectFlavor3 = referencedHierarchy as IVsProjectFlavorReferences3; + if (referencedProjectFlavor3 != null) + { + string unused; + if (ErrorHandler.Failed(referencedProjectFlavor3.QueryCanBeReferencedEx(referencingHierarchy, ContextFlags, out canBeReferenced, out unused))) { - // At least one allows this, and neither deny. So this is allowed. - return true; + // Something went wrong even trying to see if the reference would be allowed. + // Assume it won't be allowed. + return false; + } + + if (canBeReferenced == (uint)__VSREFERENCEQUERYRESULT.REFERENCE_DENY) + { + // Adding this project reference is not allowed. + return false; } + } - // Both are unknown if they should allow this. Fall through and use the regular - // matrix check. + // Neither project denied the reference being added. At this point, if either project + // allows the reference to be added, and the other doesn't block it, then we can add + // the reference. + if (canAddProjectReference == (int)__VSREFERENCEQUERYRESULT.REFERENCE_ALLOW || + canBeReferenced == (int)__VSREFERENCEQUERYRESULT.REFERENCE_ALLOW) + { + return true; } - // Normal matrix check for projects that don't implement IVsProjectFlavorReferences3. + // In both directions things are still unknown. Fallback to the reference manager + // to make the determination here. var referenceManager = GetVsService(); if (referenceManager == null) { + // Couldn't get the reference manager. Have to assume it's not allowed. return false; } + // As long as the reference manager does not deny things, then we allow the + // reference to be added. var result = referenceManager.QueryCanReferenceProject(referencingHierarchy, referencedHierarchy); - return result == (uint)__VSREFERENCEQUERYRESULT.REFERENCE_ALLOW || - result == (uint)__VSREFERENCEQUERYRESULT.REFERENCE_UNKNOWN; + return result != (uint)__VSREFERENCEQUERYRESULT.REFERENCE_DENY; } /// -- GitLab