Ok, here is a revised patch which recursively follows the inheritance chains, and the test improved to check for that.
-- John A. Tamplin Software Engineer (GWT), Google --~--~---------~--~----~------------~-------~--~----~ http://groups.google.com/group/Google-Web-Toolkit-Contributors -~----------~----~----~----~------~----~------~--~---
Index: user/test/com/google/gwt/i18n/client/TestAnnotationInheritance.java =================================================================== --- user/test/com/google/gwt/i18n/client/TestAnnotationInheritance.java (revision 0) +++ user/test/com/google/gwt/i18n/client/TestAnnotationInheritance.java (revision 0) @@ -0,0 +1,27 @@ +/* + * Copyright 2008 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.i18n.client; + +/** + * Verifies that class-level annotations on superinterface are still used + * by this interface. In this case, we verify that this interface's keys + * are based on the MD5 hash of the default value. + */ +public interface TestAnnotationInheritance extends CommonInterfaceAnnotations { + + @DefaultMessage("bar") + String bar(); +} Property changes on: user/test/com/google/gwt/i18n/client/TestAnnotationInheritance.java ___________________________________________________________________ Name: svn:mime-type + text/x-java Name: svn:eol-style + native Index: user/test/com/google/gwt/i18n/client/TestAnnotationGrandchild_piglatin.properties =================================================================== --- user/test/com/google/gwt/i18n/client/TestAnnotationGrandchild_piglatin.properties (revision 0) +++ user/test/com/google/gwt/i18n/client/TestAnnotationGrandchild_piglatin.properties (revision 0) @@ -0,0 +1,4 @@ +# MD5 hash of "bar" +37B51D194A7513E45B56F6524F2D51F2 = bar_piglatin +# MD5 hash of "baz" +73FEFFA4B7F6BB68E44CF984C85F6E88 = baz_piglatin Property changes on: user/test/com/google/gwt/i18n/client/TestAnnotationGrandchild_piglatin.properties ___________________________________________________________________ Name: svn:eol-style + native Index: user/test/com/google/gwt/i18n/client/I18NTest.java =================================================================== --- user/test/com/google/gwt/i18n/client/I18NTest.java (revision 3866) +++ user/test/com/google/gwt/i18n/client/I18NTest.java (working copy) @@ -126,6 +126,13 @@ m.pluralWidgetsOther(150)); } + public void testAnnotationInheritance() { + TestAnnotationGrandchild m = GWT.create(TestAnnotationGrandchild.class); + assertEquals("foo", m.foo()); + assertEquals("bar_piglatin", m.bar()); + assertEquals("baz_piglatin", m.baz()); + } + public void testBindings() { TestBinding b = (TestBinding) GWT.create(TestBinding.class); assertEquals("default", b.a()); Index: user/test/com/google/gwt/i18n/client/CommonInterfaceAnnotations.java =================================================================== --- user/test/com/google/gwt/i18n/client/CommonInterfaceAnnotations.java (revision 0) +++ user/test/com/google/gwt/i18n/client/CommonInterfaceAnnotations.java (revision 0) @@ -0,0 +1,32 @@ +/* + * Copyright 2008 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.i18n.client; + +import com.google.gwt.i18n.client.LocalizableResource.GenerateKeys; + +/** + * Base interface to test annotation inheritance. + * + * <p>This works by setting the key generator to MD5 on this interface, + * then verifying that keys in the subinterface are looked up with + * MD5 hashes rather than method names. + */ [EMAIL PROTECTED]("com.google.gwt.i18n.rebind.keygen.MD5KeyGenerator") +public interface CommonInterfaceAnnotations extends Messages { + + @DefaultMessage("foo") + String foo(); +} Property changes on: user/test/com/google/gwt/i18n/client/CommonInterfaceAnnotations.java ___________________________________________________________________ Name: svn:mime-type + text/x-java Name: svn:eol-style + native Index: user/test/com/google/gwt/i18n/client/TestAnnotationGrandchild.java =================================================================== --- user/test/com/google/gwt/i18n/client/TestAnnotationGrandchild.java (revision 0) +++ user/test/com/google/gwt/i18n/client/TestAnnotationGrandchild.java (revision 0) @@ -0,0 +1,26 @@ +/* + * Copyright 2008 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.i18n.client; + +/** + * Verifies that class-level annotations on grandparent interface are still honored, + * to make sure multiple levels of inheritance are handled. + */ +public interface TestAnnotationGrandchild extends TestAnnotationInheritance { + + @DefaultMessage("baz") + String baz(); +} Property changes on: user/test/com/google/gwt/i18n/client/TestAnnotationGrandchild.java ___________________________________________________________________ Name: svn:mime-type + text/x-java Name: svn:eol-style + native Index: user/src/com/google/gwt/i18n/rebind/AnnotationsResource.java =================================================================== --- user/src/com/google/gwt/i18n/rebind/AnnotationsResource.java (revision 3866) +++ user/src/com/google/gwt/i18n/rebind/AnnotationsResource.java (working copy) @@ -13,9 +13,10 @@ * License for the specific language governing permissions and limitations under * the License. */ - package com.google.gwt.i18n.rebind; +import static com.google.gwt.i18n.rebind.AnnotationUtil.getClassAnnotation; + import com.google.gwt.core.ext.TreeLogger; import com.google.gwt.core.ext.typeinfo.JArrayType; import com.google.gwt.core.ext.typeinfo.JClassType; @@ -167,7 +168,7 @@ */ public static KeyGenerator getKeyGenerator(JClassType targetClass) throws AnnotationsError { - GenerateKeys generator = targetClass.getAnnotation(GenerateKeys.class); + GenerateKeys generator = getClassAnnotation(targetClass, GenerateKeys.class); if (generator != null) { String className = generator.value(); try { @@ -377,7 +378,7 @@ KeyGenerator keyGenerator = getKeyGenerator(clazz); map = new HashMap<String, MethodEntry>(); setPath(clazz.getQualifiedSourceName()); - DefaultLocale defLocale = clazz.getAnnotation(DefaultLocale.class); + DefaultLocale defLocale = getClassAnnotation(clazz, DefaultLocale.class); if (defLocale != null && !ResourceFactory.DEFAULT_TOKEN.equals(locale) && !locale.equalsIgnoreCase(defLocale.value())) { logger.log(TreeLogger.WARN, "@DefaultLocale on " Index: user/src/com/google/gwt/i18n/rebind/AbstractLocalizableImplCreator.java =================================================================== --- user/src/com/google/gwt/i18n/rebind/AbstractLocalizableImplCreator.java (revision 3866) +++ user/src/com/google/gwt/i18n/rebind/AbstractLocalizableImplCreator.java (working copy) @@ -15,6 +15,8 @@ */ package com.google.gwt.i18n.rebind; +import static com.google.gwt.i18n.rebind.AnnotationUtil.getClassAnnotation; + import com.google.gwt.core.ext.GeneratorContext; import com.google.gwt.core.ext.TreeLogger; import com.google.gwt.core.ext.UnableToCompleteException; @@ -139,7 +141,7 @@ context.commit(logger, pw); } // Generate a translatable output file if requested. - Generate generate = targetClass.getAnnotation(Generate.class); + Generate generate = getClassAnnotation(targetClass, Generate.class); if (generate != null) { String path = generate.fileName(); if (Generate.DEFAULT.equals(path)) { Index: user/src/com/google/gwt/i18n/rebind/AnnotationUtil.java =================================================================== --- user/src/com/google/gwt/i18n/rebind/AnnotationUtil.java (revision 0) +++ user/src/com/google/gwt/i18n/rebind/AnnotationUtil.java (revision 0) @@ -0,0 +1,66 @@ +/* + * Copyright 2008 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.i18n.rebind; + +import com.google.gwt.core.ext.typeinfo.JClassType; + +import java.lang.annotation.Annotation; + +/** + * Utility class for i18n-related annotation manipulation routines. + */ +public class AnnotationUtil { + + /** + * Find an instance of the specified annotation, walking up the inheritance + * tree if necessary. + * + * <p>Note that i18n annotations may appear on classes as well as interfaces + * (a concrete implementation can be supplied rather than just an interface + * and this is the normal way of using generic Localizable interfaces), so + * we have to search the super chain as well as other interfaces. + * + * <p>The super chain is walked first, so if an ancestor superclass has the + * requested annotation, it will be preferred over a directly implemented + * interface. + * + * @param <T> Annotation type to search for + * @param clazz root class to search, may be null + * @param annotationClass class object of Annotation subclass to search for + * @return the requested annotation or null if none + */ + static <T extends Annotation> T getClassAnnotation(JClassType clazz, + Class<T> annotationClass) { + if (clazz == null) { + return null; + } + T annot = clazz.getAnnotation(annotationClass); + if (annot == null) { + annot = getClassAnnotation(clazz.getSuperclass(), annotationClass); + if (annot != null) { + return annot; + } + for (JClassType intf : clazz.getImplementedInterfaces()) { + annot = getClassAnnotation(intf, annotationClass); + if (annot != null) { + return annot; + } + } + } + return annot; + } + +} Property changes on: user/src/com/google/gwt/i18n/rebind/AnnotationUtil.java ___________________________________________________________________ Name: svn:mime-type + text/x-java Name: svn:eol-style + native