private VariableInfo CreateFromSymbol( Compilation compilation, ISymbol symbol, ITypeSymbol type, VariableStyle style, bool variableDeclared) { return(CreateFromSymbolCommon <LocalDeclarationStatementSyntax>(compilation, symbol, type, style, _sNonNoisySyntaxKindSet)); }
public VariableInfo( VariableSymbol variableSymbol, VariableStyle variableStyle, bool useAsReturnValue = false) { _variableSymbol = variableSymbol; _variableStyle = variableStyle; _useAsReturnValue = useAsReturnValue; }
private bool TryGetVariableStyle( Dictionary <ISymbol, List <SyntaxToken> > symbolMap, ISymbol symbol, SemanticModel model, ITypeSymbol type, bool captured, bool dataFlowIn, bool dataFlowOut, bool alwaysAssigned, bool variableDeclared, bool readInside, bool writtenInside, bool readOutside, bool writtenOutside, bool unsafeAddressTaken, out VariableStyle variableStyle) { if (!ExtractMethodMatrix.TryGetVariableStyle( dataFlowIn, dataFlowOut, alwaysAssigned, variableDeclared, readInside, writtenInside, readOutside, writtenOutside, unsafeAddressTaken, out variableStyle)) { return(false); } if (UserDefinedValueType(model.Compilation, type)) { variableStyle = AlwaysReturn(variableStyle); return(true); } // for captured variable, never try to move the decl into extracted method if (captured && variableStyle == VariableStyle.MoveIn) { variableStyle = VariableStyle.Out; return(true); } // don't blindly always return. make sure there is a write inside of the selection if (!writtenInside) { return(true); } variableStyle = AlwaysReturn(variableStyle); return(true); }
private VariableInfo CreateFromSymbolCommon <T>( Compilation compilation, ISymbol symbol, ITypeSymbol type, VariableStyle style, HashSet <int> nonNoisySyntaxKindSet) where T : SyntaxNode { switch (symbol) { case ILocalSymbol local: return(new VariableInfo( new LocalVariableSymbol <T>(compilation, local, type, nonNoisySyntaxKindSet), style)); case IParameterSymbol parameter: return(new VariableInfo(new ParameterVariableSymbol(compilation, parameter, type), style)); default: return(null); } }
protected VariableStyle AlwaysReturn(VariableStyle style) { if (style == VariableStyle.InputOnly) { return(VariableStyle.Ref); } if (style == VariableStyle.MoveIn) { return(VariableStyle.Out); } if (style == VariableStyle.SplitIn) { return(VariableStyle.Out); } if (style == VariableStyle.SplitOut) { return(VariableStyle.OutWithMoveOut); } return(style); }
public static bool TryGetVariableStyle( bool dataFlowIn, bool dataFlowOut, bool alwaysAssigned, bool variableDeclared, bool readInside, bool writtenInside, bool readOutside, bool writtenOutside, bool unsafeAddressTaken, out VariableStyle variableStyle) { if (unsafeAddressTaken) { variableStyle = VariableStyle.Out; return(true); } var key = new Key( dataFlowIn, dataFlowOut, alwaysAssigned, variableDeclared, readInside, writtenInside, readOutside, writtenOutside); // special cases if (!s_matrix.ContainsKey(key)) { // Interesting case. Due to things like constant analysis there can be regions that // the compiler considers data not to flow in (because analysis proves that that // path will never be taken). However, the variable can still be read/written inside // the region. For purposes of extract method, we check for this case, and we // pretend it's as if data flowed into the region. if (!dataFlowIn && (readInside || writtenInside)) { key = new Key(true, dataFlowOut, alwaysAssigned, variableDeclared, readInside, writtenInside, readOutside, writtenOutside); } // basically, it can happen in malformed code where a variable is not properly assigned but used outside of the selection + unreachable code region // for such cases, treat it like "MoveOut" if (!dataFlowOut && !alwaysAssigned && variableDeclared && !writtenInside && readOutside) { key = new Key(dataFlowIn, /*dataFlowOut*/ true, alwaysAssigned, variableDeclared, readInside, writtenInside, readOutside, writtenOutside); } // variable is passed by reference, and another argument is an out variable with the same name if (dataFlowIn && variableDeclared) { key = new Key(/*dataFlowIn:*/ false, dataFlowOut, alwaysAssigned, variableDeclared, readInside, writtenInside, readOutside, writtenOutside); } } if (s_matrix.TryGetValue(key, out variableStyle)) { return(true); } return(false); }