Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
  • Loading branch information
tintoy committed Apr 1, 2024
2 parents d1b431f + 918be1d commit 49bc6f6
Show file tree
Hide file tree
Showing 8 changed files with 544 additions and 37 deletions.
18 changes: 12 additions & 6 deletions GitVersion.yml
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
next-version: 0.6.1
mode: ContinuousDeployment
next-version: 0.6.3
branches:
main:
regex: ^master$|^main$
mode: ContinuousDelivery
source-branches: [ ]
source-branches: []
increment: Patch
prevent-increment-of-merged-branch-version: true
is-mainline: true
feature:
regex: ^feature(s)?\/[\d-]+
mode: ContinuousDelivery
source-branches: [ 'main', 'bugfix' ]
source-branches:
- main
- bugfix
tag: useBranchName
increment: Patch
prevent-increment-of-merged-branch-version: false
Expand All @@ -21,13 +24,16 @@ branches:
bugfix:
regex: ^bug(s)?\/[\d-]+|^hotfix(s)?\/[\d-]+|^fix(s)?\/[\d-]+
mode: ContinuousDeployment
source-branches: [ 'main' ]
tag: beta
source-branches:
- main
tag: useBranchName
increment: Patch
prevent-increment-of-merged-branch-version: false
track-merge-target: false
tracks-release-branches: false
is-release-branch: false
is-mainline: false
ignore:
sha: []
sha:
- 937c06026995c95da4bb13a02714a81db87876b1

33 changes: 18 additions & 15 deletions src/LanguageServer.Engine/Documents/MasterProjectDocument.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using Microsoft.Build.Exceptions;
using MSBuildProjectTools.LanguageServer.SemanticModel;
using MSBuildProjectTools.LanguageServer.Utilities;
using Serilog;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.IO;
using System.Linq;
Expand All @@ -10,9 +13,6 @@

namespace MSBuildProjectTools.LanguageServer.Documents
{
using SemanticModel;
using Utilities;

/// <summary>
/// Represents the document state for an MSBuild project.
/// </summary>
Expand All @@ -22,7 +22,7 @@ public class MasterProjectDocument
/// <summary>
/// Sub-projects (if any).
/// </summary>
readonly Dictionary<Uri, SubProjectDocument> _subProjects = new Dictionary<Uri, SubProjectDocument>();
readonly ConcurrentDictionary<Uri, SubProjectDocument> _subProjects = new();

/// <summary>
/// Create a new <see cref="MasterProjectDocument"/>.
Expand Down Expand Up @@ -67,15 +67,21 @@ protected override void Dispose(bool disposing)
/// <summary>
/// Add a sub-project.
/// </summary>
/// <param name="subProjectDocument">
/// The sub-project.
/// <param name="documentUri">
/// The sub-project's document URI.
/// </param>
public void AddSubProject(SubProjectDocument subProjectDocument)
/// <param name="createSubProjectDocument">
/// A factory delegate to create the <see cref="SubProjectDocument"/> if it does not already exist.
/// </param>
public SubProjectDocument GetOrAddSubProject(Uri documentUri, Func<SubProjectDocument> createSubProjectDocument)
{
if (subProjectDocument == null)
throw new ArgumentNullException(nameof(subProjectDocument));
if (documentUri == null)
throw new ArgumentNullException(nameof(documentUri));

if (createSubProjectDocument == null)
throw new ArgumentNullException(nameof(createSubProjectDocument));

_subProjects.Add(subProjectDocument.DocumentUri, subProjectDocument);
return _subProjects.GetOrAdd(documentUri, _ => createSubProjectDocument());
}

/// <summary>
Expand All @@ -89,11 +95,8 @@ public void RemoveSubProject(Uri documentUri)
if (documentUri == null)
throw new ArgumentNullException(nameof(documentUri));

if (!_subProjects.TryGetValue(documentUri, out SubProjectDocument subProjectDocument))
return;

subProjectDocument.Unload();
_subProjects.Remove(documentUri);
if (_subProjects.TryRemove(documentUri, out SubProjectDocument subProjectDocument))
subProjectDocument.Unload();
}

