Example #1
0
        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));
        }
Example #2
0
        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);
        }
Example #3
0
        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));
        }
Example #4
0
        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());
        }
Example #6
0
        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()));
        }