Files
swift-mirror/unittests/Syntax/DeclSyntaxTests.cpp

415 lines
15 KiB
C++

#include "swift/Syntax/SyntaxFactory.h"
#include "swift/Syntax/DeclSyntax.h"
#include "swift/Syntax/ExprSyntax.h"
#include "llvm/ADT/SmallString.h"
#include "gtest/gtest.h"
using llvm::None;
using llvm::SmallString;
using namespace swift;
using namespace swift::syntax;
#pragma mark - typealias-decl
TEST(DeclSyntaxTests, TypealiasMakeAPIs) {
{
SmallString<1> Scratch;
llvm::raw_svector_ostream OS(Scratch);
SyntaxFactory::makeBlankTypealiasDecl().print(OS);
ASSERT_EQ(OS.str().str(), "");
}
{
SmallString<64> Scratch;
llvm::raw_svector_ostream OS(Scratch);
auto Typealias =
SyntaxFactory::makeTypealiasKeyword({}, { Trivia::spaces(1) });
auto Subsequence = SyntaxFactory::makeIdentifier("MyCollection", {}, {});
auto ElementParam =
SyntaxFactory::makeGenericParameter("Element", {}, {});
auto LeftAngle = SyntaxFactory::makeLeftAngleToken({}, {});
auto RightAngle =
SyntaxFactory::makeRightAngleToken({}, { Trivia::spaces(1) });
auto GenericParams = GenericParameterClauseBuilder()
.useLeftAngleBracket(LeftAngle)
.useRightAngleBracket(RightAngle)
.addParameter(None, ElementParam)
.build();
auto Assignment = SyntaxFactory::makeEqualToken({}, { Trivia::spaces(1) });
auto ElementArg = SyntaxFactory::makeTypeIdentifier("Element", {}, {});
auto GenericArgs = GenericArgumentClauseBuilder()
.useLeftAngleBracket(LeftAngle)
.useRightAngleBracket(SyntaxFactory::makeRightAngleToken({}, {}))
.addGenericArgument(None, ElementArg)
.build();
auto Array = SyntaxFactory::makeIdentifier("Array", {}, {});
auto Array_Int = SyntaxFactory::makeTypeIdentifier(Array, GenericArgs);
SyntaxFactory::makeTypealiasDecl(Typealias, Subsequence, GenericParams,
Assignment, Array_Int)
.print(OS);
ASSERT_EQ(OS.str().str(),
"typealias MyCollection<Element> = Array<Element>");
}
}
TEST(DeclSyntaxTests, TypealiasWithAPIs) {
auto Typealias =
SyntaxFactory::makeTypealiasKeyword({}, { Trivia::spaces(1) });
auto MyCollection = SyntaxFactory::makeIdentifier("MyCollection", {}, {});
auto ElementParam =
SyntaxFactory::makeGenericParameter("Element", {}, {});
auto LeftAngle = SyntaxFactory::makeLeftAngleToken({}, {});
auto RightAngle =
SyntaxFactory::makeRightAngleToken({}, { Trivia::spaces(1) });
auto GenericParams = GenericParameterClauseBuilder()
.useLeftAngleBracket(LeftAngle)
.useRightAngleBracket(RightAngle)
.addParameter(None, ElementParam)
.build();
auto Equal = SyntaxFactory::makeEqualToken({}, { Trivia::spaces(1) });
auto ElementArg = SyntaxFactory::makeTypeIdentifier("Element", {}, {});
auto GenericArgs = GenericArgumentClauseBuilder()
.useLeftAngleBracket(LeftAngle)
.useRightAngleBracket(SyntaxFactory::makeRightAngleToken({}, {}))
.addGenericArgument(None, ElementArg)
.build();
auto Array = SyntaxFactory::makeIdentifier("Array", {}, {});
auto Array_Int = SyntaxFactory::makeTypeIdentifier(Array, GenericArgs);
{
SmallString<1> Scratch;
llvm::raw_svector_ostream OS(Scratch);
SyntaxFactory::makeBlankTypealiasDecl()
.withTypeAliasKeyword(Typealias)
.withIdentifier(MyCollection)
.withGenericParameterClause(GenericParams)
.withEqualToken(Equal)
.withTypeSyntax(Array_Int)
.print(OS);
ASSERT_EQ(OS.str().str(),
"typealias MyCollection<Element> = Array<Element>");
}
}
TEST(DeclSyntaxTests, TypealiasBuilderAPIs) {
SmallString<64> Scratch;
llvm::raw_svector_ostream OS(Scratch);
auto Typealias =
SyntaxFactory::makeTypealiasKeyword({}, { Trivia::spaces(1) });
auto MyCollection = SyntaxFactory::makeIdentifier("MyCollection", {}, {});
auto ElementParam =
SyntaxFactory::makeGenericParameter("Element", {}, {});
auto LeftAngle = SyntaxFactory::makeLeftAngleToken({}, {});
auto RightAngle =
SyntaxFactory::makeRightAngleToken({}, { Trivia::spaces(1) });
auto GenericParams = GenericParameterClauseBuilder()
.useLeftAngleBracket(LeftAngle)
.useRightAngleBracket(RightAngle)
.addParameter(None, ElementParam)
.build();
auto Equal =
SyntaxFactory::makeEqualToken({}, { Trivia::spaces(1) });
auto ElementArg = SyntaxFactory::makeTypeIdentifier("Element", {}, {});
auto GenericArgs = GenericArgumentClauseBuilder()
.useLeftAngleBracket(LeftAngle)
.useRightAngleBracket(SyntaxFactory::makeRightAngleToken({}, {}))
.addGenericArgument(None, ElementArg)
.build();
auto Array = SyntaxFactory::makeIdentifier("Array", {}, {});
auto Array_Int = SyntaxFactory::makeTypeIdentifier(Array, GenericArgs);
TypeAliasDeclSyntaxBuilder()
.useTypeAliasKeyword(Typealias)
.useIdentifier(MyCollection)
.useGenericParameterClause(GenericParams)
.useEqualToken(Equal)
.useType(Array_Int)
.build()
.print(OS);
ASSERT_EQ(OS.str().str(),
"typealias MyCollection<Element> = Array<Element>");
}
#pragma mark - parameter
FunctionParameterSyntax getCannedFunctionParameter() {
auto ExternalName = SyntaxFactory::makeIdentifier("with", {},
Trivia::spaces(1));
auto LocalName = SyntaxFactory::makeIdentifier("radius", {}, {});
auto Colon = SyntaxFactory::makeColonToken({}, Trivia::spaces(1));
auto Int = SyntaxFactory::makeTypeIdentifier("Int", {},
Trivia::spaces(1));
auto NoEllipsis = TokenSyntax::missingToken(tok::identifier, "...");
auto Equal = SyntaxFactory::makeEqualToken({}, Trivia::spaces(1));
auto Sign = SyntaxFactory::makePrefixOpereator("-", {});
auto OneDigits = SyntaxFactory::makeIntegerLiteralToken("1", {}, {});
auto One = SyntaxFactory::makeIntegerLiteralExpr(Sign, OneDigits);
auto Comma = SyntaxFactory::makeCommaToken({}, Trivia::spaces(1));
return SyntaxFactory::makeFunctionParameter(ExternalName, LocalName, Colon,
Int, NoEllipsis, Equal, One,
Comma);
}
TEST(DeclSyntaxTests, FunctionParameterMakeAPIs) {
{
SmallString<48> Scratch;
llvm::raw_svector_ostream OS(Scratch);
getCannedFunctionParameter().print(OS);
ASSERT_EQ(OS.str().str(), "with radius: Int = -1, ");
}
{
SmallString<48> Scratch;
llvm::raw_svector_ostream OS(Scratch);
SyntaxFactory::makeBlankFunctionParameter().print(OS);
ASSERT_EQ(OS.str().str(), "");
}
}
TEST(DeclSyntaxTests, FunctionParameterGetAPIs) {
auto ExternalName = SyntaxFactory::makeIdentifier("with", {},
Trivia::spaces(1));
auto LocalName = SyntaxFactory::makeIdentifier("radius", {}, {});
auto Colon = SyntaxFactory::makeColonToken({}, Trivia::spaces(1));
auto Int = SyntaxFactory::makeTypeIdentifier("Int", {},
Trivia::spaces(1));
auto NoEllipsis = TokenSyntax::missingToken(tok::identifier, "...");
auto Equal = SyntaxFactory::makeEqualToken({}, Trivia::spaces(1));
auto Sign = SyntaxFactory::makePrefixOpereator("-", {});
auto OneDigits = SyntaxFactory::makeIntegerLiteralToken("1", {}, {});
auto One = SyntaxFactory::makeIntegerLiteralExpr(Sign, OneDigits);
auto Comma = SyntaxFactory::makeCommaToken({}, {});
auto Param = SyntaxFactory::makeFunctionParameter(ExternalName, LocalName,
Colon, Int, NoEllipsis,
Equal, One, Comma);
ASSERT_EQ(ExternalName, Param.getExternalName());
ASSERT_EQ(LocalName, Param.getLocalName());
ASSERT_EQ(Colon, Param.getColonToken());
auto GottenType = Param.getTypeSyntax().getValue();
auto GottenType2 = Param.getTypeSyntax().getValue();
ASSERT_TRUE(GottenType.hasSameIdentityAs(GottenType2));
ASSERT_EQ(Equal, Param.getEqualToken());
auto GottenDefaultValue = Param.getDefaultValue().getValue();
auto GottenDefaultValue2 = Param.getDefaultValue().getValue();
ASSERT_TRUE(GottenDefaultValue.hasSameIdentityAs(GottenDefaultValue2));
ASSERT_EQ(Comma, Param.getTrailingComma());
// Test that llvm::None is returned for non-token missing children:
auto Decimated = Param
.withTypeSyntax(llvm::None)
.withDefaultValue(llvm::None);
ASSERT_FALSE(Decimated.getTypeSyntax().hasValue());
ASSERT_FALSE(Decimated.getDefaultValue().hasValue());
}
TEST(DeclSyntaxTests, FunctionParameterWithAPIs) {
auto ExternalName = SyntaxFactory::makeIdentifier("for", {},
Trivia::spaces(1));
auto LocalName = SyntaxFactory::makeIdentifier("integer", {}, {});
auto Colon = SyntaxFactory::makeColonToken(Trivia::spaces(1),
Trivia::spaces(1));
auto Int = SyntaxFactory::makeTypeIdentifier("Int", {},
Trivia::spaces(1));
auto Equal = SyntaxFactory::makeEqualToken({}, Trivia::spaces(1));
auto NoSign = TokenSyntax::missingToken(tok::oper_prefix, "");
auto OneDigits = SyntaxFactory::makeIntegerLiteralToken("1", {}, {});
auto One = SyntaxFactory::makeIntegerLiteralExpr(NoSign, OneDigits);
auto Comma = SyntaxFactory::makeCommaToken({}, {});
{
SmallString<48> Scratch;
llvm::raw_svector_ostream OS(Scratch);
getCannedFunctionParameter()
.withExternalName(ExternalName)
.withLocalName(LocalName)
.withColonToken(Colon)
.withTypeSyntax(Int)
.withEqualToken(Equal)
.withDefaultValue(One)
.withTrailingComma(Comma)
.print(OS);
ASSERT_EQ(OS.str().str(), "for integer : Int = 1,");
}
{
SmallString<48> Scratch;
llvm::raw_svector_ostream OS(Scratch);
getCannedFunctionParameter()
.withTypeSyntax(llvm::None)
.withDefaultValue(llvm::None)
.print(OS);
ASSERT_EQ(OS.str().str(), "with radius: = , ");
}
}
#pragma mark - parameter-list
TEST(DeclSyntaxTests, FunctionParameterListMakeAPIs) {
{
SmallString<1> Scratch;
llvm::raw_svector_ostream OS(Scratch);
SyntaxFactory::makeBlankFunctionParameterList().print(OS);
ASSERT_EQ(OS.str().str(), "");
}
{
SmallString<48> Scratch;
llvm::raw_svector_ostream OS(Scratch);
auto Param = getCannedFunctionParameter();
std::vector<FunctionParameterSyntax> Params { Param, Param, Param };
SyntaxFactory::makeFunctionParameterList(Params).print(OS);
ASSERT_EQ(OS.str().str(),
"with radius: Int = -1, with radius: Int = -1, with radius: Int = -1, ");
}
}
#pragma mark - function-signature
FunctionSignatureSyntax getCannedFunctionSignature() {
auto LParen = SyntaxFactory::makeLeftParenToken({}, {});
auto Param = getCannedFunctionParameter();
auto List = SyntaxFactory::makeBlankFunctionParameterList()
.appending(Param)
.appending(Param)
.appending(Param)
.castTo<FunctionParameterListSyntax>();
auto RParen = SyntaxFactory::makeRightParenToken({}, Trivia::spaces(1));
auto Throws = SyntaxFactory::makeThrowsKeyword({}, Trivia::spaces(1));
auto Arrow = SyntaxFactory::makeArrow({}, Trivia::spaces(1));
auto NoAttributes = SyntaxFactory::makeBlankTypeAttributes();
auto Int = SyntaxFactory::makeTypeIdentifier("Int", {}, {});
return SyntaxFactory::makeFunctionSignature(LParen, List, RParen, Throws,
Arrow, NoAttributes, Int);
}
TEST(DeclSyntaxTests, FunctionSignatureMakeAPIs) {
{
SmallString<1> Scratch;
llvm::raw_svector_ostream OS(Scratch);
SyntaxFactory::makeBlankFunctionSignature().print(OS);
ASSERT_EQ(OS.str().str(), "");
}
{
SmallString<48> Scratch;
llvm::raw_svector_ostream OS(Scratch);
getCannedFunctionSignature().print(OS);
ASSERT_EQ(OS.str().str(),
"(with radius: Int = -1, "
"with radius: Int = -1, "
"with radius: Int = -1, ) throws -> Int");
}
}
TEST(DeclSyntaxTests, FunctionSignatureGetAPIs) {
auto LParen = SyntaxFactory::makeLeftParenToken({}, {});
auto Param = getCannedFunctionParameter();
auto List = SyntaxFactory::makeBlankFunctionParameterList()
.appending(Param)
.appending(Param)
.appending(Param)
.castTo<FunctionParameterListSyntax>();
auto RParen = SyntaxFactory::makeRightParenToken({}, Trivia::spaces(1));
auto Throws = SyntaxFactory::makeThrowsKeyword({}, Trivia::spaces(1));
auto Arrow = SyntaxFactory::makeArrow({}, Trivia::spaces(1));
auto NoAttributes = SyntaxFactory::makeBlankTypeAttributes();
auto Int = SyntaxFactory::makeTypeIdentifier("Int", {}, {});
auto Sig = SyntaxFactory::makeFunctionSignature(LParen, List, RParen, Throws,
Arrow, NoAttributes, Int);
ASSERT_EQ(LParen, Sig.getLeftParenToken());
{
SmallString<48> Scratch;
llvm::raw_svector_ostream OS(Scratch);
auto GottenList1 = Sig.getParameterList();
auto GottenList2 = Sig.getParameterList();
ASSERT_TRUE(GottenList1.hasSameIdentityAs(GottenList2));
GottenList1.print(OS);
ASSERT_EQ(OS.str().str(),
"with radius: Int = -1, "
"with radius: Int = -1, "
"with radius: Int = -1, ");
}
ASSERT_EQ(RParen, Sig.getRightParenToken());
ASSERT_EQ(Throws, Sig.getThrowsToken());
ASSERT_TRUE(Sig.getRethrowsToken()->isMissing());
ASSERT_EQ(Arrow, Sig.getArrowToken());
{
SmallString<48> Scratch;
llvm::raw_svector_ostream OS(Scratch);
auto GottenAttrs1 = Sig.getReturnTypeAttributes();
auto GottenAttrs2 = Sig.getReturnTypeAttributes();
ASSERT_TRUE(GottenAttrs1.hasSameIdentityAs(GottenAttrs2));
ASSERT_EQ(OS.str().str(), "");
}
{
SmallString<3> Scratch;
llvm::raw_svector_ostream OS(Scratch);
auto GottenReturnType1 = Sig.getReturnTypeSyntax();
auto GottenReturnType2 = Sig.getReturnTypeSyntax();
ASSERT_TRUE(GottenReturnType1.hasSameIdentityAs(GottenReturnType2));
GottenReturnType1.print(OS);
ASSERT_EQ(OS.str().str(), "Int");
}
}
TEST(DeclSyntaxTests, FunctionSignatureWithAPIs) {
auto LParen = SyntaxFactory::makeLeftParenToken({}, {});
auto Param = getCannedFunctionParameter();
auto List = SyntaxFactory::makeBlankFunctionParameterList()
.appending(Param)
.appending(Param)
.appending(Param)
.castTo<FunctionParameterListSyntax>();
auto RParen = SyntaxFactory::makeRightParenToken({}, Trivia::spaces(1));
auto Throws = SyntaxFactory::makeThrowsKeyword({}, Trivia::spaces(1));
auto Arrow = SyntaxFactory::makeArrow({}, Trivia::spaces(1));
auto NoAttributes = SyntaxFactory::makeBlankTypeAttributes();
auto Int = SyntaxFactory::makeTypeIdentifier("Int", {}, {});
SmallString<48> Scratch;
llvm::raw_svector_ostream OS(Scratch);
SyntaxFactory::makeBlankFunctionSignature()
.withLeftParenToken(LParen)
.withParameterList(List)
.withRightParenToken(RParen)
.withThrowsToken(Throws)
.withReturnTypeAttributes(NoAttributes)
.withArrowToken(Arrow)
.withReturnTypeSyntax(Int)
.print(OS);
ASSERT_EQ(OS.str().str(),
"(with radius: Int = -1, "
"with radius: Int = -1, "
"with radius: Int = -1, ) throws -> Int");
}
#pragma mark - function-declaration
// TODO: Nodes
// TODO: Tests