private static (TextRange, IStringLiteralAlterer) FindTokenTextRange(this ICSharpArgument argument, MessageTemplateToken token) { var documentRange = argument.GetDocumentRange(); if (argument.Value is IAdditiveExpression additiveExpression && additiveExpression.ConstantValue.IsString()) { var arguments = new LinkedList <ExpressionArgumentInfo>(); FlattenAdditiveExpression(additiveExpression, arguments); var globalOffset = 0; foreach (var additiveArgument in arguments) { var range = additiveArgument.GetDocumentRange(); var start = range.StartOffset.Offset; var end = range.EndOffset.Offset; // The token index is zero-based and we remove two quotes if (token.StartIndex < end - start - 3 + globalOffset) { var tokenStartIndex = start + token.StartIndex - globalOffset + 1; var tokenEndIndex = tokenStartIndex + token.Length; return(new TextRange(tokenStartIndex, end > tokenEndIndex ? tokenEndIndex : end), StringLiteralAltererUtil.TryCreateStringLiteralByExpression(additiveArgument.Expression)); } globalOffset += end - start - 2; } } var startOffset = documentRange.TextRange.StartOffset + token.StartIndex + 1; // ReSharper disable once AssignNullToNotNullAttribute return(new TextRange(startOffset, startOffset + token.Length), StringLiteralAltererUtil.TryCreateStringLiteralByExpression(argument.Expression)); }
private static (PropertyToken token, int index) GetSelectedToken( IPsiView psiView, ICSharpArgument templateArgument, PropertyToken[] properties) { var documentRange = templateArgument.GetDocumentRange(); var selectedTreeRange = psiView.GetSelectedTreeRange(templateArgument); var startSelectedIndex = selectedTreeRange.StartOffset.Offset - documentRange.StartOffset.Offset; var endSelectedIndex = selectedTreeRange.EndOffset.Offset - documentRange.StartOffset.Offset - 1; var propertyIndex = 0; foreach (var property in properties) { if (property.StartIndex < startSelectedIndex && property.StartIndex + property.Length >= endSelectedIndex) { return(property, propertyIndex); } propertyIndex++; } return(null, -1); }
public static MessageTemplateTokenInformation GetTokenInformation(this ICSharpArgument argument, MessageTemplateToken token) { var(tokenTextRange, tokenArgument) = FindTokenTextRange(argument, token); var tokenDocument = argument.GetDocumentRange().Document; var documentRange = new DocumentRange(tokenDocument, tokenTextRange); return(new MessageTemplateTokenInformation(documentRange, tokenArgument)); }
private static (TextRange, IStringLiteralAlterer) FindTokenTextRange(this ICSharpArgument argument, MessageTemplateToken token) { if (argument.Value is IAdditiveExpression additiveExpression && additiveExpression.ConstantValue.IsString()) { var arguments = new LinkedList <ExpressionArgumentInfo>(); FlattenAdditiveExpression(additiveExpression, arguments); var globalOffset = 0; foreach (var additiveArgument in arguments) { var range = additiveArgument.GetDocumentRange(); var start = range.StartOffset.Offset; var end = range.EndOffset.Offset; // Usually there are two quotes in the string expression // But if it's a verbatim string, we should count @ symbol as well var isVerbatimString = additiveArgument.Expression.IsVerbatimString(); var nonTemplateTokenCount = isVerbatimString ? 3 : 2; // The token index is zero-based so we need to subtract 1 if (token.StartIndex < end - start - 1 - nonTemplateTokenCount + globalOffset) { var tokenStartIndex = start + token.StartIndex - globalOffset + 1; if (isVerbatimString) { tokenStartIndex++; } var tokenEndIndex = tokenStartIndex + token.Length; return(new TextRange(tokenStartIndex, end > tokenEndIndex ? tokenEndIndex : end), StringLiteralAltererUtil.TryCreateStringLiteralByExpression(additiveArgument.Expression)); } globalOffset += end - start - nonTemplateTokenCount; } } var startOffset = argument.GetDocumentRange().TextRange.StartOffset + token.StartIndex + 1; if (argument.Expression.IsVerbatimString()) { startOffset++; } // ReSharper disable once AssignNullToNotNullAttribute return(new TextRange(startOffset, startOffset + token.Length), StringLiteralAltererUtil.TryCreateStringLiteralByExpression(argument.Expression)); }
private static void HighlightByArgument( HighlightingsConsumer consumer, ICSharpArgument selectedArgument, ICSharpArgument templateArgument, MessageTemplate messageTemplate) { var argumentIndex = selectedArgument.IndexOf() - templateArgument.IndexOf() - 1; var namedProperties = messageTemplate.NamedProperties; var positionalProperties = messageTemplate.PositionalProperties; if (namedProperties != null && argumentIndex < namedProperties.Length) { var property = namedProperties[argumentIndex]; consumer.ConsumeHighlighting( GeneralHighlightingAttributeIds.USAGE_OF_ELEMENT_UNDER_CURSOR, templateArgument.GetTokenInformation(property).DocumentRange); } else if (positionalProperties != null) { foreach (var property in positionalProperties) { if (!property.TryGetPositionalValue(out int position)) { continue; } if (position != argumentIndex) { continue; } consumer.ConsumeHighlighting( GeneralHighlightingAttributeIds.USAGE_OF_ELEMENT_UNDER_CURSOR, templateArgument.GetTokenInformation(property).DocumentRange); } } consumer.ConsumeHighlighting( GeneralHighlightingAttributeIds.USAGE_OF_ELEMENT_UNDER_CURSOR, selectedArgument.GetDocumentRange()); }
public static DocumentRange GetTokenDocumentRange(this ICSharpArgument argument, MessageTemplateToken token) { var documentRange = argument.GetDocumentRange(); return(GetTokenDocumentRange(token, documentRange)); }
protected override void Run( IInvocationExpression element, ElementProblemAnalyzerData data, IHighlightingConsumer consumer) { var templateArgument = element.GetTemplateArgument(); if (templateArgument == null) { return; } var templateArgumentIndex = templateArgument.IndexOf(); var exceptionType = element.PsiModule.GetPredefinedType().TryGetType(PredefinedType.EXCEPTION_FQN, NullableAnnotation.Unknown); if (exceptionType == null) { return; } ICSharpArgument invalidExceptionArgument = null; foreach (var argument in element.ArgumentList.Arguments) { var argumentType = argument.Value?.Type(); if (!(argumentType is IDeclaredType declaredType)) { continue; } if (!declaredType.IsSubtypeOf(exceptionType)) { continue; } if (templateArgumentIndex > argument.IndexOf()) { return; } invalidExceptionArgument = argument; break; } if (invalidExceptionArgument == null) { return; } var overloadAvailable = false; var candidates = element.InvocationExpressionReference.GetCandidates().ToArray(); var invalidArgumentIndex = invalidExceptionArgument.IndexOf(); foreach (var candidate in candidates) { if (!(candidate.GetDeclaredElement() is IMethod declaredElement)) { continue; } foreach (var parameter in declaredElement.Parameters) { if (invalidArgumentIndex <= parameter.IndexOf()) { break; } if (parameter.Type.IsSubtypeOf(exceptionType)) { overloadAvailable = true; break; } } if (overloadAvailable) { break; } } if (!overloadAvailable) { return; } consumer.AddHighlighting(new ExceptionPassedAsTemplateArgumentWarning(invalidExceptionArgument.GetDocumentRange())); }