提交 b8a169ec 编写于 作者: C Cyrus Najmabadi

Merge branch 'master' into addImportReferences

......@@ -10,10 +10,16 @@ set RoslynSolution=%1
if "%RoslynSolution%" == "" set RoslynSolution=%~dp0Roslyn.sln
echo Restoring packages: Toolsets
call %NugetExe% restore -verbosity quiet "%~dp0build\ToolsetPackages\project.json" -configfile "%~dp0nuget.config"
call %NugetExe% restore -verbosity quiet "%~dp0build\ToolsetPackages\project.json" -configfile "%~dp0nuget.config" || goto :RestoreFailed
echo Restoring packages: Samples
call %NugetExe% restore -verbosity quiet "%~dp0src\Samples\Samples.sln" -configfile "%~dp0nuget.config"
call %NugetExe% restore -verbosity quiet "%~dp0src\Samples\Samples.sln" -configfile "%~dp0nuget.config" || goto :RestoreFailed
echo Restoring packages: Roslyn (this may take some time)
call %NugetExe% restore -verbosity quiet "%RoslynSolution%" -configfile "%~dp0nuget.config"
call %NugetExe% restore -verbosity quiet "%RoslynSolution%" -configfile "%~dp0nuget.config" || goto :RestoreFailed
exit /b 0
:RestoreFailed
echo Restore failed with ERRORLEVEL %ERRORLEVEL%
exit /b 1
\ No newline at end of file
......@@ -3,7 +3,7 @@
<PropertyGroup>
<StartAction Condition="'$(StartActions)' == ''">Program</StartAction>
<StartProgram Condition="'$(StartProgram)' == ''">$(NuGetPackagesPath)\xunit.runner.console.2.1.0\tools\xunit.console.x86.exe</StartProgram>
<StartProgram Condition="'$(StartProgram)' == ''">$(NuGetPackageRoot)\xunit.runner.console\2.1.0\tools\xunit.console.x86.exe</StartProgram>
<StartArguments Condition="'$(StartArguments)' == ''">$(AssemblyName).dll -html $(OurDir)\xUnitResults\$(AssemblyName).html -noshadow</StartArguments>
<StartWorkingDirectory Condition="'$(StartWorkingDirectory)' == ''">$(OutDir)</StartWorkingDirectory>
</PropertyGroup>
......
# Required Software
1. [Visual Studio 2015 with Update 1](http://go.microsoft.com/fwlink/?LinkId=691129). _You need Update 1_.
2. Visual Studio 2015 Extensibility Tools. If you already installed Visual Studio, choose "Modify" from the Programs and Features control panel, and check "Visual Studio Extensibility".
# Getting the Code
1. Clone https://github.com/dotnet/roslyn
2. Run the "Developer Command Prompt for VS2015" from your start menu.
3. Run `Restore.cmd` in the command prompt to restore NuGet packages.
4. Due to [Issue #5876](https://github.com/dotnet/roslyn/issues/5876), you should build on the command line before opening in Visual Studio. Run `msbuild /v:m /m Roslyn.sln`
5. Open _Roslyn.sln_
# Running Tests
Tests cannot be run via Test Explorer due to some Visual Studio limitations.
1. Run the "Developer Command Prompt for VS2015" from your start menu.
2. Run `msbuild /v:m /m BuildAndTest.proj` in the command prompt.
To debug through tests, you can right click the test project that contains your
tests and choose **Set as Startup Project**. Then press F5. This will run the
tests under the command line runner. Some members of the team have been
working on a GUI runner that allows selection of individual tests, etc. Grab
the source from
[xunit.runner.wpf](https://github.com/pilchie/xunit.runner.wpf), build it and
give it a try.
# Trying Your Changes in Visual Studio
Starting with Update 1, it is now possible to run your changes inside Visual
Studio to try them out. Some projects in Roslyn.sln, listed below, build Visual
Studio extensions. When you build those projects, they automatically deploy
into an experimental instance of Visual Studio. The first time you clone, you
should first do a full build of Roslyn.sln to make sure everything is primed.
Then, you can run Visual Studio by right clicking the appropriate project in
Visual Studio, setting it as a startup project, and pressing F5. You can also
run Visual Studio after building by running a "Developer Command Prompt for
VS2015" and then running `devenv /rootsuffix RoslynDev`.
Here are what is deployed with each extension, by project that builds it. If
you're working on a particular area, you probably want to set the appropriate
project as your startup project to ensure the right things are built and
deployed.
- **VisualStudioSetup**: this project builds Roslyn.VisualStudio.Setup.vsix. It
contains the core language services that provide C# and VB editing. It also
contains the copy of the compiler that is used to drive IntelliSense and
semantic analysis in Visual Studio. Although this is the copy of the compiler
that's used to generate squiggles and other information, it's not the
compiler used to actually produce your final .exe or .dll when you do a
build. If you're working on fixing an IDE bug, this is the project you want
to use.
- **CompilerExtension**: this project builds Roslyn.Compilers.Extension.vsix.
This deploys a copy of the command line compilers that are used to do actual
builds in the IDE. It only affects builds triggered from the Visual Studio
experimental instance it's installed into, so it won't affect your regular
builds. Note that if you install just this, the IDE won't know about any
language features included in your build. If you're regularly working on new
language features, you may wish to consider building both the
CompilerExtension and VisualStudioSetup projects to ensure the real build and
live analysis are synchronized.
- **ExpressionEvaluatorPackage**: this deploys the expression evaluator and
result providers, the components that are used by the debugger to parse and
evaluate C# and VB expressions in the watch window, immediate window, and
more. These components are only used when debugging.
- **VisualStudioInteractiveWindow**: this deploys the "base" interactive window
experience that is shared by Roslyn, Python, and other languages. This code
is core support only and doesn't include any language specific logic.
- **VisualStudioInteractiveSetup**: this deploys the Roslyn (i.e. C# and VB)
specific parts of the interactive window. If you're working on the
interactive experience, this the project you want to use as your startup
project.
The experimental instance used by Roslyn is an entirely separate instance of
Visual Studio with it's own settings and installed extensions. It's also, by
default, a separate instance than the standard "Experimental Instance" used by
other Visual Studio SDK projects. If you're familiar with the idea of Visual
Studio hives, we deploy into the RoslynDev root suffix.
If you want to try your extension in your day-to-day use of Visual Studio, you
can find the extensions you built in your Binaries folder with the .vsix extension.
You can double-click the extension to install it into your
main Visual Studio hive. This will replace the base installed version. You can
uninstall your version and go back to the "real" version by going Tools >
Extensions and Updates, finding your extension, and choosing Uninstall. Your
extension should be marked with the "Experimental" flag.
# Contributing
Please see [Contributing Code](https://github.com/dotnet/wiki/Contributing-Code) for details on contributing changes back to the code.
无法预览此类型文件
......@@ -2103,6 +2103,42 @@ public class Methods
CompileAndVerify(sources, sourceSymbolValidator: validator(true), symbolValidator: validator(false));
}
[Fact]
public void Issue4695()
{
string source = @"
using System;
class Program
{
sealed class Cache
{
abstract class BucketwiseBase<TArg> where TArg : class
{
internal abstract void Default(TArg arg);
}
class BucketwiseBase<TAccumulator, TArg> : BucketwiseBase<TArg> where TArg : class
{
internal override void Default(TArg arg = null) { }
}
public string GetAll()
{
new BucketwiseBase<object, object>().Default(); // Bad image format thrown here on legacy compiler
return ""OK"";
}
}
static void Main(string[] args)
{
Console.WriteLine(new Cache().GetAll());
}
}
";
CompileAndVerify(source, expectedOutput: "OK");
}
private void CheckInternalMembers(NamedTypeSymbol type, bool isFromSource)
{
Assert.NotNull(type.GetMembers("Public").SingleOrDefault());
......
......@@ -20,6 +20,14 @@
}
},
"Microsoft.DiaSymReader.Native/1.3.3": {},
"Moq/4.2.1402.2112": {
"compile": {
"lib/net40/Moq.dll": {}
},
"runtime": {
"lib/net40/Moq.dll": {}
}
},
"System.Collections/4.0.0": {
"compile": {
"ref/net45/_._": {}
......@@ -252,6 +260,14 @@
}
},
"Microsoft.DiaSymReader.Native/1.3.3": {},
"Moq/4.2.1402.2112": {
"compile": {
"lib/net40/Moq.dll": {}
},
"runtime": {
"lib/net40/Moq.dll": {}
}
},
"System.Collections/4.0.0": {
"compile": {
"ref/net45/_._": {}
......@@ -510,6 +526,22 @@
"runtimes/win-x86/native/Microsoft.DiaSymReader.Native.x86.dll"
]
},
"Moq/4.2.1402.2112": {
"sha512": "/TWoXE2OIjJjSvcxER7HMoZwpgETSGlKbLZiME7sVVoPMoqgLvDyjSISveTyHxNoDXd18cZlM8aHdS9ZOAbjMw==",
"type": "Package",
"files": [
"[Content_Types].xml",
"_rels/.rels",
"lib/net35/Moq.dll",
"lib/net35/Moq.xml",
"lib/net40/Moq.dll",
"lib/net40/Moq.xml",
"lib/sl4/Moq.Silverlight.dll",
"lib/sl4/Moq.Silverlight.xml",
"Moq.nuspec",
"package/services/metadata/core-properties/98e2d674c8ec4e5fbda07a9e01280647.psmdcp"
]
},
"System.Collections/4.0.0": {
"sha512": "i2vsGDIEbWdHcUSNDPKZP/ZWod6o740el7mGTCy0dqbCxQh74W4QoC+klUwPEtGEFuvzJ7bJgvwJqscosVNyZQ==",
"type": "Package",
......
......@@ -42,6 +42,7 @@
<Compile Include="MetadataReferences\AssemblyIdentityExtensions.cs" />
<Compile Include="PEWriter\BlobUtilitiesTests.cs" />
<Compile Include="PEWriter\BlobTests.cs" />
<Compile Include="PEWriter\UsedNamespaceOrTypeTests.cs" />
<Compile Include="RealParserTests.cs" />
<Compile Include="SimpleAnalyzerAssemblyLoaderTests.cs" />
<Compile Include="SourceFileResolverTest.cs" />
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Reflection.Metadata;
using Microsoft.Cci;
using Microsoft.CodeAnalysis.Emit;
using Moq;
using Roslyn.Test.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.UnitTests.PEWriter
{
public sealed class UsedNamespaceOrTypeTests
{
public class EqualsProxy
{
public readonly string Name;
public EqualsProxy(string name)
{
Name = name;
}
public override int GetHashCode() => Name.GetHashCode();
public override bool Equals(object obj) => (obj as EqualsProxy)?.Name.Equals(Name) == true;
}
private static Mock<T> CreateEqualsInterface<T>(string name) where T : class
{
var mock = new Mock<EqualsProxy>(name) { CallBase = true };
return mock.As<T>();
}
private static void RunAll(EqualityUnit<UsedNamespaceOrType> unit)
{
EqualityUtil.RunAll(unit);
}
[Fact]
public void EqualsTargetTypeSameObject()
{
var ref1 = CreateEqualsInterface<ITypeReference>("ref1");
var ref2 = CreateEqualsInterface<ITypeReference>("ref2");
var value = UsedNamespaceOrType.CreateType(ref1.Object, "alias");
var unit = EqualityUnit
.Create(value)
.WithEqualValues(
value,
UsedNamespaceOrType.CreateType(ref1.Object, "alias"))
.WithNotEqualValues(
UsedNamespaceOrType.CreateNamespace(new Mock<INamespace>().Object),
UsedNamespaceOrType.CreateType(ref2.Object, "alias"),
UsedNamespaceOrType.CreateType(ref1.Object, "different alias"));
RunAll(unit);
}
[WorkItem(7015, "https://github.com/dotnet/roslyn/issues/7015")]
[Fact]
public void EqualsTargetTypeSameValue()
{
var type1 = CreateEqualsInterface<ITypeReference>("type name");
var type2 = CreateEqualsInterface<ITypeReference>("type name");
var type3 = CreateEqualsInterface<ITypeReference>("other type name");
Assert.True(type1.Object.Equals(type2.Object));
Assert.False(type1.Object.Equals(type3.Object));
Assert.True(object.Equals(type1.Object, type2.Object));
var value = UsedNamespaceOrType.CreateType(type1.Object, "alias");
var unit = EqualityUnit
.Create(value)
.WithEqualValues(
value,
UsedNamespaceOrType.CreateType(type1.Object, "alias"),
UsedNamespaceOrType.CreateType(type2.Object, "alias"))
.WithNotEqualValues(
UsedNamespaceOrType.CreateType(type1.Object, "different alias"),
UsedNamespaceOrType.CreateType(type2.Object, "different alias"),
UsedNamespaceOrType.CreateType(type3.Object, "alias"),
UsedNamespaceOrType.CreateNamespace(new Mock<INamespace>().Object));
RunAll(unit);
}
[Fact]
public void EqualsExternAlias()
{
var value = UsedNamespaceOrType.CreateExternAlias("alias1");
var unit = EqualityUnit
.Create(value)
.WithEqualValues(
value,
UsedNamespaceOrType.CreateExternAlias("alias1"))
.WithNotEqualValues(UsedNamespaceOrType.CreateExternAlias("alias2"));
RunAll(unit);
}
[Fact]
public void EqualsNamespace()
{
var ns1 = CreateEqualsInterface<INamespace>("namespace");
var ns2 = CreateEqualsInterface<INamespace>("namespace");
var ns3 = CreateEqualsInterface<INamespace>("other namespace");
var value = UsedNamespaceOrType.CreateNamespace(ns1.Object);
var unit = EqualityUnit
.Create(value)
.WithEqualValues(
value,
UsedNamespaceOrType.CreateNamespace(ns1.Object),
UsedNamespaceOrType.CreateNamespace(ns2.Object))
.WithNotEqualValues(
UsedNamespaceOrType.CreateExternAlias("alias"),
UsedNamespaceOrType.CreateNamespace(ns1.Object, CreateEqualsInterface<IAssemblyReference>("a").Object),
UsedNamespaceOrType.CreateNamespace(ns3.Object));
RunAll(unit);
}
[Fact]
public void EqualsNamespaceAndAssembly()
{
var assembly1 = CreateEqualsInterface<IAssembly>("assembly");
var assembly2 = CreateEqualsInterface<IAssembly>("assembly");
var assembly3 = CreateEqualsInterface<IAssembly>("other assembly");
var ns1 = CreateEqualsInterface<INamespace>("namespace");
var ns2 = CreateEqualsInterface<INamespace>("namespace");
var ns3 = CreateEqualsInterface<INamespace>("other namespace");
var value = UsedNamespaceOrType.CreateNamespace(ns1.Object, assembly1.Object);
var unit = EqualityUnit
.Create(value)
.WithEqualValues(
value,
UsedNamespaceOrType.CreateNamespace(ns1.Object, assembly1.Object),
UsedNamespaceOrType.CreateNamespace(ns1.Object, assembly2.Object),
UsedNamespaceOrType.CreateNamespace(ns2.Object, assembly1.Object))
.WithNotEqualValues(
UsedNamespaceOrType.CreateExternAlias("alias"),
UsedNamespaceOrType.CreateNamespace(ns1.Object, new Mock<IAssemblyReference>().Object),
UsedNamespaceOrType.CreateNamespace(ns3.Object));
RunAll(unit);
}
}
}
{
"dependencies": {
"xunit": "2.1.0",
"xunit.runner.console": "2.1.0"
"xunit.runner.console": "2.1.0",
"Moq": "4.2.1402.2112",
},
"frameworks": {
"net45": {}
......
......@@ -20,6 +20,14 @@
}
},
"Microsoft.DiaSymReader.Native/1.3.3": {},
"Moq/4.2.1402.2112": {
"compile": {
"lib/net40/Moq.dll": {}
},
"runtime": {
"lib/net40/Moq.dll": {}
}
},
"System.Collections/4.0.0": {
"compile": {
"ref/net45/_._": {}
......@@ -252,6 +260,14 @@
}
},
"Microsoft.DiaSymReader.Native/1.3.3": {},
"Moq/4.2.1402.2112": {
"compile": {
"lib/net40/Moq.dll": {}
},
"runtime": {
"lib/net40/Moq.dll": {}
}
},
"System.Collections/4.0.0": {
"compile": {
"ref/net45/_._": {}
......@@ -510,6 +526,22 @@
"runtimes/win-x86/native/Microsoft.DiaSymReader.Native.x86.dll"
]
},
"Moq/4.2.1402.2112": {
"sha512": "/TWoXE2OIjJjSvcxER7HMoZwpgETSGlKbLZiME7sVVoPMoqgLvDyjSISveTyHxNoDXd18cZlM8aHdS9ZOAbjMw==",
"type": "Package",
"files": [
"[Content_Types].xml",
"_rels/.rels",
"lib/net35/Moq.dll",
"lib/net35/Moq.xml",
"lib/net40/Moq.dll",
"lib/net40/Moq.xml",
"lib/sl4/Moq.Silverlight.dll",
"lib/sl4/Moq.Silverlight.xml",
"Moq.nuspec",
"package/services/metadata/core-properties/98e2d674c8ec4e5fbda07a9e01280647.psmdcp"
]
},
"System.Collections/4.0.0": {
"sha512": "i2vsGDIEbWdHcUSNDPKZP/ZWod6o740el7mGTCy0dqbCxQh74W4QoC+klUwPEtGEFuvzJ7bJgvwJqscosVNyZQ==",
"type": "Package",
......@@ -1356,6 +1388,7 @@
},
"projectFileDependencyGroups": {
"": [
"Moq >= 4.2.1402.2112",
"xunit >= 2.1.0",
"xunit.runner.console >= 2.1.0"
],
......
......@@ -21,6 +21,8 @@
<TargetFrameworkProfile />
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
<DefineConstants>$(DefineConstants);PORTABLE50</DefineConstants>
<!-- Remove when the Microsoft.Build.Framework package is updated. See issue #6986. -->
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
</PropertyGroup>
......
......@@ -747,6 +747,7 @@
<InternalsVisibleToTest Include="Roslyn.Test.Utilities.FX45" />
<InternalsVisibleToTest Include="Roslyn.Test.Utilities" />
<InternalsVisibleToTest Include="Roslyn.Compilers.CompilerServer.UnitTests" />
<InternalsVisibleToMoq Include="DynamicProxyGenAssembly2" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="CodeAnalysisResources.resx">
......@@ -773,4 +774,4 @@
<ImportGroup Label="Targets">
<Import Project="..\..\..\..\build\Targets\VSL.Imports.targets" />
</ImportGroup>
</Project>
\ No newline at end of file
</Project>
......@@ -64,9 +64,9 @@ public override bool Equals(object obj)
public bool Equals(UsedNamespaceOrType other)
{
return AliasOpt == other.AliasOpt
&& TargetAssemblyOpt == other.TargetAssemblyOpt
&& TargetNamespaceOpt == other.TargetNamespaceOpt
&& TargetTypeOpt == other.TargetTypeOpt
&& object.Equals(TargetAssemblyOpt, other.TargetAssemblyOpt)
&& object.Equals(TargetNamespaceOpt, other.TargetNamespaceOpt)
&& object.Equals(TargetTypeOpt, other.TargetTypeOpt)
&& TargetXmlNamespaceOpt == other.TargetXmlNamespaceOpt;
}
......
......@@ -140,6 +140,7 @@ End Sub
private readonly string _basicCompilerClientExecutable;
private readonly string _compilerServerExecutable;
private readonly string _buildTaskDll;
private readonly List<Process> _existingServerList = new List<Process>();
private readonly List<Process> _processList = new List<Process>();
public CompilerServerUnitTests()
......@@ -158,12 +159,31 @@ public CompilerServerUnitTests()
_basicCompilerClientExecutable = Path.Combine(_compilerDirectory, BasicClientExeName);
_compilerServerExecutable = Path.Combine(_compilerDirectory, CompilerServerExeName);
_buildTaskDll = Path.Combine(_compilerDirectory, BuildTaskDllName);
_existingServerList = Process.GetProcessesByName(Path.GetFileNameWithoutExtension(CompilerServerExeName)).ToList();
}
public override void Dispose()
{
KillProcessList();
// Bug 7107: this unit test can spawn off multiple VBCSCompiler processes that need to be
// cleaned up. This is spawned as a grand child process of the unit test process and there
// is no reasonable way to determine its ID. Hence to avoid hundreds of zombie processs
// on the machine we kill all VBCSCompiler processes created after this test started running.
//
// This is absolutely a hack. Bug 7107 tracks doing this correctly by moving the server in
// process for the unit tests.
foreach (var process in Process.GetProcessesByName(Path.GetFileNameWithoutExtension(CompilerServerExeName)))
{
if (_existingServerList.Any(p => p.Id == process.Id))
{
continue;
}
Kill(process);
}
base.Dispose();
}
......@@ -189,16 +209,21 @@ private void KillProcessList()
{
foreach (var process in _processList)
{
try
{
process.Kill();
process.WaitForExit();
}
catch (Exception)
{
// Happens when process is killed before the Kill command is executed. That's fine. We
// just want to make sure the process is gone.
}
Kill(process);
}
}
private static void Kill(Process process)
{
try
{
process.Kill();
process.WaitForExit();
}
catch (Exception)
{
// Happens when process is killed before the Kill command is executed. That's fine. We
// just want to make sure the process is gone.
}
}
......
......@@ -20,6 +20,14 @@
}
},
"Microsoft.DiaSymReader.Native/1.3.3": {},
"Moq/4.2.1402.2112": {
"compile": {
"lib/net40/Moq.dll": {}
},
"runtime": {
"lib/net40/Moq.dll": {}
}
},
"System.Collections/4.0.0": {
"compile": {
"ref/net45/_._": {}
......@@ -252,6 +260,14 @@
}
},
"Microsoft.DiaSymReader.Native/1.3.3": {},
"Moq/4.2.1402.2112": {
"compile": {
"lib/net40/Moq.dll": {}
},
"runtime": {
"lib/net40/Moq.dll": {}
}
},
"System.Collections/4.0.0": {
"compile": {
"ref/net45/_._": {}
......@@ -510,6 +526,22 @@
"runtimes/win-x86/native/Microsoft.DiaSymReader.Native.x86.dll"
]
},
"Moq/4.2.1402.2112": {
"sha512": "/TWoXE2OIjJjSvcxER7HMoZwpgETSGlKbLZiME7sVVoPMoqgLvDyjSISveTyHxNoDXd18cZlM8aHdS9ZOAbjMw==",
"type": "Package",
"files": [
"[Content_Types].xml",
"_rels/.rels",
"lib/net35/Moq.dll",
"lib/net35/Moq.xml",
"lib/net40/Moq.dll",
"lib/net40/Moq.xml",
"lib/sl4/Moq.Silverlight.dll",
"lib/sl4/Moq.Silverlight.xml",
"Moq.nuspec",
"package/services/metadata/core-properties/98e2d674c8ec4e5fbda07a9e01280647.psmdcp"
]
},
"System.Collections/4.0.0": {
"sha512": "i2vsGDIEbWdHcUSNDPKZP/ZWod6o740el7mGTCy0dqbCxQh74W4QoC+klUwPEtGEFuvzJ7bJgvwJqscosVNyZQ==",
"type": "Package",
......
......@@ -210,7 +210,7 @@
<Compile Include="Completion\CompletionProviders\XmlDocumentationCommentCompletionProviderTests.cs" />
<Compile Include="Completion\LoadDirectiveCompletionProviderTests.cs" />
<Compile Include="Completion\ReferenceDirectiveCompletionProviderTests.cs" />
<Compile Include="CSharpGoToAdjacentMemberTests.cs" />
<Compile Include="GoToAdjacentMember\CSharpGoToAdjacentMemberTests.cs" />
<Compile Include="Diagnostics\AbstractCSharpDiagnosticProviderBasedUserDiagnosticTest.cs" />
<Compile Include="Diagnostics\AddUsing\AddUsingTests.cs" />
<Compile Include="Diagnostics\AddUsing\AddUsingTests_ExtensionMethods.cs" />
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Editor.CommandHandlers;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Microsoft.CodeAnalysis.Editor.UnitTests.GoToAdjacentMember;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests
namespace Microsoft.CodeAnalysis.Editor.CSharp.UnitTests.GoToAdjacentMember
{
public class CSharpGoToAdjacentMemberTests
public class CSharpGoToAdjacentMemberTests : AbstractGoToAdjacentMemberTests
{
protected override string LanguageName => LanguageNames.CSharp;
protected override ParseOptions DefaultParseOptions => CSharpParseOptions.Default;
[Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)]
[WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")]
public async Task EmptyFile()
......@@ -520,52 +516,5 @@ public async Task PrevInScript()
await AssertNavigatedAsync(code, next: false, sourceCodeKind: SourceCodeKind.Script);
}
private static async Task AssertNavigatedAsync(string code, bool next, SourceCodeKind? sourceCodeKind = null)
{
var kinds = sourceCodeKind != null
? SpecializedCollections.SingletonEnumerable(sourceCodeKind.Value)
: new[] { SourceCodeKind.Regular, SourceCodeKind.Script };
foreach (var kind in kinds)
{
using (var workspace = await TestWorkspaceFactory.CreateWorkspaceFromLinesAsync(
LanguageNames.CSharp,
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary),
CSharpParseOptions.Default.WithKind(kind),
code))
{
var hostDocument = workspace.DocumentWithCursor;
var document = workspace.CurrentSolution.GetDocument(hostDocument.Id);
Assert.Empty((await document.GetSyntaxTreeAsync()).GetDiagnostics());
var targetPosition = await GoToAdjacentMemberCommandHandler.GetTargetPositionAsync(
document,
hostDocument.CursorPosition.Value,
next,
CancellationToken.None);
Assert.NotNull(targetPosition);
Assert.Equal(hostDocument.SelectedSpans.Single().Start, targetPosition.Value);
}
}
}
private static async Task<int?> GetTargetPositionAsync(string code, bool next)
{
using (var workspace = await TestWorkspaceFactory.CreateWorkspaceFromLinesAsync(
LanguageNames.CSharp,
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary),
CSharpParseOptions.Default,
code))
{
var hostDocument = workspace.DocumentWithCursor;
var document = workspace.CurrentSolution.GetDocument(hostDocument.Id);
Assert.Empty((await document.GetSyntaxTreeAsync()).GetDiagnostics());
return await GoToAdjacentMemberCommandHandler.GetTargetPositionAsync(
document,
hostDocument.CursorPosition.Value,
next,
CancellationToken.None);
}
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Diagnostics.CodeAnalysis;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
namespace Microsoft.CodeAnalysis.Editor.Commands
{
[ExcludeFromCodeCoverage]
internal class SyncClassViewCommandArgs : CommandArgs
{
public SyncClassViewCommandArgs(ITextView textView, ITextBuffer subjectBuffer)
: base(textView, subjectBuffer)
{
}
}
}
......@@ -200,6 +200,7 @@
<Compile Include="Commands\SortAndRemoveUnnecessaryImportsCommandArgs.cs" />
<Compile Include="Commands\SortImportsCommandArgs.cs" />
<Compile Include="Commands\SurroundWithCommandArgs.cs" />
<Compile Include="Commands\SyncClassViewCommandArgs.cs" />
<Compile Include="Commands\TabKeyCommandArgs.cs" />
<Compile Include="Commands\ToggleCompletionModeCommandArgs.cs" />
<Compile Include="Commands\TypeCharCommandArgs.cs" />
......
......@@ -24,6 +24,11 @@ internal static class PredefinedCommandHandlerNames
/// </summary>
public const string ChangeSignature = "Change Signature";
/// <summary>
/// Command handler name for Class View.
/// </summary>
public const string ClassView = "Class View";
/// <summary>
/// Command handler name for Comment Selection.
/// </summary>
......
......@@ -251,6 +251,7 @@
<Compile Include="CodeFixes\ExtensionOrderingTests.cs" />
<Compile Include="Diagnostics\TestHostDiagnosticUpdateSource.cs" />
<Compile Include="Extensions\SourceTextContainerExtensionsTests.cs" />
<Compile Include="GoToAdjacentMember\AbstractGoToAdjacentMemberTests.cs" />
<Compile Include="Outlining\AbstractSyntaxNodeOutlinerTests.cs" />
<Compile Include="Outlining\AbstractSyntaxOutlinerTests.cs" />
<Compile Include="Outlining\AbstractSyntaxTriviaOutlinerTests.cs" />
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis.Editor.CommandHandlers;
using Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces;
using Roslyn.Utilities;
using Xunit;
namespace Microsoft.CodeAnalysis.Editor.UnitTests.GoToAdjacentMember
{
public abstract class AbstractGoToAdjacentMemberTests
{
protected abstract string LanguageName { get; }
protected abstract ParseOptions DefaultParseOptions { get; }
protected async Task AssertNavigatedAsync(string code, bool next, SourceCodeKind? sourceCodeKind = null)
{
var kinds = sourceCodeKind != null
? SpecializedCollections.SingletonEnumerable(sourceCodeKind.Value)
: new[] { SourceCodeKind.Regular, SourceCodeKind.Script };
foreach (var kind in kinds)
{
using (var workspace = await TestWorkspaceFactory.CreateWorkspaceFromLinesAsync(
LanguageName,
compilationOptions: null,
parseOptions: DefaultParseOptions.WithKind(kind),
content: code))
{
var hostDocument = workspace.DocumentWithCursor;
var document = workspace.CurrentSolution.GetDocument(hostDocument.Id);
Assert.Empty((await document.GetSyntaxTreeAsync()).GetDiagnostics());
var targetPosition = await GoToAdjacentMemberCommandHandler.GetTargetPositionAsync(
document,
hostDocument.CursorPosition.Value,
next,
CancellationToken.None);
Assert.NotNull(targetPosition);
Assert.Equal(hostDocument.SelectedSpans.Single().Start, targetPosition.Value);
}
}
}
protected async Task<int?> GetTargetPositionAsync(string code, bool next)
{
using (var workspace = await TestWorkspaceFactory.CreateWorkspaceFromLinesAsync(
LanguageName,
compilationOptions: null,
parseOptions: DefaultParseOptions,
content: code))
{
var hostDocument = workspace.DocumentWithCursor;
var document = workspace.CurrentSolution.GetDocument(hostDocument.Id);
Assert.Empty((await document.GetSyntaxTreeAsync()).GetDiagnostics());
return await GoToAdjacentMemberCommandHandler.GetTargetPositionAsync(
document,
hostDocument.CursorPosition.Value,
next,
CancellationToken.None);
}
}
}
}
......@@ -25,6 +25,7 @@ public static class Features
public const string CaseCorrection = "CaseCorrection";
public const string ChangeSignature = "ChangeSignature";
public const string Classification = "Classification";
public const string ClassView = "ClassView";
public const string CodeActionsAddConstructorParameters = "CodeActions.AddConstructorParameters";
public const string CodeActionsAddAsync = "CodeActions.AddAsync";
public const string CodeActionsAddAwait = "CodeActions.AddAwait";
......
......@@ -272,7 +272,7 @@
<Compile Include="Formatting\Indentation\SmartTokenFormatter_FormatTokenTests.vb" />
<Compile Include="Formatting\XmlLiterals.Designer.vb" />
<Compile Include="Outlining\AbstractVisualBasicSyntaxTriviaOutlinerTests.vb" />
<Compile Include="VisualBasicGoToAdjacentMemberTests.vb" />
<Compile Include="GoToAdjacentMember\VisualBasicGoToAdjacentMemberTests.vb" />
<Compile Include="KeywordHighlighting\AbstractVisualBasicKeywordHighlighterTests.vb" />
<Compile Include="KeywordHighlighting\AccessorDeclarationHighlighterTests.vb" />
<Compile Include="KeywordHighlighting\ConditionalPreprocessorHighlighterTests.vb" />
......
......@@ -677,6 +677,24 @@ End Class
Dim active = GetActiveStatements(src1, src2)
edits.VerifyRudeDiagnostics(active)
End Sub
<WpfFact>
Public Sub Delete_EntireNamespace()
Dim src1 = "
Module Module1
Sub Main()
<AS:0>Console.WriteLine(0)</AS:0>
End Sub
End Module
"
Dim src2 = "<AS:0></AS:0>"
Dim edits = GetTopEdits(src1, src2)
Dim active = GetActiveStatements(src1, src2)
edits.VerifyRudeDiagnostics(active,
Diagnostic(RudeEditKind.Delete, Nothing, "module"))
End Sub
#End Region
#Region "Constructors"
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.Threading.Tasks
Imports Microsoft.CodeAnalysis.Editor.UnitTests.GoToAdjacentMember
Namespace Microsoft.CodeAnalysis.Editor.VisualBasic.UnitTests.GoToAdjacentMember
Public Class VisualBasicGoToAdjacentMemberTests
Inherits AbstractGoToAdjacentMemberTests
Protected Overrides ReadOnly Property LanguageName As String = LanguageNames.VisualBasic
Protected Overrides ReadOnly Property DefaultParseOptions As ParseOptions = VisualBasicParseOptions.Default
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function EmptyFile() As Task
Assert.Null(Await GetTargetPositionAsync("$$", next:=True))
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function ClassWithNoMembers() As Task
Dim code = "Class C
$$
End Class"
Assert.Null(Await GetTargetPositionAsync(code, next:=True))
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function BeforeClassWithMember() As Task
Dim code = "$$
Class C
[||]Sub M()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function AfterClassWithMember() As Task
Dim code = "
Class C
[||]Sub M()
End Sub
End Class
$$"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function BetweenClasses() As Task
Dim code = "
Class C1
Sub M()
End Sub
End Class
$$
Class C2
[||]Sub M()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function BetweenClassesPrevious() As Task
Dim code = "
Class C1
[||]Sub M()
End Sub
End Class
$$
Class C2
Sub M()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=False)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function FromFirstMemberToSecond() As Task
Dim code = "
Class C
$$Sub M1()
End Sub
[||]Sub M2()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function FromSecondToFirst() As Task
Dim code = "
Class C
[||]Sub M1()
End Sub
$$Sub M2()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=False)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function NextWraps() As Task
Dim code = "
Class C
[||]Sub M1()
End Sub
$$Sub M2()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function PreviousWraps() As Task
Dim code = "
Class C
$$Sub M1()
End Sub
[||]Sub M2()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=False)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function DescendsIntoNestedType() As Task
Dim code = "
Class C
$$Sub M1()
End Sub
Class N
[||]Sub M2()
End Sub
End Class
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function StopsAtConstructor() As Task
Dim code = "
Class C
$$Sub M1()
End Sub
[||]Public Sub New()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function StopsAtOperator() As Task
Dim code = "
Class C
$$Sub M1()
End Sub
[||]Shared Operator +(left As C, right As C) As C
Throw New System.NotImplementedException()
End Operator
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
Shared Operator +(left As VisualBasicGoToAdjacentMemberTests, right As VisualBasicGoToAdjacentMemberTests) As VisualBasicGoToAdjacentMemberTests
Throw New System.NotImplementedException()
End Operator
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function StopsAtField() As Task
Dim code = "
Class C
$$Sub M1()
End Sub
[||]Dim f as Integer
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function StopsAtFieldlikeEvent() As Task
Dim code = "
Class C
$$Sub M1()
End Sub
[||]Event E As System.EventHandler
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function StopsAtAutoProperty() As Task
Dim code = "
Class C
$$Sub M1()
End Sub
[||]Property P As Integer
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function StopsAtPropertyWithAccessors() As Task
Dim code = "
Class C
$$Sub M1()
End Sub
[||]Property P As Integer
Get
Return 42
End Get
Set(value As Integer)
End Set
End Property
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function SkipsPropertyAccessors() As Task
Dim code = "
Class C
Sub M1()
End Sub
$$Property P As Integer
Get
Return 42
End Get
Set(value As Integer)
End Set
End Property
[||]Sub M2()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function FromInsidePropertyAccessor() As Task
Dim code = "
Class C
Sub M1()
End Sub
Property P As Integer
Get
Return $$42
End Get
Set(value As Integer)
End Set
End Property
[||]Sub M2()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function StopsAtEventWithAddRemove() As Task
Dim code = "
Class C
$$Sub M1()
End Sub
[||]Custom Event E As EventHandler
AddHandler(value As EventHandler)
End AddHandler
RemoveHandler(value As EventHandler)
End RemoveHandler
RaiseEvent(sender As Object, e As EventArgs)
End RaiseEvent
End Event
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function SkipsEventAddRemove() As Task
Dim code = "
Class C
Sub M1()
End Sub
$$Custom Event E As EventHandler
AddHandler(value As EventHandler)
End AddHandler
RemoveHandler(value As EventHandler)
End RemoveHandler
RaiseEvent(sender As Object, e As EventArgs)
End RaiseEvent
End Event
[||]Sub M2()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function FromInsideMethod() As Task
Dim code = "
Class C
Sub M1()
$$System.Console.WriteLine()
End Sub
[||]Sub M2()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function NextFromBetweenMethods() As Task
Dim code = "
Class C
Sub M1()
End Sub
$$
[||]Sub M2()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function PreviousFromBetweenMethods() As Task
Dim code = "
Class C
[||]Sub M1()
End Sub
$$
Sub M2()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=False)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function NextFromBetweenMethodsInTrailingTrivia() As Task
Dim code = "
Class C
Sub M1()
End Sub $$
[||]Sub M2()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function PreviousFromBetweenMethodsInTrailingTrivia() As Task
Dim code = "
Class C
[||]Sub M1()
End Sub $$
Sub M2()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=False)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function NextInScript() As Task
Dim code = "
$$Sub M1()
End Sub
[||]Sub M2()
End Sub"
Await AssertNavigatedAsync(code, next:=True, sourceCodeKind:=SourceCodeKind.Script)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function PrevInScript() As Task
Dim code = "
[||]Sub M1()
End Sub
$$Sub M2()
End Sub"
Await AssertNavigatedAsync(code, next:=False, sourceCodeKind:=SourceCodeKind.Script)
End Function
End Class
End Namespace
\ No newline at end of file
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.Threading
Imports System.Threading.Tasks
Imports Microsoft.CodeAnalysis
Imports Microsoft.CodeAnalysis.Editor.CommandHandlers
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
Public Class VisualBasicGoToAdjacentMemberTests
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function EmptyFile() As Task
Assert.Null(Await GetTargetPositionAsync("$$", next:=True))
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function ClassWithNoMembers() As Task
Dim code = "Class C
$$
End Class"
Assert.Null(Await GetTargetPositionAsync(code, next:=True))
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function BeforeClassWithMember() As Task
Dim code = "$$
Class C
[||]Sub M()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function AfterClassWithMember() As Task
Dim code = "
Class C
[||]Sub M()
End Sub
End Class
$$"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function BetweenClasses() As Task
Dim code = "
Class C1
Sub M()
End Sub
End Class
$$
Class C2
[||]Sub M()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function BetweenClassesPrevious() As Task
Dim code = "
Class C1
[||]Sub M()
End Sub
End Class
$$
Class C2
Sub M()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=False)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function FromFirstMemberToSecond() As Task
Dim code = "
Class C
$$Sub M1()
End Sub
[||]Sub M2()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function FromSecondToFirst() As Task
Dim code = "
Class C
[||]Sub M1()
End Sub
$$Sub M2()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=False)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function NextWraps() As Task
Dim code = "
Class C
[||]Sub M1()
End Sub
$$Sub M2()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function PreviousWraps() As Task
Dim code = "
Class C
$$Sub M1()
End Sub
[||]Sub M2()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=False)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function DescendsIntoNestedType() As Task
Dim code = "
Class C
$$Sub M1()
End Sub
Class N
[||]Sub M2()
End Sub
End Class
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function StopsAtConstructor() As Task
Dim code = "
Class C
$$Sub M1()
End Sub
[||]Public Sub New()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function StopsAtOperator() As Task
Dim code = "
Class C
$$Sub M1()
End Sub
[||]Shared Operator +(left As C, right As C) As C
Throw New System.NotImplementedException()
End Operator
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
Shared Operator +(left As VisualBasicGoToAdjacentMemberTests, right As VisualBasicGoToAdjacentMemberTests) As VisualBasicGoToAdjacentMemberTests
Throw New System.NotImplementedException()
End Operator
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function StopsAtField() As Task
Dim code = "
Class C
$$Sub M1()
End Sub
[||]Dim f as Integer
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function StopsAtFieldlikeEvent() As Task
Dim code = "
Class C
$$Sub M1()
End Sub
[||]Event E As System.EventHandler
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function StopsAtAutoProperty() As Task
Dim code = "
Class C
$$Sub M1()
End Sub
[||]Property P As Integer
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function StopsAtPropertyWithAccessors() As Task
Dim code = "
Class C
$$Sub M1()
End Sub
[||]Property P As Integer
Get
Return 42
End Get
Set(value As Integer)
End Set
End Property
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function SkipsPropertyAccessors() As Task
Dim code = "
Class C
Sub M1()
End Sub
$$Property P As Integer
Get
Return 42
End Get
Set(value As Integer)
End Set
End Property
[||]Sub M2()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function FromInsidePropertyAccessor() As Task
Dim code = "
Class C
Sub M1()
End Sub
Property P As Integer
Get
Return $$42
End Get
Set(value As Integer)
End Set
End Property
[||]Sub M2()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function StopsAtEventWithAddRemove() As Task
Dim code = "
Class C
$$Sub M1()
End Sub
[||]Custom Event E As EventHandler
AddHandler(value As EventHandler)
End AddHandler
RemoveHandler(value As EventHandler)
End RemoveHandler
RaiseEvent(sender As Object, e As EventArgs)
End RaiseEvent
End Event
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function SkipsEventAddRemove() As Task
Dim code = "
Class C
Sub M1()
End Sub
$$Custom Event E As EventHandler
AddHandler(value As EventHandler)
End AddHandler
RemoveHandler(value As EventHandler)
End RemoveHandler
RaiseEvent(sender As Object, e As EventArgs)
End RaiseEvent
End Event
[||]Sub M2()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function FromInsideMethod() As Task
Dim code = "
Class C
Sub M1()
$$System.Console.WriteLine()
End Sub
[||]Sub M2()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function NextFromBetweenMethods() As Task
Dim code = "
Class C
Sub M1()
End Sub
$$
[||]Sub M2()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function PreviousFromBetweenMethods() As Task
Dim code = "
Class C
[||]Sub M1()
End Sub
$$
Sub M2()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=False)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function NextFromBetweenMethodsInTrailingTrivia() As Task
Dim code = "
Class C
Sub M1()
End Sub $$
[||]Sub M2()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=True)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function PreviousFromBetweenMethodsInTrailingTrivia() As Task
Dim code = "
Class C
[||]Sub M1()
End Sub $$
Sub M2()
End Sub
End Class"
Await AssertNavigatedAsync(code, next:=False)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function NextInScript() As Task
Dim code = "
$$Sub M1()
End Sub
[||]Sub M2()
End Sub"
Await AssertNavigatedAsync(code, next:=True, kind:=SourceCodeKind.Script)
End Function
<Fact, Trait(Traits.Feature, Traits.Features.GoToAdjacentMember)>
<WorkItem(4311, "https://github.com/dotnet/roslyn/issues/4311")>
Public Async Function PrevInScript() As Task
Dim code = "
[||]Sub M1()
End Sub
$$Sub M2()
End Sub"
Await AssertNavigatedAsync(code, next:=False, kind:=SourceCodeKind.Script)
End Function
Private Async Function AssertNavigatedAsync(code As String, [next] As Boolean, Optional kind As SourceCodeKind? = Nothing) As Task
Dim kinds = If(kind IsNot Nothing,
SpecializedCollections.SingletonEnumerable(kind.Value),
{SourceCodeKind.Regular, SourceCodeKind.Script})
For Each currentKind In kinds
Using workspace = Await TestWorkspaceFactory.CreateWorkspaceFromLinesAsync(
LanguageNames.VisualBasic,
New VisualBasicCompilationOptions(OutputKind.DynamicallyLinkedLibrary),
VisualBasicParseOptions.Default.WithKind(currentKind),
code)
Dim hostDocument = workspace.DocumentWithCursor
Dim document As Document = workspace.CurrentSolution.GetDocument(hostDocument.Id)
Assert.Empty((Await document.GetSyntaxTreeAsync()).GetDiagnostics())
Dim targetPosition = Await GoToAdjacentMemberCommandHandler.GetTargetPositionAsync(
document,
hostDocument.CursorPosition.Value,
[next],
CancellationToken.None)
Assert.NotNull(targetPosition)
Assert.Equal(hostDocument.SelectedSpans.Single().Start, targetPosition.Value)
End Using
Next
End Function
Private Async Function GetTargetPositionAsync(code As String, [next] As Boolean) As Task(Of Integer?)
Using workspace = Await TestWorkspaceFactory.CreateWorkspaceFromLinesAsync(
LanguageNames.VisualBasic,
New VisualBasicCompilationOptions(OutputKind.DynamicallyLinkedLibrary),
VisualBasicParseOptions.Default,
code)
Dim hostDocument = workspace.DocumentWithCursor
Dim document As Document = workspace.CurrentSolution.GetDocument(hostDocument.Id)
Assert.Empty((Await document.GetSyntaxTreeAsync()).GetDiagnostics())
Return Await GoToAdjacentMemberCommandHandler.GetTargetPositionAsync(
document,
hostDocument.CursorPosition.Value,
[next],
CancellationToken.None)
End Using
End Function
End Class
......@@ -45,7 +45,7 @@
Inputs="@(ConcordAssemblies->'$(ConcordDir)%(Identity).Portable.il')"
Outputs="$(OutDir)%(Identity).dll">
<Exec Command="$(MSBuildFrameworkToolsPath)ilasm.exe /dll /quiet &quot;/output:$(OutDir)@(ConcordAssemblies).dll&quot; &quot;$(ConcordDir)@(ConcordAssemblies).Portable.il&quot;" />
<Exec Command="$(FakeSignToolPath) &quot;$(OutDir)@(ConcordAssemblies).dll&quot;" />
<Exec Command="&quot;$(FakeSignToolPath)&quot; &quot;$(OutDir)@(ConcordAssemblies).dll&quot;" />
</Target>
<Target Name="CleanIlasmOutputs" AfterTargets="Clean">
<Delete Files="@(ConcordAssemblies->'$(OutDir)NetFX20\%(Identity).dll')" />
......
......@@ -6,7 +6,7 @@
namespace Roslyn.Test.Utilities
{
public class EqualityUnit<T>
public sealed class EqualityUnit<T>
{
private static readonly ReadOnlyCollection<T> s_emptyCollection = new ReadOnlyCollection<T>(new T[] { });
......
......@@ -14,5 +14,11 @@ public static class EqualityUtil
var util = new EqualityUtil<T>(values, compEqualsOperator, compNotEqualsOperator);
util.RunAll();
}
public static void RunAll<T>(params EqualityUnit<T>[] values)
{
var util = new EqualityUtil<T>(values);
util.RunAll();
}
}
}
......@@ -21,8 +21,8 @@ public sealed class EqualityUtil<T>
public EqualityUtil(
IEnumerable<EqualityUnit<T>> equalityUnits,
Func<T, T, bool> compEquality,
Func<T, T, bool> compInequality)
Func<T, T, bool> compEquality = null,
Func<T, T, bool> compInequality = null)
{
_equalityUnits = equalityUnits.ToList().AsReadOnly();
_compareWithEqualityOperator = compEquality;
......@@ -31,10 +31,18 @@ public sealed class EqualityUtil<T>
public void RunAll()
{
EqualityOperator1();
EqualityOperator2();
InequalityOperator1();
InequalityOperator2();
if (_compareWithEqualityOperator != null)
{
EqualityOperator1();
EqualityOperator2();
}
if (_compareWithInequalityOperator != null)
{
InequalityOperator1();
InequalityOperator2();
}
ImplementsIEquatable();
ObjectEquals1();
ObjectEquals2();
......
......@@ -198,6 +198,7 @@
<Compile Include="Debugging\LocationInfoGetter.cs" />
<Compile Include="LanguageService\HACK_CSharpCreateServicesOnUIThread.cs" />
<Compile Include="ObjectBrowser\CSharpLibraryService.cs" />
<Compile Include="ObjectBrowser\CSharpSyncClassViewCommandHandler.cs" />
<Compile Include="ObjectBrowser\ListItemFactory.cs" />
<Compile Include="Options\AdvancedOptionPageStrings.cs" />
<Compile Include="Options\IntelliSenseOptionPageStrings.cs" />
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System.ComponentModel.Composition;
using Microsoft.CodeAnalysis.Editor;
using Microsoft.CodeAnalysis.Editor.Host;
using Microsoft.VisualStudio.LanguageServices.Implementation.Library.ClassView;
using Microsoft.VisualStudio.Shell;
namespace Microsoft.VisualStudio.LanguageServices.CSharp.ObjectBrowser
{
[ExportCommandHandler(PredefinedCommandHandlerNames.ClassView, ContentTypeNames.CSharpContentType)]
internal class CSharpSyncClassViewCommandHandler : AbstractSyncClassViewCommandHandler
{
[ImportingConstructor]
private CSharpSyncClassViewCommandHandler(SVsServiceProvider serviceProvider, IWaitIndicator waitIndicator)
: base(serviceProvider, waitIndicator)
{
}
}
}
......@@ -5,11 +5,8 @@
using Microsoft.CodeAnalysis.Editor;
using Microsoft.CodeAnalysis.Editor.Commands;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.Host;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.OrganizeImports;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem;
using Microsoft.VisualStudio.OLE.Interop;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
......@@ -19,6 +16,7 @@
using InteractiveCommandIds = Microsoft.VisualStudio.LanguageServices.InteractiveWindow.CommandIds;
using InteractiveGuids = Microsoft.VisualStudio.LanguageServices.InteractiveWindow.Guids;
#endif
namespace Microsoft.VisualStudio.LanguageServices.Implementation
{
internal abstract partial class AbstractOleCommandTarget
......@@ -104,6 +102,9 @@ private int QueryVisualStudio97Status(ref Guid pguidCmdGroup, uint commandCount,
case VSConstants.VSStd97CmdID.FindReferences:
return QueryFindReferencesStatus(prgCmds);
case VSConstants.VSStd97CmdID.SyncClassView:
return QuerySyncClassView(prgCmds);
default:
return NextCommandTarget.QueryStatus(ref pguidCmdGroup, commandCount, prgCmds, commandText);
}
......@@ -246,6 +247,7 @@ private int QueryInteractiveCommandStatus(ref Guid pguidCmdGroup, uint commandCo
}
}
#endif
private int GetCommandState<T>(
Func<ITextView, ITextBuffer, T> createArgs,
ref Guid pguidCmdGroup,
......@@ -331,6 +333,12 @@ private int QueryFindReferencesStatus(OLECMD[] prgCmds)
return VSConstants.S_OK;
}
private int QuerySyncClassView(OLECMD[] prgCmds)
{
prgCmds[0].cmdf = (uint)(OLECMDF.OLECMDF_ENABLED | OLECMDF.OLECMDF_SUPPORTED);
return VSConstants.S_OK;
}
private int QuerySortUsingsStatus(ref Guid pguidCmdGroup, uint commandCount, OLECMD[] prgCmds, IntPtr commandText)
{
return GetCommandState(
......
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using System.Diagnostics;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Extensions
{
internal static class ServiceProviderExtensions
{
public static TInterface GetService<TService, TInterface>(this IServiceProvider serviceProvider)
{
var service = (TInterface)serviceProvider.GetService(typeof(TService));
Debug.Assert(service != null);
return service;
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
using System;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.Editor;
using Microsoft.CodeAnalysis.Editor.Commands;
using Microsoft.CodeAnalysis.Editor.Host;
using Microsoft.CodeAnalysis.Editor.Shared.Extensions;
using Microsoft.CodeAnalysis.Editor.Shared.Utilities;
using Microsoft.CodeAnalysis.LanguageServices;
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.LanguageServices.Implementation.Extensions;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
using Roslyn.Utilities;
namespace Microsoft.VisualStudio.LanguageServices.Implementation.Library.ClassView
{
internal abstract class AbstractSyncClassViewCommandHandler : ForegroundThreadAffinitizedObject,
ICommandHandler<SyncClassViewCommandArgs>
{
private const string ClassView = "Class View";
private readonly IServiceProvider _serviceProvider;
private readonly IWaitIndicator _waitIndicator;
protected AbstractSyncClassViewCommandHandler(
SVsServiceProvider serviceProvider,
IWaitIndicator waitIndicator)
{
Contract.ThrowIfNull(serviceProvider);
Contract.ThrowIfNull(waitIndicator);
_serviceProvider = serviceProvider;
_waitIndicator = waitIndicator;
}
public void ExecuteCommand(SyncClassViewCommandArgs args, Action nextHandler)
{
this.AssertIsForeground();
var caretPosition = args.TextView.GetCaretPoint(args.SubjectBuffer) ?? -1;
if (caretPosition < 0)
{
nextHandler();
return;
}
var snapshot = args.SubjectBuffer.CurrentSnapshot;
_waitIndicator.Wait(
title: string.Format(ServicesVSResources.SynchronizeClassView, ClassView),
message: string.Format(ServicesVSResources.SynchronizingWithClassView, ClassView),
allowCancel: true,
action: context =>
{
var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();
if (document == null)
{
return;
}
var syntaxFactsService = document.Project.LanguageServices.GetService<ISyntaxFactsService>();
if (syntaxFactsService == null)
{
return;
}
var libraryService = document.Project.LanguageServices.GetService<ILibraryService>();
if (libraryService == null)
{
return;
}
var semanticModel = document
.GetSemanticModelAsync(context.CancellationToken)
.WaitAndGetResult(context.CancellationToken);
var root = semanticModel.SyntaxTree
.GetRootAsync(context.CancellationToken)
.WaitAndGetResult(context.CancellationToken);
var memberDeclaration = syntaxFactsService.GetContainingMemberDeclaration(root, caretPosition);
var symbol = memberDeclaration != null
? semanticModel.GetDeclaredSymbol(memberDeclaration, context.CancellationToken)
: null;
while (symbol != null && !IsValidSymbolToSynchronize(symbol))
{
symbol = symbol.ContainingSymbol;
}
IVsNavInfo navInfo = null;
if (symbol != null)
{
navInfo = libraryService.NavInfoFactory.CreateForSymbol(symbol, document.Project, semanticModel.Compilation, useExpandedHierarchy: true);
}
if (navInfo == null)
{
navInfo = libraryService.NavInfoFactory.CreateForProject(document.Project);
}
if (navInfo == null)
{
return;
}
var navigationTool = _serviceProvider.GetService<SVsClassView, IVsNavigationTool>();
navigationTool.NavigateToNavInfo(navInfo);
});
}
private static bool IsValidSymbolToSynchronize(ISymbol symbol) =>
symbol.Kind == SymbolKind.Event ||
symbol.Kind == SymbolKind.Field ||
symbol.Kind == SymbolKind.Method ||
symbol.Kind == SymbolKind.NamedType ||
symbol.Kind == SymbolKind.Property;
public CommandState GetCommandState(SyncClassViewCommandArgs args, Func<CommandState> nextHandler)
{
return nextHandler();
}
}
}
......@@ -15,6 +15,7 @@
using Microsoft.CodeAnalysis.Text;
using Microsoft.VisualStudio.ComponentModelHost;
using Microsoft.VisualStudio.Editor;
using Microsoft.VisualStudio.LanguageServices.Implementation.Extensions;
using Microsoft.VisualStudio.LanguageServices.Implementation.Library;
using Microsoft.VisualStudio.LanguageServices.Implementation.ProjectSystem;
using Microsoft.VisualStudio.Shell;
......@@ -43,7 +44,7 @@ internal partial class VisualStudioSymbolNavigationService : ForegroundThreadAff
_serviceProvider = serviceProvider;
_outliningTaggerProvider = outliningTaggerProvider;
var componentModel = GetService<SComponentModel, IComponentModel>();
var componentModel = _serviceProvider.GetService<SComponentModel, IComponentModel>();
_editorAdaptersFactory = componentModel.GetService<IVsEditorAdaptersFactoryService>();
_textEditorFactoryService = componentModel.GetService<ITextEditorFactoryService>();
_textDocumentFactoryService = componentModel.GetService<ITextDocumentFactoryService>();
......@@ -102,7 +103,7 @@ public bool TryNavigateToSymbol(ISymbol symbol, Project project, OptionSet optio
if (navInfo != null)
{
var navigationTool = GetService<SVsObjBrowser, IVsNavigationTool>();
var navigationTool = _serviceProvider.GetService<SVsObjBrowser, IVsNavigationTool>();
return navigationTool.NavigateToNavInfo(navInfo) == VSConstants.S_OK;
}
......@@ -112,10 +113,10 @@ public bool TryNavigateToSymbol(ISymbol symbol, Project project, OptionSet optio
// Generate new source or retrieve existing source for the symbol in question
var result = _metadataAsSourceFileService.GetGeneratedFileAsync(project, symbol, cancellationToken).WaitAndGetResult(cancellationToken);
var vsRunningDocumentTable4 = GetService<SVsRunningDocumentTable, IVsRunningDocumentTable4>();
var vsRunningDocumentTable4 = _serviceProvider.GetService<SVsRunningDocumentTable, IVsRunningDocumentTable4>();
var fileAlreadyOpen = vsRunningDocumentTable4.IsMonikerValid(result.FilePath);
var openDocumentService = GetService<SVsUIShellOpenDocument, IVsUIShellOpenDocument>();
var openDocumentService = _serviceProvider.GetService<SVsUIShellOpenDocument, IVsUIShellOpenDocument>();
IVsUIHierarchy hierarchy;
uint itemId;
......@@ -322,16 +323,9 @@ private bool TryGetVsHierarchyAndItemId(Document document, out IVsHierarchy hier
return false;
}
private TInterface GetService<TService, TInterface>()
{
var service = (TInterface)_serviceProvider.GetService(typeof(TService));
Debug.Assert(service != null);
return service;
}
private IVsRunningDocumentTable GetRunningDocumentTable()
{
var runningDocumentTable = GetService<SVsRunningDocumentTable, IVsRunningDocumentTable>();
var runningDocumentTable = _serviceProvider.GetService<SVsRunningDocumentTable, IVsRunningDocumentTable>();
Debug.Assert(runningDocumentTable != null);
return runningDocumentTable;
}
......
......@@ -1083,6 +1083,24 @@ internal class ServicesVSResources {
}
}
/// <summary>
/// Looks up a localized string similar to Synchronize {0}.
/// </summary>
internal static string SynchronizeClassView {
get {
return ResourceManager.GetString("SynchronizeClassView", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to Synchronizing with {0}....
/// </summary>
internal static string SynchronizingWithClassView {
get {
return ResourceManager.GetString("SynchronizingWithClassView", resourceCulture);
}
}
/// <summary>
/// Looks up a localized string similar to This workspace only supports opening documents on the UI thread..
/// </summary>
......@@ -1192,7 +1210,7 @@ internal class ServicesVSResources {
}
/// <summary>
/// Looks up a localized string similar to Analyzer assembly &apos;{0}&apos; depends on &apos;{1}&apos; but it was not found. Analyzers may not run correctly..
/// Looks up a localized string similar to Analyzer assembly &apos;{0}&apos; depends on &apos;{1}&apos; but it was not found. Analyzers may not run correctly unless the missing assembly is added as an analyzer reference as well..
/// </summary>
internal static string WRN_MissingAnalyzerReferenceMessage {
get {
......
......@@ -507,4 +507,10 @@ Use the dropdown to view and switch to other projects this file may belong to.</
<data name="ThisWorkspaceOnlySupportsOpeningDocumentsOnTheUIThread" xml:space="preserve">
<value>This workspace only supports opening documents on the UI thread.</value>
</data>
<data name="SynchronizeClassView" xml:space="preserve">
<value>Synchronize {0}</value>
</data>
<data name="SynchronizingWithClassView" xml:space="preserve">
<value>Synchronizing with {0}...</value>
</data>
</root>
\ No newline at end of file
......@@ -42,9 +42,11 @@
<Compile Include="Implementation\EditAndContinue\Interop\NativeMethods.cs" />
<Compile Include="Implementation\AnalyzerDependency\IIgnorableAssemblyList.cs" />
<Compile Include="Implementation\AnalyzerDependency\IBindingRedirectionService.cs" />
<Compile Include="Implementation\Extensions\ServiceProviderExtensions.cs" />
<Compile Include="Implementation\Interop\CleanableWeakComHandleTable.cs" />
<Compile Include="Implementation\LanguageService\AbstractLanguageService`2.IVsLanguageBlock.cs" />
<Compile Include="Implementation\Library\AbstractLibraryService.cs" />
<Compile Include="Implementation\Library\ClassView\AbstractSyncClassViewCommandHandler.cs" />
<Compile Include="Implementation\Library\FindResults\TreeItems\AbstractSourceTreeItem.cs" />
<Compile Include="Implementation\Library\FindResults\TreeItems\MetadataDefinitionTreeItem.cs" />
<Compile Include="Implementation\Library\FindResults\TreeItems\SourceDefinitionTreeItem.cs" />
......@@ -772,4 +774,4 @@
<ImportGroup Label="Targets">
<Import Project="..\..\..\..\build\Targets\VSL.Imports.targets" />
</ImportGroup>
</Project>
</Project>
\ No newline at end of file
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.VisualStudio.LanguageServices.UnitTests.Utilities.VsNavInfo
Imports Microsoft.VisualStudio.Shell.Interop
Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ClassView
Friend Class MockNavigationTool
Implements IVsNavigationTool
Private ReadOnly _canonicalNodes As NodeVerifier()
Private ReadOnly _presentationNodes As NodeVerifier()
Private _navInfo As IVsNavInfo
Public Sub New(canonicalNodes As NodeVerifier(), presentationNodes As NodeVerifier())
_canonicalNodes = canonicalNodes
_presentationNodes = presentationNodes
End Sub
Public Function GetSelectedSymbols(ByRef ppIVsSelectedSymbols As IVsSelectedSymbols) As Integer Implements IVsNavigationTool.GetSelectedSymbols
Throw New NotImplementedException()
End Function
Public Function NavigateToNavInfo(pNavInfo As IVsNavInfo) As Integer Implements IVsNavigationTool.NavigateToNavInfo
Assert.Null(_navInfo)
_navInfo = pNavInfo
Return VSConstants.S_OK
End Function
Public Function NavigateToSymbol(ByRef guidLib As Guid, rgSymbolNodes() As SYMBOL_DESCRIPTION_NODE, ulcNodes As UInteger) As Integer Implements IVsNavigationTool.NavigateToSymbol
Throw New NotImplementedException()
End Function
Public Sub VerifyNavInfo()
Assert.NotNull(_navInfo)
If _canonicalNodes IsNot Nothing Then
Dim enumerator As IVsEnumNavInfoNodes = Nothing
IsOK(_navInfo.EnumCanonicalNodes(enumerator))
VerifyNodes(enumerator, _canonicalNodes)
End If
If _presentationNodes IsNot Nothing Then
Dim enumerator As IVsEnumNavInfoNodes = Nothing
IsOK(_navInfo.EnumPresentationNodes(CUInt(_LIB_LISTFLAGS.LLF_NONE), enumerator))
VerifyNodes(enumerator, _presentationNodes)
End If
End Sub
End Class
End Namespace
\ No newline at end of file
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.CodeAnalysis.Editor.Host
Imports Microsoft.VisualStudio.LanguageServices.Implementation.Library.ClassView
Imports Microsoft.VisualStudio.Shell
Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ClassView
Friend Class MockSyncClassViewCommandHandler
Inherits AbstractSyncClassViewCommandHandler
Public Sub New(serviceProvider As SVsServiceProvider, waitIndicator As IWaitIndicator)
MyBase.New(serviceProvider, waitIndicator)
End Sub
End Class
End Namespace
\ No newline at end of file
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports Microsoft.VisualStudio.Shell
Imports Microsoft.VisualStudio.Shell.Interop
Imports Roslyn.Utilities
Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.ClassView
Friend Class MockServiceProvider
Implements SVsServiceProvider
Private ReadOnly _navigationTool As IVsNavigationTool
Public Sub New(navigationTool As IVsNavigationTool)
_navigationTool = navigationTool
End Sub
Public Function GetService(serviceType As Type) As Object Implements SVsServiceProvider.GetService
If serviceType Is GetType(SVsClassView) Then
Return _navigationTool
End If
Return Contract.FailWithReturn(Of Object)($"GetService only handles {NameOf(SVsClassView)}")
End Function
End Class
End Namespace
\ No newline at end of file
......@@ -232,6 +232,10 @@
<Compile Include="AnalyzerSupport\AnalyzerDependencyCheckerTests.vb" />
<Compile Include="ChangeSignature\ChangeSignatureViewModelTests.vb" />
<Compile Include="ChangeSignature\ChangeSignatureViewModelTestState.vb" />
<Compile Include="ClassView\MockNavigationTool.vb" />
<Compile Include="ClassView\MockVsServiceProvider.vb" />
<Compile Include="ClassView\MockSyncClassViewCommandHandler.vb" />
<Compile Include="ClassView\SyncClassViewTests.vb" />
<Compile Include="CodeModel\AbstractCodeAttributeTests.vb" />
<Compile Include="CodeModel\AbstractCodeClassTests.vb" />
<Compile Include="CodeModel\AbstractCodeDelegateTests.vb" />
......@@ -364,6 +368,7 @@
<Compile Include="Help\HelpTests.vb" />
<Compile Include="LanguageBlockTests.vb" />
<Compile Include="MockComponentModel.vb" />
<Compile Include="Utilities\VsNavInfoHelpers.vb" />
<Compile Include="VsNavInfo\VsNavInfoTests.vb" />
<Compile Include="ObjectBrowser\AbstractObjectBrowserTests.vb" />
<Compile Include="ObjectBrowser\CSharp\ObjectBrowerTests.vb" />
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.Runtime.CompilerServices
Imports Microsoft.VisualStudio.Shell.Interop
Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.Utilities.VsNavInfo
Friend Module VsNavInfoHelpers
Public Sub IsOK(result As Integer)
Assert.Equal(VSConstants.S_OK, result)
End Sub
Public Delegate Sub NodeVerifier(vsNavInfoNode As IVsNavInfoNode)
Private Function Node(expectedListType As _LIB_LISTTYPE, expectedName As String) As NodeVerifier
Return Sub(vsNavInfoNode)
Dim listType As UInteger
IsOK(vsNavInfoNode.get_Type(listType))
Assert.Equal(CUInt(expectedListType), listType)
Dim actualName As String = Nothing
IsOK(vsNavInfoNode.get_Name(actualName))
Assert.Equal(expectedName, actualName)
End Sub
End Function
Public Function Package(expectedName As String) As NodeVerifier
Return Node(_LIB_LISTTYPE.LLT_PACKAGE, expectedName)
End Function
Public Function [Namespace](expectedName As String) As NodeVerifier
Return Node(_LIB_LISTTYPE.LLT_NAMESPACES, expectedName)
End Function
Public Function [Class](expectedName As String) As NodeVerifier
Return Node(_LIB_LISTTYPE.LLT_CLASSES, expectedName)
End Function
Public Function Member(expectedName As String) As NodeVerifier
Return Node(_LIB_LISTTYPE.LLT_MEMBERS, expectedName)
End Function
Public Function Hierarchy(expectedName As String) As NodeVerifier
Return Node(_LIB_LISTTYPE.LLT_HIERARCHY, expectedName)
End Function
<Extension>
Public Sub VerifyNodes(enumerator As IVsEnumNavInfoNodes, verifiers() As NodeVerifier)
Dim index = 0
Dim actualNode = New IVsNavInfoNode(0) {}
Dim fetched As UInteger
While enumerator.Next(1, actualNode, fetched) = VSConstants.S_OK
Assert.True(index < verifiers.Length)
Dim verifier = verifiers(index)
index += 1
verifier(actualNode(0))
End While
End Sub
End Module
End Namespace
\ No newline at end of file
......@@ -5,6 +5,7 @@ Imports System.Threading.Tasks
Imports Microsoft.CodeAnalysis.Editor.UnitTests.Workspaces
Imports Microsoft.CodeAnalysis.FindSymbols
Imports Microsoft.VisualStudio.LanguageServices.Implementation.Library
Imports Microsoft.VisualStudio.LanguageServices.UnitTests.Utilities.VsNavInfo
Imports Microsoft.VisualStudio.Shell.Interop
Imports Roslyn.Test.Utilities
......@@ -809,64 +810,12 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.VsNavInfo
#End Region
Private Shared Sub IsOK(comAction As Func(Of Integer))
Assert.Equal(VSConstants.S_OK, comAction())
End Sub
Private Delegate Sub NodeVerifier(vsNavInfoNode As IVsNavInfoNode)
Private Shared Function Node(expectedListType As _LIB_LISTTYPE, expectedName As String) As NodeVerifier
Return Sub(vsNavInfoNode)
Dim listType As UInteger
IsOK(Function() vsNavInfoNode.get_Type(listType))
Assert.Equal(CUInt(expectedListType), listType)
Dim actualName As String = Nothing
IsOK(Function() vsNavInfoNode.get_Name(actualName))
Assert.Equal(expectedName, actualName)
End Sub
End Function
Private Shared Function Package(expectedName As String) As NodeVerifier
Return Node(_LIB_LISTTYPE.LLT_PACKAGE, expectedName)
End Function
Private Shared Function [Namespace](expectedName As String) As NodeVerifier
Return Node(_LIB_LISTTYPE.LLT_NAMESPACES, expectedName)
End Function
Private Shared Function [Class](expectedName As String) As NodeVerifier
Return Node(_LIB_LISTTYPE.LLT_CLASSES, expectedName)
End Function
Private Shared Function Member(expectedName As String) As NodeVerifier
Return Node(_LIB_LISTTYPE.LLT_MEMBERS, expectedName)
End Function
Private Shared Function Hierarchy(expectedName As String) As NodeVerifier
Return Node(_LIB_LISTTYPE.LLT_HIERARCHY, expectedName)
End Function
Private Shared Sub VerifyNodes(enumerator As IVsEnumNavInfoNodes, verifiers() As NodeVerifier)
Dim index = 0
Dim actualNode = New IVsNavInfoNode(0) {}
Dim fetched As UInteger
While enumerator.Next(1, actualNode, fetched) = VSConstants.S_OK
Dim verifier = verifiers(index)
index += 1
verifier(actualNode(0))
End While
Assert.Equal(index, verifiers.Length)
End Sub
Private Shared Async Function TestAsync(
workspaceDefinition As XElement,
Optional useExpandedHierarchy As Boolean = False,
Optional canonicalNodes As NodeVerifier() = Nothing,
Optional presentationNodes As NodeVerifier() = Nothing
) As Tasks.Task
) As Task
Using workspace = Await TestWorkspaceFactory.CreateWorkspaceAsync(workspaceDefinition, exportProvider:=VisualStudioTestExportProvider.ExportProvider)
Dim hostDocument = workspace.DocumentWithCursor
......@@ -887,14 +836,14 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.VsNavInfo
If canonicalNodes IsNot Nothing Then
Dim enumerator As IVsEnumNavInfoNodes = Nothing
IsOK(Function() navInfo.EnumCanonicalNodes(enumerator))
IsOK(navInfo.EnumCanonicalNodes(enumerator))
VerifyNodes(enumerator, canonicalNodes)
End If
If presentationNodes IsNot Nothing Then
Dim enumerator As IVsEnumNavInfoNodes = Nothing
IsOK(Function() navInfo.EnumPresentationNodes(CUInt(_LIB_LISTFLAGS.LLF_NONE), enumerator))
IsOK(navInfo.EnumPresentationNodes(CUInt(_LIB_LISTFLAGS.LLF_NONE), enumerator))
VerifyNodes(enumerator, presentationNodes)
End If
......@@ -904,7 +853,7 @@ Namespace Microsoft.VisualStudio.LanguageServices.UnitTests.VsNavInfo
Private Shared Async Function TestIsNullAsync(
workspaceDefinition As XElement,
Optional useExpandedHierarchy As Boolean = False
) As Tasks.Task
) As Task
Using workspace = Await TestWorkspaceFactory.CreateWorkspaceAsync(workspaceDefinition, exportProvider:=VisualStudioTestExportProvider.ExportProvider)
Dim hostDocument = workspace.DocumentWithCursor
......
......@@ -128,6 +128,7 @@
<Compile Include="ObjectBrowser\ListItemFactory.vb" />
<Compile Include="ObjectBrowser\ObjectBrowserLibraryManager.vb" />
<Compile Include="ObjectBrowser\VisualBasicLibraryService.vb" />
<Compile Include="ObjectBrowser\VisualBasicSyncClassViewCommandHandler.vb" />
<Compile Include="Options\AdvancedOptionPageStrings.vb" />
<Compile Include="Options\AutomationObject.vb" />
<Compile Include="Options\VisualBasicLanguageSettingsSerializer.vb" />
......
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports System.ComponentModel.Composition
Imports Microsoft.CodeAnalysis.Editor
Imports Microsoft.CodeAnalysis.Editor.Host
Imports Microsoft.VisualStudio.LanguageServices.Implementation.Library.ClassView
Imports Microsoft.VisualStudio.Shell
Namespace Microsoft.VisualStudio.LanguageServices.VisualBasic.ObjectBrowser
<ExportCommandHandler(PredefinedCommandHandlerNames.ClassView, ContentTypeNames.VisualBasicContentType)>
Friend Class VisualBasicSyncClassViewCommandHandler
Inherits AbstractSyncClassViewCommandHandler
<ImportingConstructor>
Private Sub New(serviceProvider As SVsServiceProvider, waitIndicator As IWaitIndicator)
MyBase.New(serviceProvider, waitIndicator)
End Sub
End Class
End Namespace
......@@ -1824,6 +1824,141 @@ End Sub
}
}
[Fact]
[Trait(Traits.Feature, Traits.Features.ReduceTokens)]
public async Task ReduceIntegerLiteralWithLeadingZeros()
{
var code = @"[|
Module Program
Sub Main(args As String())
Const i0 As Integer = 0060
Const i1 As Integer = 0060%
Const i2 As Integer = &H006F
Const i3 As Integer = &O0060
Const i4 As Integer = 0060I
Const i5 As Integer = -0060
Const i6 As Integer = 000
Const i7 As UInteger = 0060UI
Const i8 As Integer = &H0000FFFFI
Const i9 As Integer = &O000
Const i10 As Integer = &H000
Const l0 As Long = 0060L
Const l1 As Long = 0060&
Const l2 As ULong = 0060UL
Const s0 As Short = 0060S
Const s1 As UShort = 0060US
Const s2 As Short = &H0000FFFFS
End Sub
End Module
|]";
var expected = @"
Module Program
Sub Main(args As String())
Const i0 As Integer = 60
Const i1 As Integer = 60%
Const i2 As Integer = &H6F
Const i3 As Integer = &O60
Const i4 As Integer = 60I
Const i5 As Integer = -60
Const i6 As Integer = 0
Const i7 As UInteger = 60UI
Const i8 As Integer = &HFFFFI
Const i9 As Integer = &O0
Const i10 As Integer = &H0
Const l0 As Long = 60L
Const l1 As Long = 60&
Const l2 As ULong = 60UL
Const s0 As Short = 60S
Const s1 As UShort = 60US
Const s2 As Short = &HFFFFS
End Sub
End Module
";
await VerifyAsync(code, expected);
}
[Fact]
[Trait(Traits.Feature, Traits.Features.ReduceTokens)]
public async Task ReduceIntegerLiteralWithNegativeHexOrOctalValue()
{
var code = @"[|
Module Program
Sub Main(args As String())
Const s0 As Short = &HFFFFS
Const s1 As Short = &O177777S
Const s2 As Short = &H8000S
Const s3 As Short = &O100000S
Const i0 As Integer = &O37777777777I
Const i1 As Integer = &HFFFFFFFFI
Const i2 As Integer = &H80000000I
Const i3 As Integer = &O20000000000I
Const l0 As Long = &HFFFFFFFFFFFFFFFFL
Const l1 As Long = &O1777777777777777777777L
Const l2 As Long = &H8000000000000000L
Const l2 As Long = &O1000000000000000000000L
End Sub
End Module
|]";
var expected = @"
Module Program
Sub Main(args As String())
Const s0 As Short = &HFFFFS
Const s1 As Short = &O177777S
Const s2 As Short = &H8000S
Const s3 As Short = &O100000S
Const i0 As Integer = &O37777777777I
Const i1 As Integer = &HFFFFFFFFI
Const i2 As Integer = &H80000000I
Const i3 As Integer = &O20000000000I
Const l0 As Long = &HFFFFFFFFFFFFFFFFL
Const l1 As Long = &O1777777777777777777777L
Const l2 As Long = &H8000000000000000L
Const l2 As Long = &O1000000000000000000000L
End Sub
End Module
";
await VerifyAsync(code, expected);
}
[Fact]
[Trait(Traits.Feature, Traits.Features.ReduceTokens)]
public async Task ReduceIntegerLiteralWithOverflow()
{
var code = @"[|
Module Module1
Sub Main()
Dim sMax As Short = 0032768S
Dim usMax As UShort = 00655536US
Dim iMax As Integer = 002147483648I
Dim uiMax As UInteger = 004294967296UI
Dim lMax As Long = 009223372036854775808L
Dim ulMax As ULong = 0018446744073709551616UL
Dim z As Long = &O37777777777777777777777
Dim x As Long = &HFFFFFFFFFFFFFFFFF
End Sub
End Module
|]";
var expected = @"
Module Module1
Sub Main()
Dim sMax As Short = 0032768S
Dim usMax As UShort = 00655536US
Dim iMax As Integer = 002147483648I
Dim uiMax As UInteger = 004294967296UI
Dim lMax As Long = 009223372036854775808L
Dim ulMax As ULong = 0018446744073709551616UL
Dim z As Long = &O37777777777777777777777
Dim x As Long = &HFFFFFFFFFFFFFFFFF
End Sub
End Module
";
await VerifyAsync(code, expected);
}
private static async Task VerifyAsync(string codeWithMarker, string expectedResult)
{
var codeWithoutMarker = default(string);
......
......@@ -3,8 +3,10 @@
using System;
using System.Collections.Immutable;
using System.Composition;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading;
using Microsoft.CodeAnalysis;
......@@ -658,7 +660,19 @@ private Solution CreateNotKeptAliveSolution()
return workspace.CurrentSolution;
}
private void StopObservingAndWaitForReferenceToGo(ObjectReference observed, int delay = 0)
[DllImport("dbghelp.dll")]
private static extern bool MiniDumpWriteDump(IntPtr hProcess, int ProcessId, IntPtr hFile, int DumpType, IntPtr ExceptionParam, IntPtr UserStreamParam, IntPtr CallbackParam);
private static void DumpProcess(string dumpFileName)
{
using (var fs = File.Create(dumpFileName))
{
var proc = System.Diagnostics.Process.GetCurrentProcess();
MiniDumpWriteDump(proc.Handle, proc.Id, fs.SafeFileHandle.DangerousGetHandle(), /*MiniDumpWithFullMemory*/2, IntPtr.Zero, IntPtr.Zero, IntPtr.Zero);
}
}
private void StopObservingAndWaitForReferenceToGo(ObjectReference observed, int delay = 0, string dumpFileName = null)
{
// stop observing it and let GC reclaim it
observed.Strong = null;
......@@ -674,8 +688,20 @@ private void StopObservingAndWaitForReferenceToGo(ObjectReference observed, int
const int TimerPrecision = 30;
var actualTimePassed = DateTime.UtcNow - start + TimeSpan.FromMilliseconds(TimerPrecision);
var isTargetCollected = observed.Weak.Target == null;
if (!isTargetCollected && !string.IsNullOrEmpty(dumpFileName))
{
if (string.Compare(Path.GetExtension(dumpFileName), ".dmp", StringComparison.OrdinalIgnoreCase) != 0)
{
dumpFileName += ".dmp";
}
Assert.True(observed.Weak.Target == null,
DumpProcess(dumpFileName);
Assert.True(false, $"Target object not collected. Process dump saved to '{dumpFileName}'");
}
Assert.True(isTargetCollected,
string.Format("Target object ({0}) was not collected after {1} ms", observed.Weak.Target, actualTimePassed));
}
......@@ -1016,7 +1042,7 @@ public void TestRecoverableSyntaxTreeCSharp()
}
[MethodImpl(MethodImplOptions.NoInlining)]
[Fact(Skip = "https://github.com/dotnet/roslyn/issues/6409"), Trait(Traits.Feature, Traits.Features.Workspace)]
[Fact, Trait(Traits.Feature, Traits.Features.Workspace)]
public void TestRecoverableSyntaxTreeVisualBasic()
{
var pid = ProjectId.CreateNewId();
......@@ -1044,11 +1070,11 @@ End Sub
TestRecoverableSyntaxTree(sol, did);
}
private void TestRecoverableSyntaxTree(Solution sol, DocumentId did)
private void TestRecoverableSyntaxTree(Solution sol, DocumentId did, [CallerMemberName] string callingTest = null)
{
// get it async and wait for it to get GC'd
var observed = GetObservedSyntaxTreeRootAsync(sol, did);
StopObservingAndWaitForReferenceToGo(observed);
StopObservingAndWaitForReferenceToGo(observed, dumpFileName: callingTest);
var doc = sol.GetDocument(did);
......@@ -1067,7 +1093,7 @@ private void TestRecoverableSyntaxTree(Solution sol, DocumentId did)
// get it async and wait for it to get GC'd
var observed2 = GetObservedSyntaxTreeRootAsync(doc2.Project.Solution, did);
StopObservingAndWaitForReferenceToGo(observed2);
StopObservingAndWaitForReferenceToGo(observed2, dumpFileName: callingTest);
// access the tree & root again (recover it)
var tree2 = doc2.GetSyntaxTreeAsync().Result;
......
......@@ -3,6 +3,7 @@
Imports System.Composition
Imports System.Globalization
Imports System.Runtime.InteropServices
Imports System.Text
Imports System.Threading
Imports System.Threading.Tasks
Imports Microsoft.CodeAnalysis
......@@ -53,7 +54,7 @@ Namespace Microsoft.CodeAnalysis.CodeCleanup.Providers
' If the string representation of the value differs from the identifier text, create a new literal token with same value but pretty listed "valueText".
If Not CaseInsensitiveComparison.Equals(valueText, idText) Then
Return newNode.ReplaceToken(literal, CreateFloatingLiteralToken(literal, valueText, value))
Return newNode.ReplaceToken(literal, CreateLiteralToken(literal, valueText, value))
End If
Case SyntaxKind.DecimalLiteralToken
......@@ -70,7 +71,32 @@ Namespace Microsoft.CodeAnalysis.CodeCleanup.Providers
Dim valueText As String = GetDecimalLiteralValueString(value) + GetTypeCharString(literal.GetTypeCharacter())
If Not CaseInsensitiveComparison.Equals(valueText, idText) Then
Return newNode.ReplaceToken(literal, CreateDecimalLiteralToken(literal, valueText, value))
Return newNode.ReplaceToken(literal, CreateLiteralToken(literal, valueText, value))
End If
Case SyntaxKind.IntegerLiteralToken
' Get the literal identifier text which needs to be pretty listed.
Dim idText = literal.GetIdentifierText()
'The value will only ever be negative when we have a hex or oct value
'it's safe to cast to ULong as we check for negative values later
Dim value As ULong = CType(literal.Value, ULong)
If value = 0 AndAlso HasOverflow(literal.GetDiagnostics()) Then
'Overflow/underflow, skip pretty listing.
Return newNode
End If
Dim base = literal.GetBase()
If Not base.HasValue Then
Return newNode
End If
'fetch the string representation of this value in the correct base.
Dim valueText As String = GetIntegerLiteralValueString(literal.Value, base.Value) + GetTypeCharString(literal.GetTypeCharacter())
If Not CaseInsensitiveComparison.Equals(valueText, idText) Then
Return newNode.ReplaceToken(literal, CreateLiteralToken(literal, valueText, value))
End If
End Select
......@@ -91,6 +117,22 @@ Namespace Microsoft.CodeAnalysis.CodeCleanup.Providers
Return "@"
Case TypeCharacter.DecimalLiteral
Return "D"
Case TypeCharacter.Integer
Return "%"
Case TypeCharacter.IntegerLiteral
Return "I"
Case TypeCharacter.ShortLiteral
Return "S"
Case TypeCharacter.Long
Return "&"
Case TypeCharacter.LongLiteral
Return "L"
Case TypeCharacter.UIntegerLiteral
Return "UI"
Case TypeCharacter.UShortLiteral
Return "US"
Case TypeCharacter.ULongLiteral
Return "UL"
Case Else
Return ""
End Select
......@@ -222,26 +264,75 @@ Namespace Microsoft.CodeAnalysis.CodeCleanup.Providers
Return valueText
End Function
Private Shared Function CreateFloatingLiteralToken(token As SyntaxToken, newValueString As String, newValue As Double) As SyntaxToken
Debug.Assert(token.Kind = SyntaxKind.FloatingLiteralToken)
Private Function GetIntegerLiteralValueString(value As Object, base As LiteralBase) As String
Select Case base
Case LiteralBase.Decimal
Return CType(value, ULong).ToString(CultureInfo.InvariantCulture)
Case LiteralBase.Hexadecimal
Return "&H" + ConvertToULong(value).ToString("X")
Case LiteralBase.Octal
Dim val1 As ULong = ConvertToULong(value)
Return "&O" + ConvertToOctalString(val1)
Case Else
Throw ExceptionUtilities.Unreachable
End Select
End Function
Private Shared Function CreateLiteralToken(token As SyntaxToken, newValueString As String, newValue As Object) As SyntaxToken
' create a new token with valid token text and carries over annotations attached to original token to be a good citizen
' it might be replacing a token that has annotation injected by other code cleanups
Dim leading = If(token.LeadingTrivia.Count > 0, token.LeadingTrivia, SyntaxTriviaList.Create(SyntaxFactory.ElasticMarker))
Dim trailing = If(token.TrailingTrivia.Count > 0, token.TrailingTrivia, SyntaxTriviaList.Create(SyntaxFactory.ElasticMarker))
Return token.CopyAnnotationsTo(SyntaxFactory.FloatingLiteralToken(leading, newValueString, token.GetTypeCharacter(), newValue, trailing))
Select Case token.Kind
Case SyntaxKind.FloatingLiteralToken
Return token.CopyAnnotationsTo(SyntaxFactory.FloatingLiteralToken(leading, newValueString, token.GetTypeCharacter(), DirectCast(newValue, Double), trailing))
Case SyntaxKind.DecimalLiteralToken
Return token.CopyAnnotationsTo(SyntaxFactory.DecimalLiteralToken(leading, newValueString, token.GetTypeCharacter(), DirectCast(newValue, Decimal), trailing))
Case SyntaxKind.IntegerLiteralToken
Return token.CopyAnnotationsTo(SyntaxFactory.IntegerLiteralToken(leading, newValueString, token.GetBase().Value, token.GetTypeCharacter(), DirectCast(newValue, ULong), trailing))
Case Else
Throw ExceptionUtilities.Unreachable
End Select
End Function
Private Shared Function CreateDecimalLiteralToken(token As SyntaxToken, newValueString As String, newValue As Decimal) As SyntaxToken
Debug.Assert(token.Kind = SyntaxKind.DecimalLiteralToken)
Private Function ConvertToOctalString(value As ULong) As String
Dim exponent As ULong = value
Dim builder As New StringBuilder()
' create a new token with valid token text and carries over annotations attached to original token to be a good citizen
' it might be replacing a token that has annotation injected by other code cleanups
Dim leading = If(token.LeadingTrivia.Count > 0, token.LeadingTrivia, SyntaxTriviaList.Create(SyntaxFactory.ElasticMarker))
Dim trailing = If(token.TrailingTrivia.Count > 0, token.TrailingTrivia, SyntaxTriviaList.Create(SyntaxFactory.ElasticMarker))
If value = 0 Then
Return "0"
End If
While (exponent > 0)
Dim remainder = exponent Mod 8UL
Return token.CopyAnnotationsTo(SyntaxFactory.DecimalLiteralToken(leading, newValueString, token.GetTypeCharacter(), newValue, trailing))
builder.Insert(0, remainder)
exponent = exponent \ 8UL
End While
Return builder.ToString()
End Function
Private Function HasOverflow(diagnostics As IEnumerable(Of Diagnostic)) As Boolean
Return diagnostics.Any(Function(diagnostic As Diagnostic) diagnostic.Id = "BC30036")
End Function
Private Function ConvertToULong(value As Object) As ULong
'Cannot convert directly to ULong from Short or Integer as negative numbers
'appear to have all bits above the current bit range set to 1
'so short value -32768 or binary 1000000000000000 becomes
'binary 1111111111111111111111111111111111111111111111111000000000000000
'or in decimal 18446744073709518848
'This will cause the subsequent conversion to a hex or octal string to output an incorrect value
If TypeOf (value) Is Short Then
Return CType(value, UShort)
ElseIf TypeOf (value) Is Integer Then
Return CType(value, UInteger)
Else
Return CType(value, ULong)
End If
End Function
End Class
End Class
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册