diff options
author | Matt Ward <matt.ward@microsoft.com> | 2019-06-24 13:15:37 +0300 |
---|---|---|
committer | monojenkins <jo.shields+jenkins@xamarin.com> | 2019-06-24 19:45:13 +0300 |
commit | c9210b14d195556e483e9537931ad2b93260c581 (patch) | |
tree | 2257b51c785c80d25aad932be23ba302f1c2ab23 | |
parent | ce34f6838e6457d0e7d5991a1a693415e6fcae07 (diff) |
[Ide] Fix missing xaml file breaking intellisense
If a project referenced a .xaml file that did not exist then the
type system would throw a file not exception and not load any
type information for the solution. This then broke code completion,
go to declaration, etc. To avoid this error a check is made to
ensure the file exists before trying to generate projections for the
.xaml file.
Fixes VSTS #918867 - Missing xaml file breaks intellisense
6 files changed, 126 insertions, 1 deletions
diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.ProjectSystemHandler.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.ProjectSystemHandler.cs index 2e129b53b2..99d5dc5b17 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.ProjectSystemHandler.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide.TypeSystem/MonoDevelopWorkspace.ProjectSystemHandler.cs @@ -488,10 +488,14 @@ namespace MonoDevelop.Ide.TypeSystem if (node == null || !node.Parser.CanGenerateProjection (mimeType, f.BuildAction, p.SupportedLanguages)) return new List<DocumentInfo> (); + var content = TextFileProvider.Instance.GetReadOnlyTextEditorData (f.FilePath, throwOnFileNotFound: false); + if (content == null) + return new List<DocumentInfo> (); + var options = new ParseOptions { FileName = f.FilePath, Project = p, - Content = TextFileProvider.Instance.GetReadOnlyTextEditorData (f.FilePath), + Content = content, }; var generatedProjections = await node.Parser.GenerateProjections (options, token); var list = new List<Projection> (); diff --git a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs index 2d37d3ba00..18571ae0c7 100644 --- a/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs +++ b/main/src/core/MonoDevelop.Ide/MonoDevelop.Ide/ProjectOperations.cs @@ -2667,6 +2667,11 @@ namespace MonoDevelop.Ide public IReadonlyTextDocument GetReadOnlyTextEditorData (FilePath filePath) { + return GetReadOnlyTextEditorData (filePath, true); + } + + internal IReadonlyTextDocument GetReadOnlyTextEditorData (FilePath filePath, bool throwOnFileNotFound) + { if (filePath.IsNullOrEmpty) throw new ArgumentNullException ("filePath"); foreach (var doc in IdeServices.DocumentManager.Documents) { @@ -2674,6 +2679,10 @@ namespace MonoDevelop.Ide return doc.Editor; } } + + if (!throwOnFileNotFound && !File.Exists (filePath)) + return null; + var data = TextEditorFactory.CreateNewReadonlyDocument (StringTextSource.ReadFrom (filePath), filePath); return data; } diff --git a/main/tests/Ide.Tests/MonoDevelop.Ide/TypeSystemServiceTests.cs b/main/tests/Ide.Tests/MonoDevelop.Ide/TypeSystemServiceTests.cs index 8238b7d0c1..a33b5a2cf3 100644 --- a/main/tests/Ide.Tests/MonoDevelop.Ide/TypeSystemServiceTests.cs +++ b/main/tests/Ide.Tests/MonoDevelop.Ide/TypeSystemServiceTests.cs @@ -511,6 +511,46 @@ namespace MonoDevelop.Ide } } + /// <summary> + /// Tests that a missing file that supports projections does not result in the type system not loading + /// any information. + /// </summary> + [Test] + public async Task MissingProjectionFileDoesNotThrowException () + { + string solFile = Util.GetSampleProject ("projection-tests", "missing-projection-file.sln"); + + var parsers = IdeApp.TypeSystemService.Parsers; + try { + var projectionParser = new TypeSystemParserNode (); + projectionParser.BuildActions = new [] { "ProjectionTest" }; + projectionParser.MimeType = "text/plain"; + + var flags = System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic; + var field = typeof (TypeExtensionNode).GetField ("type", flags); + field.SetValue (projectionParser, typeof (ProjectionParser)); + + var newParsers = new List<TypeSystemParserNode> (); + newParsers.Add (projectionParser); + IdeApp.TypeSystemService.Parsers = newParsers; + + using (var sol = (Solution)await Services.ProjectService.ReadWorkspaceItem (Util.GetMonitor (), solFile)) + using (var ws = await TypeSystemServiceTestExtensions.LoadSolution (sol)) { + var p = sol.GetAllProjects ().OfType<DotNetProject> ().Single (); + try { + var projectId = ws.GetProjectId (p); + var roslynProject = ws.CurrentSolution.GetProject (projectId); + var doc = roslynProject.Documents.FirstOrDefault (d => Path.GetFileName (d.FilePath) == "MyClass.cs"); + Assert.IsNotNull (doc); + } finally { + TypeSystemServiceTestExtensions.UnloadSolution (sol); + } + } + } finally { + IdeApp.TypeSystemService.Parsers = parsers; + } + } + class ProjectionParser : TypeSystemParser { public override Task<ParsedDocument> Parse (ParseOptions options, CancellationToken cancellationToken = default) diff --git a/main/tests/test-projects/projection-tests/missing-projection-file.sln b/main/tests/test-projects/projection-tests/missing-projection-file.sln new file mode 100644 index 0000000000..d8e5ac313a --- /dev/null +++ b/main/tests/test-projects/projection-tests/missing-projection-file.sln @@ -0,0 +1,21 @@ + +Microsoft Visual Studio Solution File, Format Version 11.00 +# Visual Studio 2010 +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "missing-projection-file", "missing-projection-file\missing-projection-file.csproj", "{7F63CBE6-2FE7-47A7-8930-EA078DA05062}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {7F63CBE6-2FE7-47A7-8930-EA078DA05062}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {7F63CBE6-2FE7-47A7-8930-EA078DA05062}.Debug|Any CPU.Build.0 = Debug|Any CPU + {7F63CBE6-2FE7-47A7-8930-EA078DA05062}.Release|Any CPU.ActiveCfg = Release|Any CPU + {7F63CBE6-2FE7-47A7-8930-EA078DA05062}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(MonoDevelopProperties) = preSolution + StartupItem = console-with-libs\console-with-libs.csproj + name = console-with-libs + EndGlobalSection +EndGlobal diff --git a/main/tests/test-projects/projection-tests/missing-projection-file/MyClass.cs b/main/tests/test-projects/projection-tests/missing-projection-file/MyClass.cs new file mode 100644 index 0000000000..ed33ef2c0e --- /dev/null +++ b/main/tests/test-projects/projection-tests/missing-projection-file/MyClass.cs @@ -0,0 +1,12 @@ + +using System; + +namespace missing-projection-file +{ + public class MyClass + { + public MyClass() + { + } + } +} diff --git a/main/tests/test-projects/projection-tests/missing-projection-file/missing-projection-file.csproj b/main/tests/test-projects/projection-tests/missing-projection-file/missing-projection-file.csproj new file mode 100644 index 0000000000..924c7306be --- /dev/null +++ b/main/tests/test-projects/projection-tests/missing-projection-file/missing-projection-file.csproj @@ -0,0 +1,39 @@ +<?xml version="1.0" encoding="utf-8"?> +<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> + <PropertyGroup> + <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> + <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> + <ProductVersion>10.0.0</ProductVersion> + <SchemaVersion>2.0</SchemaVersion> + <ProjectGuid>{7F63CBE6-2FE7-47A7-8930-EA078DA05062}</ProjectGuid> + <OutputType>Library</OutputType> + <AssemblyName>library</AssemblyName> + <TargetFrameworkVersion>v4.5</TargetFrameworkVersion> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> + <DebugSymbols>true</DebugSymbols> + <Optimize>true</Optimize> + <OutputPath>bin\Debug</OutputPath> + <DefineConstants>DEBUG</DefineConstants> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <ConsolePause>false</ConsolePause> + <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow> + </PropertyGroup> + <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> + <Optimize>true</Optimize> + <OutputPath>bin\Release</OutputPath> + <ErrorReport>prompt</ErrorReport> + <WarningLevel>4</WarningLevel> + <ConsolePause>false</ConsolePause> + <CheckForOverflowUnderflow>true</CheckForOverflowUnderflow> + </PropertyGroup> + <ItemGroup> + <Compile Include="MyClass.cs" /> + <ProjectionTest Include="Missing-Projection-File.txt" /> + </ItemGroup> + <ItemGroup> + <Reference Include="System" /> + </ItemGroup> + <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> +</Project>
\ No newline at end of file |