Skip to content
This repository has been archived by the owner on Mar 26, 2020. It is now read-only.

Commit

Permalink
Added support for constexpr for primitives in header files (#354)
Browse files Browse the repository at this point in the history
* Got a basic version of constexpr in headers working

* got enum values to work as well

* can't do enums because interface headers forward declare so you can't set it there. So only primitives allowed

* fixing const enums in obj-c, which apparently never worked to begin with
  • Loading branch information
alancast authored and Xianwen Chen committed May 1, 2018
1 parent 9463fa9 commit a38f5ee
Show file tree
Hide file tree
Showing 23 changed files with 222 additions and 53 deletions.
1 change: 1 addition & 0 deletions CONTRIBUTORS
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@ The complete list of contributors can be identified through
Git history.

- Google Inc.
- Microsoft Corp.

2 changes: 1 addition & 1 deletion src/source/BaseObjcGenerator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ abstract class BaseObjcGenerator(spec: Spec) extends Generator(spec) {
case d: Double => w.w(boxedPrimitive(ty) + d.toString)
case b: Boolean => w.w(boxedPrimitive(ty) + (if (b) "YES" else "NO"))
case s: String => w.w("@" + s)
case e: EnumValue => w.w(idObjc.enum(e.ty + "_" + e.name))
case e: EnumValue => w.w(marshal.typename(ty) + idObjc.enum(e.name))
case v: ConstRef => w.w(selfName + idObjc.const (v.name))
case z: Map[_, _] => { // Value is record
val recordMdef = ty.resolved.base.asInstanceOf[MDef]
Expand Down
36 changes: 32 additions & 4 deletions src/source/CppGenerator.scala
Original file line number Diff line number Diff line change
Expand Up @@ -112,11 +112,35 @@ class CppGenerator(spec: Spec) extends Generator(spec) {
})
}

def shouldConstexpr(c: Const) = {
// Make sure we don't constexpr optionals as some might not support it
val canConstexpr = c.ty.resolved.base match {
case p: MPrimitive if c.ty.resolved.base != MOptional => true
case _ => false
}
canConstexpr
}

def generateHppConstants(w: IndentWriter, consts: Seq[Const]) = {
for (c <- consts) {
// set value in header if can constexpr (only primitives)
var constexpr = shouldConstexpr(c)
var constValue = ";"
if (constexpr) {
constValue = c.value match {
case l: Long => " = " + l.toString + ";"
case d: Double if marshal.fieldType(c.ty) == "float" => " = " + d.toString + "f;"
case d: Double => " = " + d.toString + ";"
case b: Boolean => if (b) " = true;" else " = false;"
case _ => ";"
}
}
val constFieldType = if (constexpr) s"constexpr ${marshal.fieldType(c.ty)}" else s"${marshal.fieldType(c.ty)} const"

// Write code to the header file
w.wl
writeDoc(w, c.doc)
w.wl(s"static ${marshal.fieldType(c.ty)} const ${idCpp.const(c.ident)};")
w.wl(s"static ${constFieldType} ${idCpp.const(c.ident)}${constValue}")
}
}

Expand All @@ -127,7 +151,7 @@ class CppGenerator(spec: Spec) extends Generator(spec) {
case d: Double => w.w(d.toString)
case b: Boolean => w.w(if (b) "true" else "false")
case s: String => w.w("{" + s + "}")
case e: EnumValue => w.w(marshal.typename(ty) + "::" + idCpp.enum(e.ty.name + "_" + e.name))
case e: EnumValue => w.w(marshal.typename(ty) + "::" + idCpp.enum(e.name))
case v: ConstRef => w.w(selfName + "::" + idCpp.const(v))
case z: Map[_, _] => { // Value is record
val recordMdef = ty.resolved.base.asInstanceOf[MDef]
Expand All @@ -150,8 +174,12 @@ class CppGenerator(spec: Spec) extends Generator(spec) {
val skipFirst = SkipFirst()
for (c <- consts) {
skipFirst{ w.wl }
w.w(s"${marshal.fieldType(c.ty)} const $selfName::${idCpp.const(c.ident)} = ")
writeCppConst(w, c.ty, c.value)
if (shouldConstexpr(c)){
w.w(s"${marshal.fieldType(c.ty)} const $selfName::${idCpp.const(c.ident)}")
} else {
w.w(s"${marshal.fieldType(c.ty)} const $selfName::${idCpp.const(c.ident)} = ")
writeCppConst(w, c.ty, c.value)
}
w.wl(";")
}
}
Expand Down
10 changes: 10 additions & 0 deletions test-suite/djinni/constants.djinni
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
# enum for use in constants
constant_enum = enum {
some_value;
some_other_value;
}

# Record for use in constants
constant_record = record {
some_integer: i32;
Expand All @@ -18,6 +24,8 @@ constants = record {
# Indented third line of multi-line documentation.)
const f64_constant: f64 = 5.0;

const const_enum: constant_enum = constant_enum::some_value;

const opt_bool_constant: optional<bool> = true;
const opt_i8_constant: optional<i8> = 1;
# opt_i16_constant has documentation.
Expand Down Expand Up @@ -59,6 +67,8 @@ constants_interface = interface +c {
const f32_constant: f32 = 5.0;
const f64_constant: f64 = 5.0;

const const_enum: constant_enum = constant_enum::some_value;

const opt_bool_constant: optional<bool> = true;
const opt_i8_constant: optional<i8> = 1;
# opt_i16_constant has documentation.
Expand Down
26 changes: 26 additions & 0 deletions test-suite/generated-src/cpp/constant_enum.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from constants.djinni

#pragma once

#include <functional>

namespace testsuite {

enum class constant_enum : int {
SOME_VALUE,
SOME_OTHER_VALUE,
};

} // namespace testsuite

namespace std {

template <>
struct hash<::testsuite::constant_enum> {
size_t operator()(::testsuite::constant_enum type) const {
return std::hash<int>()(static_cast<int>(type));
}
};

} // namespace std
18 changes: 10 additions & 8 deletions test-suite/generated-src/cpp/constants.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,21 @@

namespace testsuite {

bool const Constants::BOOL_CONSTANT = true;
bool const Constants::BOOL_CONSTANT;

int8_t const Constants::I8_CONSTANT = 1;
int8_t const Constants::I8_CONSTANT;

int16_t const Constants::I16_CONSTANT = 2;
int16_t const Constants::I16_CONSTANT;

int32_t const Constants::I32_CONSTANT = 3;
int32_t const Constants::I32_CONSTANT;

int64_t const Constants::I64_CONSTANT = 4;
int64_t const Constants::I64_CONSTANT;

float const Constants::F32_CONSTANT = 5.0f;
float const Constants::F32_CONSTANT;

double const Constants::F64_CONSTANT = 5.0;
double const Constants::F64_CONSTANT;

constant_enum const Constants::CONST_ENUM = constant_enum::SOME_VALUE;

std::experimental::optional<bool> const Constants::OPT_BOOL_CONSTANT = true;

Expand All @@ -41,6 +43,6 @@ ConstantRecord const Constants::OBJECT_CONSTANT = ConstantRecord(
Constants::I32_CONSTANT /* some_integer */ ,
Constants::STRING_CONSTANT /* some_string */ );

bool const Constants::DUMMY = false;
bool const Constants::DUMMY;

} // namespace testsuite
19 changes: 11 additions & 8 deletions test-suite/generated-src/cpp/constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#pragma once

#include "../../handwritten-src/cpp/optional.hpp"
#include "constant_enum.hpp"
#include "constant_record.hpp"
#include <cstdint>
#include <string>
Expand All @@ -15,24 +16,26 @@ namespace testsuite {
struct Constants final {

/** bool_constant has documentation. */
static bool const BOOL_CONSTANT;
static constexpr bool BOOL_CONSTANT = true;

static int8_t const I8_CONSTANT;
static constexpr int8_t I8_CONSTANT = 1;

static int16_t const I16_CONSTANT;
static constexpr int16_t I16_CONSTANT = 2;

static int32_t const I32_CONSTANT;
static constexpr int32_t I32_CONSTANT = 3;

static int64_t const I64_CONSTANT;
static constexpr int64_t I64_CONSTANT = 4;

static float const F32_CONSTANT;
static constexpr float F32_CONSTANT = 5.0f;

/**
* f64_constant has long documentation.
* (Second line of multi-line documentation.
* Indented third line of multi-line documentation.)
*/
static double const F64_CONSTANT;
static constexpr double F64_CONSTANT = 5.0;

static constant_enum const CONST_ENUM;

static std::experimental::optional<bool> const OPT_BOOL_CONSTANT;

Expand Down Expand Up @@ -65,7 +68,7 @@ struct Constants final {
* No support for optional constant records
* No support for constant binary, list, set, map
*/
static bool const DUMMY;
static constexpr bool DUMMY = false;
};

} // namespace testsuite
17 changes: 10 additions & 7 deletions test-suite/generated-src/cpp/constants_interface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,23 +2,26 @@
// This file generated by Djinni from constants.djinni

#include "constants_interface.hpp" // my header
#include "constant_enum.hpp"
#include "constant_record.hpp"

namespace testsuite {

bool const ConstantsInterface::BOOL_CONSTANT = true;
bool const ConstantsInterface::BOOL_CONSTANT;

int8_t const ConstantsInterface::I8_CONSTANT = 1;
int8_t const ConstantsInterface::I8_CONSTANT;

int16_t const ConstantsInterface::I16_CONSTANT = 2;
int16_t const ConstantsInterface::I16_CONSTANT;

int32_t const ConstantsInterface::I32_CONSTANT = 3;
int32_t const ConstantsInterface::I32_CONSTANT;

int64_t const ConstantsInterface::I64_CONSTANT = 4;
int64_t const ConstantsInterface::I64_CONSTANT;

float const ConstantsInterface::F32_CONSTANT = 5.0f;
float const ConstantsInterface::F32_CONSTANT;

double const ConstantsInterface::F64_CONSTANT = 5.0;
double const ConstantsInterface::F64_CONSTANT;

constant_enum const ConstantsInterface::CONST_ENUM = constant_enum::SOME_VALUE;

std::experimental::optional<bool> const ConstantsInterface::OPT_BOOL_CONSTANT = true;

Expand Down
17 changes: 10 additions & 7 deletions test-suite/generated-src/cpp/constants_interface.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -9,32 +9,35 @@

namespace testsuite {

enum class constant_enum;
struct ConstantRecord;

/** Interface containing constants */
class ConstantsInterface {
public:
virtual ~ConstantsInterface() {}

static bool const BOOL_CONSTANT;
static constexpr bool BOOL_CONSTANT = true;

static int8_t const I8_CONSTANT;
static constexpr int8_t I8_CONSTANT = 1;

static int16_t const I16_CONSTANT;
static constexpr int16_t I16_CONSTANT = 2;

/** i32_constant has documentation. */
static int32_t const I32_CONSTANT;
static constexpr int32_t I32_CONSTANT = 3;

/**
* i64_constant has long documentation.
* (Second line of multi-line documentation.
* Indented third line of multi-line documentation.)
*/
static int64_t const I64_CONSTANT;
static constexpr int64_t I64_CONSTANT = 4;

static float const F32_CONSTANT;
static constexpr float F32_CONSTANT = 5.0f;

static double const F64_CONSTANT;
static constexpr double F64_CONSTANT = 5.0;

static constant_enum const CONST_ENUM;

static std::experimental::optional<bool> const OPT_BOOL_CONSTANT;

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from constants.djinni

package com.dropbox.djinni.test;

import javax.annotation.CheckForNull;
import javax.annotation.Nonnull;

/** enum for use in constants */
public enum ConstantEnum {
SOME_VALUE,
SOME_OTHER_VALUE,
;
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ public class Constants {
*/
public static final double F64_CONSTANT = 5.0;

@Nonnull
public static final ConstantEnum CONST_ENUM = ConstantEnum.SOME_VALUE;

@CheckForNull
public static final Boolean OPT_BOOL_CONSTANT = true;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,9 @@ public abstract class ConstantsInterface {

public static final double F64_CONSTANT = 5.0;

@Nonnull
public static final ConstantEnum CONST_ENUM = ConstantEnum.SOME_VALUE;

@CheckForNull
public static final Boolean OPT_BOOL_CONSTANT = true;

Expand Down
26 changes: 26 additions & 0 deletions test-suite/generated-src/jni/NativeConstantEnum.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from constants.djinni

#pragma once

#include "constant_enum.hpp"
#include "djinni_support.hpp"

namespace djinni_generated {

class NativeConstantEnum final : ::djinni::JniEnum {
public:
using CppType = ::testsuite::constant_enum;
using JniType = jobject;

using Boxed = NativeConstantEnum;

static CppType toCpp(JNIEnv* jniEnv, JniType j) { return static_cast<CppType>(::djinni::JniClass<NativeConstantEnum>::get().ordinal(jniEnv, j)); }
static ::djinni::LocalRef<JniType> fromCpp(JNIEnv* jniEnv, CppType c) { return ::djinni::JniClass<NativeConstantEnum>::get().create(jniEnv, static_cast<jint>(c)); }

private:
NativeConstantEnum() : JniEnum("com/dropbox/djinni/test/ConstantEnum") {}
friend ::djinni::JniClass<NativeConstantEnum>;
};

} // namespace djinni_generated
1 change: 1 addition & 0 deletions test-suite/generated-src/jni/NativeConstantsInterface.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

#include "NativeConstantsInterface.hpp" // my header
#include "Marshal.hpp"
#include "NativeConstantEnum.hpp"
#include "NativeConstantRecord.hpp"

namespace djinni_generated {
Expand Down
6 changes: 6 additions & 0 deletions test-suite/generated-src/objc/DBConstantEnum+Private.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from constants.djinni

#include "constant_enum.hpp"
#import "DJIMarshal+Private.h"

11 changes: 11 additions & 0 deletions test-suite/generated-src/objc/DBConstantEnum.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// AUTOGENERATED FILE - DO NOT MODIFY!
// This file generated by Djinni from constants.djinni

#import <Foundation/Foundation.h>

/** enum for use in constants */
typedef NS_ENUM(NSInteger, DBConstantEnum)
{
DBConstantEnumSomeValue,
DBConstantEnumSomeOtherValue,
};
1 change: 1 addition & 0 deletions test-suite/generated-src/objc/DBConstants+Private.mm
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
// This file generated by Djinni from constants.djinni

#import "DBConstants+Private.h"
#import "DBConstantEnum+Private.h"
#import "DBConstantRecord+Private.h"
#import "DJIMarshal+Private.h"
#include <cassert>
Expand Down
Loading

0 comments on commit a38f5ee

Please sign in to comment.