提交 b76109fe 编写于 作者: C Charles Stoner 提交者: GitHub

Merge pull request #14447 from cston/bp

C# function breakpoint binding
......@@ -365,6 +365,10 @@ Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "ServicesTestUtilities2", "s
EndProject
Project("{F184B08F-C81C-45F6-A57F-5ABD9991F28F}") = "VisualStudioTestUtilities2", "src\VisualStudio\TestUtilities2\VisualStudioTestUtilities2.vbproj", "{69F853E5-BD04-4842-984F-FC68CC51F402}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FunctionResolver", "src\ExpressionEvaluator\Core\Source\FunctionResolver\FunctionResolver.csproj", "{6FC8E6F5-659C-424D-AEB5-331B95883E29}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FunctionResolverTest", "src\ExpressionEvaluator\Core\Test\FunctionResolver\FunctionResolverTest.csproj", "{DD317BE1-42A1-4795-B1D4-F370C40D649A}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
src\Compilers\Core\CommandLine\CommandLine.projitems*{06b26dcb-7a12-48ef-ae50-708593abd05f}*SharedItemsImports = 4
......@@ -3212,6 +3216,46 @@ Global
{69F853E5-BD04-4842-984F-FC68CC51F402}.Release|x64.Build.0 = Release|Any CPU
{69F853E5-BD04-4842-984F-FC68CC51F402}.Release|x86.ActiveCfg = Release|Any CPU
{69F853E5-BD04-4842-984F-FC68CC51F402}.Release|x86.Build.0 = Release|Any CPU
{6FC8E6F5-659C-424D-AEB5-331B95883E29}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6FC8E6F5-659C-424D-AEB5-331B95883E29}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6FC8E6F5-659C-424D-AEB5-331B95883E29}.Debug|ARM.ActiveCfg = Debug|Any CPU
{6FC8E6F5-659C-424D-AEB5-331B95883E29}.Debug|ARM.Build.0 = Debug|Any CPU
{6FC8E6F5-659C-424D-AEB5-331B95883E29}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{6FC8E6F5-659C-424D-AEB5-331B95883E29}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{6FC8E6F5-659C-424D-AEB5-331B95883E29}.Debug|x64.ActiveCfg = Debug|Any CPU
{6FC8E6F5-659C-424D-AEB5-331B95883E29}.Debug|x64.Build.0 = Debug|Any CPU
{6FC8E6F5-659C-424D-AEB5-331B95883E29}.Debug|x86.ActiveCfg = Debug|Any CPU
{6FC8E6F5-659C-424D-AEB5-331B95883E29}.Debug|x86.Build.0 = Debug|Any CPU
{6FC8E6F5-659C-424D-AEB5-331B95883E29}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6FC8E6F5-659C-424D-AEB5-331B95883E29}.Release|Any CPU.Build.0 = Release|Any CPU
{6FC8E6F5-659C-424D-AEB5-331B95883E29}.Release|ARM.ActiveCfg = Release|Any CPU
{6FC8E6F5-659C-424D-AEB5-331B95883E29}.Release|ARM.Build.0 = Release|Any CPU
{6FC8E6F5-659C-424D-AEB5-331B95883E29}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{6FC8E6F5-659C-424D-AEB5-331B95883E29}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{6FC8E6F5-659C-424D-AEB5-331B95883E29}.Release|x64.ActiveCfg = Release|Any CPU
{6FC8E6F5-659C-424D-AEB5-331B95883E29}.Release|x64.Build.0 = Release|Any CPU
{6FC8E6F5-659C-424D-AEB5-331B95883E29}.Release|x86.ActiveCfg = Release|Any CPU
{6FC8E6F5-659C-424D-AEB5-331B95883E29}.Release|x86.Build.0 = Release|Any CPU
{DD317BE1-42A1-4795-B1D4-F370C40D649A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{DD317BE1-42A1-4795-B1D4-F370C40D649A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DD317BE1-42A1-4795-B1D4-F370C40D649A}.Debug|ARM.ActiveCfg = Debug|Any CPU
{DD317BE1-42A1-4795-B1D4-F370C40D649A}.Debug|ARM.Build.0 = Debug|Any CPU
{DD317BE1-42A1-4795-B1D4-F370C40D649A}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
{DD317BE1-42A1-4795-B1D4-F370C40D649A}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
{DD317BE1-42A1-4795-B1D4-F370C40D649A}.Debug|x64.ActiveCfg = Debug|Any CPU
{DD317BE1-42A1-4795-B1D4-F370C40D649A}.Debug|x64.Build.0 = Debug|Any CPU
{DD317BE1-42A1-4795-B1D4-F370C40D649A}.Debug|x86.ActiveCfg = Debug|Any CPU
{DD317BE1-42A1-4795-B1D4-F370C40D649A}.Debug|x86.Build.0 = Debug|Any CPU
{DD317BE1-42A1-4795-B1D4-F370C40D649A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DD317BE1-42A1-4795-B1D4-F370C40D649A}.Release|Any CPU.Build.0 = Release|Any CPU
{DD317BE1-42A1-4795-B1D4-F370C40D649A}.Release|ARM.ActiveCfg = Release|Any CPU
{DD317BE1-42A1-4795-B1D4-F370C40D649A}.Release|ARM.Build.0 = Release|Any CPU
{DD317BE1-42A1-4795-B1D4-F370C40D649A}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
{DD317BE1-42A1-4795-B1D4-F370C40D649A}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{DD317BE1-42A1-4795-B1D4-F370C40D649A}.Release|x64.ActiveCfg = Release|Any CPU
{DD317BE1-42A1-4795-B1D4-F370C40D649A}.Release|x64.Build.0 = Release|Any CPU
{DD317BE1-42A1-4795-B1D4-F370C40D649A}.Release|x86.ActiveCfg = Release|Any CPU
{DD317BE1-42A1-4795-B1D4-F370C40D649A}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
......@@ -3383,5 +3427,7 @@ Global
{57557F32-0635-421A-BCF8-549AED50F764} = {FD0FAF5F-1DED-485C-99FA-84B97F3A8EEC}
{3DFB4701-E3D6-4435-9F70-A6E35822C4F2} = {EE97CB90-33BB-4F3A-9B3D-69375DEC6AC6}
{69F853E5-BD04-4842-984F-FC68CC51F402} = {8DBA5174-B0AA-4561-82B1-A46607697753}
{6FC8E6F5-659C-424D-AEB5-331B95883E29} = {998CAFE8-06E4-4683-A151-0F6AA4BFF6C6}
{DD317BE1-42A1-4795-B1D4-F370C40D649A} = {998CAFE8-06E4-4683-A151-0F6AA4BFF6C6}
EndGlobalSection
EndGlobal
......@@ -66,6 +66,7 @@
"strongName": "MsSharedLib72",
"values": [
"Dlls\\ExpressionCompiler\\Microsoft.CodeAnalysis.ExpressionEvaluator.ExpressionCompiler.dll",
"Dlls\\FunctionResolver\\Microsoft.CodeAnalysis.ExpressionEvaluator.FunctionResolver.dll",
"Dlls\\ResultProvider.Portable\\Microsoft.CodeAnalysis.ExpressionEvaluator.ResultProvider.dll",
"Dlls\\CSharpExpressionCompiler\\Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator.ExpressionCompiler.dll",
"Dlls\\CSharpResultProvider.Portable\\Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator.ResultProvider.dll",
......
......@@ -787,6 +787,7 @@
<Compile Include="Syntax\SyntaxExtensions.cs" />
<Compile Include="Syntax\SyntaxFactory.cs" />
<Compile Include="Syntax\LambdaUtilities.cs" />
<Compile Include="Syntax\SyntaxKindExtensions.cs" />
<Compile Include="Syntax\SyntaxNormalizer.cs" />
<Compile Include="Syntax\SyntaxKind.cs" />
<Compile Include="Syntax\SyntaxKindEqualityComparer.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 Microsoft.CodeAnalysis.CSharp.Symbols;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp.Symbols
......@@ -36,47 +33,5 @@ public static RefKind GetRefKind(this SyntaxKind syntaxKind)
throw ExceptionUtilities.UnexpectedValue(syntaxKind);
}
}
internal static SpecialType GetSpecialType(this SyntaxKind kind)
{
switch (kind)
{
case SyntaxKind.VoidKeyword:
return SpecialType.System_Void;
case SyntaxKind.BoolKeyword:
return SpecialType.System_Boolean;
case SyntaxKind.ByteKeyword:
return SpecialType.System_Byte;
case SyntaxKind.SByteKeyword:
return SpecialType.System_SByte;
case SyntaxKind.ShortKeyword:
return SpecialType.System_Int16;
case SyntaxKind.UShortKeyword:
return SpecialType.System_UInt16;
case SyntaxKind.IntKeyword:
return SpecialType.System_Int32;
case SyntaxKind.UIntKeyword:
return SpecialType.System_UInt32;
case SyntaxKind.LongKeyword:
return SpecialType.System_Int64;
case SyntaxKind.ULongKeyword:
return SpecialType.System_UInt64;
case SyntaxKind.DoubleKeyword:
return SpecialType.System_Double;
case SyntaxKind.FloatKeyword:
return SpecialType.System_Single;
case SyntaxKind.DecimalKeyword:
return SpecialType.System_Decimal;
case SyntaxKind.StringKeyword:
return SpecialType.System_String;
case SyntaxKind.CharKeyword:
return SpecialType.System_Char;
case SyntaxKind.ObjectKeyword:
return SpecialType.System_Object;
default:
// Note that "dynamic" is a contextual keyword, so it should never show up here.
throw ExceptionUtilities.UnexpectedValue(kind);
}
}
}
}
// 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 Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp
{
internal static partial class SyntaxKindExtensions
{
internal static SpecialType GetSpecialType(this SyntaxKind kind)
{
switch (kind)
{
case SyntaxKind.VoidKeyword:
return SpecialType.System_Void;
case SyntaxKind.BoolKeyword:
return SpecialType.System_Boolean;
case SyntaxKind.ByteKeyword:
return SpecialType.System_Byte;
case SyntaxKind.SByteKeyword:
return SpecialType.System_SByte;
case SyntaxKind.ShortKeyword:
return SpecialType.System_Int16;
case SyntaxKind.UShortKeyword:
return SpecialType.System_UInt16;
case SyntaxKind.IntKeyword:
return SpecialType.System_Int32;
case SyntaxKind.UIntKeyword:
return SpecialType.System_UInt32;
case SyntaxKind.LongKeyword:
return SpecialType.System_Int64;
case SyntaxKind.ULongKeyword:
return SpecialType.System_UInt64;
case SyntaxKind.DoubleKeyword:
return SpecialType.System_Double;
case SyntaxKind.FloatKeyword:
return SpecialType.System_Single;
case SyntaxKind.DecimalKeyword:
return SpecialType.System_Decimal;
case SyntaxKind.StringKeyword:
return SpecialType.System_String;
case SyntaxKind.CharKeyword:
return SpecialType.System_Char;
case SyntaxKind.ObjectKeyword:
return SpecialType.System_Object;
default:
// Note that "dynamic" is a contextual keyword, so it should never show up here.
throw ExceptionUtilities.UnexpectedValue(kind);
}
}
}
}
......@@ -107,6 +107,7 @@
<InternalsVisibleToTest Include="Roslyn.Compilers.CSharp.Symbol.UnitTests" />
<InternalsVisibleToTest Include="Roslyn.Compilers.CSharp.Syntax.UnitTests" />
<InternalsVisibleToTest Include="Roslyn.ExpressionEvaluator.CSharp.ExpressionCompiler.UnitTests" />
<InternalsVisibleToTest Include="Roslyn.ExpressionEvaluator.FunctionResolver.UnitTests" />
<InternalsVisibleToTest Include="Roslyn.InteractiveHost.UnitTests" />
<InternalsVisibleToTest Include="Microsoft.CodeAnalysis.CSharp.Scripting.UnitTests" />
<InternalsVisibleToTest Include="Roslyn.Services.Editor.CSharp.UnitTests" />
......
......@@ -21,4 +21,4 @@
<SubType>Designer</SubType>
</VsdConfigXml>
</ItemGroup>
</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.
using System;
using Microsoft.CodeAnalysis.ExpressionEvaluator;
using Microsoft.VisualStudio.Debugger.FunctionResolution;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
[DkmReportNonFatalWatsonException(ExcludeExceptionType = typeof(NotImplementedException)), DkmContinueCorruptingException]
internal sealed class CSharpFunctionResolver : FunctionResolver
{
public CSharpFunctionResolver()
{
}
internal override RequestSignature GetParsedSignature(DkmRuntimeFunctionResolutionRequest request)
{
return MemberSignatureParser.Parse(request.FunctionName);
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.CodeAnalysis
{
internal static class GreenNode
{
internal const int ListKind = 1; // See SyntaxKind.
}
}
\ 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.
using Microsoft.CodeAnalysis.ExpressionEvaluator;
using System;
using System.Collections.Immutable;
using System.Diagnostics;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
internal sealed partial class MemberSignatureParser
{
internal static RequestSignature Parse(string signature)
{
var scanner = new Scanner(signature);
var builder = ImmutableArray.CreateBuilder<Token>();
Token token;
do
{
scanner.MoveNext();
token = scanner.CurrentToken;
builder.Add(token);
} while (token.Kind != TokenKind.End);
var parser = new MemberSignatureParser(builder.ToImmutable());
try
{
return parser.Parse();
}
catch (InvalidSignatureException)
{
return null;
}
}
private readonly ImmutableArray<Token> _tokens;
private int _tokenIndex;
private MemberSignatureParser(ImmutableArray<Token> tokens)
{
_tokens = tokens;
_tokenIndex = 0;
}
private Token CurrentToken => _tokens[_tokenIndex];
private Token PeekToken(int offset)
{
return _tokens[_tokenIndex + offset];
}
private Token EatToken()
{
var token = CurrentToken;
Debug.Assert(token.Kind != TokenKind.End);
_tokenIndex++;
return token;
}
private RequestSignature Parse()
{
var methodName = ParseName();
var parameters = default(ImmutableArray<ParameterSignature>);
if (CurrentToken.Kind == TokenKind.OpenParen)
{
parameters = ParseParameters();
}
if (CurrentToken.Kind != TokenKind.End)
{
throw InvalidSignature();
}
return new RequestSignature(methodName, parameters);
}
private Name ParseName()
{
Name signature = null;
while (true)
{
if (CurrentToken.Kind != TokenKind.Identifier)
{
throw InvalidSignature();
}
var name = EatToken().Text;
signature = new QualifiedName(signature, name);
if (CurrentToken.Kind == TokenKind.LessThan)
{
var typeParameters = ParseTypeParameters();
signature = new GenericName((QualifiedName)signature, typeParameters);
}
if (CurrentToken.Kind != TokenKind.Dot)
{
return signature;
}
EatToken();
}
}
private ImmutableArray<string> ParseTypeParameters()
{
Debug.Assert(CurrentToken.Kind == TokenKind.LessThan);
EatToken();
var builder = ImmutableArray.CreateBuilder<string>();
while (true)
{
if (CurrentToken.Kind != TokenKind.Identifier)
{
throw InvalidSignature();
}
var name = EatToken().Text;
builder.Add(name);
switch (CurrentToken.Kind)
{
case TokenKind.GreaterThan:
EatToken();
return builder.ToImmutable();
case TokenKind.Comma:
EatToken();
break;
default:
throw InvalidSignature();
}
}
}
private TypeSignature ParseTypeName()
{
TypeSignature signature = null;
while (true)
{
switch (CurrentToken.Kind)
{
case TokenKind.Identifier:
{
var token = EatToken();
var name = token.Text;
signature = new QualifiedTypeSignature(signature, name);
}
break;
case TokenKind.Keyword:
if (signature == null)
{
// Expand special type keywords (object, int, etc.) to qualified names.
// This is only done for the first identifier in a qualified name.
var specialType = GetSpecialType(CurrentToken.KeywordKind);
if (specialType != SpecialType.None)
{
EatToken();
signature = specialType.GetTypeSignature();
Debug.Assert(signature != null);
}
if (signature != null)
{
break;
}
}
throw InvalidSignature();
default:
throw InvalidSignature();
}
if (CurrentToken.Kind == TokenKind.LessThan)
{
var typeArguments = ParseTypeArguments();
signature = new GenericTypeSignature((QualifiedTypeSignature)signature, typeArguments);
}
if (CurrentToken.Kind != TokenKind.Dot)
{
return signature;
}
EatToken();
}
}
private ImmutableArray<TypeSignature> ParseTypeArguments()
{
Debug.Assert(CurrentToken.Kind == TokenKind.LessThan);
EatToken();
var builder = ImmutableArray.CreateBuilder<TypeSignature>();
while (true)
{
var name = ParseType();
builder.Add(name);
switch (CurrentToken.Kind)
{
case TokenKind.GreaterThan:
EatToken();
return builder.ToImmutable();
case TokenKind.Comma:
EatToken();
break;
default:
throw InvalidSignature();
}
}
}
private TypeSignature ParseType()
{
TypeSignature type = ParseTypeName();
while (true)
{
switch (CurrentToken.Kind)
{
case TokenKind.OpenBracket:
EatToken();
int rank = 1;
while (CurrentToken.Kind == TokenKind.Comma)
{
EatToken();
rank++;
}
if (CurrentToken.Kind != TokenKind.CloseBracket)
{
throw InvalidSignature();
}
EatToken();
type = new ArrayTypeSignature(type, rank);
break;
case TokenKind.Asterisk:
EatToken();
type = new PointerTypeSignature(type);
break;
case TokenKind.QuestionMark:
EatToken();
type = new GenericTypeSignature(
SpecialType.System_Nullable_T.GetTypeSignature(),
ImmutableArray.Create(type));
break;
default:
return type;
}
}
}
// Returns true if the parameter is by reference.
private bool ParseParameterModifiers()
{
bool isByRef = false;
while (true)
{
var kind = CurrentToken.KeywordKind;
if (kind != SyntaxKind.RefKeyword && kind != SyntaxKind.OutKeyword)
{
break;
}
if (isByRef)
{
// Duplicate modifiers.
throw InvalidSignature();
}
isByRef = true;
EatToken();
}
return isByRef;
}
private ImmutableArray<ParameterSignature> ParseParameters()
{
Debug.Assert(CurrentToken.Kind == TokenKind.OpenParen);
EatToken();
if (CurrentToken.Kind == TokenKind.CloseParen)
{
EatToken();
return ImmutableArray<ParameterSignature>.Empty;
}
var builder = ImmutableArray.CreateBuilder<ParameterSignature>();
while (true)
{
bool isByRef = ParseParameterModifiers();
var parameterType = ParseType();
builder.Add(new ParameterSignature(parameterType, isByRef));
switch (CurrentToken.Kind)
{
case TokenKind.CloseParen:
EatToken();
return builder.ToImmutable();
case TokenKind.Comma:
EatToken();
break;
default:
throw InvalidSignature();
}
}
}
private static bool IsKeyword(string text)
{
return SyntaxFacts.GetKeywordKind(text) != SyntaxKind.None;
}
private static SpecialType GetSpecialType(SyntaxKind kind)
{
switch (kind)
{
case SyntaxKind.VoidKeyword:
return SpecialType.System_Void;
case SyntaxKind.BoolKeyword:
return SpecialType.System_Boolean;
case SyntaxKind.CharKeyword:
return SpecialType.System_Char;
case SyntaxKind.SByteKeyword:
return SpecialType.System_SByte;
case SyntaxKind.ByteKeyword:
return SpecialType.System_Byte;
case SyntaxKind.ShortKeyword:
return SpecialType.System_Int16;
case SyntaxKind.UShortKeyword:
return SpecialType.System_UInt16;
case SyntaxKind.IntKeyword:
return SpecialType.System_Int32;
case SyntaxKind.UIntKeyword:
return SpecialType.System_UInt32;
case SyntaxKind.LongKeyword:
return SpecialType.System_Int64;
case SyntaxKind.ULongKeyword:
return SpecialType.System_UInt64;
case SyntaxKind.FloatKeyword:
return SpecialType.System_Single;
case SyntaxKind.DoubleKeyword:
return SpecialType.System_Double;
case SyntaxKind.StringKeyword:
return SpecialType.System_String;
case SyntaxKind.ObjectKeyword:
return SpecialType.System_Object;
case SyntaxKind.DecimalKeyword:
return SpecialType.System_Decimal;
default:
return SpecialType.None;
}
}
private static Exception InvalidSignature()
{
return new InvalidSignatureException();
}
private sealed class InvalidSignatureException : Exception
{
}
}
}
// 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 Roslyn.Utilities;
using System;
using System.Diagnostics;
namespace Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator
{
internal sealed partial class MemberSignatureParser
{
private enum TokenKind
{
OpenParen = '(',
CloseParen = ')',
OpenBracket = '[',
CloseBracket = ']',
Dot = '.',
Comma = ',',
Asterisk = '*',
QuestionMark = '?',
LessThan = '<',
GreaterThan = '>',
Start = char.MaxValue + 1,
End,
Identifier,
Keyword,
ColonColon,
}
[DebuggerDisplay("{GetDebuggerDisplay(), nq}")]
private struct Token
{
internal readonly TokenKind Kind;
internal readonly string Text;
internal readonly SyntaxKind KeywordKind;
internal Token(TokenKind kind, string text = null, SyntaxKind keywordKind = SyntaxKind.None)
{
Kind = kind;
Text = text;
KeywordKind = keywordKind;
}
private string GetDebuggerDisplay()
{
return (Text == null) ?
Kind.ToString() :
$"{Kind}: \"{Text}\"";
}
}
private sealed class Scanner
{
private readonly string _text;
private int _offset;
private Token _currentToken;
internal Scanner(string text)
{
_text = text;
_offset = 0;
_currentToken = default(Token);
}
internal Token CurrentToken
{
get
{
if (_currentToken.Kind == TokenKind.Start)
{
throw new InvalidOperationException();
}
return _currentToken;
}
}
internal void MoveNext()
{
_currentToken = Scan();
}
private Token Scan()
{
int length = _text.Length;
while (_offset < length && char.IsWhiteSpace(_text[_offset]))
{
_offset++;
}
if (_offset == length)
{
return new Token(TokenKind.End);
}
var c = _text[_offset++];
if (UnicodeCharacterUtilities.IsIdentifierStartCharacter(c))
{
return ScanIdentifierAfterStartCharacter(verbatim: false);
}
else if (c == '@' && _offset < length && UnicodeCharacterUtilities.IsIdentifierStartCharacter(_text[_offset]))
{
_offset++;
return ScanIdentifierAfterStartCharacter(verbatim: true);
}
return new Token((TokenKind)c);
}
private Token ScanIdentifierAfterStartCharacter(bool verbatim)
{
// Assert the offset is immediately following the start character.
Debug.Assert(_offset > 0);
Debug.Assert(UnicodeCharacterUtilities.IsIdentifierStartCharacter(_text[_offset - 1]));
Debug.Assert(_offset == 1 || !UnicodeCharacterUtilities.IsIdentifierPartCharacter(_text[_offset - 2]));
int length = _text.Length;
int start = _offset - 1;
while ((_offset < length) && UnicodeCharacterUtilities.IsIdentifierPartCharacter(_text[_offset]))
{
_offset++;
}
var text = _text.Substring(start, _offset - start);
var keywordKind = verbatim ?
SyntaxKind.None :
SyntaxFacts.GetKeywordKind(text);
if (keywordKind == SyntaxKind.None)
{
return new Token(TokenKind.Identifier, text);
}
return new Token(TokenKind.Keyword, text, keywordKind);
}
}
}
}
// 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 Microsoft.VisualStudio.Debugger;
using Microsoft.VisualStudio.Debugger.Clr;
using Microsoft.VisualStudio.Debugger.ComponentInterfaces;
using Microsoft.VisualStudio.Debugger.Evaluation;
using Microsoft.VisualStudio.Debugger.FunctionResolution;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Reflection.Metadata;
namespace Microsoft.CodeAnalysis.ExpressionEvaluator
{
internal abstract class FunctionResolver :
FunctionResolverBase<DkmProcess, DkmClrModuleInstance, DkmRuntimeFunctionResolutionRequest>,
IDkmRuntimeFunctionResolver,
IDkmModuleInstanceLoadNotification,
IDkmModuleInstanceUnloadNotification,
IDkmModuleModifiedNotification
{
void IDkmRuntimeFunctionResolver.EnableResolution(DkmRuntimeFunctionResolutionRequest request, DkmWorkList workList)
{
if (request.LineOffset > 0)
{
return;
}
var languageId = request.CompilerId.LanguageId;
if (languageId == DkmLanguageId.MethodId)
{
return;
}
else if (languageId != default(Guid))
{
// Verify module matches language before binding
// (see https://github.com/dotnet/roslyn/issues/15119).
}
EnableResolution(request.Process, request);
}
void IDkmModuleInstanceLoadNotification.OnModuleInstanceLoad(DkmModuleInstance moduleInstance, DkmWorkList workList, DkmEventDescriptorS eventDescriptor)
{
var module = moduleInstance as DkmClrModuleInstance;
Debug.Assert(module != null); // <Filter><RuntimeId RequiredValue="DkmRuntimeId.Clr"/></Filter> should ensure this.
if (module == null)
{
// Only interested in managed modules.
return;
}
OnModuleLoad(module.Process, module);
}
void IDkmModuleInstanceUnloadNotification.OnModuleInstanceUnload(DkmModuleInstance moduleInstance, DkmWorkList workList, DkmEventDescriptor eventDescriptor)
{
// Implementing IDkmModuleInstanceUnloadNotification
// (with Synchronized="true" in .vsdconfigxml) prevents
// caller from unloading modules while binding.
}
void IDkmModuleModifiedNotification.OnModuleModified(DkmModuleInstance moduleInstance)
{
// Implementing IDkmModuleModifiedNotification
// (with Synchronized="true" in .vsdconfigxml) prevents
// caller from modifying modules while binding.
}
internal override bool ShouldEnableFunctionResolver(DkmProcess process)
{
var dataItem = process.GetDataItem<FunctionResolverDataItem>();
if (dataItem == null)
{
var enable = ShouldEnable(process);
dataItem = new FunctionResolverDataItem(enable);
process.SetDataItem(DkmDataCreationDisposition.CreateNew, dataItem);
}
return dataItem.Enabled;
}
internal override IEnumerable<DkmClrModuleInstance> GetAllModules(DkmProcess process)
{
foreach (var runtimeInstance in process.GetRuntimeInstances())
{
var runtime = runtimeInstance as DkmClrRuntimeInstance;
if (runtime == null)
{
continue;
}
foreach (var moduleInstance in runtime.GetModuleInstances())
{
var module = moduleInstance as DkmClrModuleInstance;
// Only interested in managed modules.
if (module != null)
{
yield return module;
}
}
}
}
internal override string GetModuleName(DkmClrModuleInstance module)
{
return module.Name;
}
internal override MetadataReader GetModuleMetadata(DkmClrModuleInstance module)
{
uint length;
IntPtr ptr;
try
{
ptr = module.GetMetaDataBytesPtr(out length);
}
catch (Exception e) when (IsBadOrMissingMetadataException(e))
{
return null;
}
Debug.Assert(length > 0);
unsafe
{
return new MetadataReader((byte*)ptr, (int)length);
}
}
internal override DkmRuntimeFunctionResolutionRequest[] GetRequests(DkmProcess process)
{
return process.GetRuntimeFunctionResolutionRequests();
}
internal override string GetRequestModuleName(DkmRuntimeFunctionResolutionRequest request)
{
return request.ModuleName;
}
internal override void OnFunctionResolved(
DkmClrModuleInstance module,
DkmRuntimeFunctionResolutionRequest request,
int token,
int version,
int ilOffset)
{
var address = DkmClrInstructionAddress.Create(
module.RuntimeInstance,
module,
new DkmClrMethodId(Token: token, Version: (uint)version),
NativeOffset: uint.MaxValue,
ILOffset: (uint)ilOffset,
CPUInstruction: null);
request.OnFunctionResolved(address);
}
private static readonly Guid s_messageSourceId = new Guid("ac353c9b-c599-427b-9424-cbe1ad19f81e");
private static bool ShouldEnable(DkmProcess process)
{
var message = DkmCustomMessage.Create(
process.Connection,
process,
s_messageSourceId,
MessageCode: 1, // Is legacy EE enabled?
Parameter1: null,
Parameter2: null);
try
{
var reply = message.SendLower();
var result = (int)reply.Parameter1;
// Possible values are 0 = false, 1 = true, 2 = not ready.
// At this point, we should only get 0 or 1, but to be
// safe, treat values other than 0 or 1 as false.
Debug.Assert(result == 0 || result == 1);
return result == 0;
}
catch (NotImplementedException)
{
return false;
}
}
private const uint COR_E_BADIMAGEFORMAT = 0x8007000b;
private const uint CORDBG_E_MISSING_METADATA = 0x80131c35;
private static bool IsBadOrMissingMetadataException(Exception e)
{
switch (unchecked((uint)e.HResult))
{
case COR_E_BADIMAGEFORMAT:
case CORDBG_E_MISSING_METADATA:
return true;
default:
return false;
}
}
private sealed class FunctionResolverDataItem : DkmDataItem
{
internal FunctionResolverDataItem(bool enabled)
{
Enabled = enabled;
}
internal readonly bool Enabled;
}
}
}
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\..\..\build\Targets\Settings.props" />
<PropertyGroup>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{6FC8E6F5-659C-424D-AEB5-331B95883E29}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>Microsoft.CodeAnalysis.ExpressionEvaluator</RootNamespace>
<AssemblyName>Microsoft.CodeAnalysis.ExpressionEvaluator.FunctionResolver</AssemblyName>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworkIdentifier>.NETPortable</TargetFrameworkIdentifier>
<TargetFrameworkVersion>v5.0</TargetFrameworkVersion>
<ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<CopyNuGetImplementations>false</CopyNuGetImplementations>
</PropertyGroup>
<ItemGroup>
<Compile Include="..\..\..\..\Compilers\Core\Portable\InternalUtilities\ExceptionUtilities.cs">
<Link>Compiler\ExceptionUtilities.cs</Link>
</Compile>
<Compile Include="..\..\..\..\Compilers\Core\Portable\MetadataReader\MetadataTypeCodeExtensions.cs">
<Link>Compiler\MetadataTypeCodeExtensions.cs</Link>
</Compile>
<Compile Include="..\..\..\..\Compilers\Core\Portable\SpecialType.cs">
<Link>Compiler\SpecialType.cs</Link>
</Compile>
<Compile Include="..\..\..\..\Compilers\Core\Portable\Symbols\WellKnownMemberNames.cs">
<Link>Compiler\WellKnownMemberNames.cs</Link>
</Compile>
<Compile Include="..\..\..\..\Compilers\Core\Portable\InternalUtilities\UnicodeCharacterUtilities.cs">
<Link>Compiler\UnicodeCharacterUtilities.cs</Link>
</Compile>
<Compile Include="..\..\..\..\Compilers\CSharp\Portable\Syntax\SyntaxKind.cs">
<Link>CSharp\Compiler\SyntaxKind.cs</Link>
</Compile>
<Compile Include="..\..\..\..\Compilers\CSharp\Portable\Syntax\SyntaxKindFacts.cs">
<Link>CSharp\Compiler\SyntaxKindFacts.cs</Link>
</Compile>
<Compile Include="CSharp\CSharpFunctionResolver.cs" />
<Compile Include="CSharp\GreenNode.cs" />
<Compile Include="CSharp\MemberSignatureParser.cs" />
<Compile Include="CSharp\Scanner.cs" />
<Compile Include="FunctionResolver.cs" />
<Compile Include="FunctionResolverBase.cs" />
<Compile Include="MetadataDecoder.cs" />
<Compile Include="MetadataResolver.cs" />
<Compile Include="Name.cs" />
<Compile Include="ParameterSignature.cs" />
<Compile Include="RequestSignature.cs" />
<Compile Include="SpecialTypeExtensions.cs" />
<Compile Include="TypeSignature.cs" />
<VsdConfigXml Include="FunctionResolver.vsdconfigxml" />
</ItemGroup>
<ItemGroup Label="Project References">
<ProjectReference Include="..\Concord\Concord.csproj">
<Project>{5002636a-fe8d-40bf-8818-ab513a2194fa}</Project>
<Name>Concord</Name>
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
</ItemGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' " />
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' " />
<ItemGroup>
<InternalsVisibleToTest Include="Roslyn.ExpressionEvaluator.FunctionResolver.UnitTests" />
</ItemGroup>
<ItemGroup>
<None Include="project.json" />
</ItemGroup>
<Import Project="..\..\..\..\Tools\Vsdconfig\Vsdconfig.targets" />
<Import Project="..\..\..\..\..\build\Targets\Imports.targets" />
</Project>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
-->
<Configuration xmlns="http://schemas.microsoft.com/vstudio/vsdconfig/2008">
<DefineGuid Name="CSharpFunctionResolverId" Value="CFE62047-C343-4DE4-B31E-88B7AFF8E7F7"/>
<ManagedComponent
ComponentId="CSharpFunctionResolverId"
ComponentLevel="65100"
Synchronized="true"
AssemblyName="Microsoft.CodeAnalysis.ExpressionEvaluator.FunctionResolver">
<Class Name="Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator.CSharpFunctionResolver">
<Implements>
<InterfaceGroup Priority="Normal">
<Filter>
<BaseDebugMonitorId RequiredValue="DkmBaseDebugMonitorId.InProcessManagedNativeInterop"/>
<BaseDebugMonitorId RequiredValue="DkmBaseDebugMonitorId.ClrVirtualMachine"/>
</Filter>
<Interface Name="IDkmRuntimeFunctionResolver"/>
</InterfaceGroup>
<InterfaceGroup CallOnlyWhenLoaded="true" Priority="Normal">
<Filter>
<RuntimeId RequiredValue="DkmRuntimeId.Clr"/>
<RuntimeId RequiredValue="DkmRuntimeId.ClrNativeCompilation"/>
</Filter>
<Interface Name="IDkmModuleInstanceLoadNotification"/>
<Interface Name="IDkmModuleInstanceUnloadNotification"/>
<Interface Name="IDkmModuleModifiedNotification"/>
</InterfaceGroup>
</Implements>
</Class>
</ManagedComponent>
</Configuration>
\ 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.
using System;
using System.Collections.Generic;
using System.Reflection.Metadata;
namespace Microsoft.CodeAnalysis.ExpressionEvaluator
{
internal abstract class FunctionResolverBase<TProcess, TModule, TRequest>
where TProcess : class
where TModule : class
where TRequest : class
{
internal void EnableResolution(TProcess process, TRequest request)
{
ResolveRequest(process, request);
}
internal void OnModuleLoad(TProcess process, TModule module)
{
var requests = GetRequests(process);
ResolveRequests(process, module, requests);
}
internal abstract bool ShouldEnableFunctionResolver(TProcess process);
internal abstract IEnumerable<TModule> GetAllModules(TProcess process);
internal abstract string GetModuleName(TModule module);
internal abstract MetadataReader GetModuleMetadata(TModule module);
internal abstract TRequest[] GetRequests(TProcess process);
internal abstract string GetRequestModuleName(TRequest request);
internal abstract RequestSignature GetParsedSignature(TRequest request);
internal abstract void OnFunctionResolved(TModule module, TRequest request, int token, int version, int ilOffset);
private void ResolveRequest(TProcess process, TRequest request)
{
var moduleName = GetRequestModuleName(request);
var signature = GetParsedSignature(request);
if (signature == null)
{
return;
}
bool checkEnabled = true;
foreach (var module in GetAllModules(process))
{
if (checkEnabled)
{
if (!ShouldEnableFunctionResolver(process))
{
return;
}
checkEnabled = false;
}
if (!ShouldModuleHandleRequest(module, moduleName))
{
continue;
}
var reader = GetModuleMetadata(module);
if (reader == null)
{
continue;
}
var resolver = new MetadataResolver<TProcess, TModule, TRequest>(this, process, module, reader);
resolver.Resolve(request, signature);
}
}
private void ResolveRequests(TProcess process, TModule module, TRequest[] requests)
{
if (!ShouldEnableFunctionResolver(process))
{
return;
}
MetadataResolver<TProcess, TModule, TRequest> resolver = null;
foreach (var request in requests)
{
var moduleName = GetRequestModuleName(request);
if (!ShouldModuleHandleRequest(module, moduleName))
{
continue;
}
var signature = GetParsedSignature(request);
if (signature == null)
{
continue;
}
if (resolver == null)
{
var reader = GetModuleMetadata(module);
if (reader == null)
{
return;
}
resolver = new MetadataResolver<TProcess, TModule, TRequest>(this, process, module, reader);
}
resolver.Resolve(request, signature);
}
}
private bool ShouldModuleHandleRequest(TModule module, string moduleName)
{
if (string.IsNullOrEmpty(moduleName))
{
return true;
}
var name = GetModuleName(module);
return moduleName.Equals(name, StringComparison.OrdinalIgnoreCase);
}
}
}
// 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.Immutable;
using System.Reflection.Metadata;
namespace Microsoft.CodeAnalysis.ExpressionEvaluator
{
internal struct MetadataDecoder
{
private readonly MetadataReader _reader;
private readonly ImmutableArray<string> _allTypeParameters;
private readonly int _containingArity;
private readonly ImmutableArray<string> _methodTypeParameters;
internal MetadataDecoder(
MetadataReader reader,
ImmutableArray<string> allTypeParameters,
int containingArity,
ImmutableArray<string> methodTypeParameters)
{
_reader = reader;
_allTypeParameters = allTypeParameters;
_containingArity = containingArity;
_methodTypeParameters = methodTypeParameters;
}
// cf. MetadataDecoder<>.GetSignatureForMethod.
internal ImmutableArray<ParameterSignature> DecodeParameters(MethodDefinition methodDef)
{
var signatureReader = _reader.GetBlobReader(methodDef.Signature);
var signatureHeader = signatureReader.ReadSignatureHeader();
var typeParameterCount = signatureHeader.IsGeneric ? signatureReader.ReadCompressedInteger() : 0;
var parameterCount = signatureReader.ReadCompressedInteger();
var builder = ImmutableArray.CreateBuilder<ParameterSignature>(parameterCount);
var returnType = DecodeParameter(ref signatureReader);
for (int i = 0; i < parameterCount; i++)
{
builder.Add(DecodeParameter(ref signatureReader));
}
return builder.ToImmutable();
}
// cf. MetadataDecoder<>.DecodeParameterOrThrow.
private ParameterSignature DecodeParameter(ref BlobReader signatureReader)
{
bool isByRef = false;
while (true)
{
var typeCode = signatureReader.ReadSignatureTypeCode();
switch (typeCode)
{
case SignatureTypeCode.RequiredModifier:
case SignatureTypeCode.OptionalModifier:
// Skip modifiers.
break;
case SignatureTypeCode.ByReference:
isByRef = true;
break;
default:
var type = DecodeType(ref signatureReader, typeCode);
return new ParameterSignature(type, isByRef);
}
}
}
// cf. MetadataDecoder<>.DecodeTypeOrThrow.
private TypeSignature DecodeType(ref BlobReader signatureReader, SignatureTypeCode typeCode)
{
switch (typeCode)
{
case SignatureTypeCode.TypeHandle:
{
int typeArgumentOffset = 0;
return DecodeType(signatureReader.ReadTypeHandle(), ImmutableArray<TypeSignature>.Empty, ref typeArgumentOffset);
}
case SignatureTypeCode.Array:
{
var elementType = DecodeModifiersAndType(ref signatureReader);
int rank;
int sizes;
signatureReader.TryReadCompressedInteger(out rank);
signatureReader.TryReadCompressedInteger(out sizes);
if (sizes != 0)
{
throw UnhandledMetadata();
}
return new ArrayTypeSignature(elementType, rank);
}
case SignatureTypeCode.SZArray:
{
var elementType = DecodeModifiersAndType(ref signatureReader);
return new ArrayTypeSignature(elementType, 1);
}
case SignatureTypeCode.GenericTypeInstance:
return DecodeGenericTypeInstance(ref signatureReader);
case SignatureTypeCode.Pointer:
{
var pointedAtType = DecodeModifiersAndType(ref signatureReader);
return new PointerTypeSignature(pointedAtType);
}
case SignatureTypeCode.GenericTypeParameter:
return DecodeGenericTypeParameter(ref signatureReader, _allTypeParameters, _containingArity);
case SignatureTypeCode.GenericMethodParameter:
return DecodeGenericTypeParameter(ref signatureReader, _methodTypeParameters, 0);
default:
{
var signature = typeCode.ToSpecialType().GetTypeSignature();
if (signature == null)
{
throw UnhandledMetadata();
}
return signature;
}
}
}
// Ignore modifiers and decode type.
private TypeSignature DecodeModifiersAndType(ref BlobReader signatureReader)
{
while (true)
{
var typeCode = signatureReader.ReadSignatureTypeCode();
switch (typeCode)
{
case SignatureTypeCode.RequiredModifier:
case SignatureTypeCode.OptionalModifier:
// Skip modifiers.
break;
default:
return DecodeType(ref signatureReader, typeCode);
}
}
}
private TypeSignature DecodeGenericTypeParameter(
ref BlobReader signatureReader,
ImmutableArray<string> typeParameters,
int containingArity)
{
int index = signatureReader.ReadCompressedInteger();
if (index < containingArity)
{
// Unspecified type parameter.
throw UnhandledMetadata();
}
var name = typeParameters[index - containingArity];
return new QualifiedTypeSignature(null, name);
}
// cf. MetadataDecoder<>.DecodeGenericTypeInstanceOrThrow.
private TypeSignature DecodeGenericTypeInstance(ref BlobReader signatureReader)
{
var typeCode = signatureReader.ReadSignatureTypeCode();
var typeHandle = signatureReader.ReadTypeHandle();
var typeArguments = DecodeGenericTypeArguments(ref signatureReader);
int typeArgumentOffset = 0;
var type = DecodeType(typeHandle, typeArguments, ref typeArgumentOffset);
if (typeArgumentOffset != typeArguments.Length)
{
// Generic type reference names must include arity
// to avoid loading referenced assemblies.
throw UnhandledMetadata();
}
return type;
}
private ImmutableArray<TypeSignature> DecodeGenericTypeArguments(ref BlobReader signatureReader)
{
int typeArgCount;
signatureReader.TryReadCompressedInteger(out typeArgCount);
var builder = ImmutableArray.CreateBuilder<TypeSignature>(typeArgCount);
for (int i = 0; i < typeArgCount; i++)
{
var typeArg = DecodeModifiersAndType(ref signatureReader);
builder.Add(typeArg);
}
return builder.ToImmutable();
}
// cf. MetadataDecoder<>.GetSymbolForTypeHandleOrThrow.
private TypeSignature DecodeType(
EntityHandle handle,
ImmutableArray<TypeSignature> typeArguments,
ref int typeArgumentOffset)
{
switch (handle.Kind)
{
case HandleKind.TypeDefinition:
return DecodeTypeDefinition((TypeDefinitionHandle)handle, typeArguments, ref typeArgumentOffset);
case HandleKind.TypeReference:
return DecodeTypeReference((TypeReferenceHandle)handle, typeArguments, ref typeArgumentOffset);
default:
throw new BadImageFormatException();
}
}
// cf. MetadataDecoder<>.GetTypeOfTypeDef.
private TypeSignature DecodeTypeDefinition(
TypeDefinitionHandle handle,
ImmutableArray<TypeSignature> typeArguments,
ref int typeArgumentOffset)
{
var typeDef = _reader.GetTypeDefinition(handle);
TypeSignature qualifier;
var declaringTypeHandle = typeDef.GetDeclaringType();
if (declaringTypeHandle.IsNil)
{
// Include namespace.
qualifier = GetNamespace(typeDef.Namespace);
}
else
{
// Include declaring type.
qualifier = DecodeTypeDefinition(declaringTypeHandle, typeArguments, ref typeArgumentOffset);
}
return CreateTypeSignature(qualifier, _reader.GetString(typeDef.Name), typeArguments, ref typeArgumentOffset);
}
// cf. MetadataDecoder<>.GetTypeOfTypeRef.
private TypeSignature DecodeTypeReference(
TypeReferenceHandle handle,
ImmutableArray<TypeSignature> typeArguments,
ref int typeArgumentOffset)
{
var typeRef = _reader.GetTypeReference(handle);
TypeSignature qualifier;
var scope = typeRef.ResolutionScope;
switch (scope.Kind)
{
case HandleKind.AssemblyReference:
case HandleKind.ModuleReference:
// Include namespace.
qualifier = GetNamespace(typeRef.Namespace);
break;
case HandleKind.TypeReference:
// Include declaring type.
qualifier = DecodeTypeReference((TypeReferenceHandle)scope, typeArguments, ref typeArgumentOffset);
break;
default:
throw new BadImageFormatException();
}
return CreateTypeSignature(qualifier, _reader.GetString(typeRef.Name), typeArguments, ref typeArgumentOffset);
}
private string GetTypeName(StringHandle nameHandle, out int arity)
{
return RemoveAritySeparatorIfAny(_reader.GetString(nameHandle), out arity);
}
private QualifiedTypeSignature GetNamespace(StringHandle namespaceHandle)
{
var namespaceName = _reader.GetString(namespaceHandle);
if (string.IsNullOrEmpty(namespaceName))
{
return null;
}
QualifiedTypeSignature signature = null;
var parts = namespaceName.Split('.');
foreach (var part in parts)
{
signature = new QualifiedTypeSignature(signature, part);
}
return signature;
}
private static TypeSignature CreateTypeSignature(
TypeSignature qualifier,
string typeName,
ImmutableArray<TypeSignature> typeArguments,
ref int typeArgumentOffset)
{
int arity;
typeName = RemoveAritySeparatorIfAny(typeName, out arity);
var qualifiedName = new QualifiedTypeSignature(qualifier, typeName);
if (arity == 0)
{
return qualifiedName;
}
typeArguments = ImmutableArray.Create(typeArguments, typeArgumentOffset, arity);
typeArgumentOffset += arity;
return new GenericTypeSignature(qualifiedName, typeArguments);
}
private static string RemoveAritySeparatorIfAny(string typeName, out int arity)
{
arity = 0;
int index = typeName.LastIndexOf('`');
if (index < 0)
{
return typeName;
}
int n;
if (int.TryParse(typeName.Substring(index + 1), out n))
{
arity = n;
}
return typeName.Substring(0, index);
}
private static Exception UnhandledMetadata()
{
return new NotSupportedException();
}
}
}
// 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 Roslyn.Utilities;
using System;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Reflection.Metadata;
using System.Reflection.Metadata.Ecma335;
namespace Microsoft.CodeAnalysis.ExpressionEvaluator
{
internal sealed class MetadataResolver<TProcess, TModule, TRequest>
where TProcess : class
where TModule : class
where TRequest : class
{
private static readonly StringComparer s_stringComparer = StringComparer.Ordinal;
private readonly FunctionResolverBase<TProcess, TModule, TRequest> _resolver;
private readonly TProcess _process;
private readonly TModule _module;
private readonly MetadataReader _reader;
internal MetadataResolver(
FunctionResolverBase<TProcess, TModule, TRequest> resolver,
TProcess process,
TModule module,
MetadataReader reader)
{
_resolver = resolver;
_process = process;
_module = module;
_reader = reader;
}
internal void Resolve(TRequest request, RequestSignature signature)
{
QualifiedName qualifiedTypeName;
ImmutableArray<string> memberTypeParameters;
GetNameAndTypeParameters(signature.MemberName, out qualifiedTypeName, out memberTypeParameters);
var typeName = qualifiedTypeName.Qualifier;
var memberName = qualifiedTypeName.Name;
var memberParameters = signature.Parameters;
var allTypeParameters = GetAllGenericTypeParameters(typeName);
foreach (var typeHandle in _reader.TypeDefinitions)
{
var typeDef = _reader.GetTypeDefinition(typeHandle);
int containingArity = CompareToTypeDefinition(typeDef, typeName);
if (containingArity < 0)
{
continue;
}
// Visit methods.
foreach (var methodHandle in typeDef.GetMethods())
{
var methodDef = _reader.GetMethodDefinition(methodHandle);
if (!IsResolvableMethod(methodDef))
{
continue;
}
if (MatchesMethod(typeDef, methodDef, typeName, memberName, allTypeParameters, containingArity, memberTypeParameters, memberParameters))
{
OnFunctionResolved(request, methodHandle);
}
}
if (memberTypeParameters.IsEmpty)
{
// Visit properties.
foreach (var propertyHandle in typeDef.GetProperties())
{
var propertyDef = _reader.GetPropertyDefinition(propertyHandle);
if (MatchesProperty(typeDef, propertyDef, typeName, memberName, allTypeParameters, containingArity, memberParameters))
{
var accessors = propertyDef.GetAccessors();
OnAccessorResolved(request, accessors.Getter);
OnAccessorResolved(request, accessors.Setter);
}
}
}
}
}
// If the signature matches the TypeDefinition, including some or all containing
// types and namespaces, returns a non-negative value indicating the arity of the
// containing types that were not specified in the signature; otherwise returns -1.
// For instance, "C<T>.D" will return 1 matching against metadata type N.M.A<T>.B.C<U>.D,
// where N.M is a namespace and A<T>, B, C<U>, D are nested types. The value 1
// is the arity of the containing types A<T>.B that were missing from the signature.
// "C<T>.D" will not match C<T> or C<T>.D.E since the match must include the entire
// signature, from nested TypeDefinition, out.
private int CompareToTypeDefinition(TypeDefinition typeDef, Name signature)
{
if (signature == null)
{
return typeDef.GetGenericParameters().Count;
}
QualifiedName qualifiedName;
ImmutableArray<string> typeParameters;
GetNameAndTypeParameters(signature, out qualifiedName, out typeParameters);
if (!MatchesTypeName(typeDef, qualifiedName.Name))
{
return -1;
}
var declaringTypeHandle = typeDef.GetDeclaringType();
var declaringType = declaringTypeHandle.IsNil ? default(TypeDefinition) : _reader.GetTypeDefinition(declaringTypeHandle);
int declaringTypeParameterCount = declaringTypeHandle.IsNil ? 0 : declaringType.GetGenericParameters().Count;
if (!MatchesTypeParameterCount(typeParameters, typeDef.GetGenericParameters(), declaringTypeParameterCount))
{
return -1;
}
var qualifier = qualifiedName.Qualifier;
if (declaringTypeHandle.IsNil)
{
// Compare namespace.
return MatchesNamespace(typeDef, qualifier) ? 0 : -1;
}
else
{
// Compare declaring type.
return CompareToTypeDefinition(declaringType, qualifier);
}
}
private bool MatchesNamespace(TypeDefinition typeDef, Name signature)
{
if (signature == null)
{
return true;
}
var namespaceName = _reader.GetString(typeDef.Namespace);
if (string.IsNullOrEmpty(namespaceName))
{
return false;
}
var parts = namespaceName.Split('.');
for (int index = parts.Length - 1; index >= 0; index--)
{
if (signature == null)
{
return true;
}
var qualifiedName = signature as QualifiedName;
if (qualifiedName == null)
{
return false;
}
var part = parts[index];
if (!s_stringComparer.Equals(qualifiedName.Name, part))
{
return false;
}
signature = qualifiedName.Qualifier;
}
return signature == null;
}
private bool MatchesTypeName(TypeDefinition typeDef, string name)
{
var typeName = RemoveAritySeparatorIfAny(_reader.GetString(typeDef.Name));
return s_stringComparer.Equals(typeName, name);
}
private bool MatchesMethod(
TypeDefinition typeDef,
MethodDefinition methodDef,
Name typeName,
string methodName,
ImmutableArray<string> allTypeParameters,
int containingArity,
ImmutableArray<string> methodTypeParameters,
ImmutableArray<ParameterSignature> methodParameters)
{
if ((methodDef.Attributes & MethodAttributes.RTSpecialName) != 0)
{
if (!_reader.StringComparer.Equals(methodDef.Name, ".ctor"))
{
// Unhandled special name.
return false;
}
if (!MatchesTypeName(typeDef, methodName))
{
return false;
}
}
else if (!_reader.StringComparer.Equals(methodDef.Name, methodName))
{
return false;
}
if (!MatchesTypeParameterCount(methodTypeParameters, methodDef.GetGenericParameters(), offset: 0))
{
return false;
}
if (methodParameters.IsDefault)
{
return true;
}
return MatchesParameters(methodDef, allTypeParameters, containingArity, methodTypeParameters, methodParameters);
}
private bool MatchesProperty(
TypeDefinition typeDef,
PropertyDefinition propertyDef,
Name typeName,
string propertyName,
ImmutableArray<string> allTypeParameters,
int containingArity,
ImmutableArray<ParameterSignature> propertyParameters)
{
if (!_reader.StringComparer.Equals(propertyDef.Name, propertyName))
{
return false;
}
if (propertyParameters.IsDefault)
{
return true;
}
if (propertyParameters.Length == 0)
{
// Parameter-less properties should be specified
// with no parameter list.
return false;
}
// Match parameters against getter. Not supporting
// matching against setter for write-only properties.
var methodHandle = propertyDef.GetAccessors().Getter;
if (methodHandle.IsNil)
{
return false;
}
var methodDef = _reader.GetMethodDefinition(methodHandle);
return MatchesParameters(methodDef, allTypeParameters, containingArity, ImmutableArray<string>.Empty, propertyParameters);
}
private ImmutableArray<string> GetAllGenericTypeParameters(Name typeName)
{
var builder = ImmutableArray.CreateBuilder<string>();
GetAllGenericTypeParameters(typeName, builder);
return builder.ToImmutable();
}
private void GetAllGenericTypeParameters(Name typeName, ImmutableArray<string>.Builder builder)
{
if (typeName == null)
{
return;
}
QualifiedName qualifiedName;
ImmutableArray<string> typeParameters;
GetNameAndTypeParameters(typeName, out qualifiedName, out typeParameters);
GetAllGenericTypeParameters(qualifiedName.Qualifier, builder);
builder.AddRange(typeParameters);
}
private bool MatchesParameters(
MethodDefinition methodDef,
ImmutableArray<string> allTypeParameters,
int containingArity,
ImmutableArray<string> methodTypeParameters,
ImmutableArray<ParameterSignature> methodParameters)
{
ImmutableArray<ParameterSignature> parameters;
try
{
var decoder = new MetadataDecoder(_reader, allTypeParameters, containingArity, methodTypeParameters);
parameters = decoder.DecodeParameters(methodDef);
}
catch (NotSupportedException)
{
return false;
}
catch (BadImageFormatException)
{
return false;
}
return methodParameters.SequenceEqual(parameters, MatchesParameter);
}
private void OnFunctionResolved(
TRequest request,
MethodDefinitionHandle handle)
{
Debug.Assert(!handle.IsNil);
_resolver.OnFunctionResolved(_module, request, token: MetadataTokens.GetToken(handle), version: 1, ilOffset: 0);
}
private void OnAccessorResolved(
TRequest request,
MethodDefinitionHandle handle)
{
if (handle.IsNil)
{
return;
}
var methodDef = _reader.GetMethodDefinition(handle);
if (IsResolvableMethod(methodDef))
{
OnFunctionResolved(request, handle);
}
}
private static bool MatchesTypeParameterCount(ImmutableArray<string> typeArguments, GenericParameterHandleCollection typeParameters, int offset)
{
return typeArguments.Length == typeParameters.Count - offset;
}
// parameterA from string signature, parameterB from metadata.
private static bool MatchesParameter(ParameterSignature parameterA, ParameterSignature parameterB)
{
return MatchesType(parameterA.Type, parameterB.Type) &&
parameterA.IsByRef == parameterB.IsByRef;
}
// typeA from string signature, typeB from metadata.
private static bool MatchesType(TypeSignature typeA, TypeSignature typeB)
{
if (typeA.Kind != typeB.Kind)
{
return false;
}
switch (typeA.Kind)
{
case TypeSignatureKind.GenericType:
{
var genericA = (GenericTypeSignature)typeA;
var genericB = (GenericTypeSignature)typeB;
return MatchesType(genericA.QualifiedName, genericB.QualifiedName) &&
genericA.TypeArguments.SequenceEqual(genericB.TypeArguments, MatchesType);
}
case TypeSignatureKind.QualifiedType:
{
var qualifiedA = (QualifiedTypeSignature)typeA;
var qualifiedB = (QualifiedTypeSignature)typeB;
// Metadata signature may be more qualified than the
// string signature but still considered a match
// (e.g.: "B<U>.C" should match N.A<T>.B<U>.C).
return (qualifiedA.Qualifier == null || (qualifiedB.Qualifier != null && MatchesType(qualifiedA.Qualifier, qualifiedB.Qualifier))) &&
s_stringComparer.Equals(qualifiedA.Name, qualifiedB.Name);
}
case TypeSignatureKind.ArrayType:
{
var arrayA = (ArrayTypeSignature)typeA;
var arrayB = (ArrayTypeSignature)typeB;
return MatchesType(arrayA.ElementType, arrayB.ElementType) &&
arrayA.Rank == arrayB.Rank;
}
case TypeSignatureKind.PointerType:
{
var pointerA = (PointerTypeSignature)typeA;
var pointerB = (PointerTypeSignature)typeB;
return MatchesType(pointerA.PointedAtType, pointerB.PointedAtType);
}
default:
throw ExceptionUtilities.UnexpectedValue(typeA.Kind);
}
}
private static void GetNameAndTypeParameters(
Name name,
out QualifiedName qualifiedName,
out ImmutableArray<string> typeParameters)
{
switch (name.Kind)
{
case NameKind.GenericName:
{
var genericName = (GenericName)name;
qualifiedName = genericName.QualifiedName;
typeParameters = genericName.TypeParameters;
}
break;
case NameKind.QualifiedName:
{
qualifiedName = (QualifiedName)name;
typeParameters = ImmutableArray<string>.Empty;
}
break;
default:
throw ExceptionUtilities.UnexpectedValue(name.Kind);
}
}
private static bool IsResolvableMethod(MethodDefinition methodDef)
{
return (methodDef.Attributes & (MethodAttributes.Abstract | MethodAttributes.PinvokeImpl)) == 0;
}
private static string RemoveAritySeparatorIfAny(string typeName)
{
int index = typeName.LastIndexOf('`');
return (index < 0) ? typeName : typeName.Substring(0, index);
}
}
}
// 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.Collections.Immutable;
using System.Diagnostics;
using System.Text;
namespace Microsoft.CodeAnalysis.ExpressionEvaluator
{
internal enum NameKind
{
GenericName,
QualifiedName,
}
[DebuggerDisplay("{GetDebuggerDisplay(), nq}")]
internal abstract class Name
{
internal abstract NameKind Kind { get; }
internal abstract string GetDebuggerDisplay();
}
internal sealed class GenericName : Name
{
internal GenericName(QualifiedName qualifiedName, ImmutableArray<string> typeParameters)
{
Debug.Assert(qualifiedName != null);
Debug.Assert(!typeParameters.IsDefault);
QualifiedName = qualifiedName;
TypeParameters = typeParameters;
}
internal override NameKind Kind => NameKind.GenericName;
internal QualifiedName QualifiedName { get; }
internal ImmutableArray<string> TypeParameters { get; }
internal override string GetDebuggerDisplay()
{
var builder = new StringBuilder();
builder.Append(QualifiedName.GetDebuggerDisplay());
builder.Append('<');
bool any = false;
foreach (var typeParam in TypeParameters)
{
if (any)
{
builder.Append(", ");
}
builder.Append(typeParam);
any = true;
}
builder.Append('>');
return builder.ToString();
}
}
internal sealed class QualifiedName : Name
{
internal QualifiedName(Name qualifier, string name)
{
Debug.Assert(!string.IsNullOrEmpty(name));
Qualifier = qualifier;
Name = name;
}
internal override NameKind Kind => NameKind.QualifiedName;
internal Name Qualifier { get; }
internal string Name { get; }
internal override string GetDebuggerDisplay()
{
return (Qualifier == null) ? Name : $"{Qualifier.GetDebuggerDisplay()}.{Name}";
}
}
}
// Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
namespace Microsoft.CodeAnalysis.ExpressionEvaluator
{
internal sealed class ParameterSignature
{
internal ParameterSignature(TypeSignature type, bool isByRef)
{
Type = type;
IsByRef = isByRef;
}
internal readonly TypeSignature Type;
internal readonly bool IsByRef;
}
}
// 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.Collections.Immutable;
namespace Microsoft.CodeAnalysis.ExpressionEvaluator
{
internal sealed class RequestSignature
{
internal RequestSignature(Name memberName, ImmutableArray<ParameterSignature> parameters)
{
MemberName = memberName;
Parameters = parameters;
}
internal readonly Name MemberName;
internal readonly ImmutableArray<ParameterSignature> Parameters; // default if not specified
}
}
// 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.Collections.Immutable;
namespace Microsoft.CodeAnalysis.ExpressionEvaluator
{
internal static class SpecialTypeExtensions
{
internal static QualifiedTypeSignature GetTypeSignature(this SpecialType type)
{
QualifiedTypeSignature signature;
s_typeSignatures.TryGetValue(type, out signature);
return signature;
}
private static readonly ImmutableDictionary<SpecialType, QualifiedTypeSignature> s_typeSignatures = GetTypeSignatures();
private static ImmutableDictionary<SpecialType, QualifiedTypeSignature> GetTypeSignatures()
{
var systemNamespace = new QualifiedTypeSignature(null, "System");
var builder = ImmutableDictionary.CreateBuilder<SpecialType, QualifiedTypeSignature>();
builder.Add(SpecialType.System_Void, new QualifiedTypeSignature(systemNamespace, "Void"));
builder.Add(SpecialType.System_Boolean, new QualifiedTypeSignature(systemNamespace, "Boolean"));
builder.Add(SpecialType.System_Char, new QualifiedTypeSignature(systemNamespace, "Char"));
builder.Add(SpecialType.System_SByte, new QualifiedTypeSignature(systemNamespace, "SByte"));
builder.Add(SpecialType.System_Byte, new QualifiedTypeSignature(systemNamespace, "Byte"));
builder.Add(SpecialType.System_Int16, new QualifiedTypeSignature(systemNamespace, "Int16"));
builder.Add(SpecialType.System_UInt16, new QualifiedTypeSignature(systemNamespace, "UInt16"));
builder.Add(SpecialType.System_Int32, new QualifiedTypeSignature(systemNamespace, "Int32"));
builder.Add(SpecialType.System_UInt32, new QualifiedTypeSignature(systemNamespace, "UInt32"));
builder.Add(SpecialType.System_Int64, new QualifiedTypeSignature(systemNamespace, "Int64"));
builder.Add(SpecialType.System_UInt64, new QualifiedTypeSignature(systemNamespace, "UInt64"));
builder.Add(SpecialType.System_Single, new QualifiedTypeSignature(systemNamespace, "Single"));
builder.Add(SpecialType.System_Double, new QualifiedTypeSignature(systemNamespace, "Double"));
builder.Add(SpecialType.System_String, new QualifiedTypeSignature(systemNamespace, "String"));
builder.Add(SpecialType.System_Object, new QualifiedTypeSignature(systemNamespace, "Object"));
builder.Add(SpecialType.System_Decimal, new QualifiedTypeSignature(systemNamespace, "Decimal"));
builder.Add(SpecialType.System_IntPtr, new QualifiedTypeSignature(systemNamespace, "IntPtr"));
builder.Add(SpecialType.System_UIntPtr, new QualifiedTypeSignature(systemNamespace, "UIntPtr"));
builder.Add(SpecialType.System_TypedReference, new QualifiedTypeSignature(systemNamespace, "TypedReference"));
builder.Add(SpecialType.System_Nullable_T, new QualifiedTypeSignature(systemNamespace, "Nullable"));
return builder.ToImmutable();
}
}
}
// 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.Collections.Immutable;
using System.Diagnostics;
using System.Text;
namespace Microsoft.CodeAnalysis.ExpressionEvaluator
{
internal enum TypeSignatureKind
{
GenericType,
QualifiedType,
ArrayType,
PointerType,
}
[DebuggerDisplay("{GetDebuggerDisplay(), nq}")]
internal abstract class TypeSignature
{
internal abstract TypeSignatureKind Kind { get; }
internal abstract string GetDebuggerDisplay();
}
internal sealed class GenericTypeSignature : TypeSignature
{
internal GenericTypeSignature(QualifiedTypeSignature qualifiedName, ImmutableArray<TypeSignature> typeArguments)
{
Debug.Assert(qualifiedName != null);
Debug.Assert(!typeArguments.IsDefault);
QualifiedName = qualifiedName;
TypeArguments = typeArguments;
}
internal override TypeSignatureKind Kind => TypeSignatureKind.GenericType;
internal QualifiedTypeSignature QualifiedName { get; }
internal ImmutableArray<TypeSignature> TypeArguments { get; }
internal override string GetDebuggerDisplay()
{
var builder = new StringBuilder();
builder.Append(QualifiedName.GetDebuggerDisplay());
builder.Append('<');
bool any = false;
foreach (var typeArg in TypeArguments)
{
if (any)
{
builder.Append(", ");
}
builder.Append(typeArg.GetDebuggerDisplay());
any = true;
}
builder.Append('>');
return builder.ToString();
}
}
internal sealed class QualifiedTypeSignature : TypeSignature
{
internal QualifiedTypeSignature(TypeSignature qualifier, string name)
{
Debug.Assert(!string.IsNullOrEmpty(name));
Qualifier = qualifier;
Name = name;
}
internal override TypeSignatureKind Kind => TypeSignatureKind.QualifiedType;
internal TypeSignature Qualifier { get; }
internal string Name { get; }
internal override string GetDebuggerDisplay()
{
return (Qualifier == null) ? Name : $"{Qualifier.GetDebuggerDisplay()}.{Name}";
}
}
internal sealed class ArrayTypeSignature : TypeSignature
{
internal ArrayTypeSignature(TypeSignature elementType, int rank)
{
Debug.Assert(elementType != null);
ElementType = elementType;
Rank = rank;
}
internal override TypeSignatureKind Kind => TypeSignatureKind.ArrayType;
internal TypeSignature ElementType { get; }
internal int Rank { get; }
internal override string GetDebuggerDisplay()
{
var builder = new StringBuilder();
builder.Append(ElementType.GetDebuggerDisplay());
builder.Append('[');
builder.Append(',', Rank - 1);
builder.Append(']');
return builder.ToString();
}
}
internal sealed class PointerTypeSignature : TypeSignature
{
internal PointerTypeSignature(TypeSignature pointedAtType)
{
Debug.Assert(pointedAtType != null);
PointedAtType = pointedAtType;
}
internal override TypeSignatureKind Kind => TypeSignatureKind.PointerType;
internal TypeSignature PointedAtType { get; }
internal override string GetDebuggerDisplay()
{
return $"{PointedAtType.GetDebuggerDisplay()}*";
}
}
}
{
"dependencies": {
"System.Collections.Immutable": "1.2.0",
"System.Reflection.Metadata": "1.4.1-beta-24430-01",
"Microsoft.VisualStudio.Debugger.Engine": "14.3.25422",
},
"frameworks": {
"netstandard1.3": {
"imports": "portable-net45+win8"
}
}
}
// 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 Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator;
using Microsoft.CodeAnalysis.CSharp.Test.Utilities;
using Roslyn.Test.Utilities;
using System.Collections.Immutable;
using System.Linq;
using Xunit;
namespace Microsoft.CodeAnalysis.ExpressionEvaluator.UnitTests
{
public class CSharpParsingTests : CSharpTestBase
{
[Fact]
public void Parsing()
{
// Method name only.
VerifySignature("F",
SignatureNameOnly(
Name("F")));
// Method name and empty parameters.
VerifySignature("F()",
Signature(
Name("F")));
// Method name and parameters.
VerifySignature("F(A, B)",
Signature(
Name("F"),
Identifier("A"),
Identifier("B")));
// Type and method name.
VerifySignature("C.F",
SignatureNameOnly(
Qualified(Name("C"), "F")));
// Qualified type and method name.
VerifySignature("A.B.F",
SignatureNameOnly(
Qualified(
Qualified(
Name("A"),
"B"),
"F")));
// Generic types and method names.
VerifySignature("A<T>.B<U>.F<V>",
SignatureNameOnly(
Generic(
Qualified(
Generic(
Qualified(
Generic(
Name("A"),
"T"),
"B"),
"U"),
"F"),
"V")));
}
[Fact]
public void Spaces()
{
VerifySignature(" \tC . F ( System.Object\t,object) ",
Signature(
Qualified(Name("C"), "F"),
Qualified("System", "Object"),
Qualified("System", "Object")));
}
[Fact]
public void ArraysAndPointers()
{
VerifySignature("F(C*)",
Signature(
Name("F"),
Pointer(
Identifier("C"))));
VerifySignature("F(C**)",
Signature(
Name("F"),
Pointer(
Pointer(
Identifier("C")))));
VerifySignature("F(C*[,,,])",
Signature(
Name("F"),
Array(
Pointer(
Identifier("C")),
4)));
VerifySignature("F(C[,][]*)",
Signature(
Name("F"),
Pointer(
Array(
Array(
Identifier("C"),
2),
1))));
VerifySignature("F(C<T>*)",
Signature(
Name("F"),
Pointer(
Generic(
Identifier("C"),
Identifier("T")))));
VerifySignature("F(C<T[,]*>)",
Signature(
Name("F"),
Generic(
Identifier("C"),
Pointer(
Array(
Identifier("T"),
2)))));
}
[Fact]
public void ParseErrors()
{
Assert.Null(MemberSignatureParser.Parse("A<T>B"));
Assert.Null(MemberSignatureParser.Parse("A<<T>>"));
Assert.Null(MemberSignatureParser.Parse("A<T><U>"));
Assert.Null(MemberSignatureParser.Parse("A.<T>"));
Assert.Null(MemberSignatureParser.Parse("A<T>.<U>"));
Assert.Null(MemberSignatureParser.Parse("A+B"));
Assert.Null(MemberSignatureParser.Parse("F("));
Assert.Null(MemberSignatureParser.Parse("F())"));
Assert.Null(MemberSignatureParser.Parse("F(]"));
Assert.Null(MemberSignatureParser.Parse("F(,B)"));
Assert.Null(MemberSignatureParser.Parse("F(A,)"));
Assert.Null(MemberSignatureParser.Parse("F<"));
Assert.Null(MemberSignatureParser.Parse("F<()"));
Assert.Null(MemberSignatureParser.Parse("F<T>>"));
Assert.Null(MemberSignatureParser.Parse("F<T()"));
Assert.Null(MemberSignatureParser.Parse("F<T()"));
Assert.Null(MemberSignatureParser.Parse("F?"));
Assert.Null(MemberSignatureParser.Parse("F[]"));
Assert.Null(MemberSignatureParser.Parse("F*"));
Assert.Null(MemberSignatureParser.Parse(".F"));
Assert.Null(MemberSignatureParser.Parse("()"));
Assert.Null(MemberSignatureParser.Parse("<T>"));
Assert.Null(MemberSignatureParser.Parse("1"));
}
[Fact]
public void ByRef()
{
VerifySignature("F(ref A, out B)",
Signature(
Name("F"),
Identifier("A"),
Identifier("B")));
Assert.Null(MemberSignatureParser.Parse("F(ref out C)"));
Assert.Null(MemberSignatureParser.Parse("F(ref)"));
Assert.Null(MemberSignatureParser.Parse("F<out>"));
Assert.Null(MemberSignatureParser.Parse("F<out C>"));
Assert.Null(MemberSignatureParser.Parse("F(C<ref>)"));
Assert.Null(MemberSignatureParser.Parse("F(C<ref C>)"));
}
// Special types are treated as keywords in names,
// but not recognized as special types.
[Fact]
public void SpecialTypes_Names()
{
// Method name only.
Assert.Null(MemberSignatureParser.Parse("int"));
Assert.Null(MemberSignatureParser.Parse("params"));
VerifySignature("@int",
SignatureNameOnly(
Name("int")));
// Type and method name.
Assert.Null(MemberSignatureParser.Parse("@object.int"));
Assert.Null(MemberSignatureParser.Parse("@public.private"));
VerifySignature("@object.@int",
SignatureNameOnly(
Qualified(
Name("object"),
"int")));
// Type parameters.
Assert.Null(MemberSignatureParser.Parse("F<void>"));
Assert.Null(MemberSignatureParser.Parse("F<bool>"));
Assert.Null(MemberSignatureParser.Parse("F<char>"));
Assert.Null(MemberSignatureParser.Parse("F<sbyte>"));
Assert.Null(MemberSignatureParser.Parse("F<byte>"));
Assert.Null(MemberSignatureParser.Parse("F<short>"));
Assert.Null(MemberSignatureParser.Parse("F<ushort>"));
VerifySignature("F<@void, @bool, @char, @sbyte, @byte, @short, @ushort, @int, @uint, @long, @ulong, @float, @double, @string, @object, @decimal>()",
Signature(
Generic(Name("F"),
"void",
"bool",
"char",
"sbyte",
"byte",
"short",
"ushort",
"int",
"uint",
"long",
"ulong",
"float",
"double",
"string",
"object",
"decimal")));
}
// Special types are recognized in type references.
[Fact]
public void SpecialTypes_TypeReferences()
{
// Parameters.
VerifySignature("F(void, bool, char, sbyte, byte, short, ushort, int, uint, long, ulong, float, double, string, object, decimal)",
Signature(
Name("F"),
Qualified("System", "Void"),
Qualified("System", "Boolean"),
Qualified("System", "Char"),
Qualified("System", "SByte"),
Qualified("System", "Byte"),
Qualified("System", "Int16"),
Qualified("System", "UInt16"),
Qualified("System", "Int32"),
Qualified("System", "UInt32"),
Qualified("System", "Int64"),
Qualified("System", "UInt64"),
Qualified("System", "Single"),
Qualified("System", "Double"),
Qualified("System", "String"),
Qualified("System", "Object"),
Qualified("System", "Decimal")));
// Type arguments.
VerifySignature("F(C<void, int, string, object>)",
Signature(
Name("F"),
Generic(
Identifier("C"),
Qualified("System", "Void"),
Qualified("System", "Int32"),
Qualified("System", "String"),
Qualified("System", "Object"))));
// Not special types.
VerifySignature("F(Void, Int32, @string, @object)",
Signature(
Name("F"),
Identifier("Void"),
Identifier("Int32"),
Identifier("string"),
Identifier("object")));
// dynamic is not special.
VerifySignature("F(dynamic)",
Signature(
Name("F"),
Identifier("dynamic")));
}
[Fact]
public void EscapedNames()
{
VerifySignature("@F",
SignatureNameOnly(
Name("F")));
VerifySignature("@_",
SignatureNameOnly(
Name("_")));
VerifySignature("@int",
SignatureNameOnly(
Name("int")));
VerifySignature("A.B.@int",
SignatureNameOnly(
Qualified(
Qualified(
Name("A"),
"B"),
"int")));
VerifySignature("F(@int)",
Signature(
Name("F"),
Identifier("int")));
VerifySignature("F(System.@int)",
Signature(
Name("F"),
Qualified(
Identifier("System"),
"int")));
VerifySignature("A<@object>.B<@int>.F<@void>",
SignatureNameOnly(
Generic(
Qualified(
Generic(
Qualified(
Generic(
Name("A"),
"object"),
"B"),
"int"),
"F"),
"void")));
VerifySignature("F(C<int, @void>)",
Signature(
Name("F"),
Generic(
Identifier("C"),
Qualified("System", "Int32"),
Identifier("void"))));
Assert.Null(MemberSignatureParser.Parse("@"));
Assert.Null(MemberSignatureParser.Parse("@1"));
Assert.Null(MemberSignatureParser.Parse("@@F"));
Assert.Null(MemberSignatureParser.Parse("@F@"));
Assert.Null(MemberSignatureParser.Parse("@<T>"));
Assert.Null(MemberSignatureParser.Parse("@.F"));
Assert.Null(MemberSignatureParser.Parse("@()"));
Assert.Null(MemberSignatureParser.Parse("F(@)"));
Assert.Null(MemberSignatureParser.Parse("F(A, @)"));
Assert.Null(MemberSignatureParser.Parse("F<@>"));
Assert.Null(MemberSignatureParser.Parse("F<T, @>"));
}
private static RequestSignature SignatureNameOnly(Name name)
{
return new RequestSignature(name, default(ImmutableArray<ParameterSignature>));
}
private static RequestSignature Signature(Name name)
{
return new RequestSignature(name, ImmutableArray<ParameterSignature>.Empty);
}
private static RequestSignature Signature(Name name, params TypeSignature[] parameterTypes)
{
return Signature(name, parameterTypes.Select(t => new ParameterSignature(t, isByRef: false)).ToArray());
}
private static RequestSignature Signature(Name name, params ParameterSignature[] parameters)
{
return new RequestSignature(name, ImmutableArray.CreateRange(parameters));
}
private static QualifiedName Name(string name)
{
return new QualifiedName(null, name);
}
private static GenericName Generic(QualifiedName name, params string[] typeArguments)
{
Assert.True(typeArguments.Length > 0);
return new GenericName(name, ImmutableArray.CreateRange(typeArguments));
}
private static QualifiedName Qualified(Name left, string right)
{
return new QualifiedName(left, right);
}
private static QualifiedTypeSignature Identifier(string name)
{
return new QualifiedTypeSignature(null, name);
}
private static GenericTypeSignature Generic(QualifiedTypeSignature name, params TypeSignature[] typeArguments)
{
Assert.True(typeArguments.Length > 0);
return new GenericTypeSignature(name, ImmutableArray.CreateRange(typeArguments));
}
private static QualifiedTypeSignature Qualified(TypeSignature left, string right)
{
return new QualifiedTypeSignature(left, right);
}
private static QualifiedTypeSignature Qualified(params string[] names)
{
QualifiedTypeSignature signature = null;
foreach (var name in names)
{
signature = new QualifiedTypeSignature(signature, name);
}
return signature;
}
private static ArrayTypeSignature Array(TypeSignature elementType, int rank)
{
return new ArrayTypeSignature(elementType, rank);
}
private static PointerTypeSignature Pointer(TypeSignature pointedAtType)
{
return new PointerTypeSignature(pointedAtType);
}
private static void VerifySignature(string str, RequestSignature expectedSignature)
{
var actualSignature = MemberSignatureParser.Parse(str);
if (expectedSignature == null)
{
Assert.Null(actualSignature);
}
else
{
Assert.NotNull(actualSignature);
Assert.Equal(expectedSignature.MemberName, actualSignature.MemberName, NameComparer.Instance);
if (expectedSignature.Parameters.IsDefault)
{
Assert.True(actualSignature.Parameters.IsDefault);
}
else
{
AssertEx.Equal(
expectedSignature.Parameters,
actualSignature.Parameters,
comparer: ParameterComparer.Instance,
itemInspector: p => p.Type.GetDebuggerDisplay());
}
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="..\..\..\..\..\build\Targets\Settings.props" />
<PropertyGroup>
<NonShipping>true</NonShipping>
<Platform Condition="'$(Platform)' == ''">AnyCPU</Platform>
<ProjectGuid>{DD317BE1-42A1-4795-B1D4-F370C40D649A}</ProjectGuid>
<OutputType>Library</OutputType>
<RootNamespace>Microsoft.CodeAnalysis.ExpressionEvaluator.UnitTests</RootNamespace>
<AssemblyName>Roslyn.ExpressionEvaluator.FunctionResolver.UnitTests</AssemblyName>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<RoslynProjectType>UnitTest</RoslynProjectType>
<!-- Don't transitively copy output files, since everything builds to the same folder. -->
</PropertyGroup>
<ItemGroup Label="Project References">
<ProjectReference Include="..\..\..\..\Compilers\Test\Utilities\CSharp.Desktop\CSharpCompilerTestUtilities.Desktop.csproj">
<Project>{7a4b2176-7bfd-4b75-a61a-e25a1fdd0a1e}</Project>
<Name>CSharpCompilerTestUtilities.Desktop</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\..\Test\Utilities\Portable.FX45\TestUtilities.FX45.csproj">
<Project>{f7712928-1175-47b3-8819-ee086753dee2}</Project>
<Name>TestUtilities.FX45</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\..\Compilers\Core\Portable\CodeAnalysis.csproj">
<Project>{1EE8CAD3-55F9-4D91-96B2-084641DA9A6C}</Project>
<Name>CodeAnalysis</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\..\Compilers\CSharp\Portable\CSharpCodeAnalysis.csproj">
<Project>{B501A547-C911-4A05-AC6E-274A50DFF30E}</Project>
<Name>CSharpCodeAnalysis</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\..\Compilers\VisualBasic\Portable\BasicCodeAnalysis.vbproj">
<Project>{2523d0e6-df32-4a3e-8ae0-a19bffae2ef6}</Project>
<Name>BasicCodeAnalysis</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\Core\Source\FunctionResolver\FunctionResolver.csproj">
<Project>{6FC8E6F5-659C-424D-AEB5-331B95883E29}</Project>
<Name>FunctionResolver</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\..\Test\PdbUtilities\PdbUtilities.csproj">
<Project>{AFDE6BEA-5038-4A4A-A88E-DBD2E4088EED}</Project>
<Name>PdbUtilities</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\..\Test\Utilities\Desktop\TestUtilities.Desktop.csproj">
<Project>{76C6F005-C89D-4348-BB4A-391898DBEB52}</Project>
<Name>TestUtilities.Desktop</Name>
</ProjectReference>
<ProjectReference Include="..\..\..\..\Compilers\Test\Resources\Core\CompilerTestResources.csproj">
<Project>{7fe6b002-89d8-4298-9b1b-0b5c247dd1fd}</Project>
<Name>CompilerTestResources</Name>
</ProjectReference>
</ItemGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup>
<ItemGroup>
<Compile Include="CSharpFunctionResolverTests.cs" />
<Compile Include="CSharpParsingTests.cs" />
<Compile Include="Module.cs" />
<Compile Include="NameComparer.cs" />
<Compile Include="ParameterComparer.cs" />
<Compile Include="Process.cs" />
<Compile Include="Request.cs" />
<Compile Include="Resolver.cs" />
<Compile Include="TypeComparer.cs" />
</ItemGroup>
<ItemGroup>
<None Include="project.json" />
</ItemGroup>
<Import Project="..\..\..\..\..\build\Targets\Imports.targets" />
</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.
using System;
using System.Collections.Immutable;
using System.Reflection.Metadata;
using System.Reflection.PortableExecutable;
namespace Microsoft.CodeAnalysis.ExpressionEvaluator.UnitTests
{
internal sealed class Module : IDisposable
{
private readonly string _name;
private readonly PEReader _reader;
private int _getMetadataCount;
internal Module(ImmutableArray<byte> bytes, string name = null)
{
_name = name;
_reader = bytes.IsDefault ? null : new PEReader(bytes);
}
internal string Name => _name;
internal int GetMetadataCount => _getMetadataCount;
internal MetadataReader GetMetadata()
{
_getMetadataCount++;
return GetMetadataInternal();
}
internal MetadataReader GetMetadataInternal()
{
if (_reader == null)
{
return null;
}
unsafe
{
var block = _reader.GetMetadata();
return new MetadataReader(block.Pointer, block.Length);
}
}
void IDisposable.Dispose()
{
if (_reader != null)
{
_reader.Dispose();
}
}
}
}
// 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;
namespace Microsoft.CodeAnalysis.ExpressionEvaluator.UnitTests
{
internal sealed class NameComparer : IEqualityComparer<Name>
{
internal static readonly NameComparer Instance = new NameComparer();
public bool Equals(Name x, Name y)
{
if (x == null)
{
return y == null;
}
if (y == null)
{
return false;
}
if (x.Kind != y.Kind)
{
return false;
}
switch (x.Kind)
{
case NameKind.QualifiedName:
{
var xQualified = (QualifiedName)x;
var yQualified = (QualifiedName)y;
return Equals(xQualified.Qualifier, yQualified.Qualifier) &&
Equals(xQualified.Name, yQualified.Name);
}
case NameKind.GenericName:
{
var xGeneric = (GenericName)x;
var yGeneric = (GenericName)y;
return Equals(xGeneric.QualifiedName, yGeneric.QualifiedName) &&
xGeneric.TypeParameters.SequenceEqual(yGeneric.TypeParameters);
}
default:
throw new NotImplementedException();
}
}
public int GetHashCode(Name obj)
{
throw new NotImplementedException();
}
}
}
// 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;
namespace Microsoft.CodeAnalysis.ExpressionEvaluator.UnitTests
{
internal sealed class ParameterComparer : IEqualityComparer<ParameterSignature>
{
internal static readonly ParameterComparer Instance = new ParameterComparer();
public bool Equals(ParameterSignature x, ParameterSignature y)
{
return TypeComparer.Instance.Equals(x.Type, y.Type);
}
public int GetHashCode(ParameterSignature obj)
{
throw new NotImplementedException();
}
}
}
// 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;
namespace Microsoft.CodeAnalysis.ExpressionEvaluator.UnitTests
{
internal sealed class Process : IDisposable
{
private readonly bool _shouldEnable;
private readonly List<Module> _modules;
private int _shouldEnableRequests;
internal Process(params Module[] modules) : this(true, modules)
{
}
internal Process(bool shouldEnable, params Module[] modules)
{
_shouldEnable = shouldEnable;
_modules = new List<Module>(modules);
}
internal int ShouldEnableRequests => _shouldEnableRequests;
internal bool ShouldEnableFunctionResolver()
{
_shouldEnableRequests++;
return _shouldEnable;
}
internal void AddModule(Module module)
{
_modules.Add(module);
}
internal Module[] GetModules()
{
return _modules.ToArray();
}
void IDisposable.Dispose()
{
foreach (var module in _modules)
{
((IDisposable)module).Dispose();
}
}
}
}
// 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.Collections.Generic;
using System.Collections.Immutable;
namespace Microsoft.CodeAnalysis.ExpressionEvaluator.UnitTests
{
internal struct Address
{
internal readonly Module Module;
internal readonly int Token;
internal readonly int Version;
internal readonly int ILOffset;
internal Address(Module module, int token, int version, int ilOffset)
{
Module = module;
Token = token;
Version = version;
ILOffset = ilOffset;
}
}
internal sealed class Request
{
internal readonly List<Address> _resolvedAddresses;
internal Request(string moduleName, RequestSignature signature)
{
ModuleName = moduleName;
Signature = signature;
_resolvedAddresses = new List<Address>();
}
internal readonly string ModuleName;
internal readonly RequestSignature Signature;
internal void OnFunctionResolved(Module module, int token, int version, int ilOffset)
{
_resolvedAddresses.Add(new Address(module, token, version, ilOffset));
}
internal ImmutableArray<Address> GetResolvedAddresses()
{
return ImmutableArray.CreateRange(_resolvedAddresses);
}
}
}
// 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.Collections.Generic;
using System.Reflection.Metadata;
namespace Microsoft.CodeAnalysis.ExpressionEvaluator.UnitTests
{
internal sealed class Resolver : FunctionResolverBase<Process, Module, Request>
{
private readonly Dictionary<Process, List<Request>> _requests;
internal Resolver()
{
_requests = new Dictionary<Process, List<Request>>();
}
internal new void EnableResolution(Process process, Request request)
{
List<Request> requests;
if (!_requests.TryGetValue(process, out requests))
{
requests = new List<Request>();
_requests.Add(process, requests);
}
requests.Add(request);
base.EnableResolution(process, request);
}
internal override bool ShouldEnableFunctionResolver(Process process)
{
return process.ShouldEnableFunctionResolver();
}
internal override IEnumerable<Module> GetAllModules(Process process)
{
return process.GetModules();
}
internal override string GetModuleName(Module module)
{
return module.Name;
}
internal override MetadataReader GetModuleMetadata(Module module)
{
return module.GetMetadata();
}
internal override Request[] GetRequests(Process process)
{
List<Request> requests;
if (!_requests.TryGetValue(process, out requests))
{
return new Request[0];
}
return requests.ToArray();
}
internal override string GetRequestModuleName(Request request)
{
return request.ModuleName;
}
internal override RequestSignature GetParsedSignature(Request request)
{
return request.Signature;
}
internal override void OnFunctionResolved(Module module, Request request, int token, int version, int ilOffset)
{
request.OnFunctionResolved(module, token, version, ilOffset);
}
private void OnModuleLoaded(object sender, Module e)
{
OnModuleLoad((Process)sender, e);
}
}
}
// 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;
namespace Microsoft.CodeAnalysis.ExpressionEvaluator.UnitTests
{
internal sealed class TypeComparer : IEqualityComparer<TypeSignature>
{
internal static readonly TypeComparer Instance = new TypeComparer();
public bool Equals(TypeSignature x, TypeSignature y)
{
if (x == null)
{
return y == null;
}
if (y == null)
{
return false;
}
if (x.Kind != y.Kind)
{
return false;
}
switch (x.Kind)
{
case TypeSignatureKind.QualifiedType:
{
var xQualified = (QualifiedTypeSignature)x;
var yQualified = (QualifiedTypeSignature)y;
return Equals(xQualified.Qualifier, yQualified.Qualifier) &&
Equals(xQualified.Name, yQualified.Name);
}
case TypeSignatureKind.GenericType:
{
var xGeneric = (GenericTypeSignature)x;
var yGeneric = (GenericTypeSignature)y;
return Equals(xGeneric.QualifiedName, yGeneric.QualifiedName) &&
xGeneric.TypeArguments.SequenceEqual(yGeneric.TypeArguments, this);
}
case TypeSignatureKind.ArrayType:
{
var xArray = (ArrayTypeSignature)x;
var yArray = (ArrayTypeSignature)y;
return Equals(xArray.ElementType, yArray.ElementType) &&
xArray.Rank == yArray.Rank;
}
case TypeSignatureKind.PointerType:
{
var xPointer = (PointerTypeSignature)x;
var yPointer = (PointerTypeSignature)y;
return Equals(xPointer.PointedAtType, yPointer.PointedAtType);
}
default:
throw new NotImplementedException();
}
}
public int GetHashCode(TypeSignature obj)
{
throw new NotImplementedException();
}
}
}
{
"dependencies": {
"Microsoft.VisualStudio.Debugger.Engine": "14.3.25422",
"xunit": "2.1.0",
"xunit.runner.console": "2.2.0-beta1-build3239"
},
"frameworks": {
"net46": { }
},
"runtimes": {
"win7": { }
}
}
\ No newline at end of file
......@@ -38,6 +38,8 @@ public DkmClrRuntimeInstance RuntimeInstance
get { return _runtimeInstance; }
}
public DkmProcess Process => _runtimeInstance.Process;
public DkmClrType ResolveTypeName(string typeName, ReadOnlyCollection<DkmClrType> typeArguments)
{
var type = this.Assembly.GetType(typeName);
......
......@@ -12,10 +12,6 @@ public class DkmProcess
private readonly bool _nativeDebuggingEnabled;
public DkmProcess()
{
}
public DkmProcess(bool enableNativeDebugging)
{
_nativeDebuggingEnabled = enableNativeDebugging;
......
......@@ -8,16 +8,11 @@ namespace Microsoft.VisualStudio.Debugger
{
public class DkmRuntimeInstance
{
internal static readonly DkmProcess DefaultProcess = new DkmProcess();
internal static readonly DkmProcess ProcessWithNativeDebugging = new DkmProcess(enableNativeDebugging: true);
public readonly DkmProcess Process;
public DkmRuntimeInstance(bool enableNativeDebugging)
{
Process = enableNativeDebugging ?
ProcessWithNativeDebugging :
DefaultProcess;
Process = new DkmProcess(enableNativeDebugging);
}
}
}
......@@ -5,6 +5,7 @@
[assembly: ProvideRoslynBindingRedirection("Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator.ExpressionCompiler.dll")]
[assembly: ProvideRoslynBindingRedirection("Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator.ResultProvider.dll")]
[assembly: ProvideRoslynBindingRedirection("Microsoft.CodeAnalysis.ExpressionEvaluator.ExpressionCompiler.dll")]
[assembly: ProvideRoslynBindingRedirection("Microsoft.CodeAnalysis.ExpressionEvaluator.FunctionResolver.dll")]
[assembly: ProvideRoslynBindingRedirection("Microsoft.CodeAnalysis.ExpressionEvaluator.ResultProvider.dll")]
[assembly: ProvideRoslynBindingRedirection("Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator.ExpressionCompiler.dll")]
[assembly: ProvideRoslynBindingRedirection("Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator.ResultProvider.dll")]
......@@ -47,6 +47,13 @@
<IncludeOutputGroupsInVSIXLocalOnly>DebugSymbolsProjectOutputGroup</IncludeOutputGroupsInVSIXLocalOnly>
<ForceIncludeInVSIX>true</ForceIncludeInVSIX>
</ProjectReference>
<ProjectReference Include="..\Core\Source\FunctionResolver\FunctionResolver.csproj">
<Project>{6FC8E6F5-659C-424D-AEB5-331B95883E29}</Project>
<Name>FunctionResolver</Name>
<IncludeOutputGroupsInVSIX>BuiltProjectOutputGroup%3bVsdConfigOutputGroup</IncludeOutputGroupsInVSIX>
<IncludeOutputGroupsInVSIXLocalOnly>DebugSymbolsProjectOutputGroup</IncludeOutputGroupsInVSIXLocalOnly>
<ForceIncludeInVSIX>true</ForceIncludeInVSIX>
</ProjectReference>
<ProjectReference Include="..\Core\Source\ResultProvider\Portable\ResultProvider.Portable.csproj">
<Project>{BEDC5A4A-809E-4017-9CFD-6C8D4E1847F0}</Project>
<Name>ResultProvider.Portable</Name>
......
......@@ -17,6 +17,7 @@
<Action Type="Ngen" Path="Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator.ExpressionCompiler.dll" />
<Action Type="Ngen" Path="Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator.ResultProvider.dll" />
<Action Type="Ngen" Path="Microsoft.CodeAnalysis.ExpressionEvaluator.ExpressionCompiler.dll" />
<Action Type="Ngen" Path="Microsoft.CodeAnalysis.ExpressionEvaluator.FunctionResolver.dll" />
<Action Type="Ngen" Path="Microsoft.CodeAnalysis.ExpressionEvaluator.ResultProvider.dll" />
<Action Type="Ngen" Path="Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator.ExpressionCompiler.dll" />
<Action Type="Ngen" Path="Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator.ResultProvider.dll" />
......@@ -30,6 +31,7 @@
<Asset Type="DebuggerEngineExtension" d:Source="Project" d:ProjectName="BasicResultProvider.Portable" Path="|BasicResultProvider.Portable;VsdConfigOutputGroup|" />
<Asset Type="DebuggerEngineExtension" d:Source="Project" d:ProjectName="CSharpExpressionCompiler" Path="|CSharpExpressionCompiler;VsdConfigOutputGroup|" />
<Asset Type="DebuggerEngineExtension" d:Source="Project" d:ProjectName="CSharpResultProvider.Portable" Path="|CSharpResultProvider.Portable;VsdConfigOutputGroup|" />
<Asset Type="DebuggerEngineExtension" d:Source="Project" d:ProjectName="FunctionResolver" Path="|FunctionResolver;VsdConfigOutputGroup|" />
<Asset Type="Microsoft.VisualStudio.VsPackage" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%;PkgdefProjectOutputGroup|" />
</Assets>
<Prerequisites>
......
......@@ -99,9 +99,6 @@
<Compile Include="VisualBasicInstructionDecoder.vb" />
<Compile Include="VisualBasicLanguageInstructionDecoder.vb" />
</ItemGroup>
<ItemGroup>
<Folder Include="My Project\" />
</ItemGroup>
<ItemGroup>
<None Include="project.json" />
</ItemGroup>
......
......@@ -297,6 +297,7 @@ Public Class BuildDevDivInsertionFiles
"Microsoft.CodeAnalysis.EditorFeatures.dll",
"Microsoft.CodeAnalysis.EditorFeatures.Text.dll",
"Microsoft.CodeAnalysis.ExpressionEvaluator.ExpressionCompiler.dll",
"Microsoft.CodeAnalysis.ExpressionEvaluator.FunctionResolver.dll",
"Microsoft.CodeAnalysis.ExpressionEvaluator.ResultProvider.dll",
"Microsoft.CodeAnalysis.Features.dll",
"Microsoft.CodeAnalysis.InteractiveEditorFeatures.dll",
......@@ -835,6 +836,7 @@ Public Class BuildDevDivInsertionFiles
add("Dlls\BasicResultProvider.Portable\Microsoft.CodeAnalysis.VisualBasic.ExpressionEvaluator.ResultProvider.vsdconfig")
add("Dlls\CSharpExpressionCompiler\Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator.ExpressionCompiler.vsdconfig")
add("Dlls\CSharpResultProvider.Portable\Microsoft.CodeAnalysis.CSharp.ExpressionEvaluator.ResultProvider.vsdconfig")
add("Dlls\FunctionResolver\Microsoft.CodeAnalysis.ExpressionEvaluator.FunctionResolver.vsdconfig")
add("Dlls\MSBuildTask\Microsoft.CSharp.Core.targets")
add("Dlls\MSBuildTask\Microsoft.VisualBasic.Core.targets")
add("Dlls\CSharpCompilerTestUtilities\Roslyn.Compilers.CSharp.Test.Utilities.dll")
......
......@@ -142,6 +142,7 @@
<InternalsVisibleToTest Include="Roslyn.ExpressionEvaluator.CSharp.ExpressionCompiler.UnitTests" />
<InternalsVisibleToTest Include="Roslyn.ExpressionEvaluator.CSharp.ResultProvider.UnitTests" />
<InternalsVisibleToTest Include="Roslyn.ExpressionEvaluator.ExpressionCompiler.Test.Utilities" />
<InternalsVisibleToTest Include="Roslyn.ExpressionEvaluator.FunctionResolver.UnitTests" />
<InternalsVisibleToTest Include="Roslyn.ExpressionEvaluator.VisualBasic.ExpressionCompiler.UnitTests" />
<InternalsVisibleToTest Include="Roslyn.ExpressionEvaluator.VisualBasic.ResultProvider.UnitTests" />
<InternalsVisibleToTest Include="Roslyn.InteractiveHost.UnitTests" />
......
......@@ -95,6 +95,7 @@
<InternalsVisibleToTest Include="Roslyn.ExpressionEvaluator.CSharp.ExpressionCompiler.UnitTests" />
<InternalsVisibleToTest Include="Roslyn.ExpressionEvaluator.CSharp.ResultProvider.UnitTests" />
<InternalsVisibleToTest Include="Roslyn.ExpressionEvaluator.ExpressionCompiler.Test.Utilities" />
<InternalsVisibleToTest Include="Roslyn.ExpressionEvaluator.FunctionResolver.UnitTests" />
<InternalsVisibleToTest Include="Roslyn.ExpressionEvaluator.VisualBasic.ExpressionCompiler.UnitTests" />
<InternalsVisibleToTest Include="Roslyn.ExpressionEvaluator.VisualBasic.ResultProvider.UnitTests" />
<InternalsVisibleToTest Include="Roslyn.InteractiveHost.UnitTests" />
......
......@@ -79,6 +79,7 @@
<InternalsVisibleToTest Include="Roslyn.ExpressionEvaluator.CSharp.ExpressionCompiler.UnitTests" />
<InternalsVisibleToTest Include="Roslyn.ExpressionEvaluator.CSharp.ResultProvider.UnitTests" />
<InternalsVisibleToTest Include="Roslyn.ExpressionEvaluator.ExpressionCompiler.Test.Utilities" />
<InternalsVisibleToTest Include="Roslyn.ExpressionEvaluator.FunctionResolver.UnitTests" />
<InternalsVisibleToTest Include="Roslyn.ExpressionEvaluator.VisualBasic.ExpressionCompiler.UnitTests" />
<InternalsVisibleToTest Include="Roslyn.ExpressionEvaluator.VisualBasic.ResultProvider.UnitTests" />
<InternalsVisibleToTest Include="Roslyn.InteractiveHost.UnitTests" />
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册