Пример #1
0
            public OperationDeconstructor(
                Analyzer analyzer, IMethodSymbol method, ILocalSymbol?hashCodeVariable)
            {
                _analyzer         = analyzer;
                _method           = method;
                _hashCodeVariable = hashCodeVariable;
                _hashedSymbols    = ArrayBuilder <ISymbol> .GetInstance();

                _accessesBase = false;
            }
 private static bool TryFindVariableDeclarator(
     SemanticModel semanticModel,
     IdentifierNameSyntax identifier,
     [NotNullWhen(true)] out ILocalSymbol?localSymbol,
     [NotNullWhen(true)] out VariableDeclaratorSyntax?declarator)
 {
     localSymbol = semanticModel.GetSymbolInfo(identifier).Symbol as ILocalSymbol;
     declarator  = localSymbol?.DeclaringSyntaxReferences.FirstOrDefault()?.GetSyntax() as VariableDeclaratorSyntax;
     return(localSymbol != null && declarator != null);
 }
        private static bool TryGetTypeCheckParts(
            SemanticModel semanticModel,
            SyntaxNode operand,
            [NotNullWhen(true)] out VariableDeclaratorSyntax?declarator,
            [NotNullWhen(true)] out BinaryExpressionSyntax?asExpression,
            [NotNullWhen(true)] out ILocalSymbol?localSymbol)
        {
            switch (operand.Kind())
            {
            case SyntaxKind.IdentifierName:
            {
                // var x = e as T;
                // if (x != null) F(x);
                var identifier = (IdentifierNameSyntax)operand;
                if (!TryFindVariableDeclarator(semanticModel, identifier, out localSymbol, out declarator))
                {
                    break;
                }

                var initializerValue = declarator.Initializer?.Value;
                if (!initializerValue.IsKind(SyntaxKind.AsExpression, out asExpression))
                {
                    break;
                }

                return(true);
            }

            case SyntaxKind.SimpleAssignmentExpression:
            {
                // T x;
                // if ((x = e as T) != null) F(x);
                var assignment = (AssignmentExpressionSyntax)operand;
                if (!assignment.Right.IsKind(SyntaxKind.AsExpression, out asExpression) ||
                    !assignment.Left.IsKind(SyntaxKind.IdentifierName, out IdentifierNameSyntax? identifier))
                {
                    break;
                }

                if (!TryFindVariableDeclarator(semanticModel, identifier, out localSymbol, out declarator))
                {
                    break;
                }

                return(true);
            }
            }

            declarator   = null;
            asExpression = null;
            localSymbol  = null;
            return(false);
        }
        /// <summary> Determines equality by name and containing symbol. </summary>
        /// <param name="x">The first instance.</param>
        /// <param name="y">The other instance.</param>
        /// <returns>True if the instances are found equal.</returns>
        public static bool Equal(ILocalSymbol?x, ILocalSymbol?y)
        {
            if (ReferenceEquals(x, y))
            {
                return(true);
            }

            if (x is null ||
                y is null)
            {
                return(false);
            }

            return(x.MetadataName == y.MetadataName &&
                   SymbolComparer.Equal(x.ContainingSymbol, y.ContainingSymbol));
        }
Пример #5
0
 public LocalDefinition(
     ILocalSymbol?symbolOpt,
     string?nameOpt,
     Cci.ITypeReference type,
     int slot,
     SynthesizedLocalKind synthesizedKind,
     LocalDebugId id,
     LocalVariableAttributes pdbAttributes,
     LocalSlotConstraints constraints,
     ImmutableArray <bool> dynamicTransformFlags,
     ImmutableArray <string> tupleElementNames)
 {
     _symbolOpt             = symbolOpt;
     _nameOpt               = nameOpt;
     _type                  = type;
     _slot                  = slot;
     _slotInfo              = new LocalSlotDebugInfo(synthesizedKind, id);
     _pdbAttributes         = pdbAttributes;
     _dynamicTransformFlags = dynamicTransformFlags.NullToEmpty();
     _tupleElementNames     = tupleElementNames.NullToEmpty();
     _constraints           = constraints;
 }
