forked from qt-creator/qt-creator
		
	These come directly from clang. If converting for display in the completion list widget, skip new line chunks. Fixes: QTCREATORBUG-21600 Change-Id: I83749ed73fa68658ec073d97177768f59a87cebf Reviewed-by: David Schulz <david.schulz@qt.io> Reviewed-by: Ivan Donchevskii <ivan.donchevskii@qt.io>
		
			
				
	
	
		
			380 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			380 lines
		
	
	
		
			17 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/****************************************************************************
 | 
						|
**
 | 
						|
** Copyright (C) 2016 The Qt Company Ltd.
 | 
						|
** Contact: https://www.qt.io/licensing/
 | 
						|
**
 | 
						|
** This file is part of Qt Creator.
 | 
						|
**
 | 
						|
** Commercial License Usage
 | 
						|
** Licensees holding valid commercial Qt licenses may use this file in
 | 
						|
** accordance with the commercial license agreement provided with the
 | 
						|
** Software or, alternatively, in accordance with the terms contained in
 | 
						|
** a written agreement between you and The Qt Company. For licensing terms
 | 
						|
** and conditions see https://www.qt.io/terms-conditions. For further
 | 
						|
** information use the contact form at https://www.qt.io/contact-us.
 | 
						|
**
 | 
						|
** GNU General Public License Usage
 | 
						|
** Alternatively, this file may be used under the terms of the GNU
 | 
						|
** General Public License version 3 as published by the Free Software
 | 
						|
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
 | 
						|
** included in the packaging of this file. Please review the following
 | 
						|
** information to ensure the GNU General Public License requirements will
 | 
						|
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
 | 
						|
**
 | 
						|
****************************************************************************/
 | 
						|
 | 
						|
#include "googletest.h"
 | 
						|
 | 
						|
#include <codecompletionchunk.h>
 | 
						|
#include <clangcompletionchunkstotextconverter.h>
 | 
						|
 | 
						|
