Revision: 9208
Author: [email protected]
Date: Wed Nov 10 08:12:36 2010
Log: This patch makes three changes:
1. Excludes the client-side validation from being analyzed by api checker.
Will
remove this unnecessary exclusion once
http://code.google.com/p/google-web-toolkit/issues/detail?id=5566 is
resolved.
Currently, because of this bug there is a lot of console spew from
typeOracle
unable to find sources.
2. Removes the unnecessary entry from the white-list. The entry is removed
because even prior to the addition of HTML(SafeHtml ..) call to the HTML
class
in 2.1, the class had two constructors, so a call like new HTML(null)
wouldn't
have compiled before. There is no API breakage because of this new
constructor.
3. Adds a unit test to exercise the case above.
Patch by: amitmanjhi
Review by: jat
Review at http://gwt-code-reviews.appspot.com/1093801
http://code.google.com/p/google-web-toolkit/source/detail?r=9208
Modified:
/trunk/tools/api-checker/config/gwt20_21userApi.conf
/trunk/tools/api-checker/test/com/google/gwt/tools/apichecker/ApiCompatibilityUnitTest.java
=======================================
--- /trunk/tools/api-checker/config/gwt20_21userApi.conf Fri Nov 5
04:25:19 2010
+++ /trunk/tools/api-checker/config/gwt20_21userApi.conf Wed Nov 10
08:12:36 2010
@@ -59,6 +59,8 @@
:user/super\
#excludedFiles is specified as colon-separated ant patterns
+# The last 3 entries exclude the validation stuff.
+# Bug: http://code.google.com/p/google-web-toolkit/issues/detail?id=5566
excludedFiles_new user/src/com/google/gwt/benchmarks/BenchmarkReport.java\
:user/src/com/google/gwt/benchmarks/BenchmarkShell.java\
:user/src/com/google/gwt/benchmarks/client/Benchmark.java\
@@ -87,6 +89,9 @@
:user/src/com/google/gwt/uibinder/elementparsers\
:user/src/com/google/gwt/uibinder/testing\
:user/src/com/google/gwt/util/regexfilter\
+:user/src/javax\
+:user/src/org\
+:user/src/com/google/gwt/validation/
##############################################
#excluded packages
@@ -127,7 +132,6 @@
com.google.gwt.user.client.ui.CheckBox::setHTML(Ljava/lang/String;)
OVERLOADED_METHOD_CALL
com.google.gwt.user.client.ui.CustomButton::setHTML(Ljava/lang/String;)
OVERLOADED_METHOD_CALL
com.google.gwt.user.client.ui.DialogBox::setHTML(Ljava/lang/String;)
OVERLOADED_METHOD_CALL
-com.google.gwt.user.client.ui.HTML::HTML(Ljava/lang/String;Z)
OVERLOADED_METHOD_CALL
com.google.gwt.user.client.ui.HTML::setHTML(Ljava/lang/String;)
OVERLOADED_METHOD_CALL
com.google.gwt.user.client.ui.HTMLPanel::HTMLPanel(Ljava/lang/String;)
OVERLOADED_METHOD_CALL
com.google.gwt.user.client.ui.HTMLTable::setHTML(IILjava/lang/String;)
OVERLOADED_METHOD_CALL
=======================================
---
/trunk/tools/api-checker/test/com/google/gwt/tools/apichecker/ApiCompatibilityUnitTest.java
Mon Nov 9 19:37:01 2009
+++
/trunk/tools/api-checker/test/com/google/gwt/tools/apichecker/ApiCompatibilityUnitTest.java
Wed Nov 10 08:12:36 2010
@@ -100,6 +100,71 @@
}
}
+ /**
+ * Test when constructor overloading results in Api incompatibilities.
+ * <p>
+ * Imagine a class Foo had a constructor Foo(String ..). If in the new
Api, a
+ * constructor Foo(Integer ..) is added, ApiChecker should output a
+ * OVERLOADED_METHOD_CALL Api change (because Foo(null) cannot be
compiled).
+ * However, if Foo(Object ..) is added, it should be okay since JLS
matches
+ * from the most specific to the least specific.
+ */
+ private static class OverloadedConstructorRefactoring {
+ private static String getFirstApiSourceForObject() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("package java.lang;\n");
+ sb.append("public class Object {\n");
+ sb.append("\tpublic static class Foo extends java.lang.Object {\n");
+ sb.append("\tpublic Foo(Foo x){}\n");
+ sb.append("\t}\n");
+ sb.append("\tpublic static class Bar extends java.lang.Object {\n");
+ sb.append("\tpublic Bar(Bar y){}\n");
+ sb.append("\t}\n");
+ sb.append("}\n");
+ return sb.toString();
+ }
+
+ private static String getSecondApiSourceForObject() {
+ StringBuffer sb = new StringBuffer();
+ sb.append("package java.lang;\n");
+ sb.append("public class Object {\n");
+ sb.append("\tpublic static class Foo extends java.lang.Object {\n");
+ sb.append("\tpublic Foo(Foo x){}\n");
+ sb.append("\tpublic Foo(Object x){}\n");
+ sb.append("\t}\n");
+ sb.append("\tpublic static class Bar extends java.lang.Object {\n");
+ sb.append("\tpublic Bar(Bar y){}\n");
+ sb.append("\tpublic Bar(Foo y){}\n");
+ sb.append("\t}\n");
+ sb.append("}\n");
+ return sb.toString();
+ }
+
+ void testBothWays() throws NotFoundException,
UnableToCompleteException {
+ Map<String, String> firstApi = new HashMap<String, String>();
+ firstApi.put("java.lang.Object", getFirstApiSourceForObject());
+ Map<String, String> secondApi = new HashMap<String, String>();
+ secondApi.put("java.lang.Object", getSecondApiSourceForObject());
+
+ // firstApi is the reference Api
+ Collection<ApiChange> apiChanges = getApiChanges(firstApi,
secondApi);
+ assertEquals(
+ Arrays.asList(new ApiChange[] {new ApiChange(new MockApiElement(
+ "java.lang.Object.Bar::Bar(Ljava/lang/Object$Bar;)"),
+ ApiChange.Status.OVERLOADED_METHOD_CALL),}), apiChanges);
+
+ // secondApi is the reference Api
+ apiChanges = getApiChanges(secondApi, firstApi);
+ assertEquals(Arrays.asList(new ApiChange[] {
+ new ApiChange(new MockApiElement(
+ "java.lang.Object.Foo::Foo(Ljava/lang/Object;)"),
+ ApiChange.Status.MISSING),
+ new ApiChange(new MockApiElement(
+ "java.lang.Object.Bar::Bar(Ljava/lang/Object$Foo;)"),
+ ApiChange.Status.MISSING),}), apiChanges);
+ }
+ }
+
/**
* Test when method overloading results in Api incompatibilities.
* <p>
@@ -281,6 +346,11 @@
return ApiCompatibilityChecker.getApiDiff(newApi, existingApi,
emptyList);
}
+ public void testConstructorOverloading() throws NotFoundException,
+ UnableToCompleteException {
+ new OverloadedConstructorRefactoring().testBothWays();
+ }
+
public void testFinalKeywordRefactoring() throws NotFoundException,
UnableToCompleteException {
new FinalKeywordRefactoring().testBothWays();
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors