Fix covariant return types for methods declared in domain objects.
Issue 5512.
Patch by: bobv
Review by: rchandia

Review at http://gwt-code-reviews.appspot.com/1136801


git-svn-id: https://google-web-toolkit.googlecode.com/svn/trunk@9270 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/user/src/com/google/gwt/requestfactory/server/RequestFactoryInterfaceValidator.java b/user/src/com/google/gwt/requestfactory/server/RequestFactoryInterfaceValidator.java
index 95f26a8..5dafce4 100644
--- a/user/src/com/google/gwt/requestfactory/server/RequestFactoryInterfaceValidator.java
+++ b/user/src/com/google/gwt/requestfactory/server/RequestFactoryInterfaceValidator.java
@@ -324,7 +324,23 @@
 
     public Set<RFMethod> exec(String internalName) {
       RequestFactoryInterfaceValidator.this.visit(logger, internalName, this);
-      return methods;
+
+      Map<RFMethod, RFMethod> toReturn = new HashMap<RFMethod, RFMethod>();
+      // Return most-derived methods
+      for (RFMethod method : methods) {
+        RFMethod key = new RFMethod(method.getName(), Type.getMethodDescriptor(
+            Type.VOID_TYPE, method.getArgumentTypes()));
+
+        RFMethod compareTo = toReturn.get(key);
+        if (compareTo == null) {
+          toReturn.put(key, method);
+        } else if (isAssignable(logger, compareTo.getReturnType(),
+            method.getReturnType())) {
+          toReturn.put(key, method);
+        }
+      }
+
+      return new HashSet<RFMethod>(toReturn.values());
     }
 
     @Override
@@ -856,6 +872,7 @@
     clientToDomainType.put(clientType, domainType);
 
     if (isAssignable(logger, baseProxyIntf, clientType)) {
+      maybeCheckProxyType(logger, clientType);
       List<Type> list = domainToClientType.get(domainType);
       if (list == null) {
         list = new ArrayList<Type>();
diff --git a/user/test/com/google/gwt/requestfactory/server/HasId.java b/user/test/com/google/gwt/requestfactory/server/HasId.java
new file mode 100644
index 0000000..b715b52
--- /dev/null
+++ b/user/test/com/google/gwt/requestfactory/server/HasId.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2010 Google Inc.
+ * 
+ * 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.
+ */
+package com.google.gwt.requestfactory.server;
+
+/**
+ * Used to test covariant return types.
+ */
+public interface HasId {
+  Object getId();
+
+  Object persistAndReturnSelf();
+}
diff --git a/user/test/com/google/gwt/requestfactory/server/SimpleBar.java b/user/test/com/google/gwt/requestfactory/server/SimpleBar.java
index d0a625c..cd22c05 100644
--- a/user/test/com/google/gwt/requestfactory/server/SimpleBar.java
+++ b/user/test/com/google/gwt/requestfactory/server/SimpleBar.java
@@ -28,7 +28,7 @@
 /**
  * Domain object for SimpleFooRequest.
  */
-public class SimpleBar {
+public class SimpleBar implements HasId {
   /**
    * DO NOT USE THIS UGLY HACK DIRECTLY! Call {@link #get} instead.
    */
@@ -88,7 +88,7 @@
   public static SimpleBar getSingleton() {
     return findSimpleBar("1L");
   }
-  
+
   public static void reset() {
     resetImpl();
   }