namespace {
 | 
						|
 | 
						|
using ClangBackEnd::CodeCompletionChunk;
 | 
						|
using ClangBackEnd::CodeCompletionChunks;
 | 
						|
using Converter = ClangCodeModel::Internal::CompletionChunksToTextConverter;
 | 
						|
 | 
						|
class CompletionChunksToTextConverter : public ::testing::Test
 | 
						|
{
 | 
						|
protected:
 | 
						|
    Converter converter;
 | 
						|
    CodeCompletionChunk integerResultType{CodeCompletionChunk::ResultType, Utf8StringLiteral("int")};
 | 
						|
    CodeCompletionChunk templateResultType{CodeCompletionChunk::ResultType, Utf8StringLiteral("Foo<int>")};
 | 
						|
    CodeCompletionChunk enumerationResultType{CodeCompletionChunk::ResultType, Utf8StringLiteral("Enumeration")};
 | 
						|
    CodeCompletionChunk functionName{CodeCompletionChunk::TypedText, Utf8StringLiteral("Function")};
 | 
						|
    CodeCompletionChunk namespaceName{CodeCompletionChunk::TypedText, Utf8StringLiteral("Namespace")};
 | 
						|
    CodeCompletionChunk variableName{CodeCompletionChunk::TypedText, Utf8StringLiteral("Variable")};
 | 
						|
    CodeCompletionChunk enumeratorName{CodeCompletionChunk::TypedText, Utf8StringLiteral("Enumerator")};
 | 
						|
    CodeCompletionChunk enumerationName{CodeCompletionChunk::TypedText, Utf8StringLiteral("Enumeration")};
 | 
						|
    CodeCompletionChunk className{CodeCompletionChunk::TypedText, Utf8StringLiteral("Class")};
 | 
						|
    CodeCompletionChunk leftParen{CodeCompletionChunk::LeftParen, Utf8StringLiteral("(")};
 | 
						|
    CodeCompletionChunk rightParen{CodeCompletionChunk::RightParen, Utf8StringLiteral(")")};
 | 
						|
    CodeCompletionChunk comma{CodeCompletionChunk::Comma, Utf8StringLiteral(", ")};
 | 
						|
    CodeCompletionChunk semicolon{CodeCompletionChunk::SemiColon, Utf8StringLiteral(";")};
 | 
						|
    CodeCompletionChunk colonColonText{CodeCompletionChunk::Text, Utf8StringLiteral("::")};
 | 
						|
    CodeCompletionChunk functionArgumentX{CodeCompletionChunk::Placeholder, Utf8StringLiteral("char x")};
 | 
						|
    CodeCompletionChunk functionArgumentXAsCurrentParameter{CodeCompletionChunk::CurrentParameter, Utf8StringLiteral("char x")};
 | 
						|
    CodeCompletionChunk functionArgumentY{CodeCompletionChunk::Placeholder, Utf8StringLiteral("int y")};
 | 
						|
    CodeCompletionChunk functionArgumentYAsCurrentParamter{CodeCompletionChunk::CurrentParameter, Utf8StringLiteral("int y")};
 | 
						|
    CodeCompletionChunk functionArgumentZ{CodeCompletionChunk::Placeholder, Utf8StringLiteral("int z")};
 | 
						|
    CodeCompletionChunk functionArgumentTemplate{CodeCompletionChunk::Placeholder, Utf8StringLiteral("const Foo<int> &foo")};
 | 
						|
    CodeCompletionChunk switchName{CodeCompletionChunk::TypedText, Utf8StringLiteral("switch")};
 | 
						|
    CodeCompletionChunk condition{CodeCompletionChunk::Placeholder, Utf8StringLiteral("condition")};
 | 
						|
    CodeCompletionChunk leftBrace{CodeCompletionChunk::LeftBrace, Utf8StringLiteral("{")};
 | 
						|
    CodeCompletionChunk rightBrace{CodeCompletionChunk::RightBrace, Utf8StringLiteral("}")};
 | 
						|
    CodeCompletionChunk verticalSpace{CodeCompletionChunk::VerticalSpace, Utf8StringLiteral("\n")};
 | 
						|
    CodeCompletionChunk throwName{CodeCompletionChunk::TypedText, Utf8StringLiteral("throw")};
 | 
						|
    CodeCompletionChunk voidResultType{CodeCompletionChunk::ResultType, Utf8StringLiteral("void")};
 | 
						|
    CodeCompletionChunk forName{CodeCompletionChunk::TypedText, Utf8StringLiteral("for")};
 | 
						|
    CodeCompletionChunk initStatement{CodeCompletionChunk::Placeholder, Utf8StringLiteral("init-statement")};
 | 
						|
    CodeCompletionChunk initExpression{CodeCompletionChunk::Placeholder, Utf8StringLiteral("init-expression")};
 | 
						|
    CodeCompletionChunk statements{CodeCompletionChunk::Placeholder, Utf8StringLiteral("statements")};
 | 
						|
    CodeCompletionChunk constCastName{CodeCompletionChunk::TypedText, Utf8StringLiteral("const_cast")};
 | 
						|
    CodeCompletionChunk leftAngle{CodeCompletionChunk::LeftAngle, Utf8StringLiteral("<")};
 | 
						|
    CodeCompletionChunk rightAngle{CodeCompletionChunk::RightAngle, Utf8StringLiteral(">")};
 | 
						|
    CodeCompletionChunk elseName{CodeCompletionChunk::TypedText, Utf8StringLiteral("else")};
 | 
						|
    CodeCompletionChunk ifName{CodeCompletionChunk::TypedText, Utf8StringLiteral("if")};
 | 
						|
    CodeCompletionChunk horizontalSpace{CodeCompletionChunk::HorizontalSpace, Utf8StringLiteral(" ")};
 | 
						|
    CodeCompletionChunk enableIfT{CodeCompletionChunk::TypedText, Utf8StringLiteral("enable_if_t")};
 | 
						|
    CodeCompletionChunk enableIfTCondition{CodeCompletionChunk::Placeholder, Utf8StringLiteral("_Cond")};
 | 
						|
    CodeCompletionChunk  optionalEnableIfTType{CodeCompletionChunk::Placeholder, Utf8StringLiteral("_Tp"), true};
 | 
						|
    CodeCompletionChunk optionalComma{CodeCompletionChunk::Comma, Utf8StringLiteral(", "), true};
 | 
						|
    CodeCompletionChunk optionalFunctionArgumentY{CodeCompletionChunk::Placeholder, Utf8StringLiteral("int y"), true};
 | 
						|
    CodeCompletionChunk optionalFunctionArgumentYAsCurrentParameter{CodeCompletionChunk::CurrentParameter, Utf8StringLiteral("int y"), true};
 | 
						|
    CodeCompletionChunk optionalFunctionArgumentZ{CodeCompletionChunk::Placeholder, Utf8StringLiteral("int z"), true};
 | 
						|
};
 | 
						|
 | 
						|
TEST_F(CompletionChunksToTextConverter, ParseIsClearingText)
 | 
						|
{
 | 
						|
    CodeCompletionChunks completionChunks({integerResultType, functionName, leftParen, rightParen});
 | 
						|
    converter.setAddResultType(true);
 | 
						|
 | 
						|
    converter.parseChunks(completionChunks);
 | 
						|
 | 
						|
    ASSERT_THAT(converter.text(), QStringLiteral("int Function()"));
 | 
						|
}
 | 
						|
 | 
						|
TEST_F(CompletionChunksToTextConverter, ConvertFunction)
 | 
						|
{
 | 
						|
    CodeCompletionChunks completionChunks({integerResultType, functionName, leftParen, rightParen});
 | 
						|
    converter.setAddResultType(true);
 | 
						|
 | 
						|
    converter.parseChunks(completionChunks);
 | 
						|
 | 
						|
    ASSERT_THAT(converter.text(), QStringLiteral("int Function()"));
 | 
						|
}
 | 
						|
 | 
						|
TEST_F(CompletionChunksToTextConverter, ConvertFunctionWithParameters)
 | 
						|
{
 | 
						|
    CodeCompletionChunks completionChunks({integerResultType, functionName, leftParen, functionArgumentX,rightParen});
 | 
						|
    converter.setAddResultType(true);
 | 
						|
    converter.setAddPlaceHolderText(true);
 | 
						|
 | 
						|
    converter.parseChunks(completionChunks);
 | 
						|
 | 
						|
    ASSERT_THAT(converter.text(), QStringLiteral("int Function(char x)"));
 | 
						|
}
 | 
						|
 | 
						|
TEST_F(CompletionChunksToTextConverter, ConvertToFunctionSignatureWithOneArgument)
 | 
						|
{
 | 
						|
    CodeCompletionChunks completionChunks({integerResultType,
 | 
						|
                                           functionName,
 | 
						|
                                           leftParen,
 | 
						|
                                            functionArgumentXAsCurrentParameter,
 | 
						|
                                           rightParen});
 | 
						|
 | 
						|
    ASSERT_THAT(converter.convertToFunctionSignatureWithHtml(
 | 
						|
                    completionChunks,
 | 
						|
                    ClangBackEnd::CodeCompletion::FunctionCompletionKind),
 | 
						|
                QStringLiteral("int Function(char x)"));
 | 
						|
}
 | 
						|
 | 
						|
TEST_F(CompletionChunksToTextConverter, ConvertToFunctionSignatureWithOneParameterThatIsActive)
 | 
						|
{
 | 
						|
    CodeCompletionChunks completionChunks({integerResultType,
 | 
						|
                                           functionName,
 | 
						|
                                           leftParen,
 | 
						|
                                            functionArgumentXAsCurrentParameter,
 | 
						|
                                           rightParen});
 | 
						|
 | 
						|
    ASSERT_THAT(converter.convertToFunctionSignatureWithHtml(
 | 
						|
                    completionChunks,
 | 
						|
                    ClangBackEnd::CodeCompletion::FunctionCompletionKind,
 | 
						|
                    1),
 | 
						|
                QStringLiteral("int Function(<b>char x</b>)"));
 | 
						|
}
 | 
						|
 | 
						|
TEST_F(CompletionChunksToTextConverter, ConvertToFunctionSignatureWithTwoParametersWhereOneIsActive)
 | 
						|
{
 | 
						|
    CodeCompletionChunks completionChunks({integerResultType,
 | 
						|
                                           functionName,
 | 
						|
                                           leftParen,
 | 
						|
                                            functionArgumentX,
 | 
						|
                                            comma,
 | 
						|
                                            functionArgumentYAsCurrentParamter,
 | 
						|
                                           rightParen});
 | 
						|
 | 
						|
    ASSERT_THAT(converter.convertToFunctionSignatureWithHtml(
 | 
						|
                    completionChunks,
 | 
						|
                    ClangBackEnd::CodeCompletion::FunctionCompletionKind,
 | 
						|
                    2),
 | 
						|
                QStringLiteral("int Function(char x, <b>int y</b>)"));
 | 
						|
}
 | 
						|
 | 
						|
TEST_F(CompletionChunksToTextConverter, ConvertToFunctionSignatureWithTwoParametersWhereOneIsOptionalAndActive)
 | 
						|
{
 | 
						|
    CodeCompletionChunks completionChunks({integerResultType,
 | 
						|
                                           functionName,
 | 
						|
                                           leftParen,
 | 
						|
                                            functionArgumentX,
 | 
						|
                                            optionalComma,
 | 
						|
                                            optionalFunctionArgumentYAsCurrentParameter,
 | 
						|
                                           rightParen});
 | 
						|
 | 
						|
    ASSERT_THAT(converter.convertToFunctionSignatureWithHtml(
 | 
						|
                    completionChunks,
 | 
						|
                    ClangBackEnd::CodeCompletion::FunctionCompletionKind,
 | 
						|
                    2),
 | 
						|
                QStringLiteral("int Function(char x<i>, <b>int y</b></i>)"));
 | 
						|
}
 | 
						|
 | 
						|
TEST_F(CompletionChunksToTextConverter, ConvertToFunctionSignatureWithTemplateReturnType)
 | 
						|
{
 | 
						|
    CodeCompletionChunks completionChunks({templateResultType,
 | 
						|
                                           functionName,
 | 
						|
                                           leftParen,
 | 
						|
                                            functionArgumentX,
 | 
						|
                                           rightParen});
 | 
						|
 | 
						|
    using ClangCodeModel::Internal::CompletionChunksToTextConverter;
 | 
						|
 | 
						|
    ASSERT_THAT(CompletionChunksToTextConverter::convertToFunctionSignatureWithHtml(
 | 
						|
                    completionChunks,
 | 
						|
                    ClangBackEnd::CodeCompletion::FunctionCompletionKind),
 | 
						|
                QStringLiteral("Foo<int> Function(char x)"));
 | 
						|
}
 | 
						|
 | 
						|
TEST_F(CompletionChunksToTextConverter, ConvertToFunctionSignatureWithTemplateArgument)
 | 
						|
{
 | 
						|
    CodeCompletionChunks completionChunks({integerResultType,
 | 
						|
                                           functionName,
 | 
						|
                                           leftParen,
 | 
						|
                                            functionArgumentTemplate,
 | 
						|
                                           rightParen});
 | 
						|
 | 
						|
    using ClangCodeModel::Internal::CompletionChunksToTextConverter;
 | 
						|
 | 
						|
    ASSERT_THAT(CompletionChunksToTextConverter::convertToFunctionSignatureWithHtml(
 | 
						|
                    completionChunks,
 | 
						|
                    ClangBackEnd::CodeCompletion::FunctionCompletionKind),
 | 
						|
                QStringLiteral("int Function(const Foo<int> &foo)"));
 | 
						|
}
 | 
						|
 | 
						|
TEST_F(CompletionChunksToTextConverter, ConvertFunctionWithOptionalParameter)
 | 
						|
{
 | 
						|
    CodeCompletionChunks completionChunks({integerResultType,
 | 
						|
                                           functionName,
 | 
						|
                                           leftParen,
 | 
						|
                                            functionArgumentX,
 | 
						|
                                            optionalComma,
 | 
						|
                                            optionalFunctionArgumentY,
 | 
						|
                                            optionalComma,
 | 
						|
                                            optionalFunctionArgumentZ,
 | 
						|
                                           rightParen});
 | 
						|
 | 
						|
    ASSERT_THAT(Converter::convertToToolTipWithHtml(completionChunks,
 | 
						|
                                                    ClangBackEnd::CodeCompletion::FunctionCompletionKind),
 | 
						|
                QStringLiteral("int Function(char x<i>, int y, int z</i>)"));
 | 
						|
}
 | 
						|
 | 
						|
TEST_F(CompletionChunksToTextConverter, ConvertVariable)
 | 
						|
{
 | 
						|
    CodeCompletionChunks completionChunks({integerResultType, variableName});
 | 
						|
    converter.setAddResultType(true);
 | 
						|
 | 
						|
    converter.parseChunks(completionChunks);
 | 
						|
 | 
						|
    ASSERT_THAT(converter.text(), QStringLiteral("int Variable"));
 | 
						|
}
 | 
						|
 | 
						|
TEST_F(CompletionChunksToTextConverter, Enumerator)
 | 
						|
{
 | 
						|
    CodeCompletionChunks completionChunks({enumerationResultType, enumeratorName});
 | 
						|
    converter.setAddResultType(true);
 | 
						|
 | 
						|
    converter.parseChunks(completionChunks);
 | 
						|
 | 
						|
    ASSERT_THAT(converter.text(), QStringLiteral("Enumeration Enumerator"));
 | 
						|
}
 | 
						|
 | 
						|
TEST_F(CompletionChunksToTextConverter, Enumeration)
 | 
						|
{
 | 
						|
    CodeCompletionChunks completionChunks({className});
 | 
						|
 | 
						|
    converter.parseChunks(completionChunks);
 | 
						|
 | 
						|
    ASSERT_THAT(converter.text(), QStringLiteral("Class"));
 | 
						|
}
 | 
						|
 | 
						|
TEST_F(CompletionChunksToTextConverter, SwitchAsKeyword)
 | 
						|
{
 | 
						|
    CodeCompletionChunks completionChunks({switchName,
 | 
						|
                                           leftParen,
 | 
						|
                                           condition,
 | 
						|
                                           rightParen,
 | 
						|
                                           leftBrace,
 | 
						|
                                           verticalSpace,
 | 
						|
                                           rightBrace});
 | 
						|
    converter.setupForKeywords();
 | 
						|
 | 
						|
    converter.parseChunks(completionChunks);
 | 
						|
 | 
						|
    ASSERT_THAT(converter.text(), QStringLiteral("switch () {\n\n}"));
 | 
						|
    ASSERT_THAT(converter.placeholderPositions().at(0), 8);
 | 
						|
}
 | 
						|
 | 
						|
TEST_F(CompletionChunksToTextConverter, SwitchAsName)
 | 
						|
{
 | 
						|
    CodeCompletionChunks completionChunks({switchName,
 | 
						|
                                           leftParen,
 | 
						|
                                           condition,
 | 
						|
                                           rightParen,
 | 
						|
                                           leftBrace,
 | 
						|
                                           verticalSpace,
 | 
						|
                                           rightBrace});
 | 
						|
 | 
						|
    const QString text = ClangCodeModel::Internal::CompletionChunksToTextConverter::convertToName(
 | 
						|
        completionChunks);
 | 
						|
 | 
						|
    ASSERT_THAT(text, QStringLiteral("switch(){}"));
 | 
						|
}
 | 
						|
 | 
						|
TEST_F(CompletionChunksToTextConverter, For)
 | 
						|
{
 | 
						|
    CodeCompletionChunks completionChunks({forName,
 | 
						|
                                           leftParen,
 | 
						|
                                           initStatement,
 | 
						|
                                           semicolon,
 | 
						|
                                           initExpression,
 | 
						|
                                           semicolon,
 | 
						|
                                           condition,
 | 
						|
                                           rightParen,
 | 
						|
                                           leftBrace,
 | 
						|
                                           verticalSpace,
 | 
						|
                                           statements,
 | 
						|
                                           verticalSpace,
 | 
						|
                                           rightBrace});
 | 
						|
    converter.setupForKeywords();
 | 
						|
 | 
						|
    converter.parseChunks(completionChunks);
 | 
						|
 | 
						|
    ASSERT_THAT(converter.text(), QStringLiteral("for (;;) {\n\n}"));
 | 
						|
}
 | 
						|
 | 
						|
TEST_F(CompletionChunksToTextConverter, const_cast)
 | 
						|
{
 | 
						|
    CodeCompletionChunks completionChunks({constCastName,
 | 
						|
                                           leftAngle,
 | 
						|
                                           rightAngle,
 | 
						|
                                           leftParen,
 | 
						|
                                           rightParen});
 | 
						|
    converter.setupForKeywords();
 | 
						|
 | 
						|
    converter.parseChunks(completionChunks);
 | 
						|
 | 
						|
    ASSERT_THAT(converter.text(), QStringLiteral("const_cast<>()"));
 | 
						|
}
 | 
						|
 | 
						|
TEST_F(CompletionChunksToTextConverter, Throw)
 | 
						|
{
 | 
						|
    CodeCompletionChunks completionChunks({voidResultType, throwName});
 | 
						|
 | 
						|
    auto completionName = Converter::convertToName(completionChunks);
 | 
						|
 | 
						|
    ASSERT_THAT(completionName, QStringLiteral("throw"));
 | 
						|
}
 | 
						|
 | 
						|
TEST_F(CompletionChunksToTextConverter, ElseIf)
 | 
						|
{
 | 
						|
    CodeCompletionChunks completionChunks({elseName,
 | 
						|
                                           horizontalSpace,
 | 
						|
                                           ifName,
 | 
						|
                                           horizontalSpace,
 | 
						|
                                           leftBrace,
 | 
						|
                                           verticalSpace,
 | 
						|
                                           statements,
 | 
						|
                                           verticalSpace,
 | 
						|
                                           rightBrace});
 | 
						|
    converter.setupForKeywords();
 | 
						|
 | 
						|
    converter.parseChunks(completionChunks);
 | 
						|
 | 
						|
    ASSERT_THAT(converter.text(), QStringLiteral("else if {\n\n}"));
 | 
						|
}
 | 
						|
 | 
						|
TEST_F(CompletionChunksToTextConverter, EnableIfT)
 | 
						|
{
 | 
						|
    CodeCompletionChunks completionChunks({enableIfT,
 | 
						|
                                           leftAngle,
 | 
						|
                                           enableIfTCondition,
 | 
						|
                                           optionalComma,
 | 
						|
                                           optionalEnableIfTType,
 | 
						|
                                           rightAngle});
 | 
						|
    converter.setupForKeywords();
 | 
						|
 | 
						|
    converter.parseChunks(completionChunks);
 | 
						|
 | 
						|
    ASSERT_THAT(converter.text(), QStringLiteral("enable_if_t<>"));
 | 
						|
}
 | 
						|
 | 
						|
TEST_F(CompletionChunksToTextConverter, Namespace)
 | 
						|
{
 | 
						|
    CodeCompletionChunks completionChunks({namespaceName, colonColonText});
 | 
						|
 | 
						|
    converter.parseChunks(completionChunks);
 | 
						|
 | 
						|
    ASSERT_THAT(converter.text(), QStringLiteral("Namespace::"));
 | 
						|
}
 | 
						|
 | 
						|
}
 |