Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lwm1986
roslyn
提交
8058ba4e
R
roslyn
项目概览
lwm1986
/
roslyn
与 Fork 源项目一致
从无法访问的项目Fork
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
roslyn
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
8058ba4e
编写于
5月 07, 2017
作者:
S
Shyam N
提交者:
GitHub
5月 07, 2017
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #19282 from shyamnamboodiripad/FixPartialMethodInstrumentation
Fix partial method instrumentation
上级
6a463b29
8cc7daac
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
409 addition
and
47 deletion
+409
-47
src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs
src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs
+11
-1
src/Compilers/CSharp/Test/Emit/Emit/DynamicAnalysis/DynamicInstrumentationTests.cs
.../Emit/Emit/DynamicAnalysis/DynamicInstrumentationTests.cs
+174
-2
src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs
src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs
+37
-35
src/Compilers/VisualBasic/Portable/CodeGen/EmitExpression.vb
src/Compilers/VisualBasic/Portable/CodeGen/EmitExpression.vb
+12
-7
src/Compilers/VisualBasic/Test/Emit/Emit/DynamicAnalysis/DynamicInstrumentationTests.vb
.../Emit/Emit/DynamicAnalysis/DynamicInstrumentationTests.vb
+175
-2
未找到文件。
src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs
浏览文件 @
8058ba4e
...
...
@@ -2719,7 +2719,17 @@ private void EmitMethodDefIndexExpression(BoundMethodDefIndex node)
Debug
.
Assert
(
node
.
Method
.
IsDefinition
);
Debug
.
Assert
(
node
.
Type
.
SpecialType
==
SpecialType
.
System_Int32
);
_builder
.
EmitOpCode
(
ILOpCode
.
Ldtoken
);
EmitSymbolToken
(
node
.
Method
,
node
.
Syntax
,
null
,
encodeAsRawDefinitionToken
:
true
);
// For partial methods, we emit pseudo token based on the symbol for the partial
// definition part as opposed to the symbol for the partial implementation part.
// We will need to resolve the symbol associated with each pseudo token in order
// to compute the real method definition tokens later. For partial methods, this
// resolution can only succeed if the associated symbol is the symbol for the
// partial definition and not the symbol for the partial implementation (see
// MethodSymbol.ResolvedMethodImpl()).
var
symbol
=
node
.
Method
.
PartialDefinitionPart
??
node
.
Method
;
EmitSymbolToken
(
symbol
,
node
.
Syntax
,
null
,
encodeAsRawDefinitionToken
:
true
);
}
private
void
EmitMaximumMethodDefIndexExpression
(
BoundMaximumMethodDefIndex
node
)
...
...
src/Compilers/CSharp/Test/Emit/Emit/DynamicAnalysis/DynamicInstrumentationTests.cs
浏览文件 @
8058ba4e
...
...
@@ -2380,7 +2380,7 @@ int P2
}
"
;
var
verifier
=
CompileAndVerify
(
source
+
InstrumentationHelperSource
,
options
:
TestOptions
.
ReleaseDll
);
AssertNotInstrumented
(
verifier
,
"C.P1.get"
);
AssertNotInstrumented
(
verifier
,
"C.P1.set"
);
AssertNotInstrumented
(
verifier
,
"C.<get_P1>g__L11_0"
);
...
...
@@ -2526,7 +2526,7 @@ class C
}
"
;
var
verifier
=
CompileAndVerify
(
source
+
InstrumentationHelperSource
,
options
:
TestOptions
.
ReleaseDll
);
AssertNotInstrumented
(
verifier
,
"C.P1.get"
);
AssertNotInstrumented
(
verifier
,
"C.P1.set"
);
AssertNotInstrumented
(
verifier
,
"C.E1.add"
);
...
...
@@ -2612,6 +2612,178 @@ class D
AssertInstrumented
(
verifier
,
"D.M"
);
}
[
Fact
]
public
void
TestPartialMethodsWithImplementation
()
{
var
source
=
@"
using System;
public partial class Class1<T>
{
partial void Method1<U>(int x);
public void Method2(int x)
{
Console.WriteLine($""Method2: x = {x}"");
Method1<T>(x);
}
}
public partial class Class1<T>
{
partial void Method1<U>(int x)
{
Console.WriteLine($""Method1: x = {x}"");
if (x > 0)
{
Console.WriteLine(""Method1: x > 0"");
Method1<U>(0);
}
else if (x < 0)
{
Console.WriteLine(""Method1: x < 0"");
}
}
}
public class Program
{
public static void Main(string[] args)
{
Test();
Microsoft.CodeAnalysis.Runtime.Instrumentation.FlushPayload();
}
static void Test()
{
Console.WriteLine(""Test"");
var c = new Class1<int>();
c.Method2(1);
}
}
"
+
InstrumentationHelperSource
;
var
checker
=
new
CSharpInstrumentationChecker
();
checker
.
Method
(
1
,
1
,
"partial void Method1<U>(int x)"
)
.
True
(
@"Console.WriteLine($""Method1: x = {x}"");"
)
.
True
(
@"Console.WriteLine(""Method1: x > 0"");"
)
.
True
(
"Method1<U>(0);"
)
.
False
(
@"Console.WriteLine(""Method1: x < 0"");"
)
.
True
(
"x < 0)"
)
.
True
(
"x > 0)"
);
checker
.
Method
(
2
,
1
,
"public void Method2(int x)"
)
.
True
(
@"Console.WriteLine($""Method2: x = {x}"");"
)
.
True
(
"Method1<T>(x);"
);
checker
.
Method
(
3
,
1
,
".ctor()"
,
expectBodySpan
:
false
);
checker
.
Method
(
4
,
1
,
"public static void Main(string[] args)"
)
.
True
(
"Test();"
)
.
True
(
"Microsoft.CodeAnalysis.Runtime.Instrumentation.FlushPayload();"
);
checker
.
Method
(
5
,
1
,
"static void Test()"
)
.
True
(
@"Console.WriteLine(""Test"");"
)
.
True
(
"var c = new Class1<int>();"
)
.
True
(
"c.Method2(1);"
);
checker
.
Method
(
8
,
1
)
.
True
()
.
False
()
.
True
()
.
True
()
.
True
()
.
True
()
.
True
()
.
True
()
.
True
()
.
True
()
.
True
()
.
True
()
.
True
();
var
expectedOutput
=
@"Test
Method2: x = 1
Method1: x = 1
Method1: x > 0
Method1: x = 0
"
+
checker
.
ExpectedOutput
;
var
verifier
=
CompileAndVerify
(
source
,
expectedOutput
,
options
:
TestOptions
.
ReleaseExe
);
checker
.
CompleteCheck
(
verifier
.
Compilation
,
source
);
verifier
.
VerifyDiagnostics
();
verifier
=
CompileAndVerify
(
source
,
expectedOutput
,
options
:
TestOptions
.
DebugExe
);
checker
.
CompleteCheck
(
verifier
.
Compilation
,
source
);
verifier
.
VerifyDiagnostics
();
}
[
Fact
]
public
void
TestPartialMethodsWithoutImplementation
()
{
var
source
=
@"
using System;
public partial class Class1<T>
{
partial void Method1<U>(int x);
public void Method2(int x)
{
Console.WriteLine($""Method2: x = {x}"");
Method1<T>(x);
}
}
public class Program
{
public static void Main(string[] args)
{
Test();
Microsoft.CodeAnalysis.Runtime.Instrumentation.FlushPayload();
}
static void Test()
{
Console.WriteLine(""Test"");
var c = new Class1<int>();
c.Method2(1);
}
}
"
+
InstrumentationHelperSource
;
var
checker
=
new
CSharpInstrumentationChecker
();
checker
.
Method
(
1
,
1
,
"public void Method2(int x)"
)
.
True
(
@"Console.WriteLine($""Method2: x = {x}"");"
);
checker
.
Method
(
2
,
1
,
".ctor()"
,
expectBodySpan
:
false
);
checker
.
Method
(
3
,
1
,
"public static void Main(string[] args)"
)
.
True
(
"Test();"
)
.
True
(
"Microsoft.CodeAnalysis.Runtime.Instrumentation.FlushPayload();"
);
checker
.
Method
(
4
,
1
,
"static void Test()"
)
.
True
(
@"Console.WriteLine(""Test"");"
)
.
True
(
"var c = new Class1<int>();"
)
.
True
(
"c.Method2(1);"
);
checker
.
Method
(
7
,
1
)
.
True
()
.
False
()
.
True
()
.
True
()
.
True
()
.
True
()
.
True
()
.
True
()
.
True
()
.
True
()
.
True
()
.
True
()
.
True
();
var
expectedOutput
=
@"Test
Method2: x = 1
"
+
checker
.
ExpectedOutput
;
var
verifier
=
CompileAndVerify
(
source
,
expectedOutput
,
options
:
TestOptions
.
ReleaseExe
);
checker
.
CompleteCheck
(
verifier
.
Compilation
,
source
);
verifier
.
VerifyDiagnostics
();
verifier
=
CompileAndVerify
(
source
,
expectedOutput
,
options
:
TestOptions
.
DebugExe
);
checker
.
CompleteCheck
(
verifier
.
Compilation
,
source
);
verifier
.
VerifyDiagnostics
();
}
private
static
void
AssertNotInstrumented
(
CompilationVerifier
verifier
,
string
qualifiedMethodName
)
=>
AssertInstrumented
(
verifier
,
qualifiedMethodName
,
expected
:
false
);
...
...
src/Compilers/Core/Portable/PEWriter/MetadataWriter.cs
浏览文件 @
8058ba4e
...
...
@@ -95,7 +95,7 @@ internal abstract partial class MetadataWriter
this
.
Context
=
context
;
this
.
messageProvider
=
messageProvider
;
_cancellationToken
=
cancellationToken
;
this
.
metadata
=
metadata
;
_debugMetadataOpt
=
debugMetadataOpt
;
_dynamicAnalysisDataWriterOpt
=
dynamicAnalysisDataWriterOpt
;
...
...
@@ -322,7 +322,7 @@ private bool IsMinimalDelta
/// The greatest index given to any method definition.
/// </summary>
protected
abstract
int
GreatestMethodDefIndex
{
get
;
}
/// <summary>
/// Return true and full metadata handle of the type reference
/// if the reference is available in the current generation.
...
...
@@ -423,9 +423,9 @@ private bool IsMinimalDelta
// Shared builder (reference equals heaps) if we are embedding Portable PDB into the metadata stream.
// Null otherwise.
protected
readonly
MetadataBuilder
_debugMetadataOpt
;
internal
bool
EmitStandaloneDebugMetadata
=>
_debugMetadataOpt
!=
null
&&
metadata
!=
_debugMetadataOpt
;
private
readonly
DynamicAnalysisDataWriter
_dynamicAnalysisDataWriterOpt
;
private
readonly
Dictionary
<
ICustomAttribute
,
BlobHandle
>
_customAttributeSignatureIndex
=
new
Dictionary
<
ICustomAttribute
,
BlobHandle
>();
...
...
@@ -611,8 +611,8 @@ private ImmutableArray<IParameterDefinition> GetParametersToEmitCore(IMethodDefi
// No explicit param row is needed if param has no flags (other than optionally IN),
// no name and no references to the param row, such as CustomAttribute, Constant, or FieldMarshal
if
(
parDef
.
Name
!=
String
.
Empty
||
parDef
.
HasDefaultValue
||
parDef
.
IsOptional
||
parDef
.
IsOut
||
parDef
.
IsMarshalledExplicitly
||
if
(
parDef
.
Name
!=
String
.
Empty
||
parDef
.
HasDefaultValue
||
parDef
.
IsOptional
||
parDef
.
IsOut
||
parDef
.
IsMarshalledExplicitly
||
IteratorHelper
.
EnumerableIsNotEmpty
(
parDef
.
GetAttributes
(
Context
)))
{
if
(
builder
!=
null
)
...
...
@@ -675,7 +675,7 @@ private void CreateInitialAssemblyRefIndex()
private
void
CreateInitialFileRefIndex
()
{
Debug
.
Assert
(!
_tableIndicesAreComplete
);
foreach
(
IFileReference
fileRef
in
module
.
GetFiles
(
Context
))
{
string
key
=
fileRef
.
FileName
;
...
...
@@ -1153,7 +1153,7 @@ private BlobHandle GetMethodSignatureHandleAndBlob(IMethodReference methodRefere
var
builder
=
PooledBlobBuilder
.
GetInstance
();
var
encoder
=
new
BlobEncoder
(
builder
).
MethodSignature
(
new
SignatureHeader
((
byte
)
methodReference
.
CallingConvention
).
CallingConvention
,
new
SignatureHeader
((
byte
)
methodReference
.
CallingConvention
).
CallingConvention
,
methodReference
.
GenericParameterCount
,
isInstanceMethod
:
(
methodReference
.
CallingConvention
&
CallingConvention
.
HasThis
)
!=
0
);
...
...
@@ -1724,10 +1724,10 @@ public void WriteMetadataAndIL(PdbWriter nativePdbWriterOpt, Stream metadataStre
BuildMetadataAndIL
(
nativePdbWriterOpt
,
ilBuilder
,
ilBuilder
,
mappedFieldDataBuilder
,
managedResourceDataBuilder
,
out
Blob
mvidFixup
,
out
Blob
mvidFixup
,
out
Blob
mvidStringFixup
);
var
typeSystemRowCounts
=
metadata
.
GetRowCounts
();
...
...
@@ -1791,14 +1791,14 @@ public void WriteMetadataAndIL(PdbWriter nativePdbWriterOpt, Stream metadataStre
_tableIndicesAreComplete
=
true
;
ReportReferencesToAddedSymbols
();
BlobBuilder
dynamicAnalysisDataOpt
=
null
;
if
(
_dynamicAnalysisDataWriterOpt
!=
null
)
{
dynamicAnalysisDataOpt
=
new
BlobBuilder
();
_dynamicAnalysisDataWriterOpt
.
SerializeMetadataTables
(
dynamicAnalysisDataOpt
);
}
PopulateTypeSystemTables
(
methodBodyOffsets
,
mappedFieldDataBuilder
,
managedResourceDataBuilder
,
dynamicAnalysisDataOpt
,
out
mvidFixup
);
}
...
...
@@ -1948,7 +1948,7 @@ private void PopulateAssemblyTableRows()
name
:
GetStringHandleForPathAndCheckLength
(
module
.
Name
,
module
),
culture
:
metadata
.
GetOrAddString
(
sourceAssembly
.
Identity
.
CultureName
));
}
private
void
PopulateCustomAttributeTableRows
(
ImmutableArray
<
IGenericParameter
>
sortedGenericParameters
)
{
if
(
this
.
IsFullMetadata
)
...
...
@@ -2278,9 +2278,9 @@ private void PopulateFieldMarshalTableRows()
var
marshallingInformation
=
parDef
.
MarshallingInformation
;
BlobHandle
descriptor
=
(
marshallingInformation
!=
null
)
?
GetMarshallingDescriptorHandle
(
marshallingInformation
)
:
GetMarshallingDescriptorHandle
(
parDef
.
MarshallingDescriptor
);
BlobHandle
descriptor
=
(
marshallingInformation
!=
null
)
?
GetMarshallingDescriptorHandle
(
marshallingInformation
)
:
GetMarshallingDescriptorHandle
(
parDef
.
MarshallingDescriptor
);
metadata
.
AddMarshallingDescriptor
(
parent
:
GetParameterHandle
(
parDef
),
...
...
@@ -2450,7 +2450,7 @@ private void PopulateInterfaceImplTableRows()
}
}
}
private
void
PopulateManifestResourceTableRows
(
BlobBuilder
resourceDataWriter
,
BlobBuilder
dynamicAnalysisDataOpt
)
{
if
(
dynamicAnalysisDataOpt
!=
null
)
...
...
@@ -2462,7 +2462,7 @@ private void PopulateManifestResourceTableRows(BlobBuilder resourceDataWriter, B
offset
:
GetManagedResourceOffset
(
dynamicAnalysisDataOpt
,
resourceDataWriter
)
);
}
foreach
(
var
resource
in
this
.
module
.
GetResources
(
Context
))
{
EntityHandle
implementation
;
...
...
@@ -2497,11 +2497,11 @@ private void PopulateMemberRefTableRows()
{
metadata
.
AddMemberReference
(
parent
:
GetMemberReferenceParent
(
memberRef
),
name
:
GetStringHandleForNameAndCheckLength
(
memberRef
.
Name
,
memberRef
),
name
:
GetStringHandleForNameAndCheckLength
(
memberRef
.
Name
,
memberRef
),
signature
:
GetMemberReferenceSignatureHandle
(
memberRef
));
}
}
private
void
PopulateMethodImplTableRows
()
{
metadata
.
SetCapacity
(
TableIndex
.
MethodImpl
,
methodImplList
.
Count
);
...
...
@@ -2514,7 +2514,7 @@ private void PopulateMethodImplTableRows()
methodDeclaration
:
GetMethodDefinitionOrReferenceHandle
(
methodImplementation
.
ImplementedMethod
));
}
}
private
void
PopulateMethodSpecTableRows
()
{
var
methodSpecs
=
this
.
GetMethodSpecs
();
...
...
@@ -2652,7 +2652,7 @@ private void PopulateModuleTableRow(out Blob mvidFixup)
encId
:
metadata
.
GetOrAddGuid
(
EncId
),
encBaseId
:
metadata
.
GetOrAddGuid
(
EncBaseId
));
}
private
void
PopulateParamTableRows
()
{
var
parameterDefs
=
this
.
GetParameterDefs
();
...
...
@@ -2680,7 +2680,7 @@ private void PopulatePropertyTableRows()
signature
:
GetPropertySignatureHandle
(
propertyDef
));
}
}
private
void
PopulateTypeDefTableRows
()
{
var
typeDefs
=
this
.
GetTypeDefs
();
...
...
@@ -2863,7 +2863,7 @@ private int[] SerializeMethodBodies(BlobBuilder ilBuilder, PdbWriter nativePdbWr
}
_dynamicAnalysisDataWriterOpt
?.
SerializeMethodDynamicAnalysisData
(
body
);
bodyOffsets
[
methodRid
-
1
]
=
bodyOffset
;
methodRid
++;
...
...
@@ -2891,11 +2891,11 @@ private int SerializeMethodBody(MethodBodyStreamEncoder encoder, IMethodBody met
}
var
encodedBody
=
encoder
.
AddMethodBody
(
codeSize
:
methodBody
.
IL
.
Length
,
maxStack
:
methodBody
.
MaxStack
,
exceptionRegionCount
:
exceptionRegions
.
Length
,
codeSize
:
methodBody
.
IL
.
Length
,
maxStack
:
methodBody
.
MaxStack
,
exceptionRegionCount
:
exceptionRegions
.
Length
,
hasSmallExceptionRegions
:
MayUseSmallExceptionHeaders
(
exceptionRegions
),
localVariablesSignature
:
localSignatureHandleOpt
,
localVariablesSignature
:
localSignatureHandleOpt
,
attributes
:
(
methodBody
.
LocalsAreZeroed
?
MethodBodyAttributes
.
InitLocals
:
0
));
// Don't do small body method caching during deterministic builds until this issue is fixed
...
...
@@ -3083,7 +3083,7 @@ private ReservedBlob<UserStringHandle> ReserveUserString(int length)
internal
const
uint
LiteralGreatestMethodDefinitionToken
=
0x40000000
;
internal
const
uint
SourceDocumentIndex
=
0x20000000
;
internal
const
uint
ModuleVersionIdStringToken
=
0x80000000
;
private
void
WriteInstructions
(
Blob
finalIL
,
ImmutableArray
<
byte
>
generatedIL
,
ref
UserStringHandle
mvidStringHandle
,
ref
Blob
mvidStringFixup
)
{
// write the raw body first and then patch tokens:
...
...
@@ -3119,7 +3119,9 @@ private void WriteInstructions(Blob finalIL, ImmutableArray<byte> generatedIL, r
switch
((
uint
)
tokenMask
)
{
case
LiteralMethodDefinitionToken
:
token
=
MetadataTokens
.
GetToken
(
ResolveEntityHandleFromPseudoToken
(
pseudoToken
&
0x00ffffff
))
&
0x00ffffff
;
// Crash the compiler if pseudo token fails to resolve to a MethodDefinitionHandle.
var
handle
=
(
MethodDefinitionHandle
)
ResolveEntityHandleFromPseudoToken
(
pseudoToken
&
0x00ffffff
);
token
=
MetadataTokens
.
GetToken
(
handle
)
&
0x00ffffff
;
break
;
case
LiteralGreatestMethodDefinitionToken
:
token
=
GreatestMethodDefIndex
;
...
...
@@ -3137,7 +3139,7 @@ private void WriteInstructions(Blob finalIL, ImmutableArray<byte> generatedIL, r
offset
+=
4
;
break
;
}
case
OperandType
.
InlineString
:
{
writer
.
Offset
=
offset
;
...
...
@@ -3221,7 +3223,7 @@ private void SerializeMethodBodyExceptionHandlerTable(ExceptionRegionEncoder enc
region
.
TryLength
,
region
.
HandlerStartOffset
,
region
.
HandlerLength
,
(
exceptionType
!=
null
)
?
GetTypeHandle
(
exceptionType
)
:
default
(
EntityHandle
),
(
exceptionType
!=
null
)
?
GetTypeHandle
(
exceptionType
)
:
default
(
EntityHandle
),
region
.
FilterDecisionStartOffset
);
}
}
...
...
@@ -3380,7 +3382,7 @@ private void SerializeMetadataExpression(LiteralEncoder encoder, IMetadataExpres
{
CustomAttributeElementTypeEncoder
typeEncoder
;
encoder
.
TaggedScalar
(
out
typeEncoder
,
out
scalarEncoder
);
// special case null argument assigned to Object parameter - treat as null string
if
(
c
!=
null
&&
c
.
Value
==
null
&&
...
...
@@ -3405,7 +3407,7 @@ private void SerializeMetadataExpression(LiteralEncoder encoder, IMetadataExpres
scalarEncoder
.
NullArray
();
return
;
}
Debug
.
Assert
(!
module
.
IsPlatformType
(
c
.
Type
,
PlatformType
.
SystemType
)
||
c
.
Value
==
null
);
scalarEncoder
.
Constant
(
c
.
Value
);
}
...
...
@@ -3599,7 +3601,7 @@ private void SerializePermissionSet(IEnumerable<ICustomAttribute> permissionSet,
private
void
SerializeReturnValueAndParameters
(
MethodSignatureEncoder
encoder
,
ISignature
signature
,
ImmutableArray
<
IParameterTypeInformation
>
varargParameters
)
{
var
declaredParameters
=
signature
.
GetParameters
(
Context
);
var
returnType
=
signature
.
GetType
(
Context
);
var
returnType
=
signature
.
GetType
(
Context
);
ReturnTypeEncoder
returnTypeEncoder
;
ParametersEncoder
parametersEncoder
;
...
...
src/Compilers/VisualBasic/Portable/CodeGen/EmitExpression.vb
浏览文件 @
8058ba4e
' Copyright (c) Microsoft. All Rights Reserved. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
Imports
System
Imports
System.Collections.Generic
Imports
System.Collections.Immutable
Imports
System.Diagnostics
Imports
System.Linq
Imports
System.Reflection.Metadata
Imports
Microsoft.CodeAnalysis.CodeGen
Imports
Microsoft.CodeAnalysis.VisualBasic.Symbols
Imports
TypeKind
=
Microsoft
.
CodeAnalysis
.
TypeKind
Namespace
Microsoft.CodeAnalysis.VisualBasic.CodeGen
Friend
Partial
Class
CodeGenerator
Partial
Friend
Class
CodeGenerator
Private
_recursionDepth
As
Integer
Private
Class
EmitCancelledException
...
...
@@ -2205,7 +2200,17 @@ Namespace Microsoft.CodeAnalysis.VisualBasic.CodeGen
Debug
.
Assert
(
node
.
Method
.
IsDefinition
)
Debug
.
Assert
(
node
.
Type
.
SpecialType
=
SpecialType
.
System_Int32
)
_builder
.
EmitOpCode
(
ILOpCode
.
Ldtoken
)
EmitSymbolToken
(
node
.
Method
,
node
.
Syntax
,
encodeAsRawDefinitionToken
:
=
True
)
' For partial methods, we emit pseudo token based on the symbol for the partial
' definition part as opposed to the symbol for the partial implementation part.
' We will need to resolve the symbol associated with each pseudo token in order
' to compute the real method definition tokens later. For partial methods, this
' resolution can only succeed if the associated symbol is the symbol for the
' partial definition and not the symbol for the partial implementation (see
' MethodSymbol.ResolvedMethodImpl()).
Dim
symbol
=
If
(
node
.
Method
.
PartialDefinitionPart
,
node
.
Method
)
EmitSymbolToken
(
symbol
,
node
.
Syntax
,
encodeAsRawDefinitionToken
:
=
True
)
End
Sub
Private
Sub
EmitMaximumMethodDefIndexExpression
(
node
As
BoundMaximumMethodDefIndex
)
...
...
src/Compilers/VisualBasic/Test/Emit/Emit/DynamicAnalysis/DynamicInstrumentationTests.vb
浏览文件 @
8058ba4e
...
...
@@ -7,8 +7,6 @@ Imports Microsoft.CodeAnalysis.Test.Utilities
Imports
Microsoft.CodeAnalysis.Test.Utilities.VBInstrumentationChecker
Imports
Microsoft.CodeAnalysis.VisualBasic
Imports
Microsoft.CodeAnalysis.VisualBasic.UnitTests
Imports
Roslyn.Test.Utilities
Imports
Xunit
Namespace
Microsoft.CodeAnalysis.VisualBasic.DynamicAnalysis.UnitTests
...
...
@@ -2368,6 +2366,173 @@ End Class
AssertInstrumented
(
verifier
,
"D.M"
)
End
Sub
<
Fact
>
Public
Sub
TestPartialMethodsWithImplementation
()
Dim
testSource
=
<
file
name
=
"c.vb"
>
<
!
[
CDATA
[
Imports
System
Partial
Class
Class1
Private
Partial
Sub
Method1
(
x
as
Integer
)
End
Sub
Public
Sub
Method2
(
x
as
Integer
)
Console
.
WriteLine
(
"Method2: x = {0}"
,
x
)
Method1
(
x
)
End
Sub
End
Class
Partial
Class
Class1
Private
Sub
Method1
(
x
as
Integer
)
Console
.
WriteLine
(
"Method1: x = {0}"
,
x
)
If
x
>
0
Console
.
WriteLine
(
"Method1: x > 0"
)
Method1
(
0
)
ElseIf
x
<
0
Console
.
WriteLine
(
"Method1: x < 0"
)
End
If
End
Sub
End
Class
Module
Program
Public
Sub
Main
()
Test
()
Microsoft
.
CodeAnalysis
.
Runtime
.
Instrumentation
.
FlushPayload
()
End
Sub
Sub
Test
()
Console
.
WriteLine
(
"Test"
)
Dim
c
=
new
Class1
()
c
.
Method2
(
1
)
End
Sub
End
Module
]]
>
</
file
>
Dim
source
=
<
compilation
>
<
%
=
testSource
%
>
<
%
=
InstrumentationHelperSource
%
>
</
compilation
>
Dim
checker
=
New
VBInstrumentationChecker
()
checker
.
Method
(
1
,
1
,
"New"
,
expectBodySpan
:
=
False
)
checker
.
Method
(
2
,
1
,
"Private Sub Method1(x as Integer)"
).
True
(
"Console.WriteLine(
""
Method1: x = {0}
""
, x)"
).
True
(
"Console.WriteLine(
""
Method1: x > 0
""
)"
).
True
(
"Method1(0)"
).
False
(
"Console.WriteLine(
""
Method1: x < 0
""
)"
).
True
(
"x < 0"
).
True
(
"x > 0"
)
checker
.
Method
(
3
,
1
,
"Public Sub Method2(x as Integer)"
).
True
(
"Console.WriteLine(
""
Method2: x = {0}
""
, x)"
).
True
(
"Method1(x)"
)
checker
.
Method
(
4
,
1
,
"Public Sub Main()"
).
True
(
"Test()"
).
True
(
"Microsoft.CodeAnalysis.Runtime.Instrumentation.FlushPayload()"
)
checker
.
Method
(
5
,
1
,
"Sub Test()"
).
True
(
"Console.WriteLine(
""
Test
""
)"
).
True
(
"new Class1()"
).
True
(
"c.Method2(1)"
)
checker
.
Method
(
8
,
1
).
True
().
False
().
True
().
True
().
True
().
True
().
True
().
True
().
True
().
True
().
True
()
Dim
expectedOutput
=
"Test
Method2: x = 1
Method1: x = 1
Method1: x > 0
Method1: x = 0
"
+
XCDataToString
(
checker
.
ExpectedOutput
)
Dim
verifier
=
CompileAndVerify
(
source
,
expectedOutput
,
options
:
=
TestOptions
.
ReleaseExe
)
checker
.
CompleteCheck
(
verifier
.
Compilation
,
testSource
)
verifier
.
VerifyDiagnostics
()
verifier
=
CompileAndVerify
(
source
,
expectedOutput
,
options
:
=
TestOptions
.
DebugExe
)
checker
.
CompleteCheck
(
verifier
.
Compilation
,
testSource
)
verifier
.
VerifyDiagnostics
()
End
Sub
<
Fact
>
Public
Sub
TestPartialMethodsWithoutImplementation
()
Dim
testSource
=
<
file
name
=
"c.vb"
>
<
!
[
CDATA
[
Imports
System
Partial
Class
Class1
Private
Partial
Sub
Method1
(
x
as
Integer
)
End
Sub
Public
Sub
Method2
(
x
as
Integer
)
Console
.
WriteLine
(
"Method2: x = {0}"
,
x
)
Method1
(
x
)
End
Sub
End
Class
Module
Program
Public
Sub
Main
()
Test
()
Microsoft
.
CodeAnalysis
.
Runtime
.
Instrumentation
.
FlushPayload
()
End
Sub
Sub
Test
()
Console
.
WriteLine
(
"Test"
)
Dim
c
=
new
Class1
()
c
.
Method2
(
1
)
End
Sub
End
Module
]]
>
</
file
>
Dim
source
=
<
compilation
>
<
%
=
testSource
%
>
<
%
=
InstrumentationHelperSource
%
>
</
compilation
>
Dim
checker
=
New
VBInstrumentationChecker
()
checker
.
Method
(
1
,
1
,
"New"
,
expectBodySpan
:
=
False
)
checker
.
Method
(
2
,
1
,
"Public Sub Method2(x as Integer)"
).
True
(
"Console.WriteLine(
""
Method2: x = {0}
""
, x)"
)
checker
.
Method
(
3
,
1
,
"Public Sub Main()"
).
True
(
"Test()"
).
True
(
"Microsoft.CodeAnalysis.Runtime.Instrumentation.FlushPayload()"
)
checker
.
Method
(
4
,
1
,
"Sub Test()"
).
True
(
"Console.WriteLine(
""
Test
""
)"
).
True
(
"new Class1()"
).
True
(
"c.Method2(1)"
)
checker
.
Method
(
7
,
1
).
True
().
False
().
True
().
True
().
True
().
True
().
True
().
True
().
True
().
True
().
True
()
Dim
expectedOutput
=
"Test
Method2: x = 1
"
+
XCDataToString
(
checker
.
ExpectedOutput
)
Dim
verifier
=
CompileAndVerify
(
source
,
expectedOutput
,
options
:
=
TestOptions
.
ReleaseExe
)
checker
.
CompleteCheck
(
verifier
.
Compilation
,
testSource
)
verifier
.
VerifyDiagnostics
()
verifier
=
CompileAndVerify
(
source
,
expectedOutput
,
options
:
=
TestOptions
.
DebugExe
)
checker
.
CompleteCheck
(
verifier
.
Compilation
,
testSource
)
verifier
.
VerifyDiagnostics
()
End
Sub
Private
Shared
Sub
AssertNotInstrumented
(
verifier
As
CompilationVerifier
,
qualifiedMethodName
As
String
)
AssertInstrumented
(
verifier
,
qualifiedMethodName
,
expected
:
=
False
)
End
Sub
...
...
@@ -2394,6 +2559,14 @@ End Class
emitOptions
:
=
EmitOptions
.
Default
.
WithInstrumentationKinds
(
ImmutableArray
.
Create
(
InstrumentationKind
.
TestCoverage
)))
End
Function
Private
Overloads
Function
CompileAndVerify
(
source
As
XElement
,
Optional
expectedOutput
As
String
=
Nothing
,
Optional
options
As
VisualBasicCompilationOptions
=
Nothing
)
As
CompilationVerifier
Return
CompileAndVerify
(
source
,
LatestVbReferences
,
expectedOutput
,
options
:
=
If
(
options
,
TestOptions
.
ReleaseExe
).
WithDeterministic
(
True
),
emitOptions
:
=
EmitOptions
.
Default
.
WithInstrumentationKinds
(
ImmutableArray
.
Create
(
InstrumentationKind
.
TestCoverage
)))
End
Function
Private
Overloads
Function
CompileAndVerify
(
source
As
String
,
Optional
expectedOutput
As
String
=
Nothing
,
Optional
options
As
VisualBasicCompilationOptions
=
Nothing
)
As
CompilationVerifier
Return
CompileAndVerify
(
source
,
LatestVbReferences
,
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录