resolved conflicts for ddf53180 to stage-aosp-master

Change-Id: I265ab876ef29dc731e6abb6f964c10f2e71324be
This commit is contained in:
Christopher Wiley
2015-09-14 07:34:50 -07:00
27 changed files with 0 additions and 6846 deletions

View File

@@ -1,912 +0,0 @@
#include "AST.h"
#include "Type.h"
void
WriteModifiers(FILE* to, int mod, int mask)
{
int m = mod & mask;
if (m & OVERRIDE) {
fprintf(to, "@Override ");
}
if ((m & SCOPE_MASK) == PUBLIC) {
fprintf(to, "public ");
}
else if ((m & SCOPE_MASK) == PRIVATE) {
fprintf(to, "private ");
}
else if ((m & SCOPE_MASK) == PROTECTED) {
fprintf(to, "protected ");
}
if (m & STATIC) {
fprintf(to, "static ");
}
if (m & FINAL) {
fprintf(to, "final ");
}
if (m & ABSTRACT) {
fprintf(to, "abstract ");
}
}
void
WriteArgumentList(FILE* to, const vector<Expression*>& arguments)
{
size_t N = arguments.size();
for (size_t i=0; i<N; i++) {
arguments[i]->Write(to);
if (i != N-1) {
fprintf(to, ", ");
}
}
}
ClassElement::ClassElement()
{
}
ClassElement::~ClassElement()
{
}
Field::Field()
:ClassElement(),
modifiers(0),
variable(NULL)
{
}
Field::Field(int m, Variable* v)
:ClassElement(),
modifiers(m),
variable(v)
{
}
Field::~Field()
{
}
void
Field::GatherTypes(set<Type*>* types) const
{
types->insert(this->variable->type);
}
void
Field::Write(FILE* to)
{
if (this->comment.length() != 0) {
fprintf(to, "%s\n", this->comment.c_str());
}
WriteModifiers(to, this->modifiers, SCOPE_MASK | STATIC | FINAL | OVERRIDE);
fprintf(to, "%s %s", this->variable->type->QualifiedName().c_str(),
this->variable->name.c_str());
if (this->value.length() != 0) {
fprintf(to, " = %s", this->value.c_str());
}
fprintf(to, ";\n");
}
Expression::~Expression()
{
}
LiteralExpression::LiteralExpression(const string& v)
:value(v)
{
}
LiteralExpression::~LiteralExpression()
{
}
void
LiteralExpression::Write(FILE* to)
{
fprintf(to, "%s", this->value.c_str());
}
StringLiteralExpression::StringLiteralExpression(const string& v)
:value(v)
{
}
StringLiteralExpression::~StringLiteralExpression()
{
}
void
StringLiteralExpression::Write(FILE* to)
{
fprintf(to, "\"%s\"", this->value.c_str());
}
Variable::Variable()
:type(NULL),
name(),
dimension(0)
{
}
Variable::Variable(Type* t, const string& n)
:type(t),
name(n),
dimension(0)
{
}
Variable::Variable(Type* t, const string& n, int d)
:type(t),
name(n),
dimension(d)
{
}
Variable::~Variable()
{
}
void
Variable::GatherTypes(set<Type*>* types) const
{
types->insert(this->type);
}
void
Variable::WriteDeclaration(FILE* to)
{
string dim;
for (int i=0; i<this->dimension; i++) {
dim += "[]";
}
fprintf(to, "%s%s %s", this->type->QualifiedName().c_str(), dim.c_str(),
this->name.c_str());
}
void
Variable::Write(FILE* to)
{
fprintf(to, "%s", name.c_str());
}
FieldVariable::FieldVariable(Expression* o, const string& n)
:object(o),
clazz(NULL),
name(n)
{
}
FieldVariable::FieldVariable(Type* c, const string& n)
:object(NULL),
clazz(c),
name(n)
{
}
FieldVariable::~FieldVariable()
{
}
void
FieldVariable::Write(FILE* to)
{
if (this->object != NULL) {
this->object->Write(to);
}
else if (this->clazz != NULL) {
fprintf(to, "%s", this->clazz->QualifiedName().c_str());
}
fprintf(to, ".%s", name.c_str());
}
Statement::~Statement()
{
}
StatementBlock::StatementBlock()
{
}
StatementBlock::~StatementBlock()
{
}
void
StatementBlock::Write(FILE* to)
{
fprintf(to, "{\n");
int N = this->statements.size();
for (int i=0; i<N; i++) {
this->statements[i]->Write(to);
}
fprintf(to, "}\n");
}
void
StatementBlock::Add(Statement* statement)
{
this->statements.push_back(statement);
}
void
StatementBlock::Add(Expression* expression)
{
this->statements.push_back(new ExpressionStatement(expression));
}
ExpressionStatement::ExpressionStatement(Expression* e)
:expression(e)
{
}
ExpressionStatement::~ExpressionStatement()
{
}
void
ExpressionStatement::Write(FILE* to)
{
this->expression->Write(to);
fprintf(to, ";\n");
}
Assignment::Assignment(Variable* l, Expression* r)
:lvalue(l),
rvalue(r),
cast(NULL)
{
}
Assignment::Assignment(Variable* l, Expression* r, Type* c)
:lvalue(l),
rvalue(r),
cast(c)
{
}
Assignment::~Assignment()
{
}
void
Assignment::Write(FILE* to)
{
this->lvalue->Write(to);
fprintf(to, " = ");
if (this->cast != NULL) {
fprintf(to, "(%s)", this->cast->QualifiedName().c_str());
}
this->rvalue->Write(to);
}
MethodCall::MethodCall(const string& n)
:obj(NULL),
clazz(NULL),
name(n)
{
}
MethodCall::MethodCall(const string& n, int argc = 0, ...)
:obj(NULL),
clazz(NULL),
name(n)
{
va_list args;
va_start(args, argc);
init(argc, args);
va_end(args);
}
MethodCall::MethodCall(Expression* o, const string& n)
:obj(o),
clazz(NULL),
name(n)
{
}
MethodCall::MethodCall(Type* t, const string& n)
:obj(NULL),
clazz(t),
name(n)
{
}
MethodCall::MethodCall(Expression* o, const string& n, int argc = 0, ...)
:obj(o),
clazz(NULL),
name(n)
{
va_list args;
va_start(args, argc);
init(argc, args);
va_end(args);
}
MethodCall::MethodCall(Type* t, const string& n, int argc = 0, ...)
:obj(NULL),
clazz(t),
name(n)
{
va_list args;
va_start(args, argc);
init(argc, args);
va_end(args);
}
MethodCall::~MethodCall()
{
}
void
MethodCall::init(int n, va_list args)
{
for (int i=0; i<n; i++) {
Expression* expression = (Expression*)va_arg(args, void*);
this->arguments.push_back(expression);
}
}
void
MethodCall::Write(FILE* to)
{
if (this->obj != NULL) {
this->obj->Write(to);
fprintf(to, ".");
}
else if (this->clazz != NULL) {
fprintf(to, "%s.", this->clazz->QualifiedName().c_str());
}
fprintf(to, "%s(", this->name.c_str());
WriteArgumentList(to, this->arguments);
fprintf(to, ")");
}
Comparison::Comparison(Expression* l, const string& o, Expression* r)
:lvalue(l),
op(o),
rvalue(r)
{
}
Comparison::~Comparison()
{
}
void
Comparison::Write(FILE* to)
{
fprintf(to, "(");
this->lvalue->Write(to);
fprintf(to, "%s", this->op.c_str());
this->rvalue->Write(to);
fprintf(to, ")");
}
NewExpression::NewExpression(Type* t)
:type(t)
{
}
NewExpression::NewExpression(Type* t, int argc = 0, ...)
:type(t)
{
va_list args;
va_start(args, argc);
init(argc, args);
va_end(args);
}
NewExpression::~NewExpression()
{
}
void
NewExpression::init(int n, va_list args)
{
for (int i=0; i<n; i++) {
Expression* expression = (Expression*)va_arg(args, void*);
this->arguments.push_back(expression);
}
}
void
NewExpression::Write(FILE* to)
{
fprintf(to, "new %s(", this->type->InstantiableName().c_str());
WriteArgumentList(to, this->arguments);
fprintf(to, ")");
}
NewArrayExpression::NewArrayExpression(Type* t, Expression* s)
:type(t),
size(s)
{
}
NewArrayExpression::~NewArrayExpression()
{
}
void
NewArrayExpression::Write(FILE* to)
{
fprintf(to, "new %s[", this->type->QualifiedName().c_str());
size->Write(to);
fprintf(to, "]");
}
Ternary::Ternary()
:condition(NULL),
ifpart(NULL),
elsepart(NULL)
{
}
Ternary::Ternary(Expression* a, Expression* b, Expression* c)
:condition(a),
ifpart(b),
elsepart(c)
{
}
Ternary::~Ternary()
{
}
void
Ternary::Write(FILE* to)
{
fprintf(to, "((");
this->condition->Write(to);
fprintf(to, ")?(");
this->ifpart->Write(to);
fprintf(to, "):(");
this->elsepart->Write(to);
fprintf(to, "))");
}
Cast::Cast()
:type(NULL),
expression(NULL)
{
}
Cast::Cast(Type* t, Expression* e)
:type(t),
expression(e)
{
}
Cast::~Cast()
{
}
void
Cast::Write(FILE* to)
{
fprintf(to, "((%s)", this->type->QualifiedName().c_str());
expression->Write(to);
fprintf(to, ")");
}
VariableDeclaration::VariableDeclaration(Variable* l, Expression* r, Type* c)
:lvalue(l),
cast(c),
rvalue(r)
{
}
VariableDeclaration::VariableDeclaration(Variable* l)
:lvalue(l),
cast(NULL),
rvalue(NULL)
{
}
VariableDeclaration::~VariableDeclaration()
{
}
void
VariableDeclaration::Write(FILE* to)
{
this->lvalue->WriteDeclaration(to);
if (this->rvalue != NULL) {
fprintf(to, " = ");
if (this->cast != NULL) {
fprintf(to, "(%s)", this->cast->QualifiedName().c_str());
}
this->rvalue->Write(to);
}
fprintf(to, ";\n");
}
IfStatement::IfStatement()
:expression(NULL),
statements(new StatementBlock),
elseif(NULL)
{
}
IfStatement::~IfStatement()
{
}
void
IfStatement::Write(FILE* to)
{
if (this->expression != NULL) {
fprintf(to, "if (");
this->expression->Write(to);
fprintf(to, ") ");
}
this->statements->Write(to);
if (this->elseif != NULL) {
fprintf(to, "else ");
this->elseif->Write(to);
}
}
ReturnStatement::ReturnStatement(Expression* e)
:expression(e)
{
}
ReturnStatement::~ReturnStatement()
{
}
void
ReturnStatement::Write(FILE* to)
{
fprintf(to, "return ");
this->expression->Write(to);
fprintf(to, ";\n");
}
TryStatement::TryStatement()
:statements(new StatementBlock)
{
}
TryStatement::~TryStatement()
{
}
void
TryStatement::Write(FILE* to)
{
fprintf(to, "try ");
this->statements->Write(to);
}
CatchStatement::CatchStatement(Variable* e)
:statements(new StatementBlock),
exception(e)
{
}
CatchStatement::~CatchStatement()
{
}
void
CatchStatement::Write(FILE* to)
{
fprintf(to, "catch ");
if (this->exception != NULL) {
fprintf(to, "(");
this->exception->WriteDeclaration(to);
fprintf(to, ") ");
}
this->statements->Write(to);
}
FinallyStatement::FinallyStatement()
:statements(new StatementBlock)
{
}
FinallyStatement::~FinallyStatement()
{
}
void
FinallyStatement::Write(FILE* to)
{
fprintf(to, "finally ");
this->statements->Write(to);
}
Case::Case()
:statements(new StatementBlock)
{
}
Case::Case(const string& c)
:statements(new StatementBlock)
{
cases.push_back(c);
}
Case::~Case()
{
}
void
Case::Write(FILE* to)
{
int N = this->cases.size();
if (N > 0) {
for (int i=0; i<N; i++) {
string s = this->cases[i];
if (s.length() != 0) {
fprintf(to, "case %s:\n", s.c_str());
} else {
fprintf(to, "default:\n");
}
}
} else {
fprintf(to, "default:\n");
}
statements->Write(to);
}
SwitchStatement::SwitchStatement(Expression* e)
:expression(e)
{
}
SwitchStatement::~SwitchStatement()
{
}
void
SwitchStatement::Write(FILE* to)
{
fprintf(to, "switch (");
this->expression->Write(to);
fprintf(to, ")\n{\n");
int N = this->cases.size();
for (int i=0; i<N; i++) {
this->cases[i]->Write(to);
}
fprintf(to, "}\n");
}
Break::Break()
{
}
Break::~Break()
{
}
void
Break::Write(FILE* to)
{
fprintf(to, "break;\n");
}
Method::Method()
:ClassElement(),
modifiers(0),
returnType(NULL), // (NULL means constructor)
returnTypeDimension(0),
statements(NULL)
{
}
Method::~Method()
{
}
void
Method::GatherTypes(set<Type*>* types) const
{
size_t N, i;
if (this->returnType) {
types->insert(this->returnType);
}
N = this->parameters.size();
for (i=0; i<N; i++) {
this->parameters[i]->GatherTypes(types);
}
N = this->exceptions.size();
for (i=0; i<N; i++) {
types->insert(this->exceptions[i]);
}
}
void
Method::Write(FILE* to)
{
size_t N, i;
if (this->comment.length() != 0) {
fprintf(to, "%s\n", this->comment.c_str());
}
WriteModifiers(to, this->modifiers, SCOPE_MASK | STATIC | ABSTRACT | FINAL | OVERRIDE);
if (this->returnType != NULL) {
string dim;
for (i=0; i<this->returnTypeDimension; i++) {
dim += "[]";
}
fprintf(to, "%s%s ", this->returnType->QualifiedName().c_str(),
dim.c_str());
}
fprintf(to, "%s(", this->name.c_str());
N = this->parameters.size();
for (i=0; i<N; i++) {
this->parameters[i]->WriteDeclaration(to);
if (i != N-1) {
fprintf(to, ", ");
}
}
fprintf(to, ")");
N = this->exceptions.size();
for (i=0; i<N; i++) {
if (i == 0) {
fprintf(to, " throws ");
} else {
fprintf(to, ", ");
}
fprintf(to, "%s", this->exceptions[i]->QualifiedName().c_str());
}
if (this->statements == NULL) {
fprintf(to, ";\n");
} else {
fprintf(to, "\n");
this->statements->Write(to);
}
}
Class::Class()
:modifiers(0),
what(CLASS),
type(NULL),
extends(NULL)
{
}
Class::~Class()
{
}
void
Class::GatherTypes(set<Type*>* types) const
{
int N, i;
types->insert(this->type);
if (this->extends != NULL) {
types->insert(this->extends);
}
N = this->interfaces.size();
for (i=0; i<N; i++) {
types->insert(this->interfaces[i]);
}
N = this->elements.size();
for (i=0; i<N; i++) {
this->elements[i]->GatherTypes(types);
}
}
void
Class::Write(FILE* to)
{
size_t N, i;
if (this->comment.length() != 0) {
fprintf(to, "%s\n", this->comment.c_str());
}
WriteModifiers(to, this->modifiers, ALL_MODIFIERS);
if (this->what == Class::CLASS) {
fprintf(to, "class ");
} else {
fprintf(to, "interface ");
}
string name = this->type->Name();
size_t pos = name.rfind('.');
if (pos != string::npos) {
name = name.c_str() + pos + 1;
}
fprintf(to, "%s", name.c_str());
if (this->extends != NULL) {
fprintf(to, " extends %s", this->extends->QualifiedName().c_str());
}
N = this->interfaces.size();
if (N != 0) {
if (this->what == Class::CLASS) {
fprintf(to, " implements");
} else {
fprintf(to, " extends");
}
for (i=0; i<N; i++) {
fprintf(to, " %s", this->interfaces[i]->QualifiedName().c_str());
}
}
fprintf(to, "\n");
fprintf(to, "{\n");
N = this->elements.size();
for (i=0; i<N; i++) {
this->elements[i]->Write(to);
}
fprintf(to, "}\n");
}
Document::Document()
{
}
Document::~Document()
{
}
static string
escape_backslashes(const string& str)
{
string result;
const size_t I=str.length();
for (size_t i=0; i<I; i++) {
char c = str[i];
if (c == '\\') {
result += "\\\\";
} else {
result += c;
}
}
return result;
}
void
Document::Write(FILE* to)
{
size_t N, i;
if (this->comment.length() != 0) {
fprintf(to, "%s\n", this->comment.c_str());
}
fprintf(to, "/*\n"
" * This file is auto-generated. DO NOT MODIFY.\n"
" * Original file: %s\n"
" */\n", escape_backslashes(this->originalSrc).c_str());
if (this->package.length() != 0) {
fprintf(to, "package %s;\n", this->package.c_str());
}
N = this->classes.size();
for (i=0; i<N; i++) {
Class* c = this->classes[i];
c->Write(to);
}
}

