protobuf.js icon indicating copy to clipboard operation
protobuf.js copied to clipboard

Fixing codegen issues with reserved classes

Open inightingalesc opened this issue 8 years ago • 3 comments

-Added built in classes String and Array to reserved words -Sanitized all names in the namespace before building the namespace to avoid issue with constructors and interfaces

inightingalesc avatar Nov 21 '17 18:11 inightingalesc

The initial issue should have been fixed by merging #913. Not sure about the other changes because https://github.com/dcodeIO/protobuf.js/pull/870#issuecomment-346901503.

dcodeIO avatar Nov 24 '17 22:11 dcodeIO

Thank you for taking a look at this, and for merging #913!

To give you some context for the other issue, the current implementation generates the following code when given a message with the name of a built-in javascript class (e.g, String):

SpecialString.String = (function() {

    /**
        * Properties of a String.
        * @memberof root.context.SpecialString
        * @interface IString
        * @property {string|null} [locale] String locale
        * @property {string|null} [text] String text
        */

    /**
        * Constructs a new String.
        * @memberof root.context.SpecialString
        * @classdesc Represents a String.
        * @implements IString
        * @constructor
        * @param {root.context.SpecialString.IString=} [properties] Properties to set
        */
    function String(properties) {
        if (properties)
            for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                if (properties[keys[i]] != null)
                    this[keys[i]] = properties[keys[i]];
    }

    /**
        * String locale.
        * @member {string} locale
        * @memberof root.context.SpecialString.String
        * @instance
        */
    String.prototype.locale = "";

This will fail at runtime because it will use the reserved String class instead of our new one.

Now, if I add Array|String to the list of reserved words, we have improvement, but the constructor now has the wrong name:

SpecialString.String_ = (function() {

                /**
                 * Properties of a String.
                 * @memberof root.context.SpecialString
                 * @interface IString
                 * @property {string|null} [locale] String locale
                 * @property {string|null} [text] String text
                 */

                /**
                 * Constructs a new String.
                 * @memberof root.context.SpecialString
                 * @classdesc Represents a String.
                 * @implements IString
                 * @constructor
                 * @param {root.context.SpecialString.IString_=} [properties] Properties to set
                 */
                function String(properties) {
                    if (properties)
                        for (var keys = Object.keys(properties), i = 0; i < keys.length; ++i)
                            if (properties[keys[i]] != null)
                                this[keys[i]] = properties[keys[i]];
                }

                /**
                 * String locale.
                 * @member {string} locale
                 * @memberof root.context.SpecialString.String_
                 * @instance
                 */
                String_.prototype.locale = "";

It seemed to me the simplest way to fix this is to escape the names of all types initially, so that the Type constructor generator doesn't need to worry about the function name.

Let me know what you suggest in terms of approach!

inightingalesc avatar Nov 27 '17 19:11 inightingalesc

Not sure if this PR is still alive, but the same issue happens for Object as well as String and Array

mfedderly avatar May 08 '19 15:05 mfedderly