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()); } }