-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implementation of implicit imports during evaluation instead of parsing #1492
Conversation
@dotnet-bot test Windows_NT Build for Desktop please |
{ | ||
MarkDirty("Add child element named '{0}'", child.ElementName); | ||
} | ||
MarkDirty("Add child element named '{0}'", child.ElementName); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks like a change in behavior. Does it need to happen for Remove just above this? Or others?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is removed because I'm reverting the original implementation where the stuff is added to the XML DOM. There is no IsImplicit
property anymore so the if
is removed.
The change above this is removed for the same reason.
@@ -655,6 +650,25 @@ public string InitialTargets | |||
} | |||
|
|||
/// <summary> | |||
/// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fill in the xmldoc
@@ -849,6 +861,14 @@ public ElementLocation InitialTargetsLocation | |||
} | |||
|
|||
/// <summary> | |||
/// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good, but will this affect CPS and its understanding of provenance? Does the object model expose enough information for CPS to see the implicit imports and to know whether they are at the top or bottom of the file?CPS needs this to be able to correctly manipulate project files. For example, if the implicitly imported props have <Compile Include="**\*.cs" />
, then CPS needs to understand this if an item is excluded from the project, renamed, etc.
Also, I'd suggest updating Evaluator.GetCurrentDirectoryForConditionEvaluation to return the Sdk directory if there is an Sdk
attribute on an import, so that you can have something like Condition="Exists('Sdk\Sdk.props')"
on an Sdk import.
@dsplaisted They imports show up in the The |
@jviau, is this OK for CPS (see last two comments)? |
@jeffkl @cdmihai CPS uses |
[DebuggerStepThrough] | ||
get | ||
{ | ||
return ProjectXmlUtilities.GetAttributeValue(XmlElement, XMakeAttributes.sdk); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As things get more involved with the SDKs, it might be worth creating a new SDKProjectElement which is represented as an attribute (reusing the way metadata as attributes represent themselves). This type would be a valid child for ProjectRootElements and ProjectImportElements. Then, the new type could gain responsibilities such as parsing the semicolon delimited string into a {name, version} object, doing data validation, etc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm in favor of putting duplicated logic in a central place, but here I don't think it's helpful to represent it as a child element expressed as an attribute. That just complicates the object model without any benefit that I see, and we can centralize the logic into utility methods or similar without changing the object model.
{ | ||
// SDK imports are added implicitly where they are evaluated at the top and bottom as if they are in the XML | ||
// | ||
foreach (string sdk in currentProjectOrImport.Sdk.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This splitting logic (and the subsequent name / version parsing) is an example of what could go in a new SDKProjectElement type, since most likely other parts of the codebase may want to parse the SDK string (or third party API users).
@@ -187,61 +187,6 @@ private void ParseProjectElement(XmlElementWithLocation element) | |||
// so we have to set it now | |||
_project.SetProjectRootElementFromParser(element, _project); | |||
|
|||
if (element.HasAttribute(XMakeAttributes.sdk)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shouldn't this method (and the other thing that can have SDKs, ParseImportElement too) do some SDK string validation, such as ensure it's not empty? Better to crash here than when the SDK is used in the evaluator / preprocessor.
@@ -29,24 +30,36 @@ public void SdkImportsAreInImportList() | |||
string sdkPropsPath = Path.Combine(testSdkDirectory, "Sdk.props"); | |||
string sdkTargetsPath = Path.Combine(testSdkDirectory, "Sdk.targets"); | |||
|
|||
File.WriteAllText(sdkPropsPath, "<Project />"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you also do a ProjectSdkExplicitImport_Tests class to test out the explicit SDK imports? Or rename this class to refer to both implcit and explicit SDK elements.
@@ -6,6 +6,7 @@ | |||
using System.IO; | |||
using System.Xml; | |||
using Microsoft.Build.Construction; | |||
using Microsoft.Build.Evaluation; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you also add some invalid SDK tests, like empty SDKs, or SDK names with slash in them?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM after the ProjectParser validates the SDK strings and there's tests for those situations.
I need to understand CPS more to answer this. If it uses the evaluation APIs first, the imports show up in the graph and everything has the
Good idea, I'll do this as part of the SDK resolver work and I've added your comment as a note on the Design doc #1493 |
@cdmihai The ProjectParser does not parse any of the |
…g parsing of projects. Had to do some hacky stuff in the preprocessor but all of that code is private and we can make it better in the future. Closes dotnet#1447
Added a unit test for an invalid SDK name Made ImplicitImportLocation public
… list like "One; ;Two"
8da92e7
to
98a3d6f
Compare
@dotnet-bot test OSX Build for Mono please |
Had to do some hacky stuff in the preprocessor but all of that code is private and we can make it better in the future.
Closes #1447