/// <summary>
Expand Down
11 changes: 7 additions & 4 deletions src/LanguageServer.Engine/Documents/Workspace.cs
Original file line number Diff line number Diff line change
Expand Up @@ -173,12 +173,15 @@ public async Task<ProjectDocument> GetProjectDocument(Uri documentUri, bool relo
if (MasterProject == null)
{
MasterProject = new MasterProjectDocument(this, documentUri, Log);
return MasterProject;
MasterProjectDocument masterProjectDocument = new(this, documentUri, Log);
MasterProject = masterProjectDocument;
return masterProjectDocument;
}
var subProject = new SubProjectDocument(this, documentUri, Log, MasterProject);
MasterProject.AddSubProject(subProject);
SubProjectDocument subProject = MasterProject.GetOrAddSubProject(documentUri,
() => new SubProjectDocument(this, documentUri, Log, MasterProject)
);
return subProject;
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,16 +27,6 @@

<ItemGroup>
<Content Include="TestFiles/**/*.xml" CopyToOutputDirectory="Always" CopyToPublishDirectory="Always" />
</ItemGroup>

<ItemGroup>
<Content Include="TestProjects\Project1.csproj">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
<CopyToPublishDirectory>Always</CopyToPublishDirectory>
</Content>
</ItemGroup>

<ItemGroup>
<None Include="TestProjects\Project1.csproj" />
<Content Include="TestProjects/**/*.csproj" CopyToOutputDirectory="Always" CopyToPublishDirectory="Always" />
</ItemGroup>
</Project>
4 changes: 3 additions & 1 deletion test/LanguageServer.Engine.Tests/MSBuildEngineFixture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ namespace MSBuildProjectTools.LanguageServer.Tests
/// </summary>
public sealed class MSBuildEngineFixture
{
public const string CollectionName = "MSBuild Engine";

/// <summary>
/// Create a new <see cref="MSBuildEngineFixture"/>.
/// </summary>
Expand All @@ -21,7 +23,7 @@ public MSBuildEngineFixture()
/// <summary>
/// The collection-fixture binding for <see cref="MSBuildEngineFixture"/>.
/// </summary>
[CollectionDefinition("MSBuild Engine")]
[CollectionDefinition(MSBuildEngineFixture.CollectionName)]
public sealed class MSBuildEngineFixtureCollection
: ICollectionFixture<MSBuildEngineFixture>
{
Expand Down
100 changes: 100 additions & 0 deletions test/LanguageServer.Engine.Tests/MSBuildObjectLocatorTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
using Microsoft.Build.Evaluation;
using MSBuildProjectTools.LanguageServer.SemanticModel;
using System;
using System.IO;
using Xunit;
using Xunit.Abstractions;

namespace MSBuildProjectTools.LanguageServer.Tests
{
/// <summary>
/// Tests for locating MSBuild objects by position.
/// </summary>
/// <param name="testOutput">
/// The xUnit test output for the current test.
/// </param>
[Collection(MSBuildEngineFixture.CollectionName)]
public class MSBuildObjectLocatorTests(ITestOutputHelper testOutput)
: TestBase(testOutput), IDisposable
{
/// <summary>
/// The project collection for any projects loaded by the current test.
/// </summary>
ProjectCollection _projectCollection;

/// <summary>
/// Dispose of resources being used by the test.
/// </summary>
public void Dispose()
{
if (_projectCollection != null)
{
_projectCollection.Dispose();
_projectCollection = null;
}
}

/// <summary>
/// Verify that the <see cref="MSBuildObjectLocator"/> correctly handles a property that is defined, and then redefined, in the same project file.
/// </summary>
[Fact]
public void Can_Locate_Property_Redefined_SameFile()
{
TestProject testProject = LoadTestProject("TestProjects", "RedefineProperty.SameFile.csproj");

var firstElementPosition = new Position(4, 5); // <Property2>false</Property2>
var secondElementPosition = firstElementPosition.Move(lineCount: 1); // <Property2 Condition=" '$(Property1)' == 'true' ">true</Property2>


// First "Property2" element (the overridden one).
// <Property2>false</Property2>
XmlLocation firstLocation = testProject.XmlLocations.Inspect(firstElementPosition);

XSElement firstPropertyElement;
Assert.True(firstLocation.IsElement(out firstPropertyElement));
Assert.Equal("Property2", firstPropertyElement.Name);

// Second "Property2" element (the overriding one).
// <Property2 Condition=" '$(Property1)' == 'true' ">true</Property2>
XmlLocation secondLocation = testProject.XmlLocations.Inspect(secondElementPosition);

XSElement secondPropertyElement;
Assert.True(secondLocation.IsElement(out secondPropertyElement));
Assert.Equal("Property2", secondPropertyElement.Name);

// The MSBuild property "Property2" corresponding to the first "Property" element.
MSBuildObject firstMSBuildObject = testProject.ObjectLocations.Find(firstElementPosition);
MSBuildProperty propertyFromFirstPosition = Assert.IsAssignableFrom<MSBuildProperty>(firstMSBuildObject);
Assert.Equal("Property2", propertyFromFirstPosition.Name);
Assert.Equal("true", propertyFromFirstPosition.Value); // property has second, overridden value
Assert.Equal(propertyFromFirstPosition.Element.Range, firstPropertyElement.Range); // i.e. property comes from the second Property2 element, not the first.

// The MSBuild property "Property2" corresponding to the second "Property" element.
MSBuildObject secondMSBuildObject = testProject.ObjectLocations.Find(secondElementPosition);
MSBuildProperty propertyFromSecondPosition = Assert.IsAssignableFrom<MSBuildProperty>(secondMSBuildObject);
Assert.Equal("Property2", propertyFromSecondPosition.Name);
Assert.Equal("true", propertyFromSecondPosition.Value); // property has second, overridden value
Assert.Equal(propertyFromSecondPosition.Element.Range, secondPropertyElement.Range); // i.e. property comes from the second Property2 element, not the first.
}

/// <summary>
/// Load a test project.
/// </summary>
/// <param name="relativePathSegments">
/// The file's relative path segments.
/// </param>
/// <returns>
/// The loaded project, as a <see cref="TestProject"/>.
/// </returns>
TestProject LoadTestProject(params string[] relativePathSegments)
{
if (relativePathSegments == null)
throw new ArgumentNullException(nameof(relativePathSegments));

if (_projectCollection == null)
_projectCollection = TestProjects.CreateProjectCollection<MSBuildObjectLocatorTests>(Log, relativePathSegments);

return _projectCollection.LoadTestProject<MSBuildObjectLocatorTests>(relativePathSegments);
}
}
}
Loading

0 comments on commit 49bc6f6

Please sign in to comment.