Adds min and max, comments, and all of swift's keywords + fix docs (#5737)

This commit is contained in:
mustiikhalil 2020-01-27 21:05:41 +03:00 committed by Wouter van Oortmerssen
parent f2a1272303
commit c580fa284c
6 changed files with 190 additions and 49 deletions

View File

@ -23,11 +23,9 @@ GitHub page](https://github.com/google/flatbuffers/tree/master/swift).
## Testing the FlatBuffers Swift library
The code to test the Swift library can be found at `flatbuffers/Flatbuffers.Test.Swift`.
The test code itself is located in [Flatbuffers.Test.Swift](https://github.com/google/
flatbuffers/blob/master/tests/FlatBuffers.Test.Swift).
The test code itself is located in [Flatbuffers.Test.Swift](https://github.com/google/flatbuffers/blob/master/tests/FlatBuffers.Test.Swift).
To run the tests, use the [SwiftTest.sh](https://github.com/google/flatbuffers/
blob/master/tests/FlatBuffers.Test.Swift/SwiftTest.sh) shell script.
To run the tests, use the [SwiftTest.sh](https://github.com/google/flatbuffers/blob/master/tests/FlatBuffers.Test.Swift/SwiftTest.sh) shell script.
*Note: The shell script requires [Swift](https://swift.org) to
be installed.*

View File

@ -37,8 +37,85 @@ class SwiftGenerator : public BaseGenerator {
cur_name_space_(nullptr) {
namespace_depth = 0;
static const char *const keywords[] = {
"enum", "private", "public", "internal", "fileprivate", "static", "var",
"URL", "struct", "let", "class", "Any", "nil", nullptr,
"associatedtype",
"class",
"deinit",
"enum",
"extension",
"fileprivate",
"func",
"import",
"init",
"inout",
"internal",
"let",
"open",
"operator",
"private",
"protocol",
"public",
"rethrows",
"static",
"struct",
"subscript",
"typealias",
"var",
"break",
"case",
"continue",
"default",
"defer",
"do",
"else",
"fallthrough",
"for",
"guard",
"if",
"in",
"repeat",
"return",
"switch",
"where",
"while",
"Any",
"catch",
"false",
"is",
"nil",
"super",
"self",
"Self",
"throw",
"throws",
"true",
"try",
"associativity",
"convenience",
"dynamic",
"didSet",
"final",
"get",
"infix",
"indirect",
"lazy",
"left",
"mutating",
"none",
"nonmutating",
"optional",
"override",
"postfix",
"precedence",
"prefix",
"Protocol",
"required",
"right",
"set",
"Type",
"unowned",
"weak",
"willSet",
nullptr,
};
for (auto kw = keywords; *kw; kw++) keywords_.insert(*kw);
}
@ -160,6 +237,7 @@ class SwiftGenerator : public BaseGenerator {
}
void GenObjectHeader(const StructDef &struct_def) {
GenComment(struct_def.doc_comment);
code_.SetValue("STRUCTNAME", Name(struct_def));
code_.SetValue("PROTOCOL",
struct_def.fixed ? "Readable" : "FlatBufferObject");
@ -357,7 +435,7 @@ class SwiftGenerator : public BaseGenerator {
code_.SetValue("OFFSET", offset);
code_.SetValue("CONSTANT", field.value.constant);
std::string const_string = "return o == 0 ? {{CONSTANT}} : ";
GenComment(field.doc_comment, "\t");
if (IsScalar(field.value.type.base_type) && !IsEnum(field.value.type) &&
!IsBool(field.value.type.base_type)) {
code_ += GenReaderMainBody() + GenOffset() + const_string +
@ -534,6 +612,7 @@ class SwiftGenerator : public BaseGenerator {
code_.SetValue("VALUENAME", name);
code_.SetValue("VALUETYPE", type);
code_.SetValue("OFFSET", offset);
GenComment(field.doc_comment, "\t");
if (IsScalar(field.value.type.base_type) && !IsEnum(field.value.type)) {
code_ +=
GenReaderMainBody() + "return " + GenReader("VALUETYPE") + " }";
@ -555,9 +634,10 @@ class SwiftGenerator : public BaseGenerator {
void GenEnum(const EnumDef &enum_def) {
if (enum_def.generated) return;
code_.SetValue("ENUM_NAME", GenEnumDecl(enum_def));
code_.SetValue("ENUM_NAME", Name(enum_def));
code_.SetValue("BASE_TYPE", GenTypeBasic(enum_def.underlying_type, false));
code_ += "public {{ENUM_NAME}}: {{BASE_TYPE}}, Enum { ";
GenComment(enum_def.doc_comment);
code_ += "public enum {{ENUM_NAME}}: {{BASE_TYPE}}, Enum { ";
code_ += "\tpublic typealias T = {{BASE_TYPE}}";
code_ +=
"\tpublic static var byteSize: Int { return "
@ -565,23 +645,30 @@ class SwiftGenerator : public BaseGenerator {
"}";
code_ += "\tpublic var value: {{BASE_TYPE}} { return self.rawValue }";
std::string enum_code = "\tcase ";
int keyCount = 0;
for (auto it = enum_def.Vals().begin(); it != enum_def.Vals().end(); ++it) {
const auto &ev = **it;
auto key = "KEY" + NumToString(keyCount);
auto value = "VALUE" + NumToString(keyCount);
auto name = Name(ev);
std::transform(name.begin(), name.end(), name.begin(), LowerCase);
code_.SetValue(key, name);
code_.SetValue(value, enum_def.ToString(ev));
enum_code += "{{" + key + "}} = {{" + value + "}}, ";
keyCount++;
code_.SetValue("KEY", name);
code_.SetValue("VALUE", enum_def.ToString(ev));
GenComment(ev.doc_comment, "\t");
code_ += "\tcase {{KEY}} = {{VALUE}}";
}
code_ += enum_code.substr(0, enum_code.size() - 2);
code_ += "\n";
AddMinOrMaxEnumValue(enum_def.MaxValue()->name, "max");
AddMinOrMaxEnumValue(enum_def.MinValue()->name, "min");
code_ += "}\n";
}
void AddMinOrMaxEnumValue(const std::string &str, const std::string &type) {
auto current_value = str;
std::transform(current_value.begin(), current_value.end(),
current_value.begin(), LowerCase);
code_.SetValue(type, current_value);
code_ += "\tpublic static var " + type + ": {{ENUM_NAME}} { return .{{" +
type + "}} }";
}
void GenLookup(const FieldDef &key_field) {
code_.SetValue("OFFSET", NumToString(key_field.value.offset));
auto offset_reader =
@ -629,6 +716,12 @@ class SwiftGenerator : public BaseGenerator {
code_ += "\t}";
}
void GenComment(const std::vector<std::string> &dc, const char *prefix = "") {
std::string text;
::flatbuffers::GenComment(dc, &text, nullptr, prefix);
code_ += text + "\\";
}
std::string GenOffset() { return "let o = {{ACCESS}}.offset({{OFFSET}}); "; }
std::string GenReaderMainBody(const std::string &optional = "") {
@ -723,10 +816,6 @@ class SwiftGenerator : public BaseGenerator {
return swift_type[static_cast<int>(type.base_type)];
}
std::string GenEnumDecl(const EnumDef &enum_def) const {
return "enum " + Name(enum_def);
}
std::string EscapeKeyword(const std::string &name) const {
return keywords_.find(name) == keywords_.end() ? name : name + "_";
}

View File

@ -231,13 +231,14 @@ public final class ByteBuffer {
public func duplicate(removing removeBytes: Int = 0) -> ByteBuffer {
return ByteBuffer(memory: _memory, count: _capacity, removing: _writerSize - removeBytes)
}
}
#if DEBUG
func debugMemory(str: String) {
let bufprt = UnsafeBufferPointer(start: _memory.assumingMemoryBound(to: UInt8.self),
count: _capacity)
let a = Array(bufprt)
print(str, a, " \nwith buffer size: \(a.count) and writer size: \(_writerSize)")
extension ByteBuffer: CustomDebugStringConvertible {
public var debugDescription: String {
"""
buffer located at: \(_memory), with capacity of \(_capacity)
{ writerSize: \(_writerSize), readerSize: \(reader), writerIndex: \(writerIndex) }
"""
}
#endif
}

View File

@ -77,12 +77,9 @@ public final class FlatBufferBuilder {
public func clearOffsets() {
_vtable = []
}
}
// MARK: - Create Tables
extension FlatBufferBuilder {
/// Checks if the required fields were serialized into the buffer
/// - Parameters:
/// - table: offset for the table
@ -476,11 +473,16 @@ extension FlatBufferBuilder {
_bb.push(value: element, len: MemoryLayout<T>.size)
return _bb.size
}
}
#if DEBUG
/// Used to debug the buffer and the implementation
public func debug(str: String = "normal memory: ") {
_bb.debugMemory(str: str)
extension FlatBufferBuilder: CustomDebugStringConvertible {
public var debugDescription: String {
"""
buffer debug:
\(_bb)
builder debug:
{ finished: \(finished), serializeDefaults: \(serializeDefaults), isNested: \(isNested) }
"""
}
#endif
}

View File

@ -5,39 +5,77 @@ import FlatBuffers
public enum MyGame {
public enum Example {
/// Composite components of Monster color.
public enum Color: UInt8, Enum {
public typealias T = UInt8
public static var byteSize: Int { return MemoryLayout<UInt8>.size }
public var value: UInt8 { return self.rawValue }
case red = 1, green = 2, blue = 8
case red = 1
/// \brief color Green
/// Green is bit_flag with value (1u << 1)
case green = 2
/// \brief color Blue (1u << 3)
case blue = 8
public static var max: Color { return .blue }
public static var min: Color { return .red }
}
public enum Race: Int8, Enum {
public typealias T = Int8
public static var byteSize: Int { return MemoryLayout<Int8>.size }
public var value: Int8 { return self.rawValue }
case none = -1, human = 0, dwarf = 1, elf = 2
case none = -1
case human = 0
case dwarf = 1
case elf = 2
public static var max: Race { return .elf }
public static var min: Race { return .none }
}
public enum Any_: UInt8, Enum {
public typealias T = UInt8
public static var byteSize: Int { return MemoryLayout<UInt8>.size }
public var value: UInt8 { return self.rawValue }
case none = 0, monster = 1, testsimpletablewithenum = 2, mygame_example2_monster = 3
case none = 0
case monster = 1
case testsimpletablewithenum = 2
case mygame_example2_monster = 3
public static var max: Any_ { return .mygame_example2_monster }
public static var min: Any_ { return .none }
}
public enum AnyUniqueAliases: UInt8, Enum {
public typealias T = UInt8
public static var byteSize: Int { return MemoryLayout<UInt8>.size }
public var value: UInt8 { return self.rawValue }
case none = 0, m = 1, ts = 2, m2 = 3
case none = 0
case m = 1
case ts = 2
case m2 = 3
public static var max: AnyUniqueAliases { return .m2 }
public static var min: AnyUniqueAliases { return .none }
}
public enum AnyAmbiguousAliases: UInt8, Enum {
public typealias T = UInt8
public static var byteSize: Int { return MemoryLayout<UInt8>.size }
public var value: UInt8 { return self.rawValue }
case none = 0, m1 = 1, m2 = 2, m3 = 3
case none = 0
case m1 = 1
case m2 = 2
case m3 = 3
public static var max: AnyAmbiguousAliases { return .m3 }
public static var min: AnyAmbiguousAliases { return .none }
}
public struct Test: Readable {
@ -279,6 +317,7 @@ public struct Referrable: FlatBufferObject {
}
}
/// an example documentation comment: monster object
public struct Monster: FlatBufferObject {
static func validateVersion() { FlatBuffersVersion_1_11_1() }
@ -309,6 +348,8 @@ public struct Monster: FlatBufferObject {
public func test4(at index: Int32) -> MyGame.Example.Test? { let o = _accessor.offset(22); return o == 0 ? nil : MyGame.Example.Test(_accessor.bb, o: _accessor.vector(at: o) + index * 4) }
public var testarrayofstringCount: Int32 { let o = _accessor.offset(24); return o == 0 ? 0 : _accessor.vector(count: o) }
public func testarrayofstring(at index: Int32) -> String? { let o = _accessor.offset(24); return o == 0 ? nil : _accessor.directString(at: _accessor.vector(at: o) + index * 4) }
/// an example documentation comment: this will end up in the generated code
/// multiline too
public var testarrayoftablesCount: Int32 { let o = _accessor.offset(26); return o == 0 ? 0 : _accessor.vector(count: o) }
public func testarrayoftables(at index: Int32) -> MyGame.Example.Monster? { let o = _accessor.offset(26); return o == 0 ? nil : MyGame.Example.Monster(_accessor.bb, o: _accessor.indirect(_accessor.vector(at: o) + index * 4)) }
public func testarrayoftablesBy(key: String) -> MyGame.Example.Monster? { let o = _accessor.offset(26); return o == 0 ? nil : MyGame.Example.Monster.lookupByKey(vector: _accessor.vector(at: o), key: key, fbb: _accessor.bb) }

View File

@ -6,7 +6,17 @@ public enum Character: UInt8, Enum {
public typealias T = UInt8
public static var byteSize: Int { return MemoryLayout<UInt8>.size }
public var value: UInt8 { return self.rawValue }
case none = 0, mulan = 1, rapunzel = 2, belle = 3, bookfan = 4, other = 5, unused = 6
case none = 0
case mulan = 1
case rapunzel = 2
case belle = 3
case bookfan = 4
case other = 5
case unused = 6
public static var max: Character { return .unused }
public static var min: Character { return .none }
}
public struct Rapunzel: Readable {