Generalized cpp method generation.

Change-Id: Ia91d03eaadae79eb5508e3fc57817bcf1cf9f1aa
diff --git a/AST.h b/AST.h
index cd13ac9..57676a1 100644
--- a/AST.h
+++ b/AST.h
@@ -144,8 +144,20 @@
     status_t generateTypeSource(
             Formatter &out, const std::string &ifaceName) const;
 
-    status_t generateHeaderMethodSignatures(
-            Formatter &out, bool abstract) const;
+    enum MethodLocation {
+        PROXY_HEADER,
+        STUB_HEADER
+    };
+
+    status_t generateMethods(Formatter &out,
+                             const std::string &className,
+                             MethodLocation type) const;
+    status_t generateStubMethod(Formatter &out,
+                                const std::string &className,
+                                const Method *method) const;
+    status_t generateProxyMethod(Formatter &out,
+                                 const std::string &className,
+                                 const Method *method) const;
 
     status_t generateProxySource(
             Formatter &out, const std::string &baseName) const;
diff --git a/Method.cpp b/Method.cpp
index a85735c..230ba17 100644
--- a/Method.cpp
+++ b/Method.cpp
@@ -51,8 +51,42 @@
     return *mAnnotationsByName;
 }
 
+void Method::generateCppSignature(Formatter &out,
+                                  const std::string &className) const {
+    const bool returnsValue = !results().empty();
+
+    const TypedVar *elidedReturn = canElideCallback();
+
+    if (elidedReturn == nullptr) {
+        out << "::android::hardware::Status ";
+    } else {
+        std::string extra;
+        out << "::android::hardware::Return<"
+            << elidedReturn->type().getCppResultType(&extra)
+            << "> ";
+    }
+
+    if (!className.empty()) {
+        out << className << "::";
+    }
+
+    out << name()
+        << "("
+        << GetArgSignature(args());
+
+    if (returnsValue && elidedReturn == nullptr) {
+        if (!args().empty()) {
+            out << ", ";
+        }
+
+        out << name() << "_cb _hidl_cb";
+    }
+
+    out << ") ";
+}
+
 // static
-std::string Method::GetSignature(const std::vector<TypedVar *> &args) {
+std::string Method::GetArgSignature(const std::vector<TypedVar *> &args) {
     bool first = true;
     std::string out;
     for (const auto &arg : args) {
@@ -73,7 +107,7 @@
 }
 
 // static
-std::string Method::GetJavaSignature(const std::vector<TypedVar *> &args) {
+std::string Method::GetJavaArgSignature(const std::vector<TypedVar *> &args) {
     bool first = true;
     std::string out;
     for (const auto &arg : args) {
diff --git a/Method.h b/Method.h
index 5475812..1bf1bff 100644
--- a/Method.h
+++ b/Method.h
@@ -47,8 +47,11 @@
     bool isOneway() const { return mOneway; }
     const AnnotationVector &annotations() const;
 
-    static std::string GetSignature(const std::vector<TypedVar *> &args);
-    static std::string GetJavaSignature(const std::vector<TypedVar *> &args);
+    void generateCppSignature(Formatter &out,
+                              const std::string &className) const;
+
+    static std::string GetArgSignature(const std::vector<TypedVar *> &args);
+    static std::string GetJavaArgSignature(const std::vector<TypedVar *> &args);
 
     const TypedVar* canElideCallback() const;
 
diff --git a/generateCpp.cpp b/generateCpp.cpp
index 4c22851..0d680cf 100644
--- a/generateCpp.cpp
+++ b/generateCpp.cpp
@@ -224,7 +224,7 @@
             out << "using "
                 << method->name()
                 << "_cb = std::function<void("
-                << Method::GetSignature(method->results())
+                << Method::GetArgSignature(method->results())
                 << ")>;\n";
         }
 
@@ -248,7 +248,7 @@
 
             out << method->name()
                 << "("
-                << Method::GetSignature(method->args());
+                << Method::GetArgSignature(method->args());
 
             if (returnsValue && elidedReturn == nullptr) {
                 if (!method->args().empty()) {
@@ -413,8 +413,59 @@
     return mRootScope->emitTypeDeclarations(out);
 }
 
-status_t AST::generateHeaderMethodSignatures(
-        Formatter &out, bool stub) const {
+status_t AST::generateStubMethod(Formatter &out,
+                                 const std::string &className,
+                                 const Method *method) const {
+    out << "inline ";
+
+    method->generateCppSignature(out, className);
+
+    const bool returnsValue = !method->results().empty();
+    const TypedVar *elidedReturn = method->canElideCallback();
+    out << " {\n";
+    out.indent();
+    out << "return mImpl->"
+        << method->name()
+        << "(";
+    bool first = true;
+    for (const auto &arg : method->args()) {
+        if (!first) {
+            out << ", ";
+        }
+        first = false;
+        out << arg->name();
+    }
+    if (returnsValue && elidedReturn == nullptr) {
+        if (!method->args().empty()) {
+            out << ", ";
+        }
+
+        out << "_hidl_cb";
+    }
+    out << ");\n";
+    out.unindent();
+    out << "}";
+
+    out << ";\n";
+
+    return OK;
+}
+
+status_t AST::generateProxyMethod(Formatter &out,
+                                  const std::string &className,
+                                  const Method *method) const {
+
+    method->generateCppSignature(out, className);
+    out << " override;\n";
+
+    return OK;
+}
+
+status_t AST::generateMethods(
+        Formatter &out,
+        const std::string &className,
+        MethodLocation type) const {
+
     const Interface *iface = mRootScope->getInterface();
 
     std::vector<const Interface *> chain;
@@ -431,61 +482,25 @@
             << " follow.\n";
 
         for (const auto &method : superInterface->methods()) {
-            if (stub) {
-                out << "inline ";
-            }
-            const bool returnsValue = !method->results().empty();
-
-            const TypedVar *elidedReturn = method->canElideCallback();
-
-            if (elidedReturn == nullptr) {
-                out << "::android::hardware::Status ";
-            } else {
-                std::string extra;
-                out << "::android::hardware::Return<";
-                out << elidedReturn->type().getCppResultType(&extra) << "> ";
-            }
-            out << method->name()
-                << "("
-                << Method::GetSignature(method->args());
-
-            if (returnsValue && elidedReturn == nullptr) {
-                if (!method->args().empty()) {
-                    out << ", ";
-                }
-
-                out << method->name() << "_cb _hidl_cb";
+            status_t err;
+            switch(type) {
+                case STUB_HEADER:
+                    err = generateStubMethod(out,
+                                             className,
+                                             method);
+                    break;
+                case PROXY_HEADER:
+                    err = generateProxyMethod(out,
+                                              className,
+                                              method);
+                    break;
+                default:
+                    err = UNKNOWN_ERROR;
             }
 
-            out << ") ";
-            if (stub) {
-                out << " {\n";
-                out.indent();
-                out << "return mImpl->"
-                    << method->name()
-                    << "(";
-                bool first = true;
-                for (const auto &arg : method->args()) {
-                    if (!first) {
-                        out << ", ";
-                    }
-                    first = false;
-                    out << arg->name();
-                }
-                if (returnsValue && elidedReturn == nullptr) {
-                    if (!method->args().empty()) {
-                        out << ", ";
-                    }
-
-                    out << "_hidl_cb";
-                }
-                out << ");\n";
-                out.unindent();
-                out << "}";
-            } else {
-                out << "override";
+            if (err != OK) {
+                return err;
             }
-            out << ";\n";
         }
 
         out << "\n";
@@ -561,7 +576,9 @@
     out.unindent();
     out.unindent();
 
-    generateHeaderMethodSignatures(out, true); // stub
+    generateMethods(out,
+                    "" /* class name */,
+                    MethodLocation::STUB_HEADER);
     out.unindent();
 
     out << "};\n\n";
@@ -633,7 +650,9 @@
 
     out << "virtual bool isRemote() const { return true; }\n\n";
 
-    generateHeaderMethodSignatures(out, false); // proxy
+    generateMethods(out,
+                    "" /* class name */,
+                    MethodLocation::PROXY_HEADER);
 
     out.unindent();
 
@@ -797,32 +816,12 @@
         const Interface *superInterface = *it;
 
         for (const auto &method : superInterface->methods()) {
+            method->generateCppSignature(out, klassName);
+
             const bool returnsValue = !method->results().empty();
-
             const TypedVar *elidedReturn = method->canElideCallback();
-            if (elidedReturn) {
-                std::string extra;
-                out << "::android::hardware::Return<";
-                out << elidedReturn->type().getCppResultType(&extra) << "> ";
-            } else {
-                out << "::android::hardware::Status ";
-            }
 
-            out << klassName
-                << "::"
-                << method->name()
-                << "("
-                << Method::GetSignature(method->args());
-
-            if (returnsValue && elidedReturn == nullptr) {
-                if (!method->args().empty()) {
-                    out << ", ";
-                }
-
-                out << method->name() << "_cb _hidl_cb";
-            }
-
-            out << ") {\n";
+            out << "{\n";
 
             out.indent();
 
diff --git a/generateJava.cpp b/generateJava.cpp
index 77d8ccb..bc75547 100644
--- a/generateJava.cpp
+++ b/generateJava.cpp
@@ -269,7 +269,7 @@
             out.indent();
 
             out << "public abstract void onValues("
-                << Method::GetJavaSignature(method->results())
+                << Method::GetJavaArgSignature(method->results())
                 << ");\n";
 
             out.unindent();
@@ -285,7 +285,7 @@
         out << " "
             << method->name()
             << "("
-            << Method::GetJavaSignature(method->args());
+            << Method::GetJavaArgSignature(method->args());
 
         if (needsCallback) {
             if (!method->args().empty()) {
@@ -345,7 +345,7 @@
             out << " "
                 << method->name()
                 << "("
-                << Method::GetJavaSignature(method->args());
+                << Method::GetJavaArgSignature(method->args());
 
             if (needsCallback) {
                 if (!method->args().empty()) {
@@ -529,7 +529,7 @@
 
                 out << "@Override\n"
                     << "public void onValues("
-                    << Method::GetJavaSignature(method->results())
+                    << Method::GetJavaArgSignature(method->results())
                     << ") {\n";
 
                 out.indent();