View File

@@ -1,371 +0,0 @@
#ifndef AIDL_AST_H_
#define AIDL_AST_H_
#include <string>
#include <vector>
#include <set>
#include <stdarg.h>
#include <stdio.h>
using namespace std;
class Type;
enum {
PACKAGE_PRIVATE = 0x00000000,
PUBLIC = 0x00000001,
PRIVATE = 0x00000002,
PROTECTED = 0x00000003,
SCOPE_MASK = 0x00000003,
STATIC = 0x00000010,
FINAL = 0x00000020,
ABSTRACT = 0x00000040,
OVERRIDE = 0x00000100,
ALL_MODIFIERS = 0xffffffff
};
// Write the modifiers that are set in both mod and mask
void WriteModifiers(FILE* to, int mod, int mask);
struct ClassElement
{
ClassElement();
virtual ~ClassElement();
virtual void GatherTypes(set<Type*>* types) const = 0;
virtual void Write(FILE* to) = 0;
};
struct Expression
{
virtual ~Expression();
virtual void Write(FILE* to) = 0;
};
struct LiteralExpression : public Expression
{
string value;
LiteralExpression(const string& value);
virtual ~LiteralExpression();
virtual void Write(FILE* to);
};
// TODO: also escape the contents. not needed for now
struct StringLiteralExpression : public Expression
{
string value;
StringLiteralExpression(const string& value);
virtual ~StringLiteralExpression();
virtual void Write(FILE* to);
};
struct Variable : public Expression
{
Type* type;
string name;
int dimension;
Variable();
Variable(Type* type, const string& name);
Variable(Type* type, const string& name, int dimension);
virtual ~Variable();
virtual void GatherTypes(set<Type*>* types) const;
void WriteDeclaration(FILE* to);
void Write(FILE* to);
};
struct FieldVariable : public Expression
{
Expression* object;
Type* clazz;
string name;
FieldVariable(Expression* object, const string& name);
FieldVariable(Type* clazz, const string& name);
virtual ~FieldVariable();
void Write(FILE* to);
};
struct Field : public ClassElement
{
string comment;
int modifiers;
Variable *variable;
string value;
Field();
Field(int modifiers, Variable* variable);
virtual ~Field();
virtual void GatherTypes(set<Type*>* types) const;
virtual void Write(FILE* to);
};
struct Statement
{
virtual ~Statement();
virtual void Write(FILE* to) = 0;
};
struct StatementBlock : public Statement
{
vector<Statement*> statements;
StatementBlock();
virtual ~StatementBlock();
virtual void Write(FILE* to);
void Add(Statement* statement);
void Add(Expression* expression);
};
struct ExpressionStatement : public Statement
{
Expression* expression;
ExpressionStatement(Expression* expression);
virtual ~ExpressionStatement();
virtual void Write(FILE* to);
};
struct Assignment : public Expression
{
Variable* lvalue;
Expression* rvalue;
Type* cast;
Assignment(Variable* lvalue, Expression* rvalue);
Assignment(Variable* lvalue, Expression* rvalue, Type* cast);
virtual ~Assignment();
virtual void Write(FILE* to);
};
struct MethodCall : public Expression
{
Expression* obj;
Type* clazz;
string name;
vector<Expression*> arguments;
vector<string> exceptions;
MethodCall(const string& name);
MethodCall(const string& name, int argc, ...);
MethodCall(Expression* obj, const string& name);
MethodCall(Type* clazz, const string& name);
MethodCall(Expression* obj, const string& name, int argc, ...);
MethodCall(Type* clazz, const string& name, int argc, ...);
virtual ~MethodCall();
virtual void Write(FILE* to);
private:
void init(int n, va_list args);
};
struct Comparison : public Expression
{
Expression* lvalue;
string op;
Expression* rvalue;
Comparison(Expression* lvalue, const string& op, Expression* rvalue);
virtual ~Comparison();
virtual void Write(FILE* to);
};
struct NewExpression : public Expression
{
Type* type;
vector<Expression*> arguments;
NewExpression(Type* type);
NewExpression(Type* type, int argc, ...);
virtual ~NewExpression();
virtual void Write(FILE* to);
private:
void init(int n, va_list args);
};
struct NewArrayExpression : public Expression
{
Type* type;
Expression* size;
NewArrayExpression(Type* type, Expression* size);
virtual ~NewArrayExpression();
virtual void Write(FILE* to);
};
struct Ternary : public Expression
{
Expression* condition;
Expression* ifpart;
Expression* elsepart;
Ternary();
Ternary(Expression* condition, Expression* ifpart, Expression* elsepart);
virtual ~Ternary();
virtual void Write(FILE* to);
};
struct Cast : public Expression
{
Type* type;
Expression* expression;
Cast();
Cast(Type* type, Expression* expression);
virtual ~Cast();
virtual void Write(FILE* to);
};
struct VariableDeclaration : public Statement
{
Variable* lvalue;
Type* cast;
Expression* rvalue;
VariableDeclaration(Variable* lvalue);
VariableDeclaration(Variable* lvalue, Expression* rvalue, Type* cast = NULL);
virtual ~VariableDeclaration();
virtual void Write(FILE* to);
};
struct IfStatement : public Statement
{
Expression* expression;
StatementBlock* statements;
IfStatement* elseif;
IfStatement();
virtual ~IfStatement();
virtual void Write(FILE* to);
};
struct ReturnStatement : public Statement
{
Expression* expression;
ReturnStatement(Expression* expression);
virtual ~ReturnStatement();
virtual void Write(FILE* to);
};
struct TryStatement : public Statement
{
StatementBlock* statements;
TryStatement();
virtual ~TryStatement();
virtual void Write(FILE* to);
};
struct CatchStatement : public Statement
{
StatementBlock* statements;
Variable* exception;
CatchStatement(Variable* exception);
virtual ~CatchStatement();
virtual void Write(FILE* to);
};
struct FinallyStatement : public Statement
{
StatementBlock* statements;
FinallyStatement();
virtual ~FinallyStatement();
virtual void Write(FILE* to);
};
struct Case
{
vector<string> cases;
StatementBlock* statements;
Case();
Case(const string& c);
virtual ~Case();
virtual void Write(FILE* to);
};
struct SwitchStatement : public Statement
{
Expression* expression;
vector<Case*> cases;
SwitchStatement(Expression* expression);
virtual ~SwitchStatement();
virtual void Write(FILE* to);
};
struct Break : public Statement
{
Break();
virtual ~Break();
virtual void Write(FILE* to);
};
struct Method : public ClassElement
{
string comment;
int modifiers;
Type* returnType;
size_t returnTypeDimension;
string name;
vector<Variable*> parameters;
vector<Type*> exceptions;
StatementBlock* statements;
Method();
virtual ~Method();
virtual void GatherTypes(set<Type*>* types) const;
virtual void Write(FILE* to);
};
struct Class : public ClassElement
{
enum {
CLASS,
INTERFACE
};
string comment;
int modifiers;
int what; // CLASS or INTERFACE
Type* type;
Type* extends;
vector<Type*> interfaces;
vector<ClassElement*> elements;
Class();
virtual ~Class();
virtual void GatherTypes(set<Type*>* types) const;
virtual void Write(FILE* to);
};
struct Document
{
string comment;
string package;
string originalSrc;
set<Type*> imports;
vector<Class*> classes;
Document();
virtual ~Document();
virtual void Write(FILE* to);
};
#endif // AIDL_AST_H_

View File

