Skip to content
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
70 changes: 40 additions & 30 deletions src/idl_gen_swift.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -537,7 +537,8 @@ class SwiftGenerator : public BaseGenerator {
auto &create_func_header = *create_header;
auto name = Name(field);
auto type = GenType(field.value.type);
auto opt_scalar = field.IsOptional() && IsScalar(field.value.type.base_type);
auto opt_scalar =
field.IsOptional() && IsScalar(field.value.type.base_type);
auto nullable_type = opt_scalar ? type + "?" : type;
code_.SetValue("VALUENAME", name);
code_.SetValue("VALUETYPE", nullable_type);
Expand All @@ -560,16 +561,17 @@ class SwiftGenerator : public BaseGenerator {
"{{VALUETYPE}}" + builder_string + "fbb.add(element: {{VALUENAME}}\\";

code_ += field.IsOptional() ? (optional_enum + "\\")
: (is_enum + ", def: {{CONSTANT}}\\");
: (is_enum + ", def: {{CONSTANT}}\\");

code_ += ", at: {{TABLEOFFSET}}.{{OFFSET}}.p) }";

auto default_value =
IsEnum(field.value.type)
? (field.IsOptional() ? "nil" : GenEnumDefaultValue(field))
: field.value.constant;
create_func_header.push_back("" + name + ": " + nullable_type + " = " +
(field.IsOptional() ? "nil" : default_value));
create_func_header.push_back(
"" + name + ": " + nullable_type + " = " +
(field.IsOptional() ? "nil" : default_value));
return;
}

Expand All @@ -583,8 +585,9 @@ class SwiftGenerator : public BaseGenerator {
"fbb.add(element: {{VALUENAME}},\\";
code_ += field.IsOptional() ? "\\" : " def: {{CONSTANT}},";
code_ += " at: {{TABLEOFFSET}}.{{OFFSET}}.p) }";
create_func_header.push_back(name + ": " + nullable_type + " = " +
(field.IsOptional() ? "nil" : default_value));
create_func_header.push_back(
name + ": " + nullable_type + " = " +
(field.IsOptional() ? "nil" : default_value));
return;
}

Expand Down Expand Up @@ -648,9 +651,8 @@ class SwiftGenerator : public BaseGenerator {
code_.SetValue("VALUETYPE", type);
code_.SetValue("OFFSET", name);
code_.SetValue("CONSTANT", field.value.constant);
bool opt_scalar = field.IsOptional() && IsScalar(field.value.type.base_type);
std::string def_Val = opt_scalar ? "nil" : "{{CONSTANT}}";
std::string optional = opt_scalar ? "?" : "";
std::string def_Val = field.IsDefault() ? "{{CONSTANT}}" : "nil";
std::string optional = field.IsOptional() ? "?" : "";
auto const_string = "return o == 0 ? " + def_Val + " : ";
GenComment(field.doc_comment);
if (IsScalar(field.value.type.base_type) && !IsEnum(field.value.type) &&
Expand All @@ -675,7 +677,8 @@ class SwiftGenerator : public BaseGenerator {
}

if (IsEnum(field.value.type)) {
auto default_value = field.IsOptional() ? "nil" : GenEnumDefaultValue(field);
auto default_value =
field.IsOptional() ? "nil" : GenEnumDefaultValue(field);
code_.SetValue("BASEVALUE", GenTypeBasic(field.value.type, false));
code_ += GenReaderMainBody(optional) + "\\";
code_ += GenOffset() + "return o == 0 ? " + default_value + " : " +
Expand Down Expand Up @@ -709,21 +712,20 @@ class SwiftGenerator : public BaseGenerator {
GenConstructor(GenIndirect("o + {{ACCESS}}.postion"));
break;

case BASE_TYPE_STRING:
case BASE_TYPE_STRING: {
auto default_string = "\"" + field.value.constant + "\"";
code_.SetValue("VALUETYPE", GenType(field.value.type));
code_.SetValue("CONSTANT", "nil");
code_.SetValue("CONSTANT", field.IsDefault() ? default_string : "nil");
code_ += GenReaderMainBody(is_required) + GenOffset() +
required_reader + "{{ACCESS}}.string(at: o) }";
code_ += "{{ACCESS_TYPE}} var {{VALUENAME}}SegmentArray: [UInt8]" +
is_required +
" { return "
"{{ACCESS}}.getVector(at: {{TABLEOFFSET}}.{{OFFSET}}.v) }";
break;

}
case BASE_TYPE_ARRAY: FLATBUFFERS_FALLTHROUGH(); // fall thru
case BASE_TYPE_VECTOR:
GenTableReaderVectorFields(field, const_string);
break;
case BASE_TYPE_VECTOR: GenTableReaderVectorFields(field); break;
case BASE_TYPE_UNION:
code_.SetValue("CONSTANT", "nil");
code_ +=
Expand All @@ -736,15 +738,14 @@ class SwiftGenerator : public BaseGenerator {
}
}

void GenTableReaderVectorFields(const FieldDef &field,
const std::string &const_string) {
void GenTableReaderVectorFields(const FieldDef &field) {
std::string const_string = "return o == 0 ? {{CONSTANT}} : ";
auto vectortype = field.value.type.VectorType();
code_.SetValue("SIZE", NumToString(InlineSize(vectortype)));
code_ += "{{ACCESS_TYPE}} var {{VALUENAME}}Count: Int32 { " + GenOffset() +
const_string + "{{ACCESS}}.vector(count: o) }";
code_.SetValue("CONSTANT", IsScalar(vectortype.base_type) == true
? field.value.constant
: "nil");
"return o == 0 ? 0 : {{ACCESS}}.vector(count: o) }";
code_.SetValue("CONSTANT",
IsScalar(vectortype.base_type) == true ? "0" : "nil");
auto nullable = IsScalar(vectortype.base_type) == true ? "" : "?";
nullable = IsEnum(vectortype) == true ? "?" : nullable;

Expand All @@ -759,11 +760,10 @@ class SwiftGenerator : public BaseGenerator {

if (IsBool(vectortype.base_type)) {
code_.SetValue("CONSTANT", field.value.offset == 0 ? "false" : "true");
code_.SetValue("VALUETYPE", "Byte");
code_.SetValue("VALUETYPE", "Bool");
}
if (!IsEnum(vectortype))
code_ +=
const_string + (IsBool(vectortype.base_type) ? "0 != " : "") + "\\";

if (!IsEnum(vectortype)) code_ += const_string + "\\";

if (IsScalar(vectortype.base_type) && !IsEnum(vectortype) &&
!IsBool(field.value.type.base_type)) {
Expand Down Expand Up @@ -1166,9 +1166,9 @@ class SwiftGenerator : public BaseGenerator {
buffer_constructor.push_back("" + name + " = _t." + name);
} else {
buffer_constructor.push_back("var __" + name + " = _t." + name);
buffer_constructor.push_back("" + name + " = __" + name +
(field.IsRequired() ? "!" : question_mark) +
".unpack()");
buffer_constructor.push_back(
"" + name + " = __" + name +
(field.IsRequired() ? "!" : question_mark) + ".unpack()");
}
break;
}
Expand All @@ -1181,7 +1181,17 @@ class SwiftGenerator : public BaseGenerator {
case BASE_TYPE_STRING: {
code_ += "{{ACCESS_TYPE}} var {{VALUENAME}}: String" + is_required;
buffer_constructor.push_back(name + " = _t." + name);
if (field.IsRequired()) base_constructor.push_back(name + " = \"\"");

if (field.IsRequired()) {
std::string default_value =
field.IsDefault() ? field.value.constant : "";
base_constructor.push_back(name + " = \"" + default_value + "\"");
break;
}
if (field.IsDefault() && !field.IsRequired()) {
std::string value = field.IsDefault() ? field.value.constant : "nil";
base_constructor.push_back(name + " = \"" + value + "\"");
}
break;
}
case BASE_TYPE_UTYPE: break;
Expand Down
2 changes: 1 addition & 1 deletion src/idl_parser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2434,7 +2434,7 @@ bool Parser::SupportsOptionalScalars() const {

bool Parser::SupportsDefaultVectorsAndStrings() const {
static FLATBUFFERS_CONSTEXPR unsigned long supported_langs =
IDLOptions::kRust;
IDLOptions::kRust | IDLOptions::kSwift;
return !(opts.lang_to_generate & ~supported_langs);
}

Expand Down
1 change: 1 addition & 0 deletions tests/FlatBuffers.Test.Swift/SwiftTest.sh
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ cd ${test_dir}
cd ${swift_dir}/Tests/FlatBuffers.Test.SwiftTests
fbc --swift --gen-mutable --grpc --gen-object-api -I ${test_dir}/include_test ${test_dir}/monster_test.fbs ${test_dir}/union_vector/union_vector.fbs
fbc --swift ${test_dir}/optional_scalars.fbs
fbc --swift --gen-object-api ${test_dir}/more_defaults.fbs
cd ${swift_dir}
swift build --build-tests
swift test
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,24 @@ class FlatBuffersMonsterWriterTests: XCTestCase {
readObjectApi(monster: unpacked)
}

func testArrayOfBools() {
let boolArray = [false, true, false, true, false, true, false]
var fbb = FlatBufferBuilder(initialSize: 1)
let name = fbb.create(string: "Frodo")
let bools = fbb.createVector(boolArray)
let root = Monster.createMonster(&fbb, offsetOfName: name, vectorOfTestarrayofbools: bools)
fbb.finish(offset: root)
let monster = Monster.getRootAsMonster(bb: fbb.sizedBuffer)

let values = monster.testarrayofbools

XCTAssertEqual(boolArray, values)

for i in 0..<monster.testarrayofboolsCount {
XCTAssertEqual(boolArray[Int(i)], monster.testarrayofbools(at: i))
}
}

func readMonster(fb: ByteBuffer) {
var monster = Monster.getRootAsMonster(bb: fb)
readFlatbufferMonster(monster: &monster)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright 2021 Google Inc. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

import Foundation
import XCTest
@testable import FlatBuffers

class FlatBuffersMoreDefaults: XCTestCase {

func testFlatbuffersObject() {
var fbb = FlatBufferBuilder()
let root = MoreDefaults.createMoreDefaults(&fbb)
fbb.finish(offset: root)
let defaults = MoreDefaults.getRootAsMoreDefaults(bb: fbb.sizedBuffer)
XCTAssertEqual(defaults.emptyString, "")
XCTAssertEqual(defaults.someString, "some")
XCTAssertEqual(defaults.ints, [])
XCTAssertEqual(defaults.floats, [])
XCTAssertEqual(defaults.intsCount, 0)
XCTAssertEqual(defaults.floatsCount, 0)
}

func testFlatbuffersObjectAPI() {
var fbb = FlatBufferBuilder()
let defaults = MoreDefaultsT()
XCTAssertEqual(defaults.emptyString, "")
XCTAssertEqual(defaults.someString, "some")
XCTAssertEqual(defaults.ints, [])
XCTAssertEqual(defaults.floats, [])

let buffer = defaults.serialize(builder: &fbb, type: MoreDefaults.self)
let fDefaults = MoreDefaults.getRootAsMoreDefaults(bb: buffer)
XCTAssertEqual(fDefaults.emptyString, "")
XCTAssertEqual(fDefaults.someString, "some")
XCTAssertEqual(fDefaults.ints, [])
XCTAssertEqual(fDefaults.floats, [])
XCTAssertEqual(fDefaults.intsCount, 0)
XCTAssertEqual(fDefaults.floatsCount, 0)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ extension FlatBuffersMonsterWriterTests {
// `swift test --generate-linuxmain`
// to regenerate.
static let __allTests__FlatBuffersMonsterWriterTests = [
("testArrayOfBools", testArrayOfBools),
("testCreateMonster", testCreateMonster),
("testCreateMonsterPrefixed", testCreateMonsterPrefixed),
("testCreateMonsterResizedBuffer", testCreateMonsterResizedBuffer),
Expand All @@ -43,6 +44,16 @@ extension FlatBuffersMonsterWriterTests {
]
}

extension FlatBuffersMoreDefaults {
// DO NOT MODIFY: This is autogenerated, use:
// `swift test --generate-linuxmain`
// to regenerate.
static let __allTests__FlatBuffersMoreDefaults = [
("testFlatbuffersObject", testFlatbuffersObject),
("testFlatbuffersObjectAPI", testFlatbuffersObjectAPI),
]
}

extension FlatBuffersStructsTests {
// DO NOT MODIFY: This is autogenerated, use:
// `swift test --generate-linuxmain`
Expand Down Expand Up @@ -100,6 +111,7 @@ public func __allTests() -> [XCTestCaseEntry] {
[
testCase(FlatBuffersDoubleTests.__allTests__FlatBuffersDoubleTests),
testCase(FlatBuffersMonsterWriterTests.__allTests__FlatBuffersMonsterWriterTests),
testCase(FlatBuffersMoreDefaults.__allTests__FlatBuffersMoreDefaults),
testCase(FlatBuffersStructsTests.__allTests__FlatBuffersStructsTests),
testCase(FlatBuffersTests.__allTests__FlatBuffersTests),
testCase(FlatBuffersUnionTests.__allTests__FlatBuffersUnionTests),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -800,9 +800,9 @@ public struct MyGame_Example_Monster: FlatBufferObject, ObjectAPIPacker {
public var testhashu64Fnv1a: UInt64 { let o = _accessor.offset(VTOFFSET.testhashu64Fnv1a.v); return o == 0 ? 0 : _accessor.readBuffer(of: UInt64.self, at: o) }
@discardableResult public func mutate(testhashu64Fnv1a: UInt64) -> Bool {let o = _accessor.offset(VTOFFSET.testhashu64Fnv1a.v); return _accessor.mutate(testhashu64Fnv1a, index: o) }
public var testarrayofboolsCount: Int32 { let o = _accessor.offset(VTOFFSET.testarrayofbools.v); return o == 0 ? 0 : _accessor.vector(count: o) }
public func testarrayofbools(at index: Int32) -> Bool { let o = _accessor.offset(VTOFFSET.testarrayofbools.v); return o == 0 ? true : 0 != _accessor.directRead(of: Byte.self, offset: _accessor.vector(at: o) + index * 1) }
public var testarrayofbools: [Byte] { return _accessor.getVector(at: VTOFFSET.testarrayofbools.v) ?? [] }
public func mutate(testarrayofbools: Byte, at index: Int32) -> Bool { let o = _accessor.offset(VTOFFSET.testarrayofbools.v); return _accessor.directMutate(testarrayofbools, index: _accessor.vector(at: o) + index * 1) }
public func testarrayofbools(at index: Int32) -> Bool { let o = _accessor.offset(VTOFFSET.testarrayofbools.v); return o == 0 ? true : _accessor.directRead(of: Bool.self, offset: _accessor.vector(at: o) + index * 1) }
public var testarrayofbools: [Bool] { return _accessor.getVector(at: VTOFFSET.testarrayofbools.v) ?? [] }
public func mutate(testarrayofbools: Bool, at index: Int32) -> Bool { let o = _accessor.offset(VTOFFSET.testarrayofbools.v); return _accessor.directMutate(testarrayofbools, index: _accessor.vector(at: o) + index * 1) }
public var testf: Float32 { let o = _accessor.offset(VTOFFSET.testf.v); return o == 0 ? 3.14159 : _accessor.readBuffer(of: Float32.self, at: o) }
@discardableResult public func mutate(testf: Float32) -> Bool {let o = _accessor.offset(VTOFFSET.testf.v); return _accessor.mutate(testf, index: o) }
public var testf2: Float32 { let o = _accessor.offset(VTOFFSET.testf2.v); return o == 0 ? 3.0 : _accessor.readBuffer(of: Float32.self, at: o) }
Expand Down
Loading