Skip to content

Port swiftSyntax to Windows #7588

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Feb 22, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
48 changes: 31 additions & 17 deletions include/swift/Basic/OwnedString.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,28 +44,43 @@ class OwnedString {
size_t Length;
StringOwnership Ownership;

OwnedString(const char* Data, size_t Length, StringOwnership Ownership)
: Length(Length), Ownership(Ownership) {
assert(Length >= 0 && "expected length to be non-negative");

if (Ownership == StringOwnership::Copied && Data) {
assert(
Length <= strlen(Data) &&
"expected length to be a valid index, within the length of the string");

char *substring = static_cast<char *>(malloc(Length + 1));
assert(substring && "expected successful malloc of copy");

memcpy(substring, Data, Length);
substring[Length] = '\0';

this->Data = substring;
}
else
this->Data = Data;
}

public:
OwnedString()
: Data(nullptr), Length(0), Ownership(StringOwnership::Unowned) {}
OwnedString() : OwnedString(nullptr, 0, StringOwnership::Unowned) {}

OwnedString(const char *Data, size_t Length, StringOwnership Ownership)
: Data(Ownership == StringOwnership::Copied ? strndup(Data, Length) : Data),
Length(Length), Ownership(Ownership) {}
OwnedString(const char *Data, size_t Length)
: OwnedString(Data, Length, StringOwnership::Unowned) {}

OwnedString(StringRef Str, StringOwnership Ownership)
: OwnedString(Ownership == StringOwnership::Copied
? strndup(Str.data(), Str.size())
: Str.data(),
Str.size(), Ownership) {}
OwnedString(StringRef Str) : OwnedString(Str.data(), Str.size()) {}

OwnedString(const char *Data)
: OwnedString(StringRef(Data), StringOwnership::Unowned) {}
OwnedString(const char *Data) : OwnedString(StringRef(Data)) {}

OwnedString(const OwnedString &Other)
: Data(Other.Ownership == StringOwnership::Copied
? strndup(Other.Data, Other.Length)
: Other.Data),
Length(Other.Length), Ownership(Other.Ownership) {}
: OwnedString(Other.Data, Other.Length, Other.Ownership) {}

OwnedString copy() {
return OwnedString(Data, Length, StringOwnership::Copied);
}

/// Returns the length of the string in bytes.
size_t size() const {
Expand Down Expand Up @@ -96,4 +111,3 @@ class OwnedString {
} // end namespace swift

#endif // SWIFT_BASIC_OWNEDSTRING_H

13 changes: 6 additions & 7 deletions lib/Parse/Lexer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -737,8 +737,7 @@ syntax::RC<syntax::TokenSyntax> Lexer::fullLex() {
TrailingTrivia.push_front(syntax::TriviaPiece::backtick());
}
auto Result = syntax::TokenSyntax::make(NextToken.getKind(),
OwnedString(NextToken.getText(),
StringOwnership::Copied),
OwnedString(NextToken.getText()).copy(),
syntax::SourcePresence::Present,
{LeadingTrivia}, {TrailingTrivia});
LeadingTrivia.clear();
Expand Down Expand Up @@ -1951,19 +1950,19 @@ Optional<syntax::TriviaPiece> Lexer::lexWhitespace(bool StopAtFirstNewline) {
return syntax::TriviaPiece {
syntax::TriviaKind::Newline,
Length,
OwnedString(Start, Length, StringOwnership::Unowned),
OwnedString(Start, Length),
};
case ' ':
return syntax::TriviaPiece {
syntax::TriviaKind::Space,
Length,
OwnedString(Start, Length, StringOwnership::Unowned),
OwnedString(Start, Length),
};
case '\t':
return syntax::TriviaPiece {
syntax::TriviaKind::Tab,
Length,
OwnedString(Start, Length, StringOwnership::Unowned),
OwnedString(Start, Length),
};
default:
return None;
Expand All @@ -1982,7 +1981,7 @@ Optional<syntax::TriviaPiece> Lexer::lexSingleLineComment(syntax::TriviaKind Kin
return Optional<syntax::TriviaPiece>({
Kind,
Length,
OwnedString(Start, Length, StringOwnership::Unowned)
OwnedString(Start, Length)
});
}

Expand All @@ -1997,7 +1996,7 @@ Lexer::lexBlockComment(syntax::TriviaKind Kind) {
return Optional<syntax::TriviaPiece>({
Kind,
Length,
OwnedString(Start, Length, StringOwnership::Unowned)
OwnedString(Start, Length)
});
}

Expand Down
3 changes: 1 addition & 2 deletions lib/Syntax/LegacyASTTransformer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -296,8 +296,7 @@ LegacyASTTransformer::visitStructDecl(StructDecl *D,

if (D->getNameLoc().isValid()) {
auto Identifier = findTokenSyntax(tok::identifier,
OwnedString(D->getName().str(),
StringOwnership::Unowned),
OwnedString(D->getName().str()),
SourceMgr, D->getNameLoc(), BufferID,
Tokens);
StructBuilder.useIdentifier(Identifier);
Expand Down
1 change: 1 addition & 0 deletions unittests/Basic/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ add_swift_unittest(SwiftBasicTests
FileSystemTest.cpp
ImmutablePointerSetTest.cpp
OptionSetTest.cpp
OwnedStringTest.cpp
PointerIntEnumTest.cpp
PrefixMapTest.cpp
RangeTest.cpp
Expand Down
194 changes: 194 additions & 0 deletions unittests/Basic/OwnedStringTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,194 @@
//===--- OwnedStringTest.cpp ----------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

#include "swift/Basic/OwnedString.h"
#include "gtest/gtest.h"

using namespace swift;

TEST(OwnedStringTest, char_pointer_empty) {
const char *data = "";
const size_t length = strlen(data);
OwnedString ownedString(data);

EXPECT_EQ(length, ownedString.size());
EXPECT_TRUE(ownedString.empty());

OwnedString copy = ownedString.copy();
EXPECT_EQ(length, copy.size());
EXPECT_TRUE(copy.empty());

StringRef str = copy.str();
EXPECT_EQ("", str);
EXPECT_EQ(length, str.size());
}

TEST(OwnedStringTest, char_pointer_non_empty) {
const char *data = "string";
const size_t length = strlen(data);
OwnedString ownedString(data);

EXPECT_EQ(length, ownedString.size());
EXPECT_FALSE(ownedString.empty());

OwnedString copy = ownedString.copy();
EXPECT_EQ(length, copy.size());
EXPECT_FALSE(copy.empty());

StringRef str = copy.str();
EXPECT_EQ("string", str);
EXPECT_EQ(length, strlen(str.data()));
}

TEST(OwnedStringTest, char_pointer_length_equal) {
const char *data = "string";
size_t length = strlen(data);
OwnedString ownedString(data, length);

EXPECT_EQ(length, ownedString.size());
EXPECT_FALSE(ownedString.empty());

OwnedString copy = ownedString.copy();
EXPECT_EQ(length, copy.size());
EXPECT_FALSE(copy.empty());

// Make sure we correctly copied the data and that it is null
// terminated.
StringRef str = copy.str();
EXPECT_EQ("string", str);
EXPECT_EQ(length, strlen(str.data()));
}

TEST(OwnedStringTest, char_pointer_length_nonzero) {
const char *data = "string";
const size_t length = 1;
OwnedString ownedString(data, length);

EXPECT_EQ(length, ownedString.size());
EXPECT_FALSE(ownedString.empty());

OwnedString copy = ownedString.copy();
EXPECT_EQ(length, copy.size());
EXPECT_FALSE(copy.empty());

// Make sure we correctly copied the data and that it is null
// terminated.
StringRef str = copy.str();
EXPECT_EQ("s", str);
EXPECT_EQ(1, strlen(str.data()));
}

TEST(OwnedStringTest, char_pointer_length_zero) {
const char *data = "string";
const size_t length = 0;
OwnedString ownedString(data, length);

EXPECT_EQ(length, ownedString.size());
EXPECT_TRUE(ownedString.empty());

OwnedString copy = ownedString.copy();
EXPECT_EQ(length, copy.size());
EXPECT_TRUE(copy.empty());
}

TEST(OwnedStringTest, copy_original_new_different) {
// Initialize a mutable string.
const char *original = "string";
const size_t length = strlen(original);
char *data = static_cast<char *>(malloc(length + 1));
memcpy(data, original, length);
data[length] = '\0';

// Create an OwnedString.
OwnedString ownedString(data, length);

EXPECT_EQ(length, ownedString.size());
EXPECT_FALSE(ownedString.empty());

// Copy the string
OwnedString copy = ownedString.copy();
EXPECT_EQ(length, copy.size());
EXPECT_FALSE(copy.empty());

// Make sure we correctly copied the data and that it is null
// terminated.
StringRef str = copy.str();
EXPECT_EQ("string", str);
EXPECT_EQ(length, strlen(str.data()));

// Make sure updating the original pointer doesn't affect the copy.
data[0] = 'a';

EXPECT_EQ("string", str);
}

TEST(OwnedStringTest, copy_constructor_original_not_copy) {
// Initialize a mutable string.
const char *original = "string";
const size_t length = strlen(original);
char *data = static_cast<char *>(malloc(length + 1));
memcpy(data, original, length);
data[length] = '\0';

// Create an OwnedString.
OwnedString ownedString(data, length);

EXPECT_EQ(length, ownedString.size());
EXPECT_FALSE(ownedString.empty());

// Copy the string
OwnedString copy = OwnedString(ownedString);
EXPECT_EQ(length, copy.size());
EXPECT_FALSE(copy.empty());

// Make sure we correctly copied the data and that it is null
// terminated.
StringRef str = copy.str();
EXPECT_EQ("string", str);
EXPECT_EQ(length, strlen(str.data()));

// Make sure updating the original pointer doesn't affect the copy.
data[0] = 'a';

EXPECT_EQ("atring", str);
}

TEST(OwnedStringTest, copy_constructor_original_copy) {
// Initialize a mutable string.
const char *original = "string";
const size_t length = strlen(original);
char *data = static_cast<char *>(malloc(length + 1));
memcpy(data, original, length);
data[length] = '\0';

// Create an OwnedString.
OwnedString ownedString(data, length);

EXPECT_EQ(length, ownedString.size());
EXPECT_FALSE(ownedString.empty());

// Copy the string
OwnedString copy = OwnedString(ownedString.copy());
EXPECT_EQ(length, copy.size());
EXPECT_FALSE(copy.empty());

// Make sure we correctly copied the data and that it is null
// terminated.
StringRef str = copy.str();
EXPECT_EQ("string", str);
EXPECT_EQ(length, strlen(str.data()));

// Make sure updating the original pointer doesn't affect the copy.
data[0] = 'a';

EXPECT_EQ("string", str);
}