Пример #6
0
        private bool TryFindMatchingLocalDeclarationImmediatelyAbove(
            IConditionalOperation ifOperation,
            ISimpleAssignmentOperation?trueAssignment,
            ISimpleAssignmentOperation?falseAssignment,
            [NotNullWhen(true)] out IVariableDeclarationGroupOperation?localDeclaration,
            [NotNullWhen(true)] out IVariableDeclaratorOperation?declarator)
        {
            localDeclaration = null;
            declarator       = null;

            ILocalSymbol?local = null;

            if (trueAssignment != null)
            {
                if (!(trueAssignment.Target is ILocalReferenceOperation trueLocal))
                {
                    return(false);
                }

                local = trueLocal.Local;
            }

            if (falseAssignment != null)
            {
                if (!(falseAssignment.Target is ILocalReferenceOperation falseLocal))
                {
                    return(false);
                }

                // See if both assignments are to the same local.
                if (local != null && !Equals(local, falseLocal.Local))
                {
                    return(false);
                }

                local = falseLocal.Local;
            }

            // We weren't assigning to a local.
            if (local == null)
            {
                return(false);
            }

            // If so, see if that local was declared immediately above the if-statement.
            if (!(ifOperation.Parent is IBlockOperation parentBlock))
            {
                return(false);
            }

            var ifIndex = parentBlock.Operations.IndexOf(ifOperation);

            if (ifIndex <= 0)
            {
                return(false);
            }

            localDeclaration = parentBlock.Operations[ifIndex - 1] as IVariableDeclarationGroupOperation;
            if (localDeclaration == null)
            {
                return(false);
            }

            if (localDeclaration.IsImplicit)
            {
                return(false);
            }

            if (localDeclaration.Declarations.Length != 1)
            {
                return(false);
            }

            var declaration = localDeclaration.Declarations[0];
            var declarators = declaration.Declarators;

            if (declarators.Length != 1)
            {
                return(false);
            }

            declarator = declarators[0];
            var variable = declarator.Symbol;

            if (!Equals(variable, local))
            {
                // wasn't a declaration of the local we're assigning to.
                return(false);
            }

            var variableInitializer = declarator.Initializer ?? declaration.Initializer;

            if (variableInitializer?.Value != null)
            {
                var unwrapped = UnwrapImplicitConversion(variableInitializer.Value);
                // the variable has to either not have an initializer, or it needs to be basic
                // literal/default expression.
                if (!(unwrapped is ILiteralOperation) &&
                    !(unwrapped is IDefaultValueOperation))
                {
                    return(false);
                }
            }

            // If the variable is referenced in the condition of the 'if' block, we can't merge the
            // declaration and assignments.
            return(!ReferencesLocalVariable(ifOperation.Condition, variable));
        }
Пример #7
0
 internal static LocalSymbol? GetSymbol(this ILocalSymbol? symbol)
 {
     return symbol.GetSymbol<LocalSymbol>();
 }
#pragma warning restore CS1591,CA1707,IDE1006,SA1313,SA1600
        //// ReSharper restore UnusedParameter.Global

        /// <inheritdoc />
        bool IEqualityComparer <ILocalSymbol> .Equals(ILocalSymbol?x, ILocalSymbol?y) => Equal(x, y);
 public static bool Equals(ILocalSymbol?x, ILocalSymbol?y) => Equal(x, y);
Пример #10
0
        /// <summary>
        /// Try getting the <see cref="ILocalSymbol"/> for the node.
        /// Gets the semantic model for the tree if the node is not in the tree corresponding to <paramref name="semanticModel"/>.
        /// </summary>
        /// <param name="semanticModel">The <see cref="SemanticModel"/>.</param>
        /// <param name="node">The <see cref="SingleVariableDesignationSyntax"/>.</param>
        /// <param name="cancellationToken">The <see cref="CancellationToken"/>.</param>
        /// <param name="symbol">The symbol if found.</param>
        /// <returns>True if a symbol was found.</returns>
        public static bool TryGetSymbol(this SemanticModel semanticModel, SingleVariableDesignationSyntax node, CancellationToken cancellationToken, [NotNullWhen(true)] out ILocalSymbol?symbol)
        {
            if (semanticModel is null)
            {
                throw new ArgumentNullException(nameof(semanticModel));
            }

            if (node is null)
            {
                throw new ArgumentNullException(nameof(node));
            }

            symbol = GetDeclaredSymbolSafe(semanticModel, node, cancellationToken);
            return(symbol != null);
        }