提交 676e9455 编写于 作者: J John Hamby

Remove the notion of making decisions based on being within a method without a block.

上级 aa01de86
...@@ -25,7 +25,6 @@ internal sealed class DynamicAnalysisInjector : CompoundInstrumenter ...@@ -25,7 +25,6 @@ internal sealed class DynamicAnalysisInjector : CompoundInstrumenter
private readonly LocalSymbol _methodPayload; private readonly LocalSymbol _methodPayload;
private readonly DiagnosticBag _diagnostics; private readonly DiagnosticBag _diagnostics;
private readonly DebugDocumentProvider _debugDocumentProvider; private readonly DebugDocumentProvider _debugDocumentProvider;
private readonly bool _methodHasExplicitBlock;
private readonly SyntheticBoundNodeFactory _methodBodyFactory; private readonly SyntheticBoundNodeFactory _methodBodyFactory;
public static DynamicAnalysisInjector TryCreate(MethodSymbol method, BoundStatement methodBody, SyntheticBoundNodeFactory methodBodyFactory, DiagnosticBag diagnostics, DebugDocumentProvider debugDocumentProvider, Instrumenter previous) public static DynamicAnalysisInjector TryCreate(MethodSymbol method, BoundStatement methodBody, SyntheticBoundNodeFactory methodBodyFactory, DiagnosticBag diagnostics, DebugDocumentProvider debugDocumentProvider, Instrumenter previous)
...@@ -60,7 +59,6 @@ private DynamicAnalysisInjector(MethodSymbol method, BoundStatement methodBody, ...@@ -60,7 +59,6 @@ private DynamicAnalysisInjector(MethodSymbol method, BoundStatement methodBody,
_methodPayload = methodBodyFactory.SynthesizedLocal(_payloadType, kind: SynthesizedLocalKind.InstrumentationPayload, syntax: methodBody.Syntax); _methodPayload = methodBodyFactory.SynthesizedLocal(_payloadType, kind: SynthesizedLocalKind.InstrumentationPayload, syntax: methodBody.Syntax);
_diagnostics = diagnostics; _diagnostics = diagnostics;
_debugDocumentProvider = debugDocumentProvider; _debugDocumentProvider = debugDocumentProvider;
_methodHasExplicitBlock = MethodHasExplicitBlock(method);
_methodBodyFactory = methodBodyFactory; _methodBodyFactory = methodBodyFactory;
// The first point indicates entry into the method and has the span of the method definition. // The first point indicates entry into the method and has the span of the method definition.
...@@ -139,15 +137,7 @@ public override BoundStatement InstrumentContinueStatement(BoundContinueStatemen ...@@ -139,15 +137,7 @@ public override BoundStatement InstrumentContinueStatement(BoundContinueStatemen
public override BoundStatement InstrumentExpressionStatement(BoundExpressionStatement original, BoundStatement rewritten) public override BoundStatement InstrumentExpressionStatement(BoundExpressionStatement original, BoundStatement rewritten)
{ {
rewritten = base.InstrumentExpressionStatement(original, rewritten); return AddDynamicAnalysis(original, base.InstrumentExpressionStatement(original, rewritten));
if (!_methodHasExplicitBlock)
{
// The assignment statement for a property set method defined without a block is compiler generated, but requires instrumentation.
return CollectDynamicAnalysis(original, rewritten);
}
return AddDynamicAnalysis(original, rewritten);
} }
public override BoundStatement InstrumentFieldOrPropertyInitializer(BoundExpressionStatement original, BoundStatement rewritten) public override BoundStatement InstrumentFieldOrPropertyInitializer(BoundExpressionStatement original, BoundStatement rewritten)
...@@ -210,8 +200,10 @@ public override BoundStatement InstrumentReturnStatement(BoundReturnStatement or ...@@ -210,8 +200,10 @@ public override BoundStatement InstrumentReturnStatement(BoundReturnStatement or
rewritten = base.InstrumentReturnStatement(original, rewritten); rewritten = base.InstrumentReturnStatement(original, rewritten);
// A synthesized return statement that does not return a value never requires instrumentation. // A synthesized return statement that does not return a value never requires instrumentation.
// A property set method defined without a block has such a synthesized return statement. // A property set defined without a block has such a synthesized return statement.
if ((!_methodHasExplicitBlock || _methodBodyFactory.CurrentMethod.MethodKind == MethodKind.LambdaMethod) && ((BoundReturnStatement)original).ExpressionOpt != null) // A synthesized return statement that does return a value does require instrumentation.
// A method, property get, or lambda defined without a block has such a synthesized return statement.
if (ReturnsValueWithinExpressionBodiedConstruct(original))
{ {
// The return statement for value-returning methods defined without a block is compiler generated, but requires instrumentation. // The return statement for value-returning methods defined without a block is compiler generated, but requires instrumentation.
return CollectDynamicAnalysis(original, rewritten); return CollectDynamicAnalysis(original, rewritten);
...@@ -220,6 +212,25 @@ public override BoundStatement InstrumentReturnStatement(BoundReturnStatement or ...@@ -220,6 +212,25 @@ public override BoundStatement InstrumentReturnStatement(BoundReturnStatement or
return AddDynamicAnalysis(original, rewritten); return AddDynamicAnalysis(original, rewritten);
} }
private static bool ReturnsValueWithinExpressionBodiedConstruct(BoundReturnStatement returnStatement)
{
if (returnStatement.WasCompilerGenerated &&
returnStatement.ExpressionOpt != null &&
returnStatement.ExpressionOpt.Syntax != null)
{
SyntaxKind parentKind = returnStatement.ExpressionOpt.Syntax.Parent.Kind();
switch (parentKind)
{
case SyntaxKind.ParenthesizedLambdaExpression:
case SyntaxKind.SimpleLambdaExpression:
case SyntaxKind.ArrowExpressionClause:
return true;
}
}
return false;
}
public override BoundStatement InstrumentSwitchStatement(BoundSwitchStatement original, BoundStatement rewritten) public override BoundStatement InstrumentSwitchStatement(BoundSwitchStatement original, BoundStatement rewritten)
{ {
return AddDynamicAnalysis(original, base.InstrumentSwitchStatement(original, rewritten)); return AddDynamicAnalysis(original, base.InstrumentSwitchStatement(original, rewritten));
...@@ -351,17 +362,6 @@ private static SyntaxNode SyntaxForSpan(BoundStatement statement) ...@@ -351,17 +362,6 @@ private static SyntaxNode SyntaxForSpan(BoundStatement statement)
return syntaxForSpan; return syntaxForSpan;
} }
private static bool MethodHasExplicitBlock(MethodSymbol method)
{
SourceMethodSymbol asSourceMethod = method.OriginalDefinition as SourceMethodSymbol;
if ((object)asSourceMethod != null)
{
return asSourceMethod.BodySyntax is BlockSyntax;
}
return false;
}
private static MethodSymbol GetCreatePayload(CSharpCompilation compilation, SyntaxNode syntax, DiagnosticBag diagnostics) private static MethodSymbol GetCreatePayload(CSharpCompilation compilation, SyntaxNode syntax, DiagnosticBag diagnostics)
{ {
return (MethodSymbol)Binder.GetWellKnownTypeMember(compilation, WellKnownMember.Microsoft_CodeAnalysis_Runtime_Instrumentation__CreatePayload, diagnostics, syntax: syntax); return (MethodSymbol)Binder.GetWellKnownTypeMember(compilation, WellKnownMember.Microsoft_CodeAnalysis_Runtime_Instrumentation__CreatePayload, diagnostics, syntax: syntax);
......
...@@ -53,6 +53,8 @@ public static int Wilma ...@@ -53,6 +53,8 @@ public static int Wilma
} }
public static int Betty { get; } public static int Betty { get; }
public static int Pebbles { get; set; }
} }
"; ";
...@@ -66,9 +68,9 @@ public void TestSpansPresentInResource() ...@@ -66,9 +68,9 @@ public void TestSpansPresentInResource()
var reader = DynamicAnalysisDataReader.TryCreateFromPE(peReader, "<DynamicAnalysisData>"); var reader = DynamicAnalysisDataReader.TryCreateFromPE(peReader, "<DynamicAnalysisData>");
VerifyDocuments(reader, reader.Documents, VerifyDocuments(reader, reader.Documents,
@"'C:\myproject\doc1.cs' B2-C1-91-21-17-72-39-D7-D8-C8-AC-3C-09-F6-3C-FF-B7-E5-97-8E (SHA1)"); @"'C:\myproject\doc1.cs' FF-9A-1F-F4-03-A5-A1-F7-8D-CD-00-15-67-0E-BA-F7-23-9D-3F-0F (SHA1)");
Assert.Equal(10, reader.Methods.Length); Assert.Equal(12, reader.Methods.Length);
string[] sourceLines = ExampleSource.Split('\n'); string[] sourceLines = ExampleSource.Split('\n');
...@@ -96,7 +98,15 @@ public void TestSpansPresentInResource() ...@@ -96,7 +98,15 @@ public void TestSpansPresentInResource()
new SpanResult(21, 4, 21, 36, "public static int Betty { get; }"), new SpanResult(21, 4, 21, 36, "public static int Betty { get; }"),
new SpanResult(21, 30, 21, 34, "get")); new SpanResult(21, 30, 21, 34, "get"));
VerifySpans(reader, reader.Methods[6]); VerifySpans(reader, reader.Methods[6], sourceLines, // Pebbles get
new SpanResult(23, 4, 23, 43, "public static int Pebbles { get; set; }"),
new SpanResult(23, 32, 23, 36, "get"));
VerifySpans(reader, reader.Methods[7], sourceLines, // Pebbles set
new SpanResult(23, 4, 23, 43, "public static int Pebbles { get; set; }"),
new SpanResult(23, 37, 23, 41, "set"));
VerifySpans(reader, reader.Methods[8]);
} }
[Fact] [Fact]
...@@ -834,6 +844,18 @@ void L1() ...@@ -834,6 +844,18 @@ void L1()
); );
f(); f();
var f1 = new Func<int>(
() => { return 2; }
);
var f2 = new Func<int, int>(
(x) => x + 3
);
var f3 = new Func<int, int>(
x => x + 4
);
} }
} }
} }
...@@ -856,11 +878,17 @@ void L1() ...@@ -856,11 +878,17 @@ void L1()
new SpanResult(12, 8, 12, 21, "new D().M1()")); new SpanResult(12, 8, 12, 21, "new D().M1()"));
VerifySpans(reader, reader.Methods[3], sourceLines, VerifySpans(reader, reader.Methods[3], sourceLines,
new SpanResult(18, 4, 29, 5, "public void M1()"), new SpanResult(18, 4, 41, 5, "public void M1()"),
new SpanResult(20, 8, 20, 13, "L1()"), new SpanResult(20, 8, 20, 13, "L1()"),
new SpanResult(24, 22, 24, 23, "1"), new SpanResult(24, 22, 24, 23, "1"),
new SpanResult(23, 12, 25, 14, "var f = new Func<int>"), new SpanResult(23, 12, 25, 14, "var f = new Func<int>"),
new SpanResult(27, 12, 27, 16, "f()")); new SpanResult(27, 12, 27, 16, "f()"),
new SpanResult(30, 24, 30, 33, "return 2"),
new SpanResult(29, 12, 31, 14, "var f1 = new Func<int>"),
new SpanResult(34, 23, 34, 28, "x + 3"),
new SpanResult(33, 12, 35, 14, "var f2 = new Func<int, int>"),
new SpanResult(38, 21, 38, 26, "x + 4"),
new SpanResult(37, 12, 39, 14, "var f3 = new Func<int, int>"));
} }
[Fact] [Fact]
......
...@@ -891,10 +891,19 @@ void L1() ...@@ -891,10 +891,19 @@ void L1()
); );
var f1 = new Func<int>( var f1 = new Func<int>(
() => 1 () => 2
);
var f2 = new Func<int, int>(
(x) => x + 3
);
var f3 = new Func<int, int>(
x => x + 4
); );
f(); f();
f3(2);
} }
} }
...@@ -920,6 +929,11 @@ File 1 ...@@ -920,6 +929,11 @@ File 1
True True
False False
True True
False
True
True
True
True
True True
Method 5 Method 5
File 1 File 1
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册