Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a1c6d909 authored by Joe Onorato's avatar Joe Onorato Committed by Mike Lockwood
Browse files

aidl: All flattenable types now must also be parcelable.

This is more a limitation of the grammar than anything else triggering laziness on my part.
parent 95a766dd
Loading
Loading
Loading
Loading
+17 −45
Original line number Diff line number Diff line
@@ -123,7 +123,7 @@ register_base_types()
    RPC_DATA_TYPE = new RpcDataType();
    NAMES.Add(RPC_DATA_TYPE);

    RPC_ERROR_TYPE = new ParcelableType("com.android.athome.rpc", "RpcError",
    RPC_ERROR_TYPE = new UserDataType("com.android.athome.rpc", "RpcError",
                                    true, __FILE__, __LINE__);
    NAMES.Add(RPC_ERROR_TYPE);

@@ -896,29 +896,22 @@ ListType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v, V

// ================================================================

ParcelableType::ParcelableType(const string& package, const string& name,
                        bool builtIn, const string& declFile, int declLine)
    :Type(package, name, builtIn ? BUILT_IN : PARCELABLE, true, false, true,
            declFile, declLine)
{
}

ParcelableType::ParcelableType(const string& package, const string& name,
                            bool builtIn, bool canWriteToRpcData,
UserDataType::UserDataType(const string& package, const string& name,
                        bool builtIn, bool canWriteToParcel, bool canWriteToRpcData,
                        const string& declFile, int declLine)
    :Type(package, name, builtIn ? BUILT_IN : PARCELABLE, true, canWriteToRpcData, true,
            declFile, declLine)
    :Type(package, name, builtIn ? BUILT_IN : USERDATA, canWriteToParcel, canWriteToRpcData,
            true, declFile, declLine)
{
}

string
ParcelableType::CreatorName() const
UserDataType::CreatorName() const
{
    return QualifiedName() + ".CREATOR";
}

void
ParcelableType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
UserDataType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
{
    // if (v != null) {
    //     parcel.writeInt(1);
@@ -941,7 +934,7 @@ ParcelableType::WriteToParcel(StatementBlock* addTo, Variable* v, Variable* parc
}

void
ParcelableType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
UserDataType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
    // if (0 != parcel.readInt()) {
    //     v = CLASS.CREATOR.createFromParcel(parcel)
@@ -962,7 +955,7 @@ ParcelableType::CreateFromParcel(StatementBlock* addTo, Variable* v, Variable* p
}

void
ParcelableType::ReadFromParcel(StatementBlock* addTo, Variable* v,
UserDataType::ReadFromParcel(StatementBlock* addTo, Variable* v,
                    Variable* parcel, Variable**)
{
    // TODO: really, we don't need to have this extra check, but we
@@ -978,20 +971,20 @@ ParcelableType::ReadFromParcel(StatementBlock* addTo, Variable* v,
}

bool
ParcelableType::CanBeArray() const
UserDataType::CanBeArray() const
{
    return true;
}

void
ParcelableType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
UserDataType::WriteArrayToParcel(StatementBlock* addTo, Variable* v, Variable* parcel, int flags)
{
    addTo->Add(new MethodCall(parcel, "writeTypedArray", 2, v,
                BuildWriteToParcelFlags(flags)));
}

void
ParcelableType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
UserDataType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
                            Variable* parcel, Variable**)
{
    string creator = v->type->QualifiedName() + ".CREATOR";
@@ -1000,30 +993,15 @@ ParcelableType::CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
}

void
ParcelableType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
UserDataType::ReadArrayFromParcel(StatementBlock* addTo, Variable* v, Variable* parcel, Variable**)
{
    string creator = v->type->QualifiedName() + ".CREATOR";
    addTo->Add(new MethodCall(parcel, "readTypedArray", 2,
                    v, new LiteralExpression(creator)));
}

// ================================================================

FlattenableType::FlattenableType(const string& package, const string& name,
                        bool builtIn, const string& declFile, int declLine)
    :Type(package, name, builtIn ? BUILT_IN : PARCELABLE, false, true, true,
            declFile, declLine)
{
}

string
FlattenableType::CreatorName() const
{
    return QualifiedName() + ".CREATOR";
}

void
FlattenableType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
UserDataType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
                                    Variable* data, int flags)
{
    // if (v != null) {
@@ -1042,7 +1020,7 @@ FlattenableType::WriteToRpcData(StatementBlock* addTo, Expression* k, Variable*
}

void
FlattenableType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
UserDataType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
                                    Variable* data, Variable** cl)
{
    // RpcData _obj_XX = data.getRpcData(k);
@@ -1070,12 +1048,6 @@ FlattenableType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variabl
    block->Add(ifpart);
}

bool
FlattenableType::CanBeArray() const
{
    return true;
}

// ================================================================

InterfaceType::InterfaceType(const string& package, const string& name,
@@ -1266,7 +1238,7 @@ GenericListType::CreateFromRpcData(StatementBlock* addTo, Expression* k, Variabl
// ================================================================

RpcDataType::RpcDataType()
    :ParcelableType("com.android.athome.rpc", "RpcData", true, true)
    :UserDataType("com.android.athome.rpc", "RpcData", true, true, true)
{
}

+5 −18
Original line number Diff line number Diff line
@@ -13,7 +13,7 @@ public:
    // kinds
    enum {
        BUILT_IN,
        PARCELABLE,
        USERDATA,
        INTERFACE,
        GENERATED
    };
@@ -350,13 +350,11 @@ public:
                                    Variable* data, Variable** cl);
};

class ParcelableType : public Type
class UserDataType : public Type
{
public:
                    ParcelableType(const string& package, const string& name,
                            bool builtIn, const string& declFile, int declLine);
                    ParcelableType(const string& package, const string& name,
                            bool builtIn, bool canWriteToRpcData,
                    UserDataType(const string& package, const string& name,
                            bool builtIn, bool canWriteToParcel, bool canWriteToRpcData,
                            const string& declFile = "", int declLine = -1);

    virtual string  CreatorName() const;
@@ -376,22 +374,11 @@ public:
                                    Variable* parcel, Variable** cl);
    virtual void    ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
                                    Variable* parcel, Variable** cl);
};

class FlattenableType : public Type
{
public:
                    FlattenableType(const string& package, const string& name,
                            bool builtIn, const string& declFile, int declLine);

    virtual string  CreatorName() const;

    virtual void    WriteToRpcData(StatementBlock* addTo, Expression* k, Variable* v,
                                    Variable* data, int flags);
    virtual void    CreateFromRpcData(StatementBlock* addTo, Expression* k, Variable* v,
                                    Variable* data, Variable** cl);

    virtual bool    CanBeArray() const;
};

class InterfaceType : public Type
@@ -437,7 +424,7 @@ private:
    vector<Type*> m_args;
};

class RpcDataType : public ParcelableType
class RpcDataType : public UserDataType
{
public:
                    RpcDataType();
+46 −55
Original line number Diff line number Diff line
@@ -50,14 +50,15 @@ test_document(document_item_type* d)
            }
            printf("}\n");
        }
        else if (d->item_type == PARCELABLE_TYPE) {
            parcelable_type* b = (parcelable_type*)d;
        else if (d->item_type == USER_DATA_TYPE) {
            user_data_type* b = (user_data_type*)d;
            if ((b->flattening_methods & PARCELABLE_DATA) != 0) {
                printf("parcelable %s %s;\n", b->package, b->name.data);
            }
        else if (d->item_type == FLATTENABLE_TYPE) {
            parcelable_type* b = (parcelable_type*)d;
            if ((b->flattening_methods & RPC_DATA) != 0) {
                printf("flattenable %s %s;\n", b->package, b->name.data);
            }
        }
        else {
            printf("UNKNOWN d=0x%08lx d->item_type=%d\n", (long)d, d->item_type);
        }
@@ -242,9 +243,8 @@ check_filenames(const char* filename, document_item_type* items)
{
    int err = 0;
    while (items) {
        if (items->item_type == PARCELABLE_TYPE
                || items->item_type == FLATTENABLE_TYPE) {
            parcelable_type* p = (parcelable_type*)items;
        if (items->item_type == USER_DATA_TYPE) {
            user_data_type* p = (user_data_type*)items;
            err |= check_filename(filename, p->package, &p->name);
        }
        else if (items->item_type == INTERFACE_TYPE_BINDER
@@ -270,8 +270,8 @@ kind_to_string(int kind)
    {
        case Type::INTERFACE:
            return "an interface";
        case Type::PARCELABLE:
            return "a parcelable";
        case Type::USERDATA:
            return "a user data";
        default:
            return "ERROR";
    }
@@ -296,15 +296,11 @@ gather_types(const char* filename, document_item_type* items)
    int err = 0;
    while (items) {
        Type* type;
        if (items->item_type == PARCELABLE_TYPE) {
            parcelable_type* p = (parcelable_type*)items;
            type = new ParcelableType(p->package ? p->package : "",
                            p->name.data, false, filename, p->name.lineno);
        }
        else if (items->item_type == FLATTENABLE_TYPE) {
            parcelable_type* p = (parcelable_type*)items;
            type = new FlattenableType(p->package ? p->package : "",
                            p->name.data, false, filename, p->name.lineno);
        if (items->item_type == USER_DATA_TYPE) {
            user_data_type* p = (user_data_type*)items;
            type = new UserDataType(p->package ? p->package : "", p->name.data,
                    false, ((p->flattening_methods & PARCELABLE_DATA) != 0),
                    ((p->flattening_methods & RPC_DATA) != 0), filename, p->name.lineno);
        }
        else if (items->item_type == INTERFACE_TYPE_BINDER
                || items->item_type == INTERFACE_TYPE_RPC) {
@@ -539,7 +535,7 @@ check_types(const char* filename, document_item_type* items)
{
    int err = 0;
    while (items) {
        // (nothing to check for PARCELABLE_TYPE or FLATTENABLE_TYPE)
        // (nothing to check for USER_DATA_TYPE)
        if (items->item_type == INTERFACE_TYPE_BINDER
                || items->item_type == INTERFACE_TYPE_RPC) {
            map<string,method_type*> methodNames;
@@ -593,26 +589,23 @@ exactly_one_interface(const char* filename, const document_item_type* items, con
        else if (next->item_type == INTERFACE_TYPE_RPC) {
            lineno = ((interface_type*)next)->interface_token.lineno;
        }
        else if (next->item_type == PARCELABLE_TYPE) {
            lineno = ((parcelable_type*)next)->parcelable_token.lineno;
        }
        else if (next->item_type == FLATTENABLE_TYPE) {
            lineno = ((parcelable_type*)next)->parcelable_token.lineno;
        else if (next->item_type == USER_DATA_TYPE) {
            lineno = ((user_data_type*)next)->keyword_token.lineno;
        }
        fprintf(stderr, "%s:%d aidl can only handle one interface per file\n",
                            filename, lineno);
        return 1;
    }

    if (items->item_type == PARCELABLE_TYPE || items->item_type == FLATTENABLE_TYPE) {
    if (items->item_type == USER_DATA_TYPE) {
        *onlyParcelable = true;
        if (options.failOnParcelable) {
            fprintf(stderr, "%s:%d aidl can only generate code for interfaces, not"
                            " parcelables or flattenables,\n", filename,
                            ((parcelable_type*)items)->parcelable_token.lineno);
                            ((user_data_type*)items)->keyword_token.lineno);
            fprintf(stderr, "%s:%d .aidl files that only declare parcelables or flattenables"
                            "may not go in the Makefile.\n", filename,
                            ((parcelable_type*)items)->parcelable_token.lineno);
                            ((user_data_type*)items)->keyword_token.lineno);
            return 1;
        }
    } else {
@@ -711,8 +704,8 @@ generate_outputFileName(const Options& options, const document_item_type* items)
        interface_type* type = (interface_type*)items;

        return generate_outputFileName2(options, type->name, type->package);
    } else if (items->item_type == PARCELABLE_TYPE || items->item_type == FLATTENABLE_TYPE) {
        parcelable_type* type = (parcelable_type*)items;
    } else if (items->item_type == USER_DATA_TYPE) {
        user_data_type* type = (user_data_type*)items;
        return generate_outputFileName2(options, type->name, type->package);
    }

@@ -783,31 +776,33 @@ parse_preprocessed_file(const string& filename)
        document_item_type* doc;
        
        if (0 == strcmp("parcelable", type)) {
            parcelable_type* parcl = (parcelable_type*)malloc(
                    sizeof(parcelable_type));
            memset(parcl, 0, sizeof(parcelable_type));
            parcl->document_item.item_type = PARCELABLE_TYPE;
            parcl->parcelable_token.lineno = lineno;
            parcl->parcelable_token.data = strdup(type);
            user_data_type* parcl = (user_data_type*)malloc(
                    sizeof(user_data_type));
            memset(parcl, 0, sizeof(user_data_type));
            parcl->document_item.item_type = USER_DATA_TYPE;
            parcl->keyword_token.lineno = lineno;
            parcl->keyword_token.data = strdup(type);
            parcl->package = packagename ? strdup(packagename) : NULL;
            parcl->name.lineno = lineno;
            parcl->name.data = strdup(classname);
            parcl->semicolon_token.lineno = lineno;
            parcl->semicolon_token.data = strdup(";");
            parcl->flattening_methods = PARCELABLE_DATA;
            doc = (document_item_type*)parcl;
        }
        else if (0 == strcmp("flattenable", type)) {
            parcelable_type* parcl = (parcelable_type*)malloc(
                    sizeof(parcelable_type));
            memset(parcl, 0, sizeof(parcelable_type));
            parcl->document_item.item_type = FLATTENABLE_TYPE;
            parcl->parcelable_token.lineno = lineno;
            parcl->parcelable_token.data = strdup(type);
            user_data_type* parcl = (user_data_type*)malloc(
                    sizeof(user_data_type));
            memset(parcl, 0, sizeof(user_data_type));
            parcl->document_item.item_type = USER_DATA_TYPE;
            parcl->keyword_token.lineno = lineno;
            parcl->keyword_token.data = strdup(type);
            parcl->package = packagename ? strdup(packagename) : NULL;
            parcl->name.lineno = lineno;
            parcl->name.data = strdup(classname);
            parcl->semicolon_token.lineno = lineno;
            parcl->semicolon_token.data = strdup(";");
            parcl->flattening_methods = RPC_DATA;
            doc = (document_item_type*)parcl;
        }
        else if (0 == strcmp("interface", type)) {
@@ -986,18 +981,14 @@ preprocess_aidl(const Options& options)
        }
        document_item_type* doc = g_document;
        string line;
        if (doc->item_type == PARCELABLE_TYPE) {
        if (doc->item_type == USER_DATA_TYPE) {
            user_data_type* parcelable = (user_data_type*)doc;
            if ((parcelable->flattening_methods & PARCELABLE_DATA) != 0) {
                line = "parcelable ";
            parcelable_type* parcelable = (parcelable_type*)doc;
            if (parcelable->package) {
                line += parcelable->package;
                line += '.';
            }
            line += parcelable->name.data;
            if ((parcelable->flattening_methods & RPC_DATA) != 0) {
                line = "flattenable ";
            }
        else if (doc->item_type == FLATTENABLE_TYPE) {
            line = "parcelable ";
            parcelable_type* parcelable = (parcelable_type*)doc;
            if (parcelable->package) {
                line += parcelable->package;
                line += '.';
+13 −6
Original line number Diff line number Diff line
@@ -63,8 +63,7 @@ typedef struct method_type {
} method_type;

enum {
    PARCELABLE_TYPE = 12,
    FLATTENABLE_TYPE,
    USER_DATA_TYPE = 12,
    INTERFACE_TYPE_BINDER,
    INTERFACE_TYPE_RPC
};
@@ -74,13 +73,21 @@ typedef struct document_item_type {
    struct document_item_type* next;
} document_item_type;

typedef struct parcelable_type {

// for user_data_type.flattening_methods
enum {
    PARCELABLE_DATA = 0x1,
    RPC_DATA = 0x2
};

typedef struct user_data_type {
    document_item_type document_item;
    buffer_type parcelable_token;
    buffer_type keyword_token; // only the first one
    char* package;
    buffer_type name;
    buffer_type semicolon_token;
} parcelable_type;
    int flattening_methods;
} user_data_type;

typedef struct interface_type {
    document_item_type document_item;
@@ -102,7 +109,7 @@ typedef union lexer_type {
    method_type* method;
    interface_item_type* interface_item;
    interface_type* interface_obj;
    parcelable_type* parcelable;
    user_data_type* user_data;
    document_item_type* document_item;
} lexer_type;

+15 −13
Original line number Diff line number Diff line
@@ -74,50 +74,52 @@ document_items:
    ;

declaration:
        parcelable_decl                            { $$.document_item = (document_item_type*)$1.parcelable; }
        parcelable_decl                            { $$.document_item = (document_item_type*)$1.user_data; }
    |   interface_decl                             { $$.document_item = (document_item_type*)$1.interface_item; }
    ;

parcelable_decl:
        PARCELABLE IDENTIFIER ';'                   {
                                                        parcelable_type* b = (parcelable_type*)malloc(sizeof(parcelable_type));
                                                        b->document_item.item_type = PARCELABLE_TYPE;
                                                        user_data_type* b = (user_data_type*)malloc(sizeof(user_data_type));
                                                        b->document_item.item_type = USER_DATA_TYPE;
                                                        b->document_item.next = NULL;
                                                        b->parcelable_token = $1.buffer;
                                                        b->keyword_token = $1.buffer;
                                                        b->name = $2.buffer;
                                                        b->package = g_currentPackage ? strdup(g_currentPackage) : NULL;
                                                        b->semicolon_token = $3.buffer;
                                                        $$.parcelable = b;
                                                        b->flattening_methods = PARCELABLE_DATA;
                                                        $$.user_data = b;
                                                    }
    |   PARCELABLE ';'                              {
                                                        fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name.\n",
                                                                     g_currentFilename, $1.buffer.lineno);
                                                        $$.parcelable = NULL;
                                                        $$.user_data = NULL;
                                                    }
    |   PARCELABLE error ';'                        {
                                                        fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name, saw \"%s\".\n",
                                                                     g_currentFilename, $2.buffer.lineno, $2.buffer.data);
                                                        $$.parcelable = NULL;
                                                        $$.user_data = NULL;
                                                    }
    |   FLATTENABLE IDENTIFIER ';'                  {
                                                        parcelable_type* b = (parcelable_type*)malloc(sizeof(parcelable_type));
                                                        b->document_item.item_type = FLATTENABLE_TYPE;
                                                        user_data_type* b = (user_data_type*)malloc(sizeof(user_data_type));
                                                        b->document_item.item_type = USER_DATA_TYPE;
                                                        b->document_item.next = NULL;
                                                        b->parcelable_token = $1.buffer;
                                                        b->keyword_token = $1.buffer;
                                                        b->name = $2.buffer;
                                                        b->package = g_currentPackage ? strdup(g_currentPackage) : NULL;
                                                        b->semicolon_token = $3.buffer;
                                                        $$.parcelable = b;
                                                        b->flattening_methods = PARCELABLE_DATA | RPC_DATA;
                                                        $$.user_data = b;
                                                    }
    |   FLATTENABLE ';'                             {
                                                        fprintf(stderr, "%s:%d syntax error in flattenable declaration. Expected type name.\n",
                                                                     g_currentFilename, $1.buffer.lineno);
                                                        $$.parcelable = NULL;
                                                        $$.user_data = NULL;
                                                    }
    |   FLATTENABLE error ';'                       {
                                                        fprintf(stderr, "%s:%d syntax error in flattenable declaration. Expected type name, saw \"%s\".\n",
                                                                     g_currentFilename, $2.buffer.lineno, $2.buffer.data);
                                                        $$.parcelable = NULL;
                                                        $$.user_data = NULL;
                                                    }

    ;
Loading