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)); }
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; }
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)); }
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);
/// <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); }