@@ -1,80 +0,0 @@
# Copyright 2007 The Android Open Source Project
#
# Copies files into the directory structure described by a manifest
# This tool is prebuilt if we're doing an app-only build.
ifeq ($(TARGET_BUILD_APPS)$(filter true,$(TARGET_BUILD_PDK)),)
LOCAL_PATH:= $(call my-dir)
# Logic shared between aidl and its unittests
include $(CLEAR_VARS)
LOCAL_MODULE := libaidl-common
LOCAL_MODULE_HOST_OS := darwin linux windows
LOCAL_CLANG_CFLAGS := -Wall -Werror
# Tragically, the code is riddled with unused parameters.
LOCAL_CLANG_CFLAGS += -Wno-unused-parameter
# yacc dumps a lot of code *just in case*.
LOCAL_CLANG_CFLAGS += -Wno-unused-function
LOCAL_CLANG_CFLAGS += -Wno-unneeded-internal-declaration
# yacc is a tool from a more civilized age.
LOCAL_CLANG_CFLAGS += -Wno-deprecated-register
# yacc also has a habit of using char* over const char*.
LOCAL_CLANG_CFLAGS += -Wno-writable-strings
LOCAL_SRC_FILES := \
AST.cpp \
Type.cpp \
aidl.cpp \
aidl_language.cpp \
aidl_language_l.l \
aidl_language_y.y \
generate_java.cpp \
generate_java_binder.cpp \
options.cpp \
search_path.cpp \
include $(BUILD_HOST_STATIC_LIBRARY)
# aidl executable
include $(CLEAR_VARS)
LOCAL_MODULE := aidl
LOCAL_MODULE_HOST_OS := darwin linux windows
LOCAL_CFLAGS := -Wall -Werror
LOCAL_SRC_FILES := main.cpp
LOCAL_STATIC_LIBRARIES := libaidl-common
include $(BUILD_HOST_EXECUTABLE)
# TODO(wiley) Compile these for mac as well after b/22771504
ifeq ($(HOST_OS),linux)
# Unit tests
include $(CLEAR_VARS)
LOCAL_MODULE := aidl_unittests
LOCAL_CFLAGS := -g -DUNIT_TEST -Wall -Werror
# Tragically, the code is riddled with unused parameters.
LOCAL_CLANG_CFLAGS := -Wno-unused-parameter
LOCAL_SRC_FILES := \
options_unittest.cpp \
test_main.cpp \
tests/end_to_end_tests.cpp \
tests/example_interface_test_data.cpp \
LOCAL_SHARED_LIBRARIES := \
libchrome-host \
LOCAL_STATIC_LIBRARIES := \
libaidl-common \
libgmock_host \
libgtest_host \
LOCAL_LDLIBS_linux := -lrt
include $(BUILD_HOST_NATIVE_TEST)
endif # HOST_OS == linux
endif # No TARGET_BUILD_APPS or TARGET_BUILD_PDK

View File

@@ -1,190 +0,0 @@
Copyright (c) 2005-2008, The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
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.
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS

File diff suppressed because it is too large Load Diff

View File

@@ -1,472 +0,0 @@
#ifndef AIDL_TYPE_H_
#define AIDL_TYPE_H_
#include "AST.h"
#include <string>
#include <vector>
using namespace std;
class Type
{
public:
// kinds
enum {
BUILT_IN,
USERDATA,
INTERFACE,
GENERATED
};
// WriteToParcel flags
enum {
PARCELABLE_WRITE_RETURN_VALUE = 0x0001
};
Type(const string& name, int kind, bool canWriteToParcel,
bool canBeOut);
Type(const string& package, const string& name,
int kind, bool canWriteToParcel, bool canBeOut,
const string& declFile = "", int declLine = -1);
virtual ~Type();
inline string Package() const { return m_package; }
inline string Name() const { return m_name; }
inline string QualifiedName() const { return m_qualifiedName; }
inline int Kind() const { return m_kind; }
inline string DeclFile() const { return m_declFile; }
inline int DeclLine() const { return m_declLine; }
inline bool CanWriteToParcel() const { return m_canWriteToParcel; }
inline bool CanBeOutParameter() const { return m_canBeOut; }
virtual string ImportType() const;
virtual string CreatorName() const;
virtual string InstantiableName() const;
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
virtual void ReadFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
virtual bool CanBeArray() const;
virtual void WriteArrayToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
protected:
void SetQualifiedName(const string& qualified);
Expression* BuildWriteToParcelFlags(int flags);
private:
Type();
Type(const Type&);
string m_package;
string m_name;
string m_qualifiedName;
string m_declFile;
int m_declLine;
int m_kind;
bool m_canWriteToParcel;
bool m_canBeOut;
};
class BasicType : public Type
{
public:
BasicType(const string& name,
const string& marshallParcel,
const string& unmarshallParcel,
const string& writeArrayParcel,
const string& createArrayParcel,
const string& readArrayParcel);
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
virtual bool CanBeArray() const;
virtual void WriteArrayToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
private:
string m_marshallParcel;
string m_unmarshallParcel;
string m_writeArrayParcel;
string m_createArrayParcel;
string m_readArrayParcel;
};
class BooleanType : public Type
{
public:
BooleanType();
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
virtual bool CanBeArray() const;
virtual void WriteArrayToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
};
class CharType : public Type
{
public:
CharType();
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
virtual bool CanBeArray() const;
virtual void WriteArrayToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
};
class StringType : public Type
{
public:
StringType();
virtual string CreatorName() const;
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
virtual bool CanBeArray() const;
virtual void WriteArrayToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
};
class CharSequenceType : public Type
{
public:
CharSequenceType();
virtual string CreatorName() const;
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
};
class RemoteExceptionType : public Type
{
public:
RemoteExceptionType();
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
};
class RuntimeExceptionType : public Type
{
public:
RuntimeExceptionType();
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
};
class IBinderType : public Type
{
public:
IBinderType();
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
virtual void WriteArrayToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
};
class IInterfaceType : public Type
{
public:
IInterfaceType();
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
};
class BinderType : public Type
{
public:
BinderType();
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
};
class BinderProxyType : public Type
{
public:
BinderProxyType();
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
};
class ParcelType : public Type
{
public:
ParcelType();
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
};
class ParcelableInterfaceType : public Type
{
public:
ParcelableInterfaceType();
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
};
class MapType : public Type
{
public:
MapType();
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
virtual void ReadFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
};
class ListType : public Type
{
public:
ListType();
virtual string InstantiableName() const;
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
virtual void ReadFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
};
class UserDataType : public Type
{
public:
UserDataType(const string& package, const string& name,
bool builtIn, bool canWriteToParcel,
const string& declFile = "", int declLine = -1);
virtual string CreatorName() const;
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
virtual void ReadFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
virtual bool CanBeArray() const;
virtual void WriteArrayToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateArrayFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
virtual void ReadArrayFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
};
class InterfaceType : public Type
{
public:
InterfaceType(const string& package, const string& name,
bool builtIn, bool oneway,
const string& declFile, int declLine);
bool OneWay() const;
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
private:
bool m_oneway;
};
class GenericType : public Type
{
public:
GenericType(const string& package, const string& name,
const vector<Type*>& args);
const vector<Type*>& GenericArgumentTypes() const;
string GenericArguments() const;
virtual string ImportType() const;
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
virtual void ReadFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
private:
string m_genericArguments;
string m_importName;
vector<Type*> m_args;
};
class ClassLoaderType : public Type
{
public:
ClassLoaderType();
};
class GenericListType : public GenericType
{
public:
GenericListType(const string& package, const string& name,
const vector<Type*>& args);
virtual string CreatorName() const;
virtual string InstantiableName() const;
virtual void WriteToParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, int flags);
virtual void CreateFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
virtual void ReadFromParcel(StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl);
private:
string m_creator;
};
class Namespace
{
public:
Namespace();
~Namespace();
void Add(Type* type);
// args is the number of template types (what is this called?)
void AddGenericType(const string& package, const string& name, int args);
// lookup a specific class name
Type* Find(const string& name) const;
Type* Find(const char* package, const char* name) const;
// try to search by either a full name or a partial name
Type* Search(const string& name);
void Dump() const;
private:
struct Generic {
string package;
string name;
string qualified;
int args;
};
const Generic* search_generic(const string& name) const;
vector<Type*> m_types;
vector<Generic> m_generics;
};
extern Namespace NAMES;
extern Type* VOID_TYPE;
extern Type* BOOLEAN_TYPE;
extern Type* BYTE_TYPE;
extern Type* CHAR_TYPE;
extern Type* INT_TYPE;
extern Type* LONG_TYPE;
extern Type* FLOAT_TYPE;
extern Type* DOUBLE_TYPE;
extern Type* OBJECT_TYPE;
extern Type* STRING_TYPE;
extern Type* CHAR_SEQUENCE_TYPE;
extern Type* TEXT_UTILS_TYPE;
extern Type* REMOTE_EXCEPTION_TYPE;
extern Type* RUNTIME_EXCEPTION_TYPE;
extern Type* IBINDER_TYPE;
extern Type* IINTERFACE_TYPE;
extern Type* BINDER_NATIVE_TYPE;
extern Type* BINDER_PROXY_TYPE;
extern Type* PARCEL_TYPE;
extern Type* PARCELABLE_INTERFACE_TYPE;
extern Type* CONTEXT_TYPE;
extern Expression* NULL_VALUE;
extern Expression* THIS_VALUE;
extern Expression* SUPER_VALUE;
extern Expression* TRUE_VALUE;
extern Expression* FALSE_VALUE;
void register_base_types();
#endif // AIDL_TYPE_H_

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +0,0 @@
#ifndef AIDL_AIDL_H_
#define AIDL_AIDL_H_
#include "options.h"
int compile_aidl(Options& options);
int preprocess_aidl(const Options& options);
#endif // AIDL_AIDL_H_

View File

@@ -1,94 +0,0 @@
#include "aidl_language.h"
#include "aidl_language_y.hpp"
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include <iostream>
#ifdef _WIN32
int isatty(int fd)
{
return (fd == 0);
}
#endif
using std::string;
using std::cerr;
using std::endl;
ParserCallbacks* g_callbacks = NULL; // &k_parserCallbacks;
void yylex_init(void **);
void yylex_destroy(void *);
void yyset_in(FILE *f, void *);
int yyparse(ParseState*);
ParseState::ParseState() : ParseState("") {}
ParseState::ParseState(const string& filename)
: filename_(filename) {
yylex_init(&scanner_);
}
ParseState::~ParseState() {
yylex_destroy(scanner_);
}
string ParseState::FileName() {
return filename_;
}
string ParseState::Package() {
return g_currentPackage;
}
void ParseState::ProcessDocument(const document_item_type& items) {
/* The cast is not my fault. I didn't write the code on the other side. */
/* TODO(sadmac): b/23977313 */
g_callbacks->document((document_item_type *)&items);
}
void ParseState::ProcessImport(const buffer_type& statement) {
/* The cast is not my fault. I didn't write the code on the other side. */
/* TODO(sadmac): b/23977313 */
g_callbacks->import((buffer_type *)&statement);
}
void ParseState::ReportError(const string& err) {
/* FIXME: We're printing out the line number as -1. We used to use yylineno
* (which was NEVER correct even before reentrant parsing). Now we'll need
* another way.
*/
cerr << filename_ << ":" << -1 << ": " << err << endl;
error_ = 1;
}
bool ParseState::FoundNoErrors() {
return error_ == 0;
}
void *ParseState::Scanner() {
return scanner_;
}
bool ParseState::OpenFileFromDisk() {
FILE *in = fopen(FileName().c_str(), "r");
if (! in)
return false;
yyset_in(in, Scanner());
return true;
}
int ParseState::RunParser() {
int ret = yy::parser(this).parse();
free((void *)g_currentPackage);
g_currentPackage = NULL;
if (error_)
return 1;
return ret;
}

View File

