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

Improve error messages and generate operator<< for records #417

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

danyowdee
Copy link

This PR improves the error messages when a record cannot conform to a typeclass, because it has fields of types that don’t. In addition, it generates the C++ operator<< for enums, and introduces the show typeclass to do the same for records deriving (show).

Assuming the following Djinni file:

enum CurrencyCode {
    USD;
    EUR;
};

Amount = record {
    units: i64;
    currency: CurrencyCode;
} deriving (show)

Product = record {
    name: string;
    identifier: string;
    price: Amount;
} deriving (show)

ShoppingCart = record {
    items: list<Product>;
} deriving (show)

This PR allows you to write the following C++ code:

Product p{"Little Red Corvette", "v0KpfrJE4zw", Amount{1999, CurrencyCode::USD}};
Product q{"Breakfast Can Wait", "CzWX1gv6u2s", Amount{2013, CurrencyCode::EUR}};
ShoppingCart c{{p, q}};
std::cout << c << std::endl;
/* prints
"""ShoppingCart{ items:[
Product{ name:Little Red Corvette, identifier:v0KpfrJE4zw, price:Amount{ units:1999, currency:CurrencyCode::USD } },
Product{ name:Breakfast Can Wait, identifier:CzWX1gv6u2s, price:Amount{ units:2013, currency:CurrencyCode::EUR } },
] }"""
 */

If Amount would be missing the declaration of conformance to show, the error message from running Djinni would clearly say so:

Record 'Amount' not deriving required operation(s): 'show'

Supported Field Types

  • any record deriving (show)
  • numbers and strings
  • any enum
  • any list<T> where T is any of the above (or a map, or a list)
  • any map<K,V> where K and V are any of the above (or a map)

Limitations/Known Issues

  • data fields are printed as arrays of integers by default
  • flag and optional fields require handwritten overloads of operator<< to be available in the translation unit of the record; failure to do so will not report an error until trying to compile the record’s .cppfile
  • no specific error checking/reporting is implemented for containers: if the contained type doesn’t support show, the error may not surface until trying to compile the record’s .cpp file
  • the added code is most definitely not idiomatic Scala, but rather baby steps towards learning the language

Generating a description of a record is mostly trivial.
In fact, this already happens for Objective-C and Java — only C++ is missing.
Instead of generating this code unconditionally, this commit introduces something equivalent to Haskell’s `Show` typeclass for Djinni records.
It can be written using the regular `deriving (…)` syntax, using the keyword `show`.

Due to how resolver.scala is implemented, this diff is enough to get an error message telling if a nested record isn’t deriving `show` (the message is bad, though).
@xianwen
Copy link

xianwen commented Dec 26, 2018

Hi, @danyowdee:
I noticed you haven't signed the CLA yet, could you please sign it here: https://opensource.dropbox.com/cla/
Thanks a lot!

@danyowdee
Copy link
Author

Done.

Copy link

@xianwen xianwen left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update the generated files, specifically, test-suite/generated-src/cpp/color.hpp and
test-suite/generated-src/cpp/constant_enum.hpp will be affected by this diff.

Copy link
Contributor

@artwyman artwyman left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should add some new cases to the test-suite to exercise this new functionality, as well as documentation about how to use it. E.g. the new "deriving" directive should be documented and demonstrated.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants