public override BoundNode VisitLocalFunctionStatement(BoundLocalFunctionStatement node) { var oldCurrentFunction = _F.CurrentFunction; _F.CurrentFunction = node.Symbol; var result = base.VisitLocalFunctionStatement(node); _F.CurrentFunction = oldCurrentFunction; return(result); }
public override BoundNode VisitLocalFunctionStatement(BoundLocalFunctionStatement node) { if (IsInside && !node.WasCompilerGenerated) { foreach (var parameter in node.Symbol.Parameters) { _variablesDeclared.Add(parameter); } } return(base.VisitLocalFunctionStatement(node)); }
public override BoundNode VisitLocalFunctionStatement(BoundLocalFunctionStatement node) { var outerLocalFunction = _staticLocalFunction; if (node.Symbol.IsStaticLocalFunction) { _staticLocalFunction = node.Symbol; } var result = base.VisitLocalFunctionStatement(node); _staticLocalFunction = outerLocalFunction; return(result); }
public override BoundNode VisitLocalFunctionStatement(BoundLocalFunctionStatement node) { var origLabels = this.currentLabels; var origSeenAwait = _seenAwait; this.currentLabels = null; _seenAwait = false; base.VisitLocalFunctionStatement(node); this.currentLabels = origLabels; _seenAwait = origSeenAwait; return(null); }
public override BoundNode VisitLocalFunctionStatement(BoundLocalFunctionStatement node) { var oldContainingSymbol = _F.CurrentFunction; var oldAwaitFinallyFrame = _currentAwaitFinallyFrame; _F.CurrentFunction = node.Symbol; _currentAwaitFinallyFrame = new AwaitFinallyFrame(); var result = base.VisitLocalFunctionStatement(node); _F.CurrentFunction = oldContainingSymbol; _currentAwaitFinallyFrame = oldAwaitFinallyFrame; return(result); }
public override BoundNode VisitLocalFunctionStatement(BoundLocalFunctionStatement node) { _sawLocalFunctions = true; CheckRefReadOnlySymbols(node.Symbol); var typeParameters = node.Symbol.TypeParameters; if (typeParameters.Any(typeParameter => typeParameter.HasUnmanagedTypeConstraint)) { _factory.CompilationState.ModuleBuilderOpt?.EnsureIsUnmanagedAttributeExists(); } bool constraintsNeedNullableAttribute = typeParameters.Any( typeParameter => (typeParameter.HasReferenceTypeConstraint && typeParameter.ReferenceTypeConstraintIsNullable != null) || typeParameter.ConstraintTypesNoUseSiteDiagnostics.Any( typeConstraint => typeConstraint.NeedsNullableAttribute())); bool returnTypeNeedsNullableAttribute = node.Symbol.ReturnType.NeedsNullableAttribute(); bool parametersNeedNullableAttribute = node.Symbol.ParameterTypes.Any(parameter => parameter.NeedsNullableAttribute()); if (constraintsNeedNullableAttribute || returnTypeNeedsNullableAttribute || parametersNeedNullableAttribute) { _factory.CompilationState.ModuleBuilderOpt?.EnsureNullableAttributeExists(); } var oldContainingSymbol = _factory.CurrentFunction; try { _factory.CurrentFunction = node.Symbol; return(base.VisitLocalFunctionStatement(node)); } finally { _factory.CurrentFunction = oldContainingSymbol; } }
public override BoundNode VisitLocalFunctionStatement(BoundLocalFunctionStatement node) { return(VisitLocalFunctionOrLambda(node.Body)); }
public override BoundNode VisitLocalFunctionStatement(BoundLocalFunctionStatement node) { MakeSlots(node.Symbol.Parameters); return(base.VisitLocalFunctionStatement(node)); }
public override BoundNode VisitLocalFunctionStatement(BoundLocalFunctionStatement localFunc) { var oldSymbol = this.currentSymbol; var localFuncSymbol = localFunc.Symbol; this.currentSymbol = localFuncSymbol; var oldPending = SavePending(); // we do not support branches into a lambda // SPEC: The entry point to a local function is always reachable. // Captured variables are definitely assigned if they are definitely assigned on // all branches into the local function. var savedState = this.State; this.State = this.TopState(); if (!localFunc.WasCompilerGenerated) { EnterParameters(localFuncSymbol.Parameters); } // Captured variables are definitely assigned if they are assigned on // all branches into the local function, so we store all reads from // possibly unassigned captured variables and later report definite // assignment errors if any of the captured variables is not assigned // on a particular branch. // // Assignments to captured variables are also recorded, as calls to local functions // definitely assign captured variables if the variables are definitely assigned at // all branches out of the local function. var usages = GetOrCreateLocalFuncUsages(localFuncSymbol); var oldReads = usages.ReadVars.Clone(); usages.ReadVars.Clear(); var oldPending2 = SavePending(); // If this is an iterator, there's an implicit branch before the first statement // of the function where the enumerable is returned. if (localFuncSymbol.IsIterator) { PendingBranches.Add(new PendingBranch(null, this.State, null)); } VisitAlways(localFunc.Body); RestorePending(oldPending2); // process any forward branches within the lambda body ImmutableArray <PendingBranch> pendingReturns = RemoveReturns(); RestorePending(oldPending); Location location = null; if (!localFuncSymbol.Locations.IsDefaultOrEmpty) { location = localFuncSymbol.Locations[0]; } LeaveParameters(localFuncSymbol.Parameters, localFunc.Syntax, location); // Intersect the state of all branches out of the local function LocalState stateAtReturn = this.State; foreach (PendingBranch pending in pendingReturns) { this.State = pending.State; BoundNode branch = pending.Branch; // Pass the local function identifier as a location if the branch // is null or compiler generated. LeaveParameters(localFuncSymbol.Parameters, branch?.Syntax, branch?.WasCompilerGenerated == false ? null : location); Join(ref stateAtReturn, ref this.State); } // Check for changes to the possibly unassigned and assigned sets // of captured variables if (RecordChangedVars(ref usages.WrittenVars, ref stateAtReturn, ref oldReads, ref usages.ReadVars) && usages.LocalFuncVisited) { // If the sets have changed and we already used the results // of this local function in another computation, the previous // calculations may be invalid. We need to analyze until we // reach a fixed-point. The previous writes are always valid, // so they are stored in usages.WrittenVars, while the reads // may be invalidated by new writes, so we throw the results out. stateChangedAfterUse = true; usages.LocalFuncVisited = false; } this.State = savedState; this.currentSymbol = oldSymbol; return(null); }