@@ -1,189 +0,0 @@
#ifndef AIDL_AIDL_LANGUAGE_H_
#define AIDL_AIDL_LANGUAGE_H_
#include <string>
#include "macros.h"
typedef enum {
NO_EXTRA_TEXT = 0,
SHORT_COMMENT,
LONG_COMMENT,
COPY_TEXT,
WHITESPACE
} which_extra_text;
typedef struct extra_text_type {
unsigned lineno;
which_extra_text which;
char* data;
unsigned len;
struct extra_text_type* next;
} extra_text_type;
typedef struct buffer_type {
unsigned lineno;
unsigned token;
char *data;
extra_text_type* extra;
} buffer_type;
typedef struct type_type {
buffer_type type;
buffer_type array_token;
int dimension;
} type_type;
typedef struct arg_type {
buffer_type comma_token; // empty in the first one in the list
buffer_type direction;
type_type type;
buffer_type name;
struct arg_type *next;
} arg_type;
enum {
METHOD_TYPE
};
typedef struct interface_item_type {
unsigned item_type;
struct interface_item_type* next;
} interface_item_type;
typedef struct method_type {
interface_item_type interface_item;
type_type type;
bool oneway;
buffer_type oneway_token;
buffer_type name;
buffer_type open_paren_token;
arg_type* args;
buffer_type close_paren_token;
bool hasId;
buffer_type equals_token;
buffer_type id;
// XXX missing comments/copy text here
buffer_type semicolon_token;
buffer_type* comments_token; // points into this structure, DO NOT DELETE
int assigned_id;
} method_type;
enum {
USER_DATA_TYPE = 12,
INTERFACE_TYPE_BINDER
};
typedef struct document_item_type {
unsigned item_type;
struct document_item_type* next;
} document_item_type;
typedef struct user_data_type {
document_item_type document_item;
buffer_type keyword_token; // only the first one
char* package;
buffer_type name;
buffer_type semicolon_token;
bool parcelable;
} user_data_type;
typedef struct interface_type {
document_item_type document_item;
buffer_type interface_token;
bool oneway;
buffer_type oneway_token;
char* package;
buffer_type name;
buffer_type open_brace_token;
interface_item_type* interface_items;
buffer_type close_brace_token;
buffer_type* comments_token; // points into this structure, DO NOT DELETE
} interface_type;
typedef union lexer_type {
buffer_type buffer;
type_type type;
arg_type *arg;
method_type* method;
interface_item_type* interface_item;
interface_type* interface_obj;
user_data_type* user_data;
document_item_type* document_item;
} lexer_type;
#define YYSTYPE lexer_type
#if __cplusplus
extern "C" {
#endif
int parse_aidl(char const *);
// strips off the leading whitespace, the "import" text
// also returns whether it's a local or system import
// we rely on the input matching the import regex from below
char* parse_import_statement(const char* text);
// in, out or inout
enum {
IN_PARAMETER = 1,
OUT_PARAMETER = 2,
INOUT_PARAMETER = 3
};
int convert_direction(const char* direction);
// callbacks from within the parser
// these functions all take ownership of the strings
typedef struct ParserCallbacks {
void (*document)(document_item_type* items);
void (*import)(buffer_type* statement);
} ParserCallbacks;
extern ParserCallbacks* g_callbacks;
// the package name for our current file
extern char const* g_currentPackage;
typedef enum {
STATEMENT_INSIDE_INTERFACE
} error_type;
void init_buffer_type(buffer_type* buf, int lineno);
class ParseState {
public:
ParseState();
ParseState(const std::string& filename);
~ParseState();
bool OpenFileFromDisk();
int RunParser();
void ReportError(const std::string& err);
bool FoundNoErrors();
std::string FileName();
std::string Package();
void *Scanner();
void ProcessDocument(const document_item_type& items);
void ProcessImport(const buffer_type& statement);
private:
int error_ = 0;
std::string filename_;
std::string package_;
void *scanner_ = nullptr;
DISALLOW_COPY_AND_ASSIGN(ParseState);
};
#if __cplusplus
}
#endif
#endif // AIDL_AIDL_LANGUAGE_H_

View File

@@ -1,196 +0,0 @@
%{
#include "aidl_language.h"
#include "aidl_language_y.hpp"
#include "search_path.h"
#include <string.h>
#include <stdlib.h>
extern YYSTYPE yylval;
// comment and whitespace handling
// these functions save a copy of the buffer
static void begin_extra_text(unsigned lineno, which_extra_text which);
static void append_extra_text(char* text);
static extra_text_type* get_extra_text(void); // you now own the object
// this returns
static void drop_extra_text(void);
// package handling
static void do_package_statement(const char* importText);
#define SET_BUFFER(t) \
do { \
yylval->buffer.lineno = yyget_lineno(yyscanner); \
yylval->buffer.token = (t); \
yylval->buffer.data = strdup(yytext); \
yylval->buffer.extra = get_extra_text(); \
} while(0)
%}
%option yylineno
%option noyywrap
%option reentrant
%option bison-bridge
%option bison-locations
%x COPYING LONG_COMMENT
identifier [_a-zA-Z][_a-zA-Z0-9\.]*
whitespace ([ \t\n\r]+)
brackets \[{whitespace}?\]
idvalue (0|[1-9][0-9]*)
%%
\%\%\{ { begin_extra_text(yylineno, COPY_TEXT); BEGIN(COPYING); }
<COPYING>\}\%\% { BEGIN(INITIAL); }
<COPYING>.*\n { append_extra_text(yytext); }
<COPYING>.* { append_extra_text(yytext); }
<COPYING>\n+ { append_extra_text(yytext); }
\/\* { begin_extra_text(yylineno, (which_extra_text)LONG_COMMENT);
BEGIN(LONG_COMMENT); }
<LONG_COMMENT>[^*]* { append_extra_text(yytext); }
<LONG_COMMENT>\*+[^/] { append_extra_text(yytext); }
<LONG_COMMENT>\n { append_extra_text(yytext); }
<LONG_COMMENT>\**\/ { BEGIN(INITIAL); }
^{whitespace}?import{whitespace}[^ \t\r\n]+{whitespace}?; {
SET_BUFFER(yy::parser::token::IMPORT);
return yy::parser::token::IMPORT;
}
^{whitespace}?package{whitespace}[^ \t\r\n]+{whitespace}?; {
do_package_statement(yytext);
SET_BUFFER(yy::parser::token::PACKAGE);
return yy::parser::token::PACKAGE;
}
<<EOF>> { yyterminate(); }
\/\/.*\n { begin_extra_text(yylineno, SHORT_COMMENT);
append_extra_text(yytext); }
{whitespace} { /* begin_extra_text(yylineno, WHITESPACE);
append_extra_text(yytext); */ }
; { SET_BUFFER(';'); return ';'; }
\{ { SET_BUFFER('{'); return '{'; }
\} { SET_BUFFER('}'); return '}'; }
\( { SET_BUFFER('('); return '('; }
\) { SET_BUFFER(')'); return ')'; }
, { SET_BUFFER(','); return ','; }
= { SET_BUFFER('='); return '='; }
/* keywords */
parcelable { SET_BUFFER(yy::parser::token::PARCELABLE); return yy::parser::token::PARCELABLE; }
interface { SET_BUFFER(yy::parser::token::INTERFACE); return yy::parser::token::INTERFACE; }
in { SET_BUFFER(yy::parser::token::IN); return yy::parser::token::IN; }
out { SET_BUFFER(yy::parser::token::OUT); return yy::parser::token::OUT; }
inout { SET_BUFFER(yy::parser::token::INOUT); return yy::parser::token::INOUT; }
oneway { SET_BUFFER(yy::parser::token::ONEWAY); return yy::parser::token::ONEWAY; }
{brackets}+ { SET_BUFFER(yy::parser::token::ARRAY); return yy::parser::token::ARRAY; }
{idvalue} { SET_BUFFER(yy::parser::token::IDVALUE); return yy::parser::token::IDVALUE; }
{identifier} { SET_BUFFER(yy::parser::token::IDENTIFIER); return yy::parser::token::IDENTIFIER; }
{identifier}\<{whitespace}*{identifier}({whitespace}*,{whitespace}*{identifier})*{whitespace}*\> {
SET_BUFFER(yy::parser::token::GENERIC); return yy::parser::token::GENERIC; }
/* syntax error! */
. { printf("UNKNOWN(%s)", yytext);
yylval->buffer.lineno = yylineno;
yylval->buffer.token = yy::parser::token::IDENTIFIER;
yylval->buffer.data = strdup(yytext);
return yy::parser::token::IDENTIFIER;
}
%%
// comment and whitespace handling
// ================================================
extra_text_type* g_extraText = NULL;
extra_text_type* g_nextExtraText = NULL;
void begin_extra_text(unsigned lineno, which_extra_text which)
{
extra_text_type* text = (extra_text_type*)malloc(sizeof(extra_text_type));
text->lineno = lineno;
text->which = which;
text->data = NULL;
text->len = 0;
text->next = NULL;
if (g_nextExtraText == NULL) {
g_extraText = text;
} else {
g_nextExtraText->next = text;
}
g_nextExtraText = text;
}
void append_extra_text(char* text)
{
if (g_nextExtraText->data == NULL) {
g_nextExtraText->data = strdup(text);
g_nextExtraText->len = strlen(text);
} else {
char* orig = g_nextExtraText->data;
unsigned oldLen = g_nextExtraText->len;
unsigned len = strlen(text);
g_nextExtraText->len += len;
g_nextExtraText->data = (char*)malloc(g_nextExtraText->len+1);
memcpy(g_nextExtraText->data, orig, oldLen);
memcpy(g_nextExtraText->data+oldLen, text, len);
g_nextExtraText->data[g_nextExtraText->len] = '\0';
free(orig);
}
}
extra_text_type*
get_extra_text(void)
{
extra_text_type* result = g_extraText;
g_extraText = NULL;
g_nextExtraText = NULL;
return result;
}
void drop_extra_text(void)
{
extra_text_type* p = g_extraText;
while (p) {
extra_text_type* next = p->next;
free(p->data);
free(p);
free(next);
}
g_extraText = NULL;
g_nextExtraText = NULL;
}
// package handling
// ================================================
void do_package_statement(const char* importText)
{
if (g_currentPackage) free((void*)g_currentPackage);
g_currentPackage = parse_import_statement(importText);
}
// main parse function
// ================================================
extern ParseState *psGlobal;
char const* g_currentPackage = NULL;
int parse_aidl(char const *filename) {
ParseState ps(filename);
psGlobal = &ps;
if (!ps.OpenFileFromDisk()) {
fprintf(stderr, "aidl: unable to open file for read: %s\n", filename);
return 1;
}
return ps.RunParser();
}

View File

@@ -1,343 +0,0 @@
%{
#include "aidl_language.h"
#include "aidl_language_y.hpp"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int yylex(lexer_type *, yy::parser::location_type *l, void *);
static int count_brackets(const char*);
#define lex_scanner ps->Scanner()
%}
%parse-param { ParseState* ps }
%lex-param { void *lex_scanner }
%pure-parser
%skeleton "glr.cc"
%token IMPORT
%token PACKAGE
%token IDENTIFIER
%token IDVALUE
%token GENERIC
%token ARRAY
%token PARCELABLE
%token INTERFACE
%token IN
%token OUT
%token INOUT
%token ONEWAY
%%
document:
document_items { ps->ProcessDocument(*$1.document_item); }
| headers document_items { ps->ProcessDocument(*$2.document_item); }
;
headers:
package { }
| imports { }
| package imports { }
;
package:
PACKAGE { }
;
imports:
IMPORT { ps->ProcessImport($1.buffer); }
| IMPORT imports { ps->ProcessImport($1.buffer); }
;
document_items:
{ $$.document_item = NULL; }
| document_items declaration {
if ($2.document_item == NULL) {
// error cases only
$$ = $1;
} else {
document_item_type* p = $1.document_item;
while (p && p->next) {
p=p->next;
}
if (p) {
p->next = (document_item_type*)$2.document_item;
$$ = $1;
} else {
$$.document_item = (document_item_type*)$2.document_item;
}
}
}
| document_items error {
fprintf(stderr, "%s:%d: syntax error don't know what to do with \"%s\"\n",
ps->FileName().c_str(),
$2.buffer.lineno, $2.buffer.data);
$$ = $1;
}
;
declaration:
parcelable_decl { $$.document_item = (document_item_type*)$1.user_data; }
| interface_decl { $$.document_item = (document_item_type*)$1.interface_item; }
;
parcelable_decl:
PARCELABLE IDENTIFIER ';' {
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->keyword_token = $1.buffer;
b->name = $2.buffer;
b->package =
strdup(ps->Package().c_str());
b->semicolon_token = $3.buffer;
b->parcelable = true;
$$.user_data = b;
}
| PARCELABLE ';' {
fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name.\n",
ps->FileName().c_str(), $1.buffer.lineno);
$$.user_data = NULL;
}
| PARCELABLE error ';' {
fprintf(stderr, "%s:%d syntax error in parcelable declaration. Expected type name, saw \"%s\".\n",
ps->FileName().c_str(), $2.buffer.lineno, $2.buffer.data);
$$.user_data = NULL;
}
;
interface_header:
INTERFACE {
interface_type* c = (interface_type*)malloc(sizeof(interface_type));
c->document_item.item_type = INTERFACE_TYPE_BINDER;
c->document_item.next = NULL;
c->interface_token = $1.buffer;
c->oneway = false;
memset(&c->oneway_token, 0, sizeof(buffer_type));
c->comments_token = &c->interface_token;
$$.interface_obj = c;
}
| ONEWAY INTERFACE {
interface_type* c = (interface_type*)malloc(sizeof(interface_type));
c->document_item.item_type = INTERFACE_TYPE_BINDER;
c->document_item.next = NULL;
c->interface_token = $2.buffer;
c->oneway = true;
c->oneway_token = $1.buffer;
c->comments_token = &c->oneway_token;
$$.interface_obj = c;
}
;
interface_decl:
interface_header IDENTIFIER '{' interface_items '}' {
interface_type* c = $1.interface_obj;
c->name = $2.buffer;
c->package =
strdup(ps->Package().c_str());
c->open_brace_token = $3.buffer;
c->interface_items = $4.interface_item;
c->close_brace_token = $5.buffer;
$$.interface_obj = c;
}
| INTERFACE error '{' interface_items '}' {
fprintf(stderr, "%s:%d: syntax error in interface declaration. Expected type name, saw \"%s\"\n",
ps->FileName().c_str(), $2.buffer.lineno, $2.buffer.data);
$$.document_item = NULL;
}
| INTERFACE error '}' {
fprintf(stderr, "%s:%d: syntax error in interface declaration. Expected type name, saw \"%s\"\n",
ps->FileName().c_str(), $2.buffer.lineno, $2.buffer.data);
$$.document_item = NULL;
}
;
interface_items:
{ $$.interface_item = NULL; }
| interface_items method_decl {
interface_item_type* p=$1.interface_item;
while (p && p->next) {
p=p->next;
}
if (p) {
p->next = (interface_item_type*)$2.method;
$$ = $1;
} else {
$$.interface_item = (interface_item_type*)$2.method;
}
}
| interface_items error ';' {
fprintf(stderr, "%s:%d: syntax error before ';' (expected method declaration)\n",
ps->FileName().c_str(), $3.buffer.lineno);
$$ = $1;
}
;
method_decl:
type IDENTIFIER '(' arg_list ')' ';' {
method_type *method = (method_type*)malloc(sizeof(method_type));
method->interface_item.item_type = METHOD_TYPE;
method->interface_item.next = NULL;
method->oneway = false;
method->type = $1.type;
memset(&method->oneway_token, 0, sizeof(buffer_type));
method->name = $2.buffer;
method->open_paren_token = $3.buffer;
method->args = $4.arg;
method->close_paren_token = $5.buffer;
method->hasId = false;
memset(&method->equals_token, 0, sizeof(buffer_type));
memset(&method->id, 0, sizeof(buffer_type));
method->semicolon_token = $6.buffer;
method->comments_token = &method->type.type;
$$.method = method;
}
| ONEWAY type IDENTIFIER '(' arg_list ')' ';' {
method_type *method = (method_type*)malloc(sizeof(method_type));
method->interface_item.item_type = METHOD_TYPE;
method->interface_item.next = NULL;
method->oneway = true;
method->oneway_token = $1.buffer;
method->type = $2.type;
method->name = $3.buffer;
method->open_paren_token = $4.buffer;
method->args = $5.arg;
method->close_paren_token = $6.buffer;
method->hasId = false;
memset(&method->equals_token, 0, sizeof(buffer_type));
memset(&method->id, 0, sizeof(buffer_type));
method->semicolon_token = $7.buffer;
method->comments_token = &method->oneway_token;
$$.method = method;
}
| type IDENTIFIER '(' arg_list ')' '=' IDVALUE ';' {
method_type *method = (method_type*)malloc(sizeof(method_type));
method->interface_item.item_type = METHOD_TYPE;
method->interface_item.next = NULL;
method->oneway = false;
memset(&method->oneway_token, 0, sizeof(buffer_type));
method->type = $1.type;
method->name = $2.buffer;
method->open_paren_token = $3.buffer;
method->args = $4.arg;
method->close_paren_token = $5.buffer;
method->hasId = true;
method->equals_token = $6.buffer;
method->id = $7.buffer;
method->semicolon_token = $8.buffer;
method->comments_token = &method->type.type;
$$.method = method;
}
| ONEWAY type IDENTIFIER '(' arg_list ')' '=' IDVALUE ';' {
method_type *method = (method_type*)malloc(sizeof(method_type));
method->interface_item.item_type = METHOD_TYPE;
method->interface_item.next = NULL;
method->oneway = true;
method->oneway_token = $1.buffer;
method->type = $2.type;
method->name = $3.buffer;
method->open_paren_token = $4.buffer;
method->args = $5.arg;
method->close_paren_token = $6.buffer;
method->hasId = true;
method->equals_token = $7.buffer;
method->id = $8.buffer;
method->semicolon_token = $9.buffer;
method->comments_token = &method->oneway_token;
$$.method = method;
}
;
arg_list:
{ $$.arg = NULL; }
| arg { $$ = $1; }
| arg_list ',' arg {
if ($$.arg != NULL) {
// only NULL on error
$$ = $1;
arg_type *p = $1.arg;
while (p && p->next) {
p=p->next;
}
$3.arg->comma_token = $2.buffer;
p->next = $3.arg;
}
}
| error {
fprintf(stderr, "%s:%d: syntax error in parameter list\n",
ps->FileName().c_str(), $1.buffer.lineno);
$$.arg = NULL;
}
;
arg:
direction type IDENTIFIER {
arg_type* arg = (arg_type*)malloc(sizeof(arg_type));
memset(&arg->comma_token, 0, sizeof(buffer_type));
arg->direction = $1.buffer;
arg->type = $2.type;
arg->name = $3.buffer;
arg->next = NULL;
$$.arg = arg;
}
;
type:
IDENTIFIER {
$$.type.type = $1.buffer;
init_buffer_type(&$$.type.array_token,
$1.buffer.lineno);
$$.type.dimension = 0;
}
| IDENTIFIER ARRAY {
$$.type.type = $1.buffer;
$$.type.array_token = $2.buffer;
$$.type.dimension = count_brackets($2.buffer.data);
}
| GENERIC {
$$.type.type = $1.buffer;
init_buffer_type(&$$.type.array_token,
$1.buffer.lineno);
$$.type.dimension = 0;
}
;
direction:
{ init_buffer_type(&$$.buffer, $$.buffer.lineno); }
| IN { $$.buffer = $1.buffer; }
| OUT { $$.buffer = $1.buffer; }
| INOUT { $$.buffer = $1.buffer; }
;
%%
#include <ctype.h>
#include <stdio.h>
void init_buffer_type(buffer_type* buf, int lineno)
{
buf->lineno = lineno;
buf->token = 0;
buf->data = NULL;
buf->extra = NULL;
}
static int count_brackets(const char* s)
{
int n=0;
while (*s) {
if (*s == '[') n++;
s++;
}
return n;
}
void yy::parser::error(const yy::parser::location_type& l, const std::string& errstr)
{
ps->ReportError(errstr);
}

View File

@@ -1,96 +0,0 @@
#include "generate_java.h"
#include "Type.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// =================================================
VariableFactory::VariableFactory(const string& base)
:m_base(base),
m_index(0)
{
}
Variable*
VariableFactory::Get(Type* type)
{
char name[100];
sprintf(name, "%s%d", m_base.c_str(), m_index);
m_index++;
Variable* v = new Variable(type, name);
m_vars.push_back(v);
return v;
}
Variable*
VariableFactory::Get(int index)
{
return m_vars[index];
}
// =================================================
string
gather_comments(extra_text_type* extra)
{
string s;
while (extra) {
if (extra->which == SHORT_COMMENT) {
s += extra->data;
}
else if (extra->which == LONG_COMMENT) {
s += "/*";
s += extra->data;
s += "*/";
}
extra = extra->next;
}
return s;
}
string
append(const char* a, const char* b)
{
string s = a;
s += b;
return s;
}
// =================================================
int
generate_java(const string& filename, const string& originalSrc,
interface_type* iface)
{
Class* cl;
if (iface->document_item.item_type == INTERFACE_TYPE_BINDER) {
cl = generate_binder_interface_class(iface);
}
Document* document = new Document;
document->comment = "";
if (iface->package) document->package = iface->package;
document->originalSrc = originalSrc;
document->classes.push_back(cl);
// printf("outputting... filename=%s\n", filename.c_str());
FILE* to;
if (filename == "-") {
to = stdout;
} else {
/* open file in binary mode to ensure that the tool produces the
* same output on all platforms !!
*/
to = fopen(filename.c_str(), "wb");
if (to == NULL) {
fprintf(stderr, "unable to open %s for write\n", filename.c_str());
return 1;
}
}
document->Write(to);
fclose(to);
return 0;
}

View File

@@ -1,32 +0,0 @@
#ifndef AIDL_GENERATE_JAVA_H_
#define AIDL_GENERATE_JAVA_H_
#include "aidl_language.h"
#include "AST.h"
#include <string>
using namespace std;
int generate_java(const string& filename, const string& originalSrc,
interface_type* iface);
Class* generate_binder_interface_class(const interface_type* iface);
string gather_comments(extra_text_type* extra);
string append(const char* a, const char* b);
class VariableFactory
{
public:
VariableFactory(const string& base); // base must be short
Variable* Get(Type* type);
Variable* Get(int index);
private:
vector<Variable*> m_vars;
string m_base;
int m_index;
};
#endif // AIDL_GENERATE_JAVA_H_

View File

@@ -1,560 +0,0 @@
#include "generate_java.h"
#include "Type.h"
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// =================================================
class StubClass : public Class
{
public:
StubClass(Type* type, Type* interfaceType);
virtual ~StubClass();
Variable* transact_code;
Variable* transact_data;
Variable* transact_reply;
Variable* transact_flags;
SwitchStatement* transact_switch;
private:
void make_as_interface(Type* interfaceType);
};
StubClass::StubClass(Type* type, Type* interfaceType)
:Class()
{
this->comment = "/** Local-side IPC implementation stub class. */";
this->modifiers = PUBLIC | ABSTRACT | STATIC;
this->what = Class::CLASS;
this->type = type;
this->extends = BINDER_NATIVE_TYPE;
this->interfaces.push_back(interfaceType);
// descriptor
Field* descriptor = new Field(STATIC | FINAL | PRIVATE,
new Variable(STRING_TYPE, "DESCRIPTOR"));
descriptor->value = "\"" + interfaceType->QualifiedName() + "\"";
this->elements.push_back(descriptor);
// ctor
Method* ctor = new Method;
ctor->modifiers = PUBLIC;
ctor->comment = "/** Construct the stub at attach it to the "
"interface. */";
ctor->name = "Stub";
ctor->statements = new StatementBlock;
MethodCall* attach = new MethodCall(THIS_VALUE, "attachInterface",
2, THIS_VALUE, new LiteralExpression("DESCRIPTOR"));
ctor->statements->Add(attach);
this->elements.push_back(ctor);
// asInterface
make_as_interface(interfaceType);
// asBinder
Method* asBinder = new Method;
asBinder->modifiers = PUBLIC | OVERRIDE;
asBinder->returnType = IBINDER_TYPE;
asBinder->name = "asBinder";
asBinder->statements = new StatementBlock;
asBinder->statements->Add(new ReturnStatement(THIS_VALUE));
this->elements.push_back(asBinder);
// onTransact
this->transact_code = new Variable(INT_TYPE, "code");
this->transact_data = new Variable(PARCEL_TYPE, "data");
this->transact_reply = new Variable(PARCEL_TYPE, "reply");
this->transact_flags = new Variable(INT_TYPE, "flags");
Method* onTransact = new Method;
onTransact->modifiers = PUBLIC | OVERRIDE;
onTransact->returnType = BOOLEAN_TYPE;
onTransact->name = "onTransact";
onTransact->parameters.push_back(this->transact_code);
onTransact->parameters.push_back(this->transact_data);
onTransact->parameters.push_back(this->transact_reply);
onTransact->parameters.push_back(this->transact_flags);
onTransact->statements = new StatementBlock;
onTransact->exceptions.push_back(REMOTE_EXCEPTION_TYPE);
this->elements.push_back(onTransact);
this->transact_switch = new SwitchStatement(this->transact_code);
onTransact->statements->Add(this->transact_switch);
MethodCall* superCall = new MethodCall(SUPER_VALUE, "onTransact", 4,
this->transact_code, this->transact_data,
this->transact_reply, this->transact_flags);
onTransact->statements->Add(new ReturnStatement(superCall));
}
StubClass::~StubClass()
{
}
void
StubClass::make_as_interface(Type *interfaceType)
{
Variable* obj = new Variable(IBINDER_TYPE, "obj");
Method* m = new Method;
m->comment = "/**\n * Cast an IBinder object into an ";
m->comment += interfaceType->QualifiedName();
m->comment += " interface,\n";
m->comment += " * generating a proxy if needed.\n */";
m->modifiers = PUBLIC | STATIC;
m->returnType = interfaceType;
m->name = "asInterface";
m->parameters.push_back(obj);
m->statements = new StatementBlock;
IfStatement* ifstatement = new IfStatement();
ifstatement->expression = new Comparison(obj, "==", NULL_VALUE);
ifstatement->statements = new StatementBlock;
ifstatement->statements->Add(new ReturnStatement(NULL_VALUE));
m->statements->Add(ifstatement);
// IInterface iin = obj.queryLocalInterface(DESCRIPTOR)
MethodCall* queryLocalInterface = new MethodCall(obj, "queryLocalInterface");
queryLocalInterface->arguments.push_back(new LiteralExpression("DESCRIPTOR"));
IInterfaceType* iinType = new IInterfaceType();
Variable *iin = new Variable(iinType, "iin");
VariableDeclaration* iinVd = new VariableDeclaration(iin, queryLocalInterface, NULL);
m->statements->Add(iinVd);
// Ensure the instance type of the local object is as expected.
// One scenario where this is needed is if another package (with a
// different class loader) runs in the same process as the service.
// if (iin != null && iin instanceof <interfaceType>) return (<interfaceType>) iin;
Comparison* iinNotNull = new Comparison(iin, "!=", NULL_VALUE);
Comparison* instOfCheck = new Comparison(iin, " instanceof ",
new LiteralExpression(interfaceType->QualifiedName()));
IfStatement* instOfStatement = new IfStatement();
instOfStatement->expression = new Comparison(iinNotNull, "&&", instOfCheck);
instOfStatement->statements = new StatementBlock;
instOfStatement->statements->Add(new ReturnStatement(new Cast(interfaceType, iin)));
m->statements->Add(instOfStatement);
string proxyType = interfaceType->QualifiedName();
proxyType += ".Stub.Proxy";
NewExpression* ne = new NewExpression(NAMES.Find(proxyType));
ne->arguments.push_back(obj);
m->statements->Add(new ReturnStatement(ne));
this->elements.push_back(m);
}
// =================================================
class ProxyClass : public Class
{
public:
ProxyClass(Type* type, InterfaceType* interfaceType);
virtual ~ProxyClass();
Variable* mRemote;
bool mOneWay;
};
ProxyClass::ProxyClass(Type* type, InterfaceType* interfaceType)
:Class()
{
this->modifiers = PRIVATE | STATIC;
this->what = Class::CLASS;
this->type = type;
this->interfaces.push_back(interfaceType);
mOneWay = interfaceType->OneWay();
// IBinder mRemote
mRemote = new Variable(IBINDER_TYPE, "mRemote");
this->elements.push_back(new Field(PRIVATE, mRemote));
// Proxy()
Variable* remote = new Variable(IBINDER_TYPE, "remote");
Method* ctor = new Method;
ctor->name = "Proxy";
ctor->statements = new StatementBlock;
ctor->parameters.push_back(remote);
ctor->statements->Add(new Assignment(mRemote, remote));
this->elements.push_back(ctor);
// IBinder asBinder()
Method* asBinder = new Method;
asBinder->modifiers = PUBLIC | OVERRIDE;
asBinder->returnType = IBINDER_TYPE;
asBinder->name = "asBinder";
asBinder->statements = new StatementBlock;
asBinder->statements->Add(new ReturnStatement(mRemote));
this->elements.push_back(asBinder);
}
ProxyClass::~ProxyClass()
{
}
// =================================================
static void
generate_new_array(Type* t, StatementBlock* addTo, Variable* v,
Variable* parcel)
{
Variable* len = new Variable(INT_TYPE, v->name + "_length");
addTo->Add(new VariableDeclaration(len, new MethodCall(parcel, "readInt")));
IfStatement* lencheck = new IfStatement();
lencheck->expression = new Comparison(len, "<", new LiteralExpression("0"));
lencheck->statements->Add(new Assignment(v, NULL_VALUE));
lencheck->elseif = new IfStatement();
lencheck->elseif->statements->Add(new Assignment(v,
new NewArrayExpression(t, len)));
addTo->Add(lencheck);
}
static void
generate_write_to_parcel(Type* t, StatementBlock* addTo, Variable* v,
Variable* parcel, int flags)
{
if (v->dimension == 0) {
t->WriteToParcel(addTo, v, parcel, flags);
}
if (v->dimension == 1) {
t->WriteArrayToParcel(addTo, v, parcel, flags);
}
}
static void
generate_create_from_parcel(Type* t, StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl)
{
if (v->dimension == 0) {
t->CreateFromParcel(addTo, v, parcel, cl);
}
if (v->dimension == 1) {
t->CreateArrayFromParcel(addTo, v, parcel, cl);
}
}
static void
generate_read_from_parcel(Type* t, StatementBlock* addTo, Variable* v,
Variable* parcel, Variable** cl)
{
if (v->dimension == 0) {
t->ReadFromParcel(addTo, v, parcel, cl);
}
if (v->dimension == 1) {
t->ReadArrayFromParcel(addTo, v, parcel, cl);
}
}
static void
generate_method(const method_type* method, Class* interface,
StubClass* stubClass, ProxyClass* proxyClass, int index)
{
arg_type* arg;
int i;
bool hasOutParams = false;
const bool oneway = proxyClass->mOneWay || method->oneway;
// == the TRANSACT_ constant =============================================
string transactCodeName = "TRANSACTION_";
transactCodeName += method->name.data;
char transactCodeValue[60];
sprintf(transactCodeValue, "(android.os.IBinder.FIRST_CALL_TRANSACTION + %d)", index);
Field* transactCode = new Field(STATIC | FINAL,
new Variable(INT_TYPE, transactCodeName));
transactCode->value = transactCodeValue;
stubClass->elements.push_back(transactCode);
// == the declaration in the interface ===================================
Method* decl = new Method;
decl->comment = gather_comments(method->comments_token->extra);
decl->modifiers = PUBLIC;
decl->returnType = NAMES.Search(method->type.type.data);
decl->returnTypeDimension = method->type.dimension;
decl->name = method->name.data;
arg = method->args;
while (arg != NULL) {
decl->parameters.push_back(new Variable(
NAMES.Search(arg->type.type.data), arg->name.data,
arg->type.dimension));
arg = arg->next;
}
decl->exceptions.push_back(REMOTE_EXCEPTION_TYPE);
interface->elements.push_back(decl);
// == the stub method ====================================================
Case* c = new Case(transactCodeName);
MethodCall* realCall = new MethodCall(THIS_VALUE, method->name.data);
// interface token validation is the very first thing we do
c->statements->Add(new MethodCall(stubClass->transact_data,
"enforceInterface", 1, new LiteralExpression("DESCRIPTOR")));
// args
Variable* cl = NULL;
VariableFactory stubArgs("_arg");
arg = method->args;
while (arg != NULL) {
Type* t = NAMES.Search(arg->type.type.data);
Variable* v = stubArgs.Get(t);
v->dimension = arg->type.dimension;
c->statements->Add(new VariableDeclaration(v));
if (convert_direction(arg->direction.data) & IN_PARAMETER) {
generate_create_from_parcel(t, c->statements, v,
stubClass->transact_data, &cl);
} else {
if (arg->type.dimension == 0) {
c->statements->Add(new Assignment(v, new NewExpression(v->type)));
}
else if (arg->type.dimension == 1) {
generate_new_array(v->type, c->statements, v,
stubClass->transact_data);
}
else {
fprintf(stderr, "aidl:internal error %s:%d\n", __FILE__,
__LINE__);
}
}
realCall->arguments.push_back(v);
arg = arg->next;
}
// the real call
Variable* _result = NULL;
if (0 == strcmp(method->type.type.data, "void")) {
c->statements->Add(realCall);
if (!oneway) {
// report that there were no exceptions
MethodCall* ex = new MethodCall(stubClass->transact_reply,
"writeNoException", 0);
c->statements->Add(ex);
}
} else {
_result = new Variable(decl->returnType, "_result",
decl->returnTypeDimension);
c->statements->Add(new VariableDeclaration(_result, realCall));
if (!oneway) {
// report that there were no exceptions
MethodCall* ex = new MethodCall(stubClass->transact_reply,
"writeNoException", 0);
c->statements->Add(ex);
}
// marshall the return value
generate_write_to_parcel(decl->returnType, c->statements, _result,
stubClass->transact_reply,
Type::PARCELABLE_WRITE_RETURN_VALUE);
}
// out parameters
i = 0;
arg = method->args;
while (arg != NULL) {
Type* t = NAMES.Search(arg->type.type.data);
Variable* v = stubArgs.Get(i++);
if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
generate_write_to_parcel(t, c->statements, v,
stubClass->transact_reply,
Type::PARCELABLE_WRITE_RETURN_VALUE);
hasOutParams = true;
}
arg = arg->next;
}
// return true
c->statements->Add(new ReturnStatement(TRUE_VALUE));
stubClass->transact_switch->cases.push_back(c);
// == the proxy method ===================================================
Method* proxy = new Method;
proxy->comment = gather_comments(method->comments_token->extra);
proxy->modifiers = PUBLIC | OVERRIDE;
proxy->returnType = NAMES.Search(method->type.type.data);
proxy->returnTypeDimension = method->type.dimension;
proxy->name = method->name.data;
proxy->statements = new StatementBlock;
arg = method->args;
while (arg != NULL) {
proxy->parameters.push_back(new Variable(
NAMES.Search(arg->type.type.data), arg->name.data,
arg->type.dimension));
arg = arg->next;
}
proxy->exceptions.push_back(REMOTE_EXCEPTION_TYPE);
proxyClass->elements.push_back(proxy);
// the parcels
Variable* _data = new Variable(PARCEL_TYPE, "_data");
proxy->statements->Add(new VariableDeclaration(_data,
new MethodCall(PARCEL_TYPE, "obtain")));
Variable* _reply = NULL;
if (!oneway) {
_reply = new Variable(PARCEL_TYPE, "_reply");
proxy->statements->Add(new VariableDeclaration(_reply,
new MethodCall(PARCEL_TYPE, "obtain")));
}
// the return value
_result = NULL;
if (0 != strcmp(method->type.type.data, "void")) {
_result = new Variable(proxy->returnType, "_result",
method->type.dimension);
proxy->statements->Add(new VariableDeclaration(_result));
}
// try and finally
TryStatement* tryStatement = new TryStatement();
proxy->statements->Add(tryStatement);
FinallyStatement* finallyStatement = new FinallyStatement();
proxy->statements->Add(finallyStatement);
// the interface identifier token: the DESCRIPTOR constant, marshalled as a string
tryStatement->statements->Add(new MethodCall(_data, "writeInterfaceToken",
1, new LiteralExpression("DESCRIPTOR")));
// the parameters
arg = method->args;
while (arg != NULL) {
Type* t = NAMES.Search(arg->type.type.data);
Variable* v = new Variable(t, arg->name.data, arg->type.dimension);
int dir = convert_direction(arg->direction.data);
if (dir == OUT_PARAMETER && arg->type.dimension != 0) {
IfStatement* checklen = new IfStatement();
checklen->expression = new Comparison(v, "==", NULL_VALUE);
checklen->statements->Add(new MethodCall(_data, "writeInt", 1,
new LiteralExpression("-1")));
checklen->elseif = new IfStatement();
checklen->elseif->statements->Add(new MethodCall(_data, "writeInt",
1, new FieldVariable(v, "length")));
tryStatement->statements->Add(checklen);
}
else if (dir & IN_PARAMETER) {
generate_write_to_parcel(t, tryStatement->statements, v, _data, 0);
}
arg = arg->next;
}
// the transact call
MethodCall* call = new MethodCall(proxyClass->mRemote, "transact", 4,
new LiteralExpression("Stub." + transactCodeName),
_data, _reply ? _reply : NULL_VALUE,
new LiteralExpression(
oneway ? "android.os.IBinder.FLAG_ONEWAY" : "0"));
tryStatement->statements->Add(call);
// throw back exceptions.
if (_reply) {
MethodCall* ex = new MethodCall(_reply, "readException", 0);
tryStatement->statements->Add(ex);
}
// returning and cleanup
if (_reply != NULL) {
if (_result != NULL) {
generate_create_from_parcel(proxy->returnType,
tryStatement->statements, _result, _reply, &cl);
}
// the out/inout parameters
arg = method->args;
while (arg != NULL) {
Type* t = NAMES.Search(arg->type.type.data);
Variable* v = new Variable(t, arg->name.data, arg->type.dimension);
if (convert_direction(arg->direction.data) & OUT_PARAMETER) {
generate_read_from_parcel(t, tryStatement->statements,
v, _reply, &cl);
}
arg = arg->next;
}
finallyStatement->statements->Add(new MethodCall(_reply, "recycle"));
}
finallyStatement->statements->Add(new MethodCall(_data, "recycle"));
if (_result != NULL) {
proxy->statements->Add(new ReturnStatement(_result));
}
}
static void
generate_interface_descriptors(StubClass* stub, ProxyClass* proxy)
{
// the interface descriptor transaction handler
Case* c = new Case("INTERFACE_TRANSACTION");
c->statements->Add(new MethodCall(stub->transact_reply, "writeString",
1, new LiteralExpression("DESCRIPTOR")));
c->statements->Add(new ReturnStatement(TRUE_VALUE));
stub->transact_switch->cases.push_back(c);
// and the proxy-side method returning the descriptor directly
Method* getDesc = new Method;
getDesc->modifiers = PUBLIC;
getDesc->returnType = STRING_TYPE;
getDesc->returnTypeDimension = 0;
getDesc->name = "getInterfaceDescriptor";
getDesc->statements = new StatementBlock;
getDesc->statements->Add(new ReturnStatement(new LiteralExpression("DESCRIPTOR")));
proxy->elements.push_back(getDesc);
}
Class*
generate_binder_interface_class(const interface_type* iface)
{
InterfaceType* interfaceType = static_cast<InterfaceType*>(
NAMES.Find(iface->package, iface->name.data));
// the interface class
Class* interface = new Class;
interface->comment = gather_comments(iface->comments_token->extra);
interface->modifiers = PUBLIC;
interface->what = Class::INTERFACE;
interface->type = interfaceType;
interface->interfaces.push_back(IINTERFACE_TYPE);
// the stub inner class
StubClass* stub = new StubClass(
NAMES.Find(iface->package, append(iface->name.data, ".Stub").c_str()),
interfaceType);
interface->elements.push_back(stub);
// the proxy inner class
ProxyClass* proxy = new ProxyClass(
NAMES.Find(iface->package,
append(iface->name.data, ".Stub.Proxy").c_str()),
interfaceType);
stub->elements.push_back(proxy);
// stub and proxy support for getInterfaceDescriptor()
generate_interface_descriptors(stub, proxy);
// all the declared methods of the interface
int index = 0;
interface_item_type* item = iface->interface_items;
while (item != NULL) {
if (item->item_type == METHOD_TYPE) {
method_type * method_item = (method_type*) item;
generate_method(method_item, interface, stub, proxy, method_item->assigned_id);
}
item = item->next;
index++;
}
return interface;
}

View File

@@ -1,8 +0,0 @@
#ifndef AIDL_MACROS_H_
#define AIDL_MACROS_H_
#define DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&); \
void operator=(const TypeName&)
#endif // AIDL_MACROS_H_

View File

@@ -1,23 +0,0 @@
#include "aidl.h"
#include "options.h"
#include <stdio.h>
int
main(int argc, const char **argv)
{
Options options;
int result = parse_options(argc, argv, &options);
if (result) {
return result;
}
switch (options.task) {
case COMPILE_AIDL:
return compile_aidl(options);
case PREPROCESS_AIDL:
return preprocess_aidl(options);
}
fprintf(stderr, "aidl: internal error\n");
return 1;
}

View File

@@ -1,150 +0,0 @@
#include "options.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
static int
usage()
{
fprintf(stderr,
"usage: aidl OPTIONS INPUT [OUTPUT]\n"
" aidl --preprocess OUTPUT INPUT...\n"
"\n"
"OPTIONS:\n"
" -I<DIR> search path for import statements.\n"
" -d<FILE> generate dependency file.\n"
" -a generate dependency file next to the output file with the name based on the input file.\n"
" -p<FILE> file created by --preprocess to import.\n"
" -o<FOLDER> base output folder for generated files.\n"
" -b fail when trying to compile a parcelable.\n"
"\n"
"INPUT:\n"
" An aidl interface file.\n"
"\n"
"OUTPUT:\n"
" The generated interface files.\n"
" If omitted and the -o option is not used, the input filename is used, with the .aidl extension changed to a .java extension.\n"
" If the -o option is used, the generated files will be placed in the base output folder, under their package folder\n"
);
return 1;
}
int
parse_options(int argc, const char* const* argv, Options *options)
{
int i = 1;
if (argc >= 2 && 0 == strcmp(argv[1], "--preprocess")) {
if (argc < 4) {
return usage();
}
options->outputFileName = argv[2];
for (int i=3; i<argc; i++) {
options->filesToPreprocess.push_back(argv[i]);
}
options->task = PREPROCESS_AIDL;
return 0;
}
// OPTIONS
while (i < argc) {
const char* s = argv[i];
int len = strlen(s);
if (s[0] == '-') {
if (len > 1) {
// -I<system-import-path>
if (s[1] == 'I') {
if (len > 2) {
options->importPaths.push_back(s+2);
} else {
fprintf(stderr, "-I option (%d) requires a path.\n", i);
return usage();
}
}
else if (s[1] == 'd') {
if (len > 2) {
options->depFileName = s+2;
} else {
fprintf(stderr, "-d option (%d) requires a file.\n", i);
return usage();
}
}
else if (s[1] == 'a') {
options->autoDepFile = true;
}
else if (s[1] == 'p') {
if (len > 2) {
options->preprocessedFiles.push_back(s+2);
} else {
fprintf(stderr, "-p option (%d) requires a file.\n", i);
return usage();
}
}
else if (s[1] == 'o') {
if (len > 2) {
options->outputBaseFolder = s+2;
} else {
fprintf(stderr, "-o option (%d) requires a path.\n", i);
return usage();
}
}
else if (len == 2 && s[1] == 'b') {
options->failOnParcelable = true;
}
else {
// s[1] is not known
fprintf(stderr, "unknown option (%d): %s\n", i, s);
return usage();
}
} else {
// len <= 1
fprintf(stderr, "unknown option (%d): %s\n", i, s);
return usage();
}
} else {
// s[0] != '-'
break;
}
i++;
}
// INPUT
if (i < argc) {
options->inputFileName = argv[i];
i++;
} else {
fprintf(stderr, "INPUT required\n");
return usage();
}
// OUTPUT
if (i < argc) {
options->outputFileName = argv[i];
i++;
} else if (options->outputBaseFolder.length() == 0) {
// copy input into output and change the extension from .aidl to .java
options->outputFileName = options->inputFileName;
string::size_type pos = options->outputFileName.size()-5;
if (options->outputFileName.compare(pos, 5, ".aidl") == 0) { // 5 = strlen(".aidl")
options->outputFileName.replace(pos, 5, ".java"); // 5 = strlen(".aidl")
} else {
fprintf(stderr, "INPUT is not an .aidl file.\n");
return usage();
}
}
// anything remaining?
if (i != argc) {
fprintf(stderr, "unknown option%s:", (i==argc-1?(const char*)"":(const char*)"s"));
for (; i<argc-1; i++) {
fprintf(stderr, " %s", argv[i]);
}
fprintf(stderr, "\n");
return usage();
}
return 0;
}

View File

@@ -1,36 +0,0 @@
#ifndef AIDL_OPTIONS_H_
#define AIDL_OPTIONS_H_
#include <string.h>
#include <string>
#include <vector>
using namespace std;
enum {
COMPILE_AIDL,
PREPROCESS_AIDL
};
// This struct is the parsed version of the command line options
struct Options
{
int task{COMPILE_AIDL};
bool failOnParcelable{false};
vector<string> importPaths;
vector<string> preprocessedFiles;
string inputFileName;
string outputFileName;
string outputBaseFolder;
string depFileName;
bool autoDepFile{false};
vector<string> filesToPreprocess;
};
// takes the inputs from the command line and fills in the Options struct
// Returns 0 on success, and nonzero on failure.
// It also prints the usage statement on failure.
int parse_options(int argc, const char* const* argv, Options *options);
#endif // AIDL_OPTIONS_H_

View File

@@ -1,54 +0,0 @@
/*
* Copyright (C) 2015, The Android Open Source Project
*
* 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.
*/
#include <string>
#include <vector>
#include <gtest/gtest.h>
#include "options.h"
using std::vector;
using std::string;
const char kPreprocessCommandOutputFile[] = "output_file_name";
const char kPreprocessCommandInput1[] = "input1";
const char kPreprocessCommandInput2[] = "input2";
const char kPreprocessCommandInput3[] = "input3";
const char* kPreprocessCommand[] = {
"aidl", "--preprocess",
kPreprocessCommandOutputFile,
kPreprocessCommandInput1,
kPreprocessCommandInput2,
kPreprocessCommandInput3,
};
TEST(OptionsTests, ParsesPreprocess) {
Options options;
const int argc = sizeof(kPreprocessCommand) / sizeof(*kPreprocessCommand);
EXPECT_EQ(parse_options(argc, kPreprocessCommand, &options), 0);
EXPECT_EQ(options.task, PREPROCESS_AIDL);
EXPECT_EQ(options.failOnParcelable, false);
EXPECT_EQ(options.importPaths.size(), 0u);
EXPECT_EQ(options.preprocessedFiles.size(), 0u);
EXPECT_EQ(options.inputFileName, string{""});
EXPECT_EQ(options.outputFileName, string{kPreprocessCommandOutputFile});
EXPECT_EQ(options.autoDepFile, false);
const vector<string> expected_input{kPreprocessCommandInput1,
kPreprocessCommandInput2,
kPreprocessCommandInput3};
EXPECT_EQ(options.filesToPreprocess, expected_input);
}

View File

@@ -1,26 +0,0 @@
/*
* Copyright 2015, The Android Open Source Project
*
* 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.
*/
#ifndef AIDL_OS_H_
#define AIDL_OS_H_
#if defined(_WIN32)
#define OS_PATH_SEPARATOR '\\'
#else
#define OS_PATH_SEPARATOR '/'
#endif
#endif // AIDL_OS_H_

View File

@@ -1,58 +0,0 @@
#include <unistd.h>
#include "search_path.h"
#include "options.h"
#include "os.h"
#include <string.h>
#ifdef _WIN32
#include <io.h>
#endif
static vector<string> g_importPaths;
void
set_import_paths(const vector<string>& importPaths)
{
g_importPaths = importPaths;
}
char*
find_import_file(const char* given)
{
string expected = given;
int N = expected.length();
for (int i=0; i<N; i++) {
char c = expected[i];
if (c == '.') {
expected[i] = OS_PATH_SEPARATOR;
}
}
expected += ".aidl";
vector<string>& paths = g_importPaths;
for (vector<string>::iterator it=paths.begin(); it!=paths.end(); it++) {
string f = *it;
if (f.size() == 0) {
f = ".";
f += OS_PATH_SEPARATOR;
}
else if (f[f.size()-1] != OS_PATH_SEPARATOR) {
f += OS_PATH_SEPARATOR;
}
f.append(expected);
#ifdef _WIN32
/* check that the file exists and is not write-only */
if (0 == _access(f.c_str(), 0) && /* mode 0=exist */
0 == _access(f.c_str(), 4) ) { /* mode 4=readable */
#else
if (0 == access(f.c_str(), R_OK)) {
#endif
return strdup(f.c_str());
}
}
return NULL;
}

View File

@@ -1,22 +0,0 @@
#ifndef AIDL_SEARCH_PATH_H_
#define AIDL_SEARCH_PATH_H_
#include <stdio.h>
#if __cplusplus
#include <vector>
#include <string>
using namespace std;
extern "C" {
#endif
// returns a FILE* and the char* for the file that it found
// given is the class name we're looking for
char* find_import_file(const char* given);
#if __cplusplus
}; // extern "C"
void set_import_paths(const vector<string>& importPaths);
#endif
#endif // AIDL_SEARCH_PATH_H_

View File

@@ -1,6 +0,0 @@
#include <gtest/gtest.h>
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@@ -1,165 +0,0 @@
/*
* Copyright (C) 2015, The Android Open Source Project
*
* 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.
*/
#include <memory>
#include <string>
#include <vector>
#include <base/logging.h>
#include <base/files/file_path.h>
#include <base/files/file_util.h>
#include <gtest/gtest.h>
#include "aidl.h"
#include "options.h"
#include "tests/test_data.h"
using base::FilePath;
using std::string;
using std::unique_ptr;
using std::vector;
using namespace aidl::test_data;
namespace {
const char kDiffTemplate[] = "diff %s %s";
const char kStubInterfaceTemplate[] = "package %s;\ninterface %s { }";
const char kStubParcelableTemplate[] = "package %s;\nparcelable %s;";
FilePath GetPathForPackageClass(const char* package_class,
const char* extension) {
string rel_path{package_class};
for (char& c : rel_path) {
if (c == '.') {
c = FilePath::kSeparators[0];
}
}
rel_path += extension;
return FilePath(rel_path);
}
void SplitPackageClass(const string& package_class,
FilePath* rel_path,
string* package,
string* class_name) {
*package = string{package_class, 0, package_class.rfind('.')};
*class_name = string{package_class, package_class.rfind('.') + 1};
*rel_path = GetPathForPackageClass(package_class.c_str(), ".aidl");
}
} // namespace
class EndToEndTest : public ::testing::Test {
protected:
virtual void SetUp() {
ASSERT_TRUE(base::CreateNewTempDirectory(
string{"end_to_end_testsyyyy"}, &tmpDir_));
inputDir_ = tmpDir_.Append("input");
outputDir_ = tmpDir_.Append("output");
ASSERT_TRUE(base::CreateDirectory(inputDir_));
ASSERT_TRUE(base::CreateDirectory(outputDir_));
}
virtual void TearDown() {
ASSERT_TRUE(DeleteFile(tmpDir_, true))
<< "Failed to remove temp directory: " << tmpDir_.value();
}
FilePath CreateInputFile(const FilePath& relative_path,
const char contents[],
int size) {
const FilePath created_file = inputDir_.Append(relative_path);
EXPECT_TRUE(base::CreateDirectory(created_file.DirName()));
EXPECT_TRUE(base::WriteFile(created_file, contents, size));
return created_file;
}
void CreateStubAidlFile(const string& package_class,
const char* file_template) {
string package, class_name;
FilePath rel_path;
SplitPackageClass(package_class, &rel_path, &package, &class_name);
const size_t buf_len =
strlen(file_template) + package.length() + class_name.length() + 1;
unique_ptr<char[]> contents(new char[buf_len]);
const int written = snprintf(contents.get(), buf_len, file_template,
package.c_str(), class_name.c_str());
EXPECT_GT(written, 0);
CreateInputFile(rel_path, contents.get(), written);
}
void WriteStubAidls(const char** parcelables, const char** interfaces) {
while (*parcelables) {
CreateStubAidlFile(string{*parcelables}, kStubParcelableTemplate);
++parcelables;
}
while (*interfaces) {
CreateStubAidlFile(string{*interfaces}, kStubInterfaceTemplate);
++interfaces;
}
}
void CheckFileContents(const FilePath& rel_path,
const string& expected_content) {
string actual_contents;
FilePath actual_path = outputDir_.Append(rel_path);
if (!ReadFileToString(actual_path, &actual_contents)) {
FAIL() << "Failed to read expected output file: " << rel_path.value();
}
// Generated .java files mention the "original" file as part of their
// comment header. Thus we look for expected_content being a substring.
if (actual_contents.find(expected_content) == string::npos) {
// When the match fails, display a diff of what's wrong. This greatly
// aids in debugging.
FilePath expected_path;
EXPECT_TRUE(CreateTemporaryFileInDir(tmpDir_, &expected_path));
base::WriteFile(expected_path, expected_content.c_str(),
expected_content.length());
const size_t buf_len =
strlen(kDiffTemplate) + actual_path.value().length() +
expected_path.value().length() + 1;
unique_ptr<char[]> diff_cmd(new char[buf_len]);
EXPECT_GT(snprintf(diff_cmd.get(), buf_len, kDiffTemplate,
expected_path.value().c_str(),
actual_path.value().c_str()), 0);
system(diff_cmd.get());
FAIL() << "Actual contents of " << rel_path.value()
<< " did not match expected content";
}
}
FilePath tmpDir_;
FilePath inputDir_;
FilePath outputDir_;
};
TEST_F(EndToEndTest, IExampleInterface) {
Options options;
options.failOnParcelable = true;
options.importPaths.push_back(inputDir_.value());
options.inputFileName =
CreateInputFile(GetPathForPackageClass(kIExampleInterfaceClass, ".aidl"),
kIExampleInterfaceContents,
strlen(kIExampleInterfaceContents)).value();
options.autoDepFile = true;
options.outputBaseFolder = outputDir_.value();
WriteStubAidls(kIExampleInterfaceParcelables, kIExampleInterfaceInterfaces);
EXPECT_EQ(compile_aidl(options), 0);
CheckFileContents(GetPathForPackageClass(kIExampleInterfaceClass, ".java"),
kIExampleInterfaceJava);
// We'd like to check the depends file, but it mentions unique file paths.
}

View File

@@ -1,404 +0,0 @@
/*
* Copyright (C) 2015, The Android Open Source Project
*
* 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.
*/
#include "tests/test_data.h"
namespace aidl {
namespace test_data {
const char kIExampleInterfaceClass[] = "android.test.IExampleInterface";
const char* kIExampleInterfaceParcelables[] = {
"android.foo.ExampleParcelable",
"android.test.ExampleParcelable2",
nullptr,
};
const char* kIExampleInterfaceInterfaces[] = {
"android.bar.IAuxInterface",
"android.test.IAuxInterface2",
nullptr,
};
const char kIExampleInterfaceContents[] = R"(
package android.test;
import android.foo.ExampleParcelable;
import android.test.ExampleParcelable2;
import android.bar.IAuxInterface;
import android.test.IAuxInterface2;
interface IExampleInterface {
boolean isEnabled();
int getState();
String getAddress();
ExampleParcelable[] getParcelables();
boolean setScanMode(int mode, int duration);
void registerBinder(IAuxInterface foo);
IExampleInterface getRecursiveBinder();
int takesAnInterface(in IAuxInterface2 arg);
int takesAParcelable(in ExampleParcelable2 arg);
}
)";
const char kIExampleInterfaceDeps[] =
R"(/tmp/.org.chromium.Chromium.Cdq7YZ/output/android/test/IExampleInterface.java: \
/tmp/.org.chromium.Chromium.Cdq7YZ/input/android/test/IExampleInterface.aidl \
/tmp/.org.chromium.Chromium.Cdq7YZ/input/android/foo/ExampleParcelable.aidl \
/tmp/.org.chromium.Chromium.Cdq7YZ/input/android/test/ExampleParcelable2.aidl \
/tmp/.org.chromium.Chromium.Cdq7YZ/input/android/bar/IAuxInterface.aidl \
/tmp/.org.chromium.Chromium.Cdq7YZ/input/android/test/IAuxInterface2.aidl
/tmp/.org.chromium.Chromium.Cdq7YZ/input/android/test/IExampleInterface.aidl :
/tmp/.org.chromium.Chromium.Cdq7YZ/input/android/foo/ExampleParcelable.aidl :
/tmp/.org.chromium.Chromium.Cdq7YZ/input/android/test/ExampleParcelable2.aidl :
/tmp/.org.chromium.Chromium.Cdq7YZ/input/android/bar/IAuxInterface.aidl :
/tmp/.org.chromium.Chromium.Cdq7YZ/input/android/test/IAuxInterface2.aidl :)";
const char kIExampleInterfaceJava[] =
R"(package android.test;
public interface IExampleInterface extends android.os.IInterface
{
/** Local-side IPC implementation stub class. */
public static abstract class Stub extends android.os.Binder implements android.test.IExampleInterface
{
private static final java.lang.String DESCRIPTOR = "android.test.IExampleInterface";
/** Construct the stub at attach it to the interface. */
public Stub()
{
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an android.test.IExampleInterface interface,
* generating a proxy if needed.
*/
public static android.test.IExampleInterface asInterface(android.os.IBinder obj)
{
if ((obj==null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin!=null)&&(iin instanceof android.test.IExampleInterface))) {
return ((android.test.IExampleInterface)iin);
}
return new android.test.IExampleInterface.Stub.Proxy(obj);
}
@Override public android.os.IBinder asBinder()
{
return this;
}
@Override public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException
{
switch (code)
{
case INTERFACE_TRANSACTION:
{
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_isEnabled:
{
data.enforceInterface(DESCRIPTOR);
boolean _result = this.isEnabled();
reply.writeNoException();
reply.writeInt(((_result)?(1):(0)));
return true;
}
case TRANSACTION_getState:
{
data.enforceInterface(DESCRIPTOR);
int _result = this.getState();
reply.writeNoException();
reply.writeInt(_result);
return true;
}
case TRANSACTION_getAddress:
{
data.enforceInterface(DESCRIPTOR);
java.lang.String _result = this.getAddress();
reply.writeNoException();
reply.writeString(_result);
return true;
}
case TRANSACTION_getParcelables:
{
data.enforceInterface(DESCRIPTOR);
android.foo.ExampleParcelable[] _result = this.getParcelables();
reply.writeNoException();
reply.writeTypedArray(_result, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
return true;
}
case TRANSACTION_setScanMode:
{
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
int _arg1;
_arg1 = data.readInt();
boolean _result = this.setScanMode(_arg0, _arg1);
reply.writeNoException();
reply.writeInt(((_result)?(1):(0)));
return true;
}
case TRANSACTION_registerBinder:
{
data.enforceInterface(DESCRIPTOR);
android.bar.IAuxInterface _arg0;
_arg0 = android.bar.IAuxInterface.Stub.asInterface(data.readStrongBinder());
this.registerBinder(_arg0);
reply.writeNoException();
return true;
}
case TRANSACTION_getRecursiveBinder:
{
data.enforceInterface(DESCRIPTOR);
android.test.IExampleInterface _result = this.getRecursiveBinder();
reply.writeNoException();
reply.writeStrongBinder((((_result!=null))?(_result.asBinder()):(null)));
return true;
}
case TRANSACTION_takesAnInterface:
{
data.enforceInterface(DESCRIPTOR);
android.test.IAuxInterface2 _arg0;
_arg0 = android.test.IAuxInterface2.Stub.asInterface(data.readStrongBinder());
int _result = this.takesAnInterface(_arg0);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
case TRANSACTION_takesAParcelable:
{
data.enforceInterface(DESCRIPTOR);
android.test.ExampleParcelable2 _arg0;
if ((0!=data.readInt())) {
_arg0 = android.test.ExampleParcelable2.CREATOR.createFromParcel(data);
}
else {
_arg0 = null;
}
int _result = this.takesAParcelable(_arg0);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements android.test.IExampleInterface
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
@Override public boolean isEnabled() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_isEnabled, _data, _reply, 0);
_reply.readException();
_result = (0!=_reply.readInt());
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override public int getState() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getState, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override public java.lang.String getAddress() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
java.lang.String _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getAddress, _data, _reply, 0);
_reply.readException();
_result = _reply.readString();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override public android.foo.ExampleParcelable[] getParcelables() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
android.foo.ExampleParcelable[] _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getParcelables, _data, _reply, 0);
_reply.readException();
_result = _reply.createTypedArray(android.foo.ExampleParcelable.CREATOR);
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override public boolean setScanMode(int mode, int duration) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
boolean _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(mode);
_data.writeInt(duration);
mRemote.transact(Stub.TRANSACTION_setScanMode, _data, _reply, 0);
_reply.readException();
_result = (0!=_reply.readInt());
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override public void registerBinder(android.bar.IAuxInterface foo) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeStrongBinder((((foo!=null))?(foo.asBinder()):(null)));
mRemote.transact(Stub.TRANSACTION_registerBinder, _data, _reply, 0);
_reply.readException();
}
finally {
_reply.recycle();
_data.recycle();
}
}
@Override public android.test.IExampleInterface getRecursiveBinder() throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
android.test.IExampleInterface _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getRecursiveBinder, _data, _reply, 0);
_reply.readException();
_result = android.test.IExampleInterface.Stub.asInterface(_reply.readStrongBinder());
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override public int takesAnInterface(android.test.IAuxInterface2 arg) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeStrongBinder((((arg!=null))?(arg.asBinder()):(null)));
mRemote.transact(Stub.TRANSACTION_takesAnInterface, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override public int takesAParcelable(android.test.ExampleParcelable2 arg) throws android.os.RemoteException
{
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
if ((arg!=null)) {
_data.writeInt(1);
arg.writeToParcel(_data, 0);
}
else {
_data.writeInt(0);
}
mRemote.transact(Stub.TRANSACTION_takesAParcelable, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
}
finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_isEnabled = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_getState = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
static final int TRANSACTION_getAddress = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);
static final int TRANSACTION_getParcelables = (android.os.IBinder.FIRST_CALL_TRANSACTION + 3);
static final int TRANSACTION_setScanMode = (android.os.IBinder.FIRST_CALL_TRANSACTION + 4);
static final int TRANSACTION_registerBinder = (android.os.IBinder.FIRST_CALL_TRANSACTION + 5);
static final int TRANSACTION_getRecursiveBinder = (android.os.IBinder.FIRST_CALL_TRANSACTION + 6);
static final int TRANSACTION_takesAnInterface = (android.os.IBinder.FIRST_CALL_TRANSACTION + 7);
static final int TRANSACTION_takesAParcelable = (android.os.IBinder.FIRST_CALL_TRANSACTION + 8);
}
public boolean isEnabled() throws android.os.RemoteException;
public int getState() throws android.os.RemoteException;
public java.lang.String getAddress() throws android.os.RemoteException;
public android.foo.ExampleParcelable[] getParcelables() throws android.os.RemoteException;
public boolean setScanMode(int mode, int duration) throws android.os.RemoteException;
public void registerBinder(android.bar.IAuxInterface foo) throws android.os.RemoteException;
public android.test.IExampleInterface getRecursiveBinder() throws android.os.RemoteException;
public int takesAnInterface(android.test.IAuxInterface2 arg) throws android.os.RemoteException;
public int takesAParcelable(android.test.ExampleParcelable2 arg) throws android.os.RemoteException;
})";
} // namespace test_data
} // namespace aidl

View File

@@ -1,33 +0,0 @@
/*
* Copyright (C) 2015, The Android Open Source Project
*
* 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.
*/
#ifndef AIDL_TESTS_TEST_DATA_H_
#define AIDL_TESTS_TEST_DATA_H_
namespace aidl {
namespace test_data {
extern const char kIExampleInterfaceClass[];
extern const char kIExampleInterfaceContents[];
extern const char* kIExampleInterfaceParcelables[];
extern const char* kIExampleInterfaceInterfaces[];
extern const char kIExampleInterfaceDeps[];
extern const char kIExampleInterfaceJava[];
} // namespace test_data
} // namespace aidl
#endif // AIDL_TESTS_TEST_DATA_H_