@@ -505,30 +505,30 @@ private static ImmutableArray<VariableInfo> GetMethodParameters(Dictionary<ISymb
505505 /// variable we don't understand has <see cref="VariableStyle.None"/></param>
506506 private void GenerateVariableInfoMap (
507507 bool bestEffort ,
508- SemanticModel model ,
508+ SemanticModel semanticModel ,
509509 DataFlowAnalysis dataFlowAnalysisData ,
510510 Dictionary < ISymbol , List < SyntaxToken > > symbolMap ,
511511 bool isInPrimaryConstructorBaseType ,
512512 out Dictionary < ISymbol , VariableInfo > variableInfoMap ,
513513 out List < ISymbol > failedVariables )
514514 {
515- Contract . ThrowIfNull ( model ) ;
515+ Contract . ThrowIfNull ( semanticModel ) ;
516516 Contract . ThrowIfNull ( dataFlowAnalysisData ) ;
517517
518518 variableInfoMap = [ ] ;
519519 failedVariables = [ ] ;
520520
521521 // create map of each data
522- var capturedMap = new HashSet < ISymbol > ( dataFlowAnalysisData . Captured ) ;
523- var dataFlowInMap = new HashSet < ISymbol > ( dataFlowAnalysisData . DataFlowsIn ) ;
524- var dataFlowOutMap = new HashSet < ISymbol > ( dataFlowAnalysisData . DataFlowsOut ) ;
525- var alwaysAssignedMap = new HashSet < ISymbol > ( dataFlowAnalysisData . AlwaysAssigned ) ;
526- var variableDeclaredMap = new HashSet < ISymbol > ( dataFlowAnalysisData . VariablesDeclared ) ;
527- var readInsideMap = new HashSet < ISymbol > ( dataFlowAnalysisData . ReadInside ) ;
528- var writtenInsideMap = new HashSet < ISymbol > ( dataFlowAnalysisData . WrittenInside ) ;
529- var readOutsideMap = new HashSet < ISymbol > ( dataFlowAnalysisData . ReadOutside ) ;
530- var writtenOutsideMap = new HashSet < ISymbol > ( dataFlowAnalysisData . WrittenOutside ) ;
531- var unsafeAddressTakenMap = new HashSet < ISymbol > ( dataFlowAnalysisData . UnsafeAddressTaken ) ;
522+ using var _0 = GetPooledSymbolSet ( dataFlowAnalysisData . Captured , out var capturedMap ) ;
523+ using var _1 = GetPooledSymbolSet ( dataFlowAnalysisData . DataFlowsIn , out var dataFlowInMap ) ;
524+ using var _2 = GetPooledSymbolSet ( dataFlowAnalysisData . DataFlowsOut , out var dataFlowOutMap ) ;
525+ using var _3 = GetPooledSymbolSet ( dataFlowAnalysisData . AlwaysAssigned , out var alwaysAssignedMap ) ;
526+ using var _4 = GetPooledSymbolSet ( dataFlowAnalysisData . VariablesDeclared , out var variableDeclaredMap ) ;
527+ using var _5 = GetPooledSymbolSet ( dataFlowAnalysisData . ReadInside , out var readInsideMap ) ;
528+ using var _6 = GetPooledSymbolSet ( dataFlowAnalysisData . WrittenInside , out var writtenInsideMap ) ;
529+ using var _7 = GetPooledSymbolSet ( dataFlowAnalysisData . ReadOutside , out var readOutsideMap ) ;
530+ using var _8 = GetPooledSymbolSet ( dataFlowAnalysisData . WrittenOutside , out var writtenOutsideMap ) ;
531+ using var _9 = GetPooledSymbolSet ( dataFlowAnalysisData . UnsafeAddressTaken , out var unsafeAddressTakenMap ) ;
532532
533533 // gather all meaningful symbols for the span.
534534 var candidates = new HashSet < ISymbol > ( readInsideMap ) ;
@@ -538,6 +538,7 @@ private void GenerateVariableInfoMap(
538538 // Need to analyze from the start of what we're extracting to the end of the scope that this variable could
539539 // have been referenced in.
540540 var analysisRange = TextSpan . FromBounds ( SelectionResult . FinalSpan . Start , SelectionResult . GetContainingScope ( ) . Span . End ) ;
541+ var selectionOperation = semanticModel . GetOperation ( SelectionResult . GetContainingScope ( ) ) ;
541542
542543 foreach ( var symbol in candidates )
543544 {
@@ -582,30 +583,22 @@ private void GenerateVariableInfoMap(
582583
583584 // variable that is declared inside but never referenced outside. just ignore it and move to next one.
584585 if ( variableDeclared && ! dataFlowOut && ! readOutside && ! writtenOutside )
585- {
586586 continue ;
587- }
588587
589588 // parameter defined inside of the selection (such as lambda parameter) will be ignored (bug # 10964)
590589 if ( symbol is IParameterSymbol && variableDeclared )
591- {
592590 continue ;
593- }
594591
595- var type = GetSymbolType ( model , symbol , analysisRange ) ;
592+ var type = GetSymbolType ( symbol ) ;
596593 if ( type == null )
597- {
598594 continue ;
599- }
600595
601596 // If the variable doesn't have a name, it is invalid.
602597 if ( symbol . Name . IsEmpty ( ) )
603- {
604598 continue ;
605- }
606599
607600 if ( ! TryGetVariableStyle (
608- bestEffort , symbolMap , symbol , model , type ,
601+ bestEffort , symbolMap , symbol , semanticModel , type ,
609602 captured , dataFlowIn , dataFlowOut , alwaysAssigned , variableDeclared ,
610603 readInside , writtenInside , readOutside , writtenOutside , unsafeAddressTaken ,
611604 out var variableStyle ) )
@@ -620,6 +613,48 @@ private void GenerateVariableInfoMap(
620613 symbol ,
621614 CreateFromSymbol ( symbol , type , variableStyle , variableDeclared ) ) ;
622615 }
616+
617+ return ;
618+
619+ PooledDisposer < PooledHashSet < ISymbol > > GetPooledSymbolSet ( ImmutableArray < ISymbol > symbols , out PooledHashSet < ISymbol > symbolSet )
620+ {
621+ var disposer = PooledHashSet < ISymbol > . GetInstance ( out symbolSet ) ;
622+ symbolSet . AddRange ( symbols ) ;
623+ return disposer ;
624+ }
625+
626+ ITypeSymbol ? GetSymbolType ( ISymbol symbol )
627+ {
628+ var type = symbol switch
629+ {
630+ ILocalSymbol local => local . Type ,
631+ IParameterSymbol parameter => parameter . Type ,
632+ IRangeVariableSymbol rangeVariable => GetRangeVariableType ( semanticModel , rangeVariable ) ,
633+ _ => throw ExceptionUtilities . UnexpectedValue ( symbol )
634+ } ;
635+
636+ if ( type is null )
637+ return type ;
638+
639+ // Check if null is possibly assigned to the symbol. If it is, leave nullable annotation as is, otherwise we
640+ // can modify the annotation to be NotAnnotated to code that more likely matches the user's intent.
641+
642+ if ( type . NullableAnnotation is not NullableAnnotation . Annotated )
643+ return type ;
644+
645+ // For Extract-Method we don't care about analyzing the declaration of this variable. For example, even if
646+ // it was initially assigned 'null' for the purposes of determining the type of it for a return value, all
647+ // we care is if it is null at the end of the selection. If it is only assigned non-null values, for
648+ // example, we want to treat it as non-null.
649+ if ( selectionOperation is not null &&
650+ NullableHelpers . IsSymbolAssignedPossiblyNullValue (
651+ this . SemanticFacts , semanticModel , selectionOperation , symbol , analysisRange , includeDeclaration : false , this . CancellationToken ) == false )
652+ {
653+ return type . WithNullableAnnotation ( NullableAnnotation . NotAnnotated ) ;
654+ }
655+
656+ return type ;
657+ }
623658 }
624659
625660 private static void AddVariableToMap ( IDictionary < ISymbol , VariableInfo > variableInfoMap , ISymbol localOrParameter , VariableInfo variableInfo )
@@ -711,44 +746,6 @@ private bool SelectionContainsOnlyIdentifierWithSameType(ITypeSymbol type)
711746 return type . Equals ( SelectionResult . GetContainingScopeType ( ) ) ;
712747 }
713748
714- private ITypeSymbol ? GetSymbolType (
715- SemanticModel semanticModel ,
716- ISymbol symbol ,
717- TextSpan analysisRange )
718- {
719- var type = symbol switch
720- {
721- ILocalSymbol local => local . Type ,
722- IParameterSymbol parameter => parameter . Type ,
723- IRangeVariableSymbol rangeVariable => GetRangeVariableType ( semanticModel , rangeVariable ) ,
724- _ => throw ExceptionUtilities . UnexpectedValue ( symbol )
725- } ;
726-
727- if ( type is null )
728- return type ;
729-
730- // Check if null is possibly assigned to the symbol. If it is, leave nullable annotation as is, otherwise we
731- // can modify the annotation to be NotAnnotated to code that more likely matches the user's intent.
732-
733- if ( type . NullableAnnotation is not NullableAnnotation . Annotated )
734- return type ;
735-
736- var selectionOperation = semanticModel . GetOperation ( SelectionResult . GetContainingScope ( ) ) ;
737-
738- // For Extract-Method we don't care about analyzing the declaration of this variable. For example, even if
739- // it was initially assigned 'null' for the purposes of determining the type of it for a return value, all
740- // we care is if it is null at the end of the selection. If it is only assigned non-null values, for
741- // example, we want to treat it as non-null.
742- if ( selectionOperation is not null &&
743- NullableHelpers . IsSymbolAssignedPossiblyNullValue (
744- this . SemanticFacts , semanticModel , selectionOperation , symbol , analysisRange , includeDeclaration : false , this . CancellationToken ) == false )
745- {
746- return type . WithNullableAnnotation ( NullableAnnotation . NotAnnotated ) ;
747- }
748-
749- return type ;
750- }
751-
752749 protected static VariableStyle AlwaysReturn ( VariableStyle style )
753750 {
754751 if ( style == VariableStyle . InputOnly )
0 commit comments