-
Notifications
You must be signed in to change notification settings - Fork 676
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
Some key error info missing when failed in loading some projects #4832
Comments
Thank you for the suggestion, that would be useful. Would you consider PRing it? |
@nohwnd i saw the |
@cateyes99 No need to uninstall the C# extension. Running the "Launch Extension" task will launch a separate VS Code instance with a local build of the extension installed. |
@JoeRobich @nohwnd, I got some time to investigate this issue last week. Turned out, I had to debug OmniSharp Roslyn, but somehow breakpoints set in VSCode for OmniSharp Roslyn C# code were all grayed out, shown as
I found the OmniSharp Roslyn just received I debugged into the external Microsoft.Build assembly directly using ReSharper. The generated code for that method is below: Microsoft.Build.Evaluation.Evaluator<P, I, M, D>.ExpandAndLoadImportsFromUnescapedImportExpressionConditioned() private void ExpandAndLoadImportsFromUnescapedImportExpressionConditioned(
string directoryOfImportingFile,
ProjectImportElement importElement,
out List<ProjectRootElement> projects,
out SdkResult sdkResult,
bool throwOnFileNotExistsError = true)
{
sdkResult = (SdkResult) null;
if (!this.EvaluateConditionCollectingConditionedProperties((ProjectElement) importElement, ExpanderOptions.ExpandProperties, ParserOptions.AllowProperties, this._projectRootElementCache))
{
if (this._logProjectImportedEvents)
{
string str = this._expander.ExpandIntoStringAndUnescape(importElement.Condition, ExpanderOptions.ExpandProperties | ExpanderOptions.LeavePropertiesUnexpandedOnError | ExpanderOptions.Truncate, (IElementLocation) importElement.ConditionLocation);
ProjectImportedEventArgs importedEventArgs = new ProjectImportedEventArgs(importElement.Location.Line, importElement.Location.Column, Evaluator<P, I, M, D>.ProjectImportSkippedFalseCondition, new object[6]
{
(object) importElement.Project,
(object) importElement.ContainingProject.FullPath,
(object) importElement.Location.Line,
(object) importElement.Location.Column,
(object) importElement.Condition,
(object) str
});
((BuildEventArgs) importedEventArgs).BuildEventContext = this._evaluationLoggingContext.BuildEventContext;
importedEventArgs.set_UnexpandedProject(importElement.Project);
((BuildMessageEventArgs) importedEventArgs).ProjectFile = importElement.ContainingProject.FullPath;
this._evaluationLoggingContext.LogBuildEvent((BuildEventArgs) importedEventArgs);
}
projects = new List<ProjectRootElement>();
}
else
{
string project = importElement.Project;
SdkReference sdk = importElement.SdkReference;
if (sdk != null)
{
string solutionPath = this._data.GetProperty("SolutionPath")?.EvaluatedValue;
if (solutionPath == "*Undefined*")
solutionPath = (string) null;
string evaluatedValue = this._data.GetProperty("MSBuildProjectFullPath")?.EvaluatedValue;
CompareInfo compareInfo = CultureInfo.InvariantCulture.CompareInfo;
if (HasProperty(sdk.get_Name(), compareInfo) || HasProperty(sdk.get_Version(), compareInfo) || HasProperty(sdk.get_MinimumVersion(), compareInfo))
{
EscapeHatches.SdkReferencePropertyExpansionMode? propertyExpansion = Traits.Instance.EscapeHatches.SdkReferencePropertyExpansion;
EscapeHatches.SdkReferencePropertyExpansionMode mode = propertyExpansion.HasValue ? propertyExpansion.GetValueOrDefault() : EscapeHatches.SdkReferencePropertyExpansionMode.DefaultExpand;
switch (mode)
{
case EscapeHatches.SdkReferencePropertyExpansionMode.NoExpansion:
goto label_11;
case EscapeHatches.SdkReferencePropertyExpansionMode.DefaultExpand:
mode = EscapeHatches.SdkReferencePropertyExpansionMode.ExpandUnescape;
break;
}
IElementLocation sdkLocation = (IElementLocation) importElement.SdkLocation;
sdk = new SdkReference(EvaluateProperty(sdk.get_Name(), sdkLocation, this._expander, mode), EvaluateProperty(sdk.get_Version(), sdkLocation, this._expander, mode), EvaluateProperty(sdk.get_MinimumVersion(), sdkLocation, this._expander, mode));
}
label_11:
sdkResult = this._sdkResolverService.ResolveSdk(this._submissionId, sdk, (LoggingContext) this._evaluationLoggingContext, importElement.Location, solutionPath, evaluatedValue, this._interactive, this._isRunningInVisualStudio);
if (!sdkResult.get_Success())
{
if (this._loadSettings.HasFlag((Enum) ProjectLoadSettings.IgnoreMissingImports) && (!ChangeWaves.AreFeaturesEnabled((Version) ChangeWaves.Wave16_10) || !this._loadSettings.HasFlag((Enum) ProjectLoadSettings.FailOnUnresolvedSdk)))
{
ProjectImportedEventArgs importedEventArgs = new ProjectImportedEventArgs(importElement.Location.Line, importElement.Location.Column, Evaluator<P, I, M, D>.CouldNotResolveSdk, new object[1]
{
(object) ((object) sdk).ToString()
});
((BuildEventArgs) importedEventArgs).BuildEventContext = this._evaluationLoggingContext.BuildEventContext;
importedEventArgs.set_UnexpandedProject(importElement.Project);
((BuildMessageEventArgs) importedEventArgs).ProjectFile = importElement.ContainingProject.FullPath;
importedEventArgs.set_ImportedProjectFile((string) null);
importedEventArgs.set_ImportIgnored(true);
this._evaluationLoggingContext.LogBuildEvent((BuildEventArgs) importedEventArgs);
projects = new List<ProjectRootElement>();
return;
}
ProjectErrorUtilities.ThrowInvalidProject<string>((IElementLocation) importElement.SdkLocation, "CouldNotResolveSdk", ((object) sdk).ToString());
}
if (sdkResult.get_Path() == null)
{
projects = new List<ProjectRootElement>();
}
else
{
int num1 = (int) this.ExpandAndLoadImportsFromUnescapedImportExpression(directoryOfImportingFile, importElement, Path.Combine(sdkResult.get_Path(), project), throwOnFileNotExistsError, out projects);
if (sdkResult.get_AdditionalPaths() != null)
{
foreach (string additionalPath in (IEnumerable<string>) sdkResult.get_AdditionalPaths())
{
List<ProjectRootElement> imports;
int num2 = (int) this.ExpandAndLoadImportsFromUnescapedImportExpression(directoryOfImportingFile, importElement, Path.Combine(additionalPath, project), throwOnFileNotExistsError, out imports);
projects.AddRange((IEnumerable<ProjectRootElement>) imports);
}
}
}
IDictionary<string, string> propertiesToAdd = sdkResult.get_PropertiesToAdd();
if ((propertiesToAdd != null ? (propertiesToAdd.Any<KeyValuePair<string, string>>() ? 1 : 0) : 0) == 0)
{
IDictionary<string, SdkResultItem> itemsToAdd = sdkResult.get_ItemsToAdd();
if ((itemsToAdd != null ? (((IEnumerable<KeyValuePair<string, SdkResultItem>>) itemsToAdd).Any<KeyValuePair<string, SdkResultItem>>() ? 1 : 0) : 0) == 0)
return;
}
projects.Insert(0, this.CreateProjectForSdkResult(sdkResult));
}
else
{
int num = (int) this.ExpandAndLoadImportsFromUnescapedImportExpression(directoryOfImportingFile, importElement, project, throwOnFileNotExistsError, out projects);
}
}
bool HasProperty(string value, CompareInfo compareInfo)
{
if (value != null)
return compareInfo.IndexOf(value, "$(") != -1;
return false;
}
string EvaluateProperty(
string value,
IElementLocation location,
Expander<P, I> expander,
EscapeHatches.SdkReferencePropertyExpansionMode mode)
{
if (value == null)
return (string) null;
switch (mode)
{
case EscapeHatches.SdkReferencePropertyExpansionMode.ExpandUnescape:
return expander.ExpandIntoStringAndUnescape(value, ExpanderOptions.ExpandProperties, location);
case EscapeHatches.SdkReferencePropertyExpansionMode.ExpandLeaveEscaped:
return expander.ExpandIntoStringLeaveEscaped(value, ExpanderOptions.ExpandProperties, location);
default:
ErrorUtilities.ThrowArgumentOutOfRange(nameof (mode));
return value;
}
}
} When it throws ProjectErrorUtilities.ThrowInvalidProject<string>((IElementLocation) importElement.SdkLocation, "CouldNotResolveSdk", ((object) sdk).ToString()); because the desired SDK 5.0.100 cannot be found on my machine, the SDK version & its file path info isn't available as shown in the below screenshot. I forced I tried to see how Microsoft.Build resolves the SDK version at the line sdkResult = this._sdkResolverService.ResolveSdk(this._submissionId, sdk, (LoggingContext) this._evaluationLoggingContext, importElement.Location, solutionPath, evaluatedValue, this._interactive, this._isRunningInVisualStudio); by debugging into the generated code: Microsoft.Build.BackEnd.SdkResolution.CachingSdkResolverService.ResolveSdk() public override SdkResult ResolveSdk(
int submissionId,
SdkReference sdk,
LoggingContext loggingContext,
ElementLocation sdkReferenceLocation,
string solutionPath,
string projectPath,
bool interactive,
bool isRunningInVisualStudio)
{
SdkResult sdkResult = !Traits.Instance.EscapeHatches.DisableSdkResolutionCache ? this._cache.GetOrAdd(submissionId, new ConcurrentDictionary<string, Lazy<SdkResult>>((IEqualityComparer<string>) MSBuildNameIgnoreCaseComparer.Default)).GetOrAdd(sdk.get_Name(), (Func<string, Lazy<SdkResult>>) (key => new Lazy<SdkResult>((Func<SdkResult>) (() => base.ResolveSdk(submissionId, sdk, loggingContext, sdkReferenceLocation, solutionPath, projectPath, interactive, isRunningInVisualStudio))))).Value : base.ResolveSdk(submissionId, sdk, loggingContext, sdkReferenceLocation, solutionPath, projectPath, interactive, isRunningInVisualStudio);
if (sdkResult != null && !SdkResolverService.IsReferenceSameVersion(sdk, sdkResult.get_SdkReference().get_Version()) && !SdkResolverService.IsReferenceSameVersion(sdk, sdkResult.get_Version()))
loggingContext.LogWarning((string) null, new BuildEventFileInfo((IElementLocation) sdkReferenceLocation), "ReferencingMultipleVersionsOfTheSameSdk", (object) sdk.get_Name(), (object) sdkResult.get_Version(), (object) sdkResult.ElementLocation, (object) sdk.get_Version());
return sdkResult;
} In the 1st line: SdkResult sdkResult = !Traits.Instance.EscapeHatches.DisableSdkResolutionCache ? this._cache.GetOrAdd(submissionId, new ConcurrentDictionary<string, Lazy<SdkResult>>((IEqualityComparer<string>) MSBuildNameIgnoreCaseComparer.Default)).GetOrAdd(sdk.get_Name(), (Func<string, Lazy<SdkResult>>) (key => new Lazy<SdkResult>((Func<SdkResult>) (() => base.ResolveSdk(submissionId, sdk, loggingContext, sdkReferenceLocation, solutionPath, projectPath, interactive, isRunningInVisualStudio))))).Value : base.ResolveSdk(submissionId, sdk, loggingContext, sdkReferenceLocation, solutionPath, projectPath, interactive, isRunningInVisualStudio); Here () => base.ResolveSdk(submissionId, sdk, loggingContext, sdkReferenceLocation, solutionPath, projectPath, interactive, isRunningInVisualStudio) So i had to stop here. That's what I found so far. Do you guys know how to debug into the Microsoft.Build assembly properly? It might help. I might also examin more info through the long call chain see if the desired SDK version info is available somewhere. I guess VS2019 & VSCode should have used the Microsoft.Build in the same way. Now I wonder why VS2019 can manage to obtain the SDK version & its file path in the case that ILSpy project fails to be loaded due to SDK 5.0.100 missing, and prints this kind of info in its error messages. |
@cateyes99 What errors are reported when you run |
@JoeRobich when running
|
@JoeRobich, @nohwnd I managed to debug into () => base.ResolveSdk(submissionId, sdk, loggingContext, sdkReferenceLocation, solutionPath, projectPath, interactive, isRunningInVisualStudio) which is in this code Microsoft.Build.BackEnd.SdkResolution.SdkResolverService. Found that the error having the sdk versions info is printed out at here loggingContext.LogErrorFromText(subcategoryResourceName: null, errorCode: null, helpKeyword: null, file: new BuildEventFileInfo(sdkReferenceLocation), message: error); You can see the error is exactly same as what VS2019 printed out:
Well, if MS Build can make this error info available outside Microsoft.Build.BackEnd.SdkResolution.SdkResolverService, and includes it in the InvalidProjectFileException, then of course, OmniSharp Roslyn doesn't need to do anything. |
@JoeRobich, @nohwnd I've managed to fix this by passing the logger, which MS Build needs, into the loading projects module. Now the same error messages are able to be printed out in VSCode with C# extension as it does in VS2019. OmniSharp log containing the info of specific missing .NET SDK version in its error messages
The fix is in OmniSharp Roslyn. I'd like to push my fix and let you guys review, but currently
What should I do now to push the fix? |
@cateyes99 That looks great. This will be very helpful to our users.
You can Fork the omnisharp-roslyn rep, push your branch to the fork, and, from your fork, you can open a pull request into the omnisharp/omnisharp-roslyn repo. |
@JoeRobich I've opened a PR, following your instructions above. Please have a look. cheers, |
Fixed by OmniSharp/omnisharp-roslyn/pull/2288 |
Environment data
dotnet --info
output:VS Code version: 1.61.1
C# Extension version: 1.23.16
OmniSharp log
Log details
Steps to reproduce
I pulled the latest master 00383f67d2 of ILSpy source from GitHub ILSpy repo.
When I used VS 2019 to open the source code, it complained and printed error messages in its Output:
I can see it complained and pin pointed to
.NET SDK 5.0.100
which was previously installed, but now there is newer version5.0.302
intsalled. And the5.0.100
folder is empty that I guess was wiped off by the newer one's installation. It's fine, this isn't an OmniSharp C# extension's issue.When I used VSCode with C# extension to open the source code, it also complained and printed error messages in its OUTPUT which is expected as well:
But VSCode OmniSharp C# extension doesn't print out any info properly about the issue with
.NET SDK 5.0.100
missing which doesn't help me to figure out what's exactly going wrong if I don't have VS2019 installed as well.BTW, it printed out error message as the following.
'{projectFilePath}'
looks like just the name of the variableprojectFilePath
, I think it's bug, as it should print out the value of the variableprojectFilePath
.Expected behavior
The OmniSharp log should contain the info about
.NET SDK 5.0.100
missing in its error messages. Also print out the value of the variableprojectFilePath
properly.Actual behavior
it doesn't.
The text was updated successfully, but these errors were encountered: