Exemplo n.º 1
0
 private VariableInfo CreateFromSymbol(
     Compilation compilation,
     ISymbol symbol,
     ITypeSymbol type,
     VariableStyle style,
     bool variableDeclared)
 {
     return(CreateFromSymbolCommon <LocalDeclarationStatementSyntax>(compilation, symbol, type, style, _sNonNoisySyntaxKindSet));
 }
Exemplo n.º 2
0
 public VariableInfo(
     VariableSymbol variableSymbol,
     VariableStyle variableStyle,
     bool useAsReturnValue = false)
 {
     _variableSymbol   = variableSymbol;
     _variableStyle    = variableStyle;
     _useAsReturnValue = useAsReturnValue;
 }
Exemplo n.º 3
0
        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);
        }
Exemplo n.º 4
0
        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);
            }
        }
Exemplo n.º 5
0
        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);
        }