Merge through trunk@6239
git-svn-id: https://google-web-toolkit.googlecode.com/svn/branches/farewellSwt@6253 8db76d5a-ed1c-0410-87a9-c151d255dfc7
diff --git a/branch-info.txt b/branch-info.txt
index 3e01cb9..8ba9e9b 100644
--- a/branch-info.txt
+++ b/branch-info.txt
@@ -11,3 +11,5 @@
svn merge --ignore-ancestry -r6142:6200 \
https://google-web-toolkit.googlecode.com/svn/trunk
(via changes/jat/noswt-merge6200)
+svn merge https://google-web-toolkit.googlecode.com/svn/trunk \
+ -r6200:6239 .
diff --git a/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java b/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java
index 81f5e9f..1310630 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/ast/JTypeOracle.java
@@ -448,7 +448,6 @@
}
}
}
- jsoSubType.clearImplements();
}
}
diff --git a/dev/core/src/com/google/gwt/dev/jjs/impl/JavaScriptObjectNormalizer.java b/dev/core/src/com/google/gwt/dev/jjs/impl/JavaScriptObjectNormalizer.java
index 3535af3..0760216 100644
--- a/dev/core/src/com/google/gwt/dev/jjs/impl/JavaScriptObjectNormalizer.java
+++ b/dev/core/src/com/google/gwt/dev/jjs/impl/JavaScriptObjectNormalizer.java
@@ -58,7 +58,8 @@
public void endVisit(JCastOperation x, Context ctx) {
JType newType = translate(x.getCastType());
if (newType != x.getCastType()) {
- ctx.replaceMe(new JCastOperation(x.getSourceInfo(), newType, x.getExpr()));
+ ctx.replaceMe(new JCastOperation(x.getSourceInfo(), newType,
+ x.getExpr()));
}
}
@@ -135,8 +136,8 @@
CloneExpressionVisitor cloner = new CloneExpressionVisitor(program);
// instance.jsoMethod(arg, arg)
- JMethodCall jsoCall = new JMethodCall(info, cloner.cloneExpression(instance),
- jsoMethod);
+ JMethodCall jsoCall = new JMethodCall(info,
+ cloner.cloneExpression(instance), jsoMethod);
jsoCall.addArgs(cloner.cloneExpressions(x.getArgs()));
// Cast.isJavaScriptObject() ? instance.jsoMethod() :
@@ -152,7 +153,8 @@
* ... otherwise, if there's only a JSO implementation, we'll just
* call that directly.
*/
- JMethodCall jsoCall = new JMethodCall(info, x.getInstance(), jsoMethod);
+ JMethodCall jsoCall = new JMethodCall(info, x.getInstance(),
+ jsoMethod);
jsoCall.addArgs(x.getArgs());
ctx.replaceMe(jsoCall);
}
@@ -177,13 +179,21 @@
private JMethod findConcreteImplementation(JMethod method,
JClassType concreteType) {
- for (JMethod m : concreteType.getMethods()) {
- if (program.typeOracle.getAllOverrides(m).contains(method)) {
- if (!m.isAbstract()) {
- return m;
+ /*
+ * Search supertypes for virtual overrides via subclass. See the javadoc
+ * on JTypeOracle.getAllVirtualOverrides for an example.
+ */
+ while (concreteType != null) {
+ for (JMethod m : concreteType.getMethods()) {
+ if (program.typeOracle.getAllOverrides(m).contains(method)) {
+ if (!m.isAbstract()) {
+ return m;
+ }
}
}
+ concreteType = concreteType.getSuperClass();
}
+
return null;
}
@@ -205,7 +215,8 @@
JExpression notJsoExpr) {
// Cast.isJavaScriptObjectOrString(instance)
JMethod isJavaScriptObjectMethod = program.getIndexedMethod("Cast.isJavaScriptObjectOrString");
- JMethodCall isJavaScriptObjectExpr = new JMethodCall(info, null, isJavaScriptObjectMethod);
+ JMethodCall isJavaScriptObjectExpr = new JMethodCall(info, null,
+ isJavaScriptObjectMethod);
isJavaScriptObjectExpr.addArg(instance);
return new JConditional(info, conditionalType, isJavaScriptObjectExpr,
isJsoExpr, notJsoExpr);
diff --git a/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java b/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java
index 0815fad..14f1a4c 100644
--- a/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java
+++ b/dev/core/src/com/google/gwt/dev/shell/CompilingClassLoader.java
@@ -36,9 +36,9 @@
import com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter;
import com.google.gwt.dev.shell.rewrite.HostedModeClassRewriter.InstanceMethodOracle;
import com.google.gwt.dev.util.JsniRef;
-import com.google.gwt.dev.util.Name.SourceOrBinaryName;
-import com.google.gwt.dev.util.Name.InternalName;
import com.google.gwt.dev.util.Util;
+import com.google.gwt.dev.util.Name.InternalName;
+import com.google.gwt.dev.util.Name.SourceOrBinaryName;
import com.google.gwt.util.tools.Utility;
import org.apache.commons.collections.map.AbstractReferenceMap;
@@ -911,6 +911,21 @@
String mangledName = getBinaryName(type).replace('.', '_') + "_"
+ m.getName();
+ JType[] parameterTypes = new JType[m.getParameters().length];
+ for (int i = 0; i < parameterTypes.length; i++) {
+ parameterTypes[i] = m.getParameters()[i].getType();
+ }
+
+ /*
+ * Handle virtual overrides by finding the method that we would normally
+ * invoke and using its declaring class as the dispatch target.
+ */
+ while (implementingType.findMethod(m.getName(), parameterTypes) == null) {
+ implementingType = implementingType.getSuperclass();
+ }
+ assert implementingType != null : "Unable to find virtual override for "
+ + m.toString();
+
/*
* Cook up the a pseudo-method declaration for the concrete type. This
* should look something like
@@ -921,9 +936,9 @@
*/
String decl = getBinaryOrPrimitiveName(m.getReturnType()) + " "
+ m.getName() + "$ (" + getBinaryOrPrimitiveName(implementingType);
- for (JParameter p : m.getParameters()) {
+ for (JType paramType : parameterTypes) {
decl += ",";
- decl += getBinaryOrPrimitiveName(p.getType());
+ decl += getBinaryOrPrimitiveName(paramType);
}
decl += ")";
diff --git a/distro-source/core/src/release_notes.html b/distro-source/core/src/release_notes.html
index a765f4c..ba04040 100644
--- a/distro-source/core/src/release_notes.html
+++ b/distro-source/core/src/release_notes.html
@@ -28,28 +28,86 @@
<body>
<h1>Google Web Toolkit Release Notes</h1>
<ul>
- <li><a href="#Release_Notes_Current">@GWT_VERSION@</a></li>
+ <li><a href="#Release_Notes_Current">@GWT_VERSION@</a></li>
+ <li><a href="#Release_Notes_1_7_0">1.7.0</a></li>
+ <li><a href="#Release_Notes_1_6_4">1.6.4</a></li>
<li><a href="#Release_Notes_1_6_3">1.6.3</a></li>
- <li><a href="#Release_Notes_1_6_2">1.6.2</a></li>
- <li><a href="#Release_Notes_1_5_3">1.5.3</a></li>
- <li><a href="#Release_Notes_1_5_2">1.5.2</a></li>
- <li><a href="#Release_Notes_1_5_1">1.5.1 (RC2)</a></li>
- <li><a href="#Release_Notes_1_5_0">1.5.0 (RC)</a></li>
- <li><a href="#Release_Notes_1_4_60">1.4.60</a></li>
- <li><a href="#Release_Notes_1_4_59">1.4.59 (RC2)</a></li>
- <li><a href="#Release_Notes_1_4_10">1.4.10 (RC)</a></li>
- <li><a href="#Release_Notes_1_3_3">1.3.3</a></li>
- <li><a href="#Release_Notes_1_3_1">1.3.1 (RC)</a></li>
- <li><a href="#Release_Notes_1_2_22">1.2.22</a></li>
- <li><a href="#Release_Notes_1_2_11">1.2.21 (RC)</a></li>
- <li><a href="#Release_Notes_1_1_10">1.1.10</a></li>
- <li><a href="#Release_Notes_1_1_0">1.1.0 (RC)</a></li>
- <li><a href="#Release_Notes_1_0_21">1.0.21</a></li>
+ <li><a href="#Release_Notes_1_6_2">1.6.2</a></li>
+ <li><a href="#Release_Notes_1_5_3">1.5.3</a></li>
+ <li><a href="#Release_Notes_1_5_2">1.5.2</a></li>
+ <li><a href="#Release_Notes_1_5_1">1.5.1 (RC2)</a></li>
+ <li><a href="#Release_Notes_1_5_0">1.5.0 (RC)</a></li>
+ <li><a href="#Release_Notes_1_4_60">1.4.60</a></li>
+ <li><a href="#Release_Notes_1_4_59">1.4.59 (RC2)</a></li>
+ <li><a href="#Release_Notes_1_4_10">1.4.10 (RC)</a></li>
+ <li><a href="#Release_Notes_1_3_3">1.3.3</a></li>
+ <li><a href="#Release_Notes_1_3_1">1.3.1 (RC)</a></li>
+ <li><a href="#Release_Notes_1_2_22">1.2.22</a></li>
+ <li><a href="#Release_Notes_1_2_11">1.2.21 (RC)</a></li>
+ <li><a href="#Release_Notes_1_1_10">1.1.10</a></li>
+ <li><a href="#Release_Notes_1_1_0">1.1.0 (RC)</a></li>
+ <li><a href="#Release_Notes_1_0_21">1.0.21</a></li>
</ul>
<hr/>
<a name="Release_Notes_Current"></a>
<h2>Release Notes for @GWT_VERSION@</h2>
+ <p>
+ This release adds support for Mac OS X version 10.6 (Snow Leopard) by allowing hosted mode to run with a 1.6 JRE in 32-bit
+ mode (using the -d32 flag).
+ </p>
+ <h3>Fixed Issues</h3>
+ <ul>
+ <li>
+ Allow hosted mode using a 1.6 JRE with the -d32 flag
+ (<a href="http://code.google.com/p/google-web-toolkit/issues/detail?id=3843">#3843</a>,
+ <a href="http://code.google.com/p/google-web-toolkit/issues/detail?id=3998">#3998</a>)
+ </li>
+ </ul>
+
+ <hr/>
+ <a name="Release_Notes_1_7_0"></a>
+ <h2>Release Notes for 1.7.0</h2>
+ <p>
+ This release adds explicit support for Internet Explorer 8, Firefox 3.5, and Safari 4 as well as a few high-priority bug fixes.
+ In all other respects, it is very similar to GWT 1.6.
+ Note, however, that this release is version 1.7.0 rather than version 1.6.5 to signify a potentially breaking change for libraries
+ that use deferred binding to specialize code based on user agent (see the next section for technical details).
+ </p>
+ <h3>Potentially breaking changes and fixes</h3>
+ <ul>
+ <li>
+ This release includes explicit support for IE8, which has some significant behavioral changes from prior versions of IE.
+ These changes are great enough that the new value <code>ie8</code> has been added for the <code>user.agent</code> deferred binding client property.
+ If you have deferred binding rules (i.e. <code><replace-with></code> or <code><generate-with></code>) or property providers
+ that are sensitive to <code>user.agent</code>, you may need to update them to account for the <code>ie8</code> value.
+ For more information, see the <a href="http://code.google.com/p/google-web-toolkit/wiki/IE8Support">technical notes</a>.
+ </li>
+ </ul>
+
+ <h3>Fixed Issues</h3>
+ <ul>
+ <li>
+ Updated GWT libraries to support IE8
+ (<a href="http://code.google.com/p/google-web-toolkit/issues/detail?id=3558">#3558</a>,
+ <a href="http://code.google.com/p/google-web-toolkit/issues/detail?id=3329">#3329</a>)
+ </li>
+ <li>Native exception in Node.is() (<a href="http://code.google.com/p/google-web-toolkit/issues/detail?id=3644">#3644</a>)</li>
+ <li>
+ Incorrect firing of two click events from CheckBox and a related issue
+ (<a href="http://code.google.com/p/google-web-toolkit/issues/detail?id=3508">#3508</a>,
+ <a href="http://code.google.com/p/google-web-toolkit/issues/detail?id=3679">#3679</a>)
+ </li>
+ <li>Compiler java.lang.StackOverflowError if you don't use -Xss to set a stack size (<a href="http://code.google.com/p/google-web-toolkit/issues/detail?id=3510">#3510</a>)</li>
+ <li>Mouse wheel in FF3 (<a href="http://code.google.com/p/google-web-toolkit/issues/detail?id=2902">#2902</a>)</li>
+ <li>GWT outputs expressions too long for WebKit (<a href="http://code.google.com/p/google-web-toolkit/issues/detail?id=3455">#3455</a>)</li>
+ <li>java.sql.Date.valueOf error (<a href="http://code.google.com/p/google-web-toolkit/issues/detail?id=3731">#3731</a>)</li>
+ <li>Added a workaround for Firefox 3.5 regression (<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=497780">bugzilla #497780</a>)</li>
+ </ul>
+
+ <hr/>
+ <a name="Release_Notes_1_6_4"></a>
+ <h2>Release Notes for 1.6.4</h2>
<h3>Fixed Issues</h3>
<ul>
<li>The classpath in the scripts created by junitCreator was updated to refer to <code>/war/WEB-INF/classes</code> rather than <code>/bin</code>.</li>
diff --git a/user/src/com/google/gwt/junit/JUnitMessageQueue.java b/user/src/com/google/gwt/junit/JUnitMessageQueue.java
index 57ccd4a..c5a2d10 100644
--- a/user/src/com/google/gwt/junit/JUnitMessageQueue.java
+++ b/user/src/com/google/gwt/junit/JUnitMessageQueue.java
@@ -306,7 +306,7 @@
buf.append('\n');
}
- if (!results.containsKey(clientStatus.clientId)) {
+ if (results == null || !results.containsKey(clientStatus.clientId)) {
buf.append(" - NO RESPONSE: ");
} else {
buf.append(" - (ok): ");
diff --git a/user/src/com/google/gwt/resources/rg/CssResourceGenerator.java b/user/src/com/google/gwt/resources/rg/CssResourceGenerator.java
index 8295ad6..adbf29c 100644
--- a/user/src/com/google/gwt/resources/rg/CssResourceGenerator.java
+++ b/user/src/com/google/gwt/resources/rg/CssResourceGenerator.java
@@ -1,12 +1,12 @@
/*
* 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
@@ -97,7 +97,6 @@
import java.util.SortedSet;
import java.util.TreeSet;
import java.util.regex.Matcher;
-import java.util.regex.Pattern;
import java.util.zip.Adler32;
/**
@@ -105,21 +104,59 @@
*/
public final class CssResourceGenerator extends AbstractResourceGenerator {
static class ClassRenamer extends CssVisitor {
- private final Map<JMethod, String> actualReplacements = new IdentityHashMap<JMethod, String>();
/**
- * This is a map of local prefixes to the obfuscated names of imported
- * methods. If a CssResource makes use of the {@link Import} annotation, the
- * keys of this map will correspond to the {@link ImportedWithPrefix} value
- * defined on the imported CssResource. The zero-length string key holds the
- * obfuscated names for the CssResource that is being generated.
+ * A tag to indicate that an externally-defined CSS class has no JMethod
+ * that is used to access it.
*/
- private final Map<String, Map<JMethod, String>> classReplacementsWithPrefix;
+ private static final Replacement UNREFERENCED_EXTERNAL = new Replacement(
+ null, null);
+
+ /*
+ * TODO: Replace with Pair<A, B>.
+ */
+ private static class Replacement {
+
+ private JMethod method;
+ private String obfuscatedClassName;
+
+ public Replacement(JMethod method, String obfuscatedClassName) {
+ this.method = method;
+ this.obfuscatedClassName = obfuscatedClassName;
+ }
+
+ public JMethod getMethod() {
+ return method;
+ }
+
+ public String getObfuscatedClassName() {
+ return obfuscatedClassName;
+ }
+
+ /**
+ * For debugging use only.
+ */
+ public String toString() {
+ if (this == UNREFERENCED_EXTERNAL) {
+ return "Unreferenced external class name";
+ } else {
+ return method.getName() + "=" + obfuscatedClassName;
+ }
+ }
+ }
+
+ /**
+ * Records replacements that have actually been performed.
+ */
+ private final Map<JMethod, String> actualReplacements = new IdentityHashMap<JMethod, String>();
private final Set<String> cssDefs = new HashSet<String>();
- private final Set<String> externalClasses;
+
+ /**
+ * The task-list of replacements to perform in the stylesheet.
+ */
+ private final Map<String, Replacement> potentialReplacements;
private final TreeLogger logger;
private final Set<JMethod> missingClasses;
- private final Set<String> replacedClasses = new HashSet<String>();
private final boolean strict;
private final Set<String> unknownClasses = new HashSet<String>();
@@ -127,9 +164,10 @@
Map<String, Map<JMethod, String>> classReplacementsWithPrefix,
boolean strict, Set<String> externalClasses) {
this.logger = logger.branch(TreeLogger.DEBUG, "Replacing CSS class names");
- this.classReplacementsWithPrefix = classReplacementsWithPrefix;
this.strict = strict;
- this.externalClasses = externalClasses;
+
+ potentialReplacements = computeReplacements(classReplacementsWithPrefix,
+ externalClasses);
// Require a definition for all classes in the default namespace
assert classReplacementsWithPrefix.containsKey("");
@@ -144,56 +182,45 @@
@Override
public void endVisit(CssSelector x, Context ctx) {
+
String sel = x.getSelector();
+ int originalLength = sel.length();
- // TODO This would be simplified by having a class hierarchy for selectors
- for (Map.Entry<String, Map<JMethod, String>> outerEntry : classReplacementsWithPrefix.entrySet()) {
- String prefix = outerEntry.getKey();
- for (Map.Entry<JMethod, String> entry : outerEntry.getValue().entrySet()) {
- JMethod method = entry.getKey();
- String sourceClassName = method.getName();
- String obfuscatedClassName = entry.getValue();
+ Matcher ma = CssSelector.CLASS_SELECTOR_PATTERN.matcher(sel);
+ StringBuilder sb = new StringBuilder(originalLength);
+ int start = 0;
- ClassName className = method.getAnnotation(ClassName.class);
- if (className != null) {
- sourceClassName = className.value();
- }
+ while (ma.find()) {
+ String sourceClassName = ma.group(1);
- sourceClassName = prefix + sourceClassName;
+ Replacement entry = potentialReplacements.get(sourceClassName);
- Pattern p = Pattern.compile("(.*)\\.("
- + Pattern.quote(sourceClassName) + ")([ :>+#.].*|$)");
- Matcher m = p.matcher(sel);
- if (m.find()) {
- if (externalClasses.contains(sourceClassName)) {
- actualReplacements.put(method, sourceClassName);
- } else {
- sel = m.group(1) + "." + obfuscatedClassName + m.group(3);
- actualReplacements.put(method, obfuscatedClassName);
- }
+ if (entry == null) {
+ unknownClasses.add(sourceClassName);
+ continue;
- missingClasses.remove(method);
- if (strict) {
- replacedClasses.add(obfuscatedClassName);
- }
- }
+ } else if (entry == UNREFERENCED_EXTERNAL) {
+ // An @external without an accessor method. This is OK.
+ continue;
}
+
+ JMethod method = entry.getMethod();
+ String obfuscatedClassName = entry.getObfuscatedClassName();
+
+ // Consume the interstitial portion of the original selector
+ sb.append(sel.subSequence(start, ma.start(1)));
+ sb.append(obfuscatedClassName);
+ start = ma.end(1);
+
+ actualReplacements.put(method, obfuscatedClassName);
+ missingClasses.remove(method);
}
- sel = sel.trim();
-
- if (strict) {
- Matcher m = CssSelector.CLASS_SELECTOR_PATTERN.matcher(sel);
- while (m.find()) {
- String classSelector = m.group(1);
- if (!replacedClasses.contains(classSelector)
- && !externalClasses.contains(classSelector)) {
- unknownClasses.add(classSelector);
- }
- }
+ if (start != 0) {
+ // Consume the remainder and update the selector
+ sb.append(sel.subSequence(start, originalLength));
+ x.setSelector(sb.toString());
}
-
- x.setSelector(sel);
}
@Override
@@ -245,9 +272,66 @@
}
}
+ /**
+ * Reports the replacements that were actually performed by this visitor.
+ */
public Map<JMethod, String> getReplacements() {
return actualReplacements;
}
+
+ /**
+ * Flatten class name lookups to speed selector rewriting.
+ *
+ * @param classReplacementsWithPrefix a map of local prefixes to the
+ * obfuscated names of imported methods. If a CssResource makes use
+ * of the {@link Import} annotation, the keys of this map will
+ * correspond to the {@link ImportedWithPrefix} value defined on
+ * the imported CssResource. The zero-length string key holds the
+ * obfuscated names for the CssResource that is being generated.
+ * @return A flattened version of the classReplacementWithPrefix map, where
+ * the keys are the source class name (with prefix included), and
+ * values have the obfuscated class name and associated JMethod.
+ */
+ private Map<String, Replacement> computeReplacements(
+ Map<String, Map<JMethod, String>> classReplacementsWithPrefix,
+ Set<String> externalClasses) {
+
+ Map<String, Replacement> toReturn = new HashMap<String, Replacement>();
+
+ for (String externalClass : externalClasses) {
+ toReturn.put(externalClass, UNREFERENCED_EXTERNAL);
+ }
+
+ for (Map.Entry<String, Map<JMethod, String>> outerEntry : classReplacementsWithPrefix.entrySet()) {
+ String prefix = outerEntry.getKey();
+
+ for (Map.Entry<JMethod, String> entry : outerEntry.getValue().entrySet()) {
+ JMethod method = entry.getKey();
+ String sourceClassName = method.getName();
+ String obfuscatedClassName = entry.getValue();
+
+ ClassName className = method.getAnnotation(ClassName.class);
+ if (className != null) {
+ sourceClassName = className.value();
+ }
+
+ sourceClassName = prefix + sourceClassName;
+
+ if (externalClasses.contains(sourceClassName)) {
+ /*
+ * It simplifies the sanity-checking logic to treat external classes
+ * as though they were simply obfuscated to exactly the value the
+ * user wants.
+ */
+ obfuscatedClassName = sourceClassName;
+ }
+
+ toReturn.put(sourceClassName, new Replacement(method,
+ obfuscatedClassName));
+ }
+ }
+ return Collections.unmodifiableMap(toReturn);
+ }
}
static class DefsCollector extends CssVisitor {
@@ -1086,7 +1170,7 @@
* Very large concatenation expressions using '+' cause the GWT compiler to
* overflow the stack due to deep AST nesting. The workaround for now is to
* force it to be more balanced using intermediate concatenation groupings.
- *
+ *
* This variable is used to track the number of subexpressions within the
* current parenthetical expression.
*/
@@ -1159,7 +1243,7 @@
/**
* Check if number of concat expressions currently exceeds limit and either
* append '+' if the limit isn't reached or ') + (' if it is.
- *
+ *
* @return numExpressions + 1 or 0 if limit was exceeded.
*/
private static int concatOp(int numExpressions, StringBuilder b) {
@@ -1439,7 +1523,8 @@
name = classNameOverride.value();
}
- String obfuscatedClassName = classPrefix + makeIdent(classCounter.next());
+ String obfuscatedClassName = classPrefix
+ + makeIdent(classCounter.next());
if (prettyOutput) {
obfuscatedClassName += "-"
+ type.getQualifiedSourceName().replaceAll("[.$]", "-") + "-"
@@ -1571,7 +1656,7 @@
* result regardless of the order in which the generators fired. (It no
* longer behaves that way, as that scheme prevented the generation of new
* CssResource interfaces, but the complexity lives on.)
- *
+ *
* TODO(rjrjr,bobv) These days scottb tells us we're guaranteed that the
* recompiling the same code will fire the generators in a consistent order,
* so the old gymnastics aren't really justified anyway. It would probably
@@ -1657,7 +1742,7 @@
/**
* Create a Java expression that evaluates to the string representation of the
* stylesheet resource.
- *
+ *
* @param actualReplacements An out parameter that will be populated by the
* obfuscated class names that should be used for the particular
* instance of the CssResource, based on any substitution
diff --git a/user/src/com/google/gwt/uibinder/rebind/GwtResourceEntityResolver.java b/user/src/com/google/gwt/uibinder/rebind/GwtResourceEntityResolver.java
index c93dbd3..8dad0ec 100644
--- a/user/src/com/google/gwt/uibinder/rebind/GwtResourceEntityResolver.java
+++ b/user/src/com/google/gwt/uibinder/rebind/GwtResourceEntityResolver.java
@@ -1,12 +1,12 @@
/*
* Copyright 2009 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
@@ -25,13 +25,13 @@
/**
* Does special handling of external entities encountered by sax xml parser,
* e.g. the uri in
- *
+ *
* <pre>
- * <!DOCTYPE gwt:UiBinder
- SYSTEM "http://google-web-toolkit.googlecode.com/svn/resources/xhtml.ent"></pre>
+ * <!DOCTYPE gwt:UiBinder
+ SYSTEM "http://google-web-toolkit.googlecode.com/files/xhtml.ent"></pre>
* <p>
* Specifically, if the requested uri starts with
- * <code>http://google-web-toolkit.googlecode.com/svn/resources</code>, provide
+ * <code>http://google-web-toolkit.googlecode.com/files</code>, provide
* the contents from a built in resource rather than allowing sax to make a
* network request.
*/
@@ -40,9 +40,9 @@
InputStream fetch(String name);
}
- private static final String EXTERNAL_ENTITY_PREFIX = "http://google-web-toolkit.googlecode.com/svn/resources";
+ private static final String EXTERNAL_ENTITY_PREFIX = "http://google-web-toolkit.googlecode.com/files/";
- private static final String RESOURCES = "com/google/gwt/uibinder/resources";
+ private static final String RESOURCES = "com/google/gwt/uibinder/resources/";
private final ResourceLoader resourceLoader;
@@ -87,4 +87,4 @@
inputSource.setSystemId(systemId);
return inputSource;
}
-}
\ No newline at end of file
+}
diff --git a/user/src/com/google/gwt/uibinder/resources/xhtml.ent b/user/src/com/google/gwt/uibinder/resources/xhtml.ent
index aa80147..1c5183f 100644
--- a/user/src/com/google/gwt/uibinder/resources/xhtml.ent
+++ b/user/src/com/google/gwt/uibinder/resources/xhtml.ent
@@ -6,12 +6,22 @@
-->
<!--
- This is the complete set of named character entites defined in XHTML1.0. It's
- essentially a union of:
+ This is the complete set of named character entites defined in
+ XHTML1.0. Though this file was created for the convenience of users
+ of the Google Web Toolkit, it should be useful for any XML
+ document. It's essentially a union of:
http://www.w3.org/TR/xhtml1/DTD/xhtml-lat1.ent
http://www.w3.org/TR/xhtml1/DTD/xhtml-special.ent
http://www.w3.org/TR/xhtml1/DTD/xhtml-symbol.ent
+
+ Sample usage:
+ <!DOCTYPE ui:UiBinder
+ SYSTEM "http://google-web-toolkit.googlecode.com/files/xhtml.ent">
+
+ This file is maintained at
+ <http://google-web-toolkit.googlecode.com/svn/trunk/user/src/com/google/gwt/uibinder/resources/xhtml.ent>. Changes
+ made to it must be propagated to the URL in the sample above.
-->
<!-- Latin-1 characters -->
@@ -208,7 +218,7 @@
existing ISO 8879 entity names. ISO 10646 character numbers
are given for each character, in hex. values are decimal
conversions of the ISO 10646 values and refer to the document
- character set. Names are Unicode names.
+ character set. Names are Unicode names.
-->
<!-- C0 Controls and Basic Latin -->
@@ -394,7 +404,7 @@
<!ENTITY uArr "⇑"> <!-- upwards double arrow, U+21D1 ISOamsa -->
<!ENTITY rArr "⇒"> <!-- rightwards double arrow,
U+21D2 ISOtech -->
- <!-- Unicode does not say this is the 'implies' character but does not have
+ <!-- Unicode does not say this is the 'implies' character but does not have
another character with this function so rArr can be used for 'implies'
as ISOtech suggests -->
<!ENTITY dArr "⇓"> <!-- downwards double arrow, U+21D3 ISOamsa -->
@@ -467,11 +477,11 @@
<!ENTITY rfloor "⌋"> <!-- right floor, U+230B ISOamsc -->
<!ENTITY lang "〈"> <!-- left-pointing angle bracket = bra,
U+2329 ISOtech -->
- <!-- lang is NOT the same character as U+003C 'less than sign'
+ <!-- lang is NOT the same character as U+003C 'less than sign'
or U+2039 'single left-pointing angle quotation mark' -->
<!ENTITY rang "〉"> <!-- right-pointing angle bracket = ket,
U+232A ISOtech -->
- <!-- rang is NOT the same character as U+003E 'greater than sign'
+ <!-- rang is NOT the same character as U+003E 'greater than sign'
or U+203A 'single right-pointing angle quotation mark' -->
<!-- Geometric Shapes -->
diff --git a/user/src/com/google/gwt/uibinder/sample/client/WidgetBasedUi.ui.xml b/user/src/com/google/gwt/uibinder/sample/client/WidgetBasedUi.ui.xml
index d16bb54..7f40dfd 100644
--- a/user/src/com/google/gwt/uibinder/sample/client/WidgetBasedUi.ui.xml
+++ b/user/src/com/google/gwt/uibinder/sample/client/WidgetBasedUi.ui.xml
@@ -14,7 +14,7 @@
-->
<!DOCTYPE ui:UiBinder
- SYSTEM "http://google-web-toolkit.googlecode.com/svn/resources/xhtml.ent"
+ SYSTEM "http://google-web-toolkit.googlecode.com/files/xhtml.ent"
[
<!ENTITY % MyEntities SYSTEM "MyEntities.ent">
%MyEntities;
@@ -26,13 +26,15 @@
First, this bit:
- SYSTEM "http://google-web-toolkit.googlecode.com/svn/trunk/resources/xhtml.ent"
+ SYSTEM "http://google-web-toolkit.googlecode.com/files/xhtml.ent"
allows you to use familiar HTML entities like %nbsp; and •,
which are not part of XML.
- Next, the bit in square brackets pulls in additional definitions for
- &point-left; and &point-right; from local file MyEntities.ent.
+ Next, the bit in square brackets is even more optional. It shows how
+ to add your own entities, in this case pulling in additional
+ definitions for &point-left; and &point-right; from local file
+ MyEntities.ent.
You don't have to be so verbose to include a local file! For
example, you might instead grab your own copy of xhtml.ent
diff --git a/user/test/com/google/gwt/dev/jjs/test/singlejso/TypeHierarchyTest.java b/user/test/com/google/gwt/dev/jjs/test/singlejso/TypeHierarchyTest.java
index b954f3e..80966f5 100644
--- a/user/test/com/google/gwt/dev/jjs/test/singlejso/TypeHierarchyTest.java
+++ b/user/test/com/google/gwt/dev/jjs/test/singlejso/TypeHierarchyTest.java
@@ -24,6 +24,16 @@
public class TypeHierarchyTest extends GWTTestCase {
/**
+ * Used with PlainJso and PlainJsoWithInterface to mix interfaces into
+ * existing base classes.
+ */
+ interface Arrayish {
+ int getLength();
+
+ JavaScriptObject getObject(int i);
+ }
+
+ /**
* The bottom type for a non-trivial diamond-shaped inheritance pattern.
*/
static class DiamondImpl extends JavaScriptObject implements IDiamond2A,
@@ -59,6 +69,35 @@
interface IDiamond2B extends IDiamond1 {
}
+ /**
+ * This is a base class that is used to test adding interfaces to a JSO via a
+ * subclass.
+ */
+ static class PlainJso extends JavaScriptObject {
+ protected PlainJso() {
+ }
+
+ public final native int getLength()/*-{
+ return this.length;
+ }-*/;
+
+ public final native JavaScriptObject getObject(int i) /*-{
+ return this[i];
+ }-*/;
+ }
+
+ /**
+ * We'll mix in an interface into PlainJso.
+ */
+ static class PlainJsoWithInterface extends PlainJso implements Arrayish {
+ public static PlainJsoWithInterface create() {
+ return JavaScriptObject.createArray().cast();
+ }
+
+ protected PlainJsoWithInterface() {
+ }
+ }
+
@Override
public String getModuleName() {
return "com.google.gwt.dev.jjs.CompilerSuite";
@@ -107,4 +146,10 @@
IDiamond2B d2b = DiamondImpl.create();
assertEquals(42, d2b.size());
}
+
+ public void testVirtualOverrides() {
+ Arrayish array = PlainJsoWithInterface.create();
+ assertEquals(0, array.getLength());
+ assertNull(array.getObject(0));
+ }
}
diff --git a/user/test/com/google/gwt/uibinder/rebind/GwtResourceEntityResolverTest.java b/user/test/com/google/gwt/uibinder/rebind/GwtResourceEntityResolverTest.java
index da630e7..5cf1b55 100644
--- a/user/test/com/google/gwt/uibinder/rebind/GwtResourceEntityResolverTest.java
+++ b/user/test/com/google/gwt/uibinder/rebind/GwtResourceEntityResolverTest.java
@@ -27,7 +27,8 @@
* Text of GwtResourceEntityResolver.
*/
public class GwtResourceEntityResolverTest extends TestCase {
-
+ private static final String SYSTEM_ID = "http://google-web-toolkit.googlecode.com/files/xhtml.ent";
+
private static class MockResourceLoader implements
GwtResourceEntityResolver.ResourceLoader {
String fetched;
@@ -37,7 +38,7 @@
return stream;
}
}
-
+
private GwtResourceEntityResolver resolver;
private MockResourceLoader loader;
@@ -46,27 +47,31 @@
super.setUp();
loader = new MockResourceLoader();
resolver = new GwtResourceEntityResolver(loader);
+
+ loader.stream = new InputStream() {
+ @Override
+ public int read() throws IOException {
+ throw new UnsupportedOperationException();
+ }
+ };
}
public void testNotOurProblem() throws SAXException, IOException {
assertNull(resolver.resolveEntity(null, "http://arbitrary"));
assertNull(resolver.resolveEntity("meaningless", "http://arbitrary"));
assertNull(resolver.resolveEntity(null, "arbitrary/relative"));
+
+ String almostCorrectAndOnceWorked = SYSTEM_ID.replace("files", "filesss");
+ assertNull(resolver.resolveEntity("meaningless", almostCorrectAndOnceWorked));
+ assertNull(resolver.resolveEntity(null, almostCorrectAndOnceWorked));
}
public void testOursGood() throws SAXException, IOException {
String publicId = "some old public thing";
- String systemId = "http://google-web-toolkit.googlecode.com/svn/resources/xhtml.ent";
- loader.stream = new InputStream() {
- @Override
- public int read() throws IOException {
- throw new UnsupportedOperationException();
- }
- };
-
- InputSource s = resolver.resolveEntity(publicId, systemId);
+
+ InputSource s = resolver.resolveEntity(publicId, SYSTEM_ID);
assertEquals(publicId, s.getPublicId());
- assertEquals(systemId, s.getSystemId());
+ assertEquals(SYSTEM_ID, s.getSystemId());
assertEquals(loader.stream, s.getByteStream());
}
}