private IndexerInfo GetIndexerInfo(SyntaxNodeAnalysisContext syntaxNodeAnalysisContext, TIndexerExpressionSyntax indexerExpressionSyntax) { var info = GetIndexerSymbol(syntaxNodeAnalysisContext, indexerExpressionSyntax); var symbol = info as IMethodSymbol; var verifyIndexerCast = symbol == null || symbol.Name != MetadataNames.CallInfoArgTypesMethod; var verifyAssignment = symbol == null; var indexerInfo = new IndexerInfo(verifyIndexerCast, verifyAssignment); return(indexerInfo); }
/// <summary> /// Resolves an indexer to a numeric value /// </summary> /// <param name="indexer">The indexer</param> /// <returns>The resolved value</returns> private int ResolverIndexerValue ( IndexerInfo indexer ) { switch (indexer.IndexerValueType) { case NettleValueType.Number: { return(indexer.ResolvedIndex); } case NettleValueType.Variable: { var value = ResolveVariableValue ( indexer.IndexerSignature ); if (value == null) { throw new NullReferenceException ( "The indexer must resolve to a numeric value." ); } if (value.GetType().IsNumeric()) { return(Convert.ToInt32(value)); } else { throw new InvalidCastException ( "{0} is not a valid indexer type.".With ( value.GetType().Name ) ); } } default: { return(-1); } } }
private bool AnalyzeAssignment(SyntaxNodeAnalysisContext syntaxNodeContext, IList <IParameterSymbol> substituteCallParameters, TIndexerExpressionSyntax indexer, IndexerInfo indexerInfo, int?position) { var assignmentExpressionSyntax = GetAssignmentExpression(indexer); if (indexerInfo.VerifyAssignment && assignmentExpressionSyntax != null && position.HasValue && position.Value < substituteCallParameters.Count) { var parameterSymbol = substituteCallParameters[position.Value]; if (parameterSymbol.RefKind != RefKind.Out && parameterSymbol.RefKind != RefKind.Ref) { var diagnostic = Diagnostic.Create( DiagnosticDescriptorsProvider.CallInfoArgumentIsNotOutOrRef, indexer.GetLocation(), position.Value, parameterSymbol.Type); syntaxNodeContext.ReportDiagnostic(diagnostic); return(true); } var typeInfo = syntaxNodeContext.SemanticModel.GetTypeInfo(assignmentExpressionSyntax); if (typeInfo.Type != null && IsAssignableTo(syntaxNodeContext.Compilation, typeInfo.Type, substituteCallParameters[position.Value].Type) == false) { var diagnostic = Diagnostic.Create( DiagnosticDescriptorsProvider.CallInfoArgumentSetWithIncompatibleValue, indexer.GetLocation(), typeInfo.Type, position.Value, substituteCallParameters[position.Value].Type); syntaxNodeContext.ReportDiagnostic(diagnostic); return(true); } } return(false); }
private bool AnalyzeCast(SyntaxNodeAnalysisContext syntaxNodeContext, IList <IParameterSymbol> substituteCallParameters, TIndexerExpressionSyntax indexer, IndexerInfo indexerInfo, int?position) { var castTypeExpression = GetCastTypeExpression(indexer); if (position.HasValue && indexerInfo.VerifyIndexerCast && castTypeExpression != null) { var typeInfo = syntaxNodeContext.SemanticModel.GetTypeInfo(castTypeExpression); if (typeInfo.Type != null && CanCast(syntaxNodeContext.Compilation, substituteCallParameters[position.Value].Type, typeInfo.Type) == false) { var diagnostic = Diagnostic.Create( DiagnosticDescriptorsProvider.CallInfoCouldNotConvertParameterAtPosition, indexer.GetLocation(), position.Value, typeInfo.Type); syntaxNodeContext.ReportDiagnostic(diagnostic); return(true); } } return(false); }
/// <summary> /// Resolves an indexed binding value /// </summary> /// <param name="bindingPath">The binding path</param> /// <param name="collection">The collection</param> /// <param name="indexer">The indexer information</param> /// <returns>The value found at the specified index</returns> private object ResolveIndexedBinding ( string bindingPath, object collection, IndexerInfo indexer ) { if (collection == null) { throw new InvalidOperationException ( "The value for '{0}' is null.".With ( bindingPath ) ); } if (false == collection.GetType().IsEnumerable()) { throw new InvalidOperationException ( "'{0}' is not a valid collection.".With ( bindingPath ) ); } var index = ResolverIndexerValue(indexer); if (index < 0) { throw new ArgumentOutOfRangeException ( "The index for '{0}' must be zero or greater.".With ( bindingPath ) ); } var counter = default(int); foreach (var item in collection as IEnumerable) { if (counter == index) { if (indexer.NextIndexer != null) { return(ResolveIndexedBinding ( indexer.FullPath, item, indexer.NextIndexer )); } else { return(item); } } counter++; } throw new IndexOutOfRangeException ( "The index {0} for '{1}' is out of range.".With ( index, bindingPath ) ); }