本文整理汇总了C#中Microsoft.CodeAnalysis.CSharp.BoundBlock类的典型用法代码示例。如果您正苦于以下问题:C# BoundBlock类的具体用法?C# BoundBlock怎么用?C# BoundBlock使用的例子?那么恭喜您, 这里精选的类代码示例或许可以为您提供帮助。
BoundBlock类属于Microsoft.CodeAnalysis.CSharp命名空间,在下文中一共展示了BoundBlock类的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。
示例1: Rewrite
/// <summary>
/// The flow analysis pass. This pass reports required diagnostics for unreachable
/// statements and uninitialized variables (through the call to FlowAnalysisWalker.Analyze),
/// and inserts a final return statement if the end of a void-returning method is reachable.
/// </summary>
/// <param name="method">the method to be analyzed</param>
/// <param name="block">the method's body</param>
/// <param name="diagnostics">the receiver of the reported diagnostics</param>
/// <returns>the rewritten block for the method (with a return statement possibly inserted)</returns>
public static BoundBlock Rewrite(
MethodSymbol method,
BoundBlock block,
DiagnosticBag diagnostics)
{
var compilation = method.DeclaringCompilation;
if (method.ReturnsVoid || (object)method.IteratorElementType != null
|| (method.IsAsync && compilation.GetWellKnownType(WellKnownType.System_Threading_Tasks_Task) == method.ReturnType))
{
if (method.IsImplicitlyDeclared || Analyze(compilation, method, block, diagnostics))
{
// we don't analyze synthesized void methods.
var sourceMethod = method as SourceMethodSymbol;
block = AppendImplicitReturn(block, method, (object)sourceMethod != null ? sourceMethod.BlockSyntax : null);
}
}
else if (Analyze(compilation, method, block, diagnostics))
{
// If the method is a lambda expression being converted to a non-void delegate type
// and the end point is reachable then suppress the error here; a special error
// will be reported by the lambda binder.
Debug.Assert(method.MethodKind != MethodKind.AnonymousFunction);
// If there's more than one location, then the method is partial and we
// have already reported a non-void partial method error.
if (method.Locations.Length == 1)
{
diagnostics.Add(ErrorCode.ERR_ReturnExpected, method.Locations[0], method);
}
}
return block;
}
示例2: Rewrite
internal static BoundBlock Rewrite(SourceMethodSymbol sourceMethodSymbol, MethodContractSyntax contract, BoundBlock body, TypeCompilationState compilationState, DiagnosticBag diagsForCurrentMethod)
{
var binder = compilationState.Compilation.GetBinderFactory(sourceMethodSymbol.SyntaxTree)
.GetBinder(body.Syntax);
SyntheticBoundNodeFactory factory = new SyntheticBoundNodeFactory(sourceMethodSymbol, sourceMethodSymbol.SyntaxNode, compilationState, diagsForCurrentMethod);
var contractType = compilationState.Compilation.GetTypeByReflectionType(typeof(System.Diagnostics.Contracts.Contract), diagsForCurrentMethod);
var contractStatements = ArrayBuilder<BoundStatement>.GetInstance(contract.Requires.Count);
foreach (var requires in contract.Requires)
{
var condition = binder.BindExpression(requires.Condition, diagsForCurrentMethod);
var methodCall = factory.StaticCall(contractType, "Requires", condition);
var statement = factory.ExpressionStatement(methodCall);
contractStatements.Add(statement);
}
foreach (var requires in contract.Ensures)
{
var condition = binder.BindExpression(requires.Condition, diagsForCurrentMethod);
var methodCall = factory.StaticCall(contractType, "Ensures", condition);
var statement = factory.ExpressionStatement(methodCall);
contractStatements.Add(statement);
}
return body.Update(body.Locals, body.Statements.InsertRange(0, contractStatements.ToImmutableAndFree()));
}
示例3: VisitBlock
public override BoundNode VisitBlock(BoundBlock node)
{
if (node.WasCompilerGenerated || !this.generateDebugInfo)
{
return node.Update(node.LocalsOpt, VisitList(node.Statements));
}
BlockSyntax syntax = node.Syntax as BlockSyntax;
Debug.Assert(syntax != null);
var builder = ArrayBuilder<BoundStatement>.GetInstance();
var oBspan = syntax.OpenBraceToken.Span;
builder.Add(new BoundSequencePointWithSpan(syntax, null, oBspan));
for (int i = 0; i < node.Statements.Length; i++)
{
var stmt = (BoundStatement)Visit(node.Statements[i]);
if (stmt != null) builder.Add(stmt);
}
// no need to mark "}" on the outermost block
// as it cannot leave it normally. The block will have "return" at the end.
if (syntax.Parent == null || !(syntax.Parent.IsAnonymousFunction() || syntax.Parent is BaseMethodDeclarationSyntax))
{
var cBspan = syntax.CloseBraceToken.Span;
builder.Add(new BoundSequencePointWithSpan(syntax, null, cBspan));
}
return new BoundBlock(syntax, node.LocalsOpt, builder.ToImmutableAndFree(), node.HasErrors);
}
示例4: BoundLambda
public BoundLambda(CSharpSyntaxNode syntax, BoundBlock body, ImmutableArray<Diagnostic> diagnostics, Binder binder, TypeSymbol delegateType, bool inferReturnType)
: this(syntax, (LambdaSymbol)binder.ContainingMemberOrLambda, body, diagnostics, binder, delegateType)
{
if (inferReturnType)
{
this._inferredReturnType = InferReturnType(
this.Body,
this.Binder,
delegateType,
this.Symbol.IsAsync,
ref this._inferredReturnTypeUseSiteDiagnostics,
out this._refKind,
out this._inferredFromSingleType);
#if DEBUG
_hasInferredReturnType = true;
#endif
}
Debug.Assert(
syntax.IsAnonymousFunction() || // lambda expressions
syntax is ExpressionSyntax && LambdaUtilities.IsLambdaBody(syntax, allowReducedLambdas: true) || // query lambdas
LambdaUtilities.IsQueryPairLambda(syntax) // "pair" lambdas in queries
);
}
示例5: VisitSwitchStatement
// Rewriting for integral and string switch statements.
//
// For switch statements, we have an option of completely rewriting the switch header
// and switch sections into simpler constructs, i.e. we can rewrite the switch header
// using bound conditional goto statements and the rewrite the switch sections into
// bound labeleled statements.
// However, all the logic for emitting the switch jump tables is language agnostic
// and includes IL optimizations. Hence we delay the switch jump table generation
// till the emit phase. This way we also get additional benefit of sharing this code
// between both VB and C# compilers.
// For integral switch statements, we delay almost all the work
// to the emit phase.
// For string switch statements, we need to determine if we are generating a hash
// table based jump table or a non hash jump table, i.e. linear string comparisons
// with each case label. We use the Dev10 Heuristic to determine this
// (see SwitchStringJumpTableEmitter.ShouldGenerateHashTableSwitch() for details).
// If we are generating a hash table based jump table, we use a simple customizable
// hash function to hash the string constants corresponding to the case labels.
// See SwitchStringJumpTableEmitter.ComputeStringHash().
// We need to emit this function to compute the hash value into the compiler generate
// <PrivateImplementationDetails> class.
// If we have at least one string switch statement in a module that needs a
// hash table based jump table, we generate a single public string hash sythesized method
// that is shared across the module.
public override BoundNode VisitSwitchStatement(BoundSwitchStatement node)
{
var syntax = node.Syntax;
var rewrittenExpression = (BoundExpression)Visit(node.BoundExpression);
var rewrittenSections = VisitSwitchSections(node.SwitchSections);
var rewrittenStatement = MakeSwitchStatement(syntax, AddConditionSequencePoint(rewrittenExpression, node), rewrittenSections, node.ConstantTargetOpt, node.InnerLocals, node.BreakLabel, node);
if (!node.OuterLocals.IsEmpty)
{
rewrittenStatement = new BoundBlock(syntax, node.OuterLocals, ImmutableArray.Create(rewrittenStatement));
}
// Create the sequence point if generating debug info and
// node is not compiler generated
if (this.generateDebugInfo && !node.WasCompilerGenerated)
{
SwitchStatementSyntax switchSyntax = (SwitchStatementSyntax)syntax;
TextSpan switchSequencePointSpan = TextSpan.FromBounds(
switchSyntax.SwitchKeyword.SpanStart,
switchSyntax.CloseParenToken.Span.End);
return new BoundSequencePointWithSpan(
syntax: syntax,
statementOpt: rewrittenStatement,
span: switchSequencePointSpan,
hasErrors: false);
}
return rewrittenStatement;
}
示例6: VisitBlock
public override BoundNode VisitBlock(BoundBlock node)
{
if (!this.Instrument || (node != _rootStatement && (node.WasCompilerGenerated || node.Syntax.Kind() != SyntaxKind.Block)))
{
return node.Update(node.Locals, node.LocalFunctions, VisitList(node.Statements));
}
var builder = ArrayBuilder<BoundStatement>.GetInstance();
for (int i = 0; i < node.Statements.Length; i++)
{
var stmt = (BoundStatement)Visit(node.Statements[i]);
if (stmt != null) builder.Add(stmt);
}
LocalSymbol synthesizedLocal;
BoundStatement prologue = _instrumenter.CreateBlockPrologue(node, out synthesizedLocal);
if (prologue != null)
{
builder.Insert(0, prologue);
}
BoundStatement epilogue = _instrumenter.CreateBlockEpilogue(node);
if (epilogue != null)
{
builder.Add(epilogue);
}
return new BoundBlock(node.Syntax, synthesizedLocal == null ? node.Locals : node.Locals.Add(synthesizedLocal), node.LocalFunctions, builder.ToImmutableAndFree(), node.HasErrors);
}
示例7: Rewrite
/// <summary>
/// The flow analysis pass. This pass reports required diagnostics for unreachable
/// statements and uninitialized variables (through the call to FlowAnalysisWalker.Analyze),
/// and inserts a final return statement if the end of a void-returning method is reachable.
/// </summary>
/// <param name="method">the method to be analyzed</param>
/// <param name="block">the method's body</param>
/// <param name="diagnostics">the receiver of the reported diagnostics</param>
/// <param name="hasTrailingExpression">indicates whether this Script had a trailing expression</param>
/// <param name="originalBodyNested">the original method body is the last statement in the block</param>
/// <returns>the rewritten block for the method (with a return statement possibly inserted)</returns>
public static BoundBlock Rewrite(
MethodSymbol method,
BoundBlock block,
DiagnosticBag diagnostics,
bool hasTrailingExpression,
bool originalBodyNested)
{
#if DEBUG
// We should only see a trailingExpression if we're in a Script initializer.
Debug.Assert(!hasTrailingExpression || method.IsScriptInitializer);
var initialDiagnosticCount = diagnostics.ToReadOnly().Length;
#endif
var compilation = method.DeclaringCompilation;
if (method.ReturnsVoid || method.IsIterator ||
(method.IsAsync && compilation.GetWellKnownType(WellKnownType.System_Threading_Tasks_Task) == method.ReturnType))
{
// we don't analyze synthesized void methods.
if ((method.IsImplicitlyDeclared && !method.IsScriptInitializer) || Analyze(compilation, method, block, diagnostics))
{
block = AppendImplicitReturn(block, method, (CSharpSyntaxNode)(method as SourceMethodSymbol)?.BodySyntax, originalBodyNested);
}
}
else if (Analyze(compilation, method, block, diagnostics))
{
// If the method is a lambda expression being converted to a non-void delegate type
// and the end point is reachable then suppress the error here; a special error
// will be reported by the lambda binder.
Debug.Assert(method.MethodKind != MethodKind.AnonymousFunction);
// Add implicit "return default(T)" if this is a submission that does not have a trailing expression.
var submissionResultType = (method as SynthesizedInteractiveInitializerMethod)?.ResultType;
if (!hasTrailingExpression && ((object)submissionResultType != null))
{
Debug.Assert(submissionResultType.SpecialType != SpecialType.System_Void);
var trailingExpression = new BoundDefaultOperator(method.GetNonNullSyntaxNode(), submissionResultType);
var newStatements = block.Statements.Add(new BoundReturnStatement(trailingExpression.Syntax, trailingExpression));
block = new BoundBlock(block.Syntax, ImmutableArray<LocalSymbol>.Empty, newStatements) { WasCompilerGenerated = true };
#if DEBUG
// It should not be necessary to repeat analysis after adding this node, because adding a trailing
// return in cases where one was missing should never produce different Diagnostics.
var flowAnalysisDiagnostics = DiagnosticBag.GetInstance();
Debug.Assert(!Analyze(compilation, method, block, flowAnalysisDiagnostics));
Debug.Assert(flowAnalysisDiagnostics.ToReadOnly().SequenceEqual(diagnostics.ToReadOnly().Skip(initialDiagnosticCount)));
flowAnalysisDiagnostics.Free();
#endif
}
// If there's more than one location, then the method is partial and we
// have already reported a non-void partial method error.
else if (method.Locations.Length == 1)
{
diagnostics.Add(ErrorCode.ERR_ReturnExpected, method.Locations[0], method);
}
}
return block;
}
示例8: CreateBlockPrologue
public override BoundStatement CreateBlockPrologue(BoundBlock original, out LocalSymbol synthesizedLocal)
{
BoundStatement previousPrologue = base.CreateBlockPrologue(original, out synthesizedLocal);
if (_methodBody == original)
{
_dynamicAnalysisSpans = _spansBuilder.ToImmutableAndFree();
// In the future there will be multiple analysis kinds.
const int analysisKind = 0;
ArrayTypeSymbol modulePayloadType = ArrayTypeSymbol.CreateCSharpArray(_methodBodyFactory.Compilation.Assembly, _payloadType);
// Synthesize the initialization of the instrumentation payload array, using concurrency-safe code:
//
// var payload = PID.PayloadRootField[methodIndex];
// if (payload == null)
// payload = Instrumentation.CreatePayload(mvid, methodIndex, fileIndex, ref PID.PayloadRootField[methodIndex], payloadLength);
BoundStatement payloadInitialization = _methodBodyFactory.Assignment(_methodBodyFactory.Local(_methodPayload), _methodBodyFactory.ArrayAccess(_methodBodyFactory.InstrumentationPayloadRoot(analysisKind, modulePayloadType), ImmutableArray.Create(_methodBodyFactory.MethodDefIndex(_method))));
BoundExpression mvid = _methodBodyFactory.ModuleVersionId();
BoundExpression methodToken = _methodBodyFactory.MethodDefIndex(_method);
BoundExpression fileIndex = _methodBodyFactory.SourceDocumentIndex(GetSourceDocument(_methodBody.Syntax));
BoundExpression payloadSlot = _methodBodyFactory.ArrayAccess(_methodBodyFactory.InstrumentationPayloadRoot(analysisKind, modulePayloadType), ImmutableArray.Create(_methodBodyFactory.MethodDefIndex(_method)));
BoundStatement createPayloadCall = _methodBodyFactory.Assignment(_methodBodyFactory.Local(_methodPayload), _methodBodyFactory.Call(null, _createPayload, mvid, methodToken, fileIndex, payloadSlot, _methodBodyFactory.Literal(_dynamicAnalysisSpans.Length)));
BoundExpression payloadNullTest = _methodBodyFactory.Binary(BinaryOperatorKind.ObjectEqual, _methodBodyFactory.SpecialType(SpecialType.System_Boolean), _methodBodyFactory.Local(_methodPayload), _methodBodyFactory.Null(_payloadType));
BoundStatement payloadIf = _methodBodyFactory.If(payloadNullTest, createPayloadCall);
Debug.Assert(synthesizedLocal == null);
synthesizedLocal = _methodPayload;
ArrayBuilder<BoundStatement> prologueStatements = ArrayBuilder<BoundStatement>.GetInstance(previousPrologue == null ? 3 : 4);
prologueStatements.Add(payloadInitialization);
prologueStatements.Add(payloadIf);
if (_methodEntryInstrumentation != null)
{
prologueStatements.Add(_methodEntryInstrumentation);
}
if (previousPrologue != null)
{
prologueStatements.Add(previousPrologue);
}
return _methodBodyFactory.StatementList(prologueStatements.ToImmutableAndFree());
}
return previousPrologue;
}
示例9: AppendImplicitReturn
private static BoundBlock AppendImplicitReturn(BoundBlock body, MethodSymbol method, CSharpSyntaxNode syntax, bool originalBodyNested)
{
if (originalBodyNested)
{
var statements = body.Statements;
int n = statements.Length;
var builder = ArrayBuilder<BoundStatement>.GetInstance(n);
builder.AddRange(statements, n - 1);
builder.Add(AppendImplicitReturn((BoundBlock)statements[n - 1], method, syntax));
return body.Update(body.Locals, ImmutableArray<LocalFunctionSymbol>.Empty, builder.ToImmutableAndFree());
}
else
{
return AppendImplicitReturn(body, method, syntax);
}
}
示例10: InferReturnType
private static TypeSymbol InferReturnType(BoundBlock block, Binder binder, bool isAsync, ref HashSet<DiagnosticInfo> useSiteDiagnostics, out bool inferredFromSingleType)
{
int numberOfDistinctReturns;
var resultTypes = BlockReturns.GetReturnTypes(block, out numberOfDistinctReturns);
inferredFromSingleType = numberOfDistinctReturns < 2;
TypeSymbol bestResultType;
if (resultTypes.IsDefaultOrEmpty)
{
bestResultType = null;
}
else if (resultTypes.Length == 1)
{
bestResultType = resultTypes[0];
}
else
{
bestResultType = BestTypeInferrer.InferBestType(resultTypes, binder.Conversions, ref useSiteDiagnostics);
}
if (!isAsync)
{
return bestResultType;
}
// Async:
if (resultTypes.IsEmpty)
{
// No return statements have expressions; inferred type Task:
return binder.Compilation.GetWellKnownType(WellKnownType.System_Threading_Tasks_Task);
}
if ((object)bestResultType == null || bestResultType.SpecialType == SpecialType.System_Void)
{
// If the best type was 'void', ERR_CantReturnVoid is reported while binding the "return void"
// statement(s).
return null;
}
// Some non-void best type T was found; infer type Task<T>:
return binder.Compilation.GetWellKnownType(WellKnownType.System_Threading_Tasks_Task_T).Construct(bestResultType);
}
示例11: VisitLocalFunctionOrLambda
private BoundNode VisitLocalFunctionOrLambda(BoundBlock body)
{
var oldPending = SavePending(); // We do not support branches *into* a lambda.
LocalState finalState = this.State;
this.State = ReachableState();
var oldPending2 = SavePending();
VisitAlways(body);
RestorePending(oldPending2); // process any forward branches within the lambda body
ImmutableArray<PendingBranch> pendingReturns = RemoveReturns();
RestorePending(oldPending);
IntersectWith(ref finalState, ref this.State);
foreach (PendingBranch returnBranch in pendingReturns)
{
this.State = returnBranch.State;
IntersectWith(ref finalState, ref this.State);
}
this.State = finalState;
return null;
}
示例12: AppendImplicitReturn
// insert the implicit "return" statement at the end of the method body
// Normally, we wouldn't bother attaching syntax trees to compiler-generated nodes, but these
// ones are going to have sequence points.
internal static BoundBlock AppendImplicitReturn(BoundBlock body, MethodSymbol method, CSharpSyntaxNode syntax = null)
{
Debug.Assert(body != null);
Debug.Assert(method != null);
if (syntax == null)
{
syntax = body.Syntax;
}
Debug.Assert(body.WasCompilerGenerated || syntax.IsKind(SyntaxKind.Block) || syntax.IsKind(SyntaxKind.ArrowExpressionClause));
BoundStatement ret = method.IsIterator
? (BoundStatement)BoundYieldBreakStatement.Synthesized(syntax)
: BoundReturnStatement.Synthesized(syntax, null);
// Implicitly added return for async method does not need sequence points since lowering would add one.
if (syntax.IsKind(SyntaxKind.Block) && !method.IsAsync)
{
var blockSyntax = (BlockSyntax)syntax;
ret = new BoundSequencePointWithSpan(
blockSyntax,
ret,
blockSyntax.CloseBraceToken.Span)
{ WasCompilerGenerated = true };
}
switch (body.Kind)
{
case BoundKind.Block:
var block = (BoundBlock)body;
return block.Update(block.Locals, block.LocalFunctions, block.Statements.Add(ret));
default:
return new BoundBlock(syntax, ImmutableArray<LocalSymbol>.Empty, ImmutableArray<LocalFunctionSymbol>.Empty, ImmutableArray.Create(ret, body));
}
}
示例13: VisitBlock
public override BoundNode VisitBlock(BoundBlock node)
{
AddVariables(node.Locals);
return base.VisitBlock(node);
}
示例14: VisitBlock
public override BoundNode VisitBlock(BoundBlock node)
{
return PossibleIteratorScope(node.LocalsOpt, () => (BoundStatement)base.VisitBlock(node));
}
示例15: BindMethodBody
// NOTE: can return null if the method has no body.
internal static BoundBlock BindMethodBody(MethodSymbol method, TypeCompilationState compilationState, DiagnosticBag diagnostics, bool generateDebugInfo, out ConsList<Imports> debugImports)
{
debugImports = null;
BoundStatement constructorInitializer = null;
BoundBlock body;
var compilation = method.DeclaringCompilation;
var sourceMethod = method as SourceMethodSymbol;
if ((object)sourceMethod != null)
{
if (sourceMethod.IsExtern)
{
if (sourceMethod.BlockSyntax == null)
{
// Generate warnings only if we are not generating ERR_ExternHasBody error
GenerateExternalMethodWarnings(sourceMethod, diagnostics);
}
return null;
}
else if (sourceMethod.IsParameterlessValueTypeConstructor(requireSynthesized: true))
{
// No body for default struct constructor.
return null;
}
var blockSyntax = sourceMethod.BlockSyntax;
if (blockSyntax != null)
{
var factory = compilation.GetBinderFactory(sourceMethod.SyntaxTree);
var inMethodBinder = factory.GetBinder(blockSyntax);
var binder = new ExecutableCodeBinder(blockSyntax, sourceMethod, inMethodBinder);
body = binder.BindBlock(blockSyntax, diagnostics);
if (generateDebugInfo)
{
debugImports = binder.ImportsList;
}
if (inMethodBinder.IsDirectlyInIterator)
{
foreach (var parameter in method.Parameters)
{
if (parameter.RefKind != RefKind.None)
{
diagnostics.Add(ErrorCode.ERR_BadIteratorArgType, parameter.Locations[0]);
}
else if (parameter.Type.IsUnsafe())
{
diagnostics.Add(ErrorCode.ERR_UnsafeIteratorArgType, parameter.Locations[0]);
}
}
if (sourceMethod.IsUnsafe && compilation.Options.AllowUnsafe) // Don't cascade
{
diagnostics.Add(ErrorCode.ERR_IllegalInnerUnsafe, sourceMethod.Locations[0]);
}
if (sourceMethod.IsVararg)
{
// error CS1636: __arglist is not allowed in the parameter list of iterators
diagnostics.Add(ErrorCode.ERR_VarargsIterator, sourceMethod.Locations[0]);
}
}
}
else // for [if (blockSyntax != null)]
{
var property = sourceMethod.AssociatedSymbol as SourcePropertySymbol;
if ((object)property != null && property.IsAutoProperty)
{
return MethodBodySynthesizer.ConstructAutoPropertyAccessorBody(sourceMethod);
}
if (sourceMethod.IsPrimaryCtor)
{
body = null;
}
else
{
return null;
}
}
}
else
{
// synthesized methods should return their bound bodies
body = null;
}
// delegates have constructors but not constructor initializers
if (method.MethodKind == MethodKind.Constructor && !method.ContainingType.IsDelegateType())
{
var initializerInvocation = BindConstructorInitializer(method, diagnostics, compilation);
if (initializerInvocation != null)
{
constructorInitializer = new BoundExpressionStatement(initializerInvocation.Syntax, initializerInvocation) { WasCompilerGenerated = true };
Debug.Assert(initializerInvocation.HasAnyErrors || constructorInitializer.IsConstructorInitializer(), "Please keep this bound node in sync with BoundNodeExtensions.IsConstructorInitializer.");
}
}
//.........这里部分代码省略.........