Revision: 9422
Author: [email protected]
Date: Tue Dec 14 13:21:45 2010
Log: Have separate devmode.js files for each permutation if we are
outputting
bootstrap in the primary fragment so we can put the properties info in
them and avoid putting it in the primary fragment. Also, fail explicitly
when we encounter a script tag in the gwt.xml
rather than failing silently (xsiframe linker does not support this feature)
Review at http://gwt-code-reviews.appspot.com/1208802
http://code.google.com/p/google-web-toolkit/source/detail?r=9422
Added:
/trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/propertiesServerSide.js
Deleted:
/trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/propertiesNull.js
Modified:
/trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/PropertiesUtil.java
/trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/SelectionScriptLinker.java
/trunk/dev/core/src/com/google/gwt/core/linker/CrossSiteIframeLinker.java
/trunk/user/test/com/google/gwt/dev/jjs/CrossSiteIframeRunAsyncMetrics.gwt.xml
=======================================
--- /dev/null
+++
/trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/propertiesServerSide.js
Tue Dec 14 13:21:45 2010
@@ -0,0 +1,27 @@
+// Computes the value of a given property that was determined during the
+// compilation process. This assumes that the bootstrap is embedded in an
MD5
+// specific file, and during the compilation phase, the PermutationsUtil
class
+// will take care of filling the __KNOWN_PROPERTIES__ section with the
values
+// of the properties for this specific permutation. Note that if a
permutation
+// is valid for more than one property value (for example user.agent =
chrome
+// or safari) then one of those values will be chosen at random. Since the
+// different values resulted in the same MD5 file, we can assume that the
+// behavior of this module is the same for either value.
+
+ var properties = [];
+
+ function computePropValue(propName) {
+ if (propName in properties) {
+ return properties[propName];
+ }
+ throw null;
+ }
+
+ __KNOWN_PROPERTIES__
+
+ // It's unclear how/if this function is applicable in the context of the
+ // properties being selected on the server. Just return false for now.
+ __gwt_isKnownPropertyValue = function(propName, propValue) {
+ return false;
+ }
+ __MODULE_FUNC__.__computePropValue = computePropValue;
=======================================
---
/trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/propertiesNull.js
Tue Oct 12 16:00:43 2010
+++ /dev/null
@@ -1,4 +0,0 @@
- __gwt_isKnownPropertyValue = function(propName, propValue) {
- return false;
- }
- __MODULE_FUNC__.__computePropValue = null;
=======================================
---
/trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/PropertiesUtil.java
Tue Nov 23 06:49:43 2010
+++
/trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/PropertiesUtil.java
Tue Dec 14 13:21:45 2010
@@ -18,12 +18,37 @@
import com.google.gwt.core.ext.LinkerContext;
import com.google.gwt.core.ext.TreeLogger;
+import com.google.gwt.core.ext.linker.CompilationResult;
import com.google.gwt.core.ext.linker.SelectionProperty;
+import java.util.Map.Entry;
+
/**
* A utility class to fill in the properties javascript in linker
templates.
*/
public class PropertiesUtil {
+ public static String addKnownPropertiesJs(TreeLogger logger,
+ CompilationResult result) {
+ StringBuffer propertiesJs = new StringBuffer();
+
+ // Multiple values for a property can result in one permutation. For
+ // example, this permutation may be valid for safari and chrome.
However,
+ // we need to pick one, since the computePropValue() needs to return a
+ // single value. It actually doesn't matter which one we pick. The
fact
+ // that safari and chrome compiled into one permutation indicates that
+ // for this module, the behavior is the same. Therefore, we just pick
+ // the first one.
+ for (Entry<SelectionProperty, String> entry :
+ result.getPropertyMap().first().entrySet()) {
+ propertiesJs.append("properties['");
+ propertiesJs.append(entry.getKey().getName());
+ propertiesJs.append("'] = '");
+ propertiesJs.append(entry.getValue());
+ propertiesJs.append("';");
+ }
+ return propertiesJs.toString();
+ }
+
public static StringBuffer addPropertiesJs(StringBuffer selectionScript,
TreeLogger logger, LinkerContext context) {
int startPos;
@@ -38,7 +63,7 @@
}
}
return selectionScript;
- }
+ }
private static String generatePropertyProvider(SelectionProperty prop) {
StringBuffer toReturn = new StringBuffer();
=======================================
---
/trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/SelectionScriptLinker.java
Wed Nov 10 07:09:21 2010
+++
/trunk/dev/core/src/com/google/gwt/core/ext/linker/impl/SelectionScriptLinker.java
Tue Dec 14 13:21:45 2010
@@ -88,8 +88,6 @@
buf.replace(pos, pos + len, replace);
}
}
-
- private String selectionScriptText = null;
/**
* This method is left in place for existing subclasses of
@@ -116,6 +114,7 @@
*/
for (CompilationResult compilation :
toReturn.find(CompilationResult.class)) {
toReturn.addAll(doEmitCompilation(logger, context, compilation,
artifacts));
+ maybeAddHostedModeFile(logger, context, toReturn, compilation);
}
return toReturn;
} else {
@@ -126,7 +125,7 @@
toReturn.add(art);
}
maybeOutputPropertyMap(logger, context, toReturn);
- maybeAddHostedModeFile(logger, context, toReturn);
+ maybeAddHostedModeFile(logger, context, toReturn, null);
return toReturn;
}
}
@@ -156,7 +155,7 @@
}
toReturn.addAll(emitSelectionInformation(result.getStrongName(),
result));
-
+
return toReturn;
}
@@ -185,7 +184,8 @@
* have been scanned using {...@link #setupPermutationsMap(ArtifactSet)}.
*/
protected String fillSelectionScriptTemplate(StringBuffer
selectionScript,
- TreeLogger logger, LinkerContext context, ArtifactSet artifacts)
throws
+ TreeLogger logger, LinkerContext context, ArtifactSet artifacts,
+ CompilationResult result) throws
UnableToCompleteException {
String computeScriptBase;
String processMetas;
@@ -231,30 +231,35 @@
ArtifactSet artifacts) throws UnableToCompleteException {
TextOutput to = new DefaultTextOutput(context.isOutputCompact());
to.print(generatePrimaryFragmentString(
- logger, context, result.getStrongName(), js[0], js.length,
artifacts));
+ logger, context, result, js[0], js.length, artifacts));
return Util.getBytes(to.toString());
}
protected String generatePrimaryFragmentString(TreeLogger logger,
- LinkerContext context, String strongName, String js, int length,
+ LinkerContext context, CompilationResult result, String js, int
length,
ArtifactSet artifacts)
throws UnableToCompleteException {
StringBuffer b = new StringBuffer();
+ String strongName = result == null ? "" : result.getStrongName();
b.append(getModulePrefix(logger, context, strongName, length));
b.append(js);
b.append(getModuleSuffix(logger, context));
- return wrapPrimaryFragment(logger, context, b.toString(), artifacts);
+ return wrapPrimaryFragment(logger, context, b.toString(), artifacts,
result);
}
protected String generateSelectionScript(TreeLogger logger,
LinkerContext context, ArtifactSet artifacts) throws
UnableToCompleteException {
- if (selectionScriptText != null) {
- return selectionScriptText;
- }
+ return generateSelectionScript(logger, context, artifacts, null);
+ }
+
+ protected String generateSelectionScript(TreeLogger logger,
+ LinkerContext context, ArtifactSet artifacts, CompilationResult
result)
+ throws UnableToCompleteException {
+ String selectionScriptText;
StringBuffer buffer = readFileToStringBuffer(
getSelectionScriptTemplate(logger,context), logger);
selectionScriptText = fillSelectionScriptTemplate(
- buffer, logger, context, artifacts);
+ buffer, logger, context, artifacts, result);
selectionScriptText =
context.optimizeJavaScript(logger, selectionScriptText);
return selectionScriptText;
@@ -300,10 +305,10 @@
* Add the hosted file to the artifact set.
*/
protected void maybeAddHostedModeFile(TreeLogger logger,
- LinkerContext context, ArtifactSet artifacts)
+ LinkerContext context, ArtifactSet artifacts, CompilationResult
result)
throws UnableToCompleteException {
String hostedFilename = getHostedFilename();
- if ("".equals(hostedFilename)) {
+ if ("".equals(hostedFilename) || result != null) {
return;
}
try {
@@ -359,7 +364,8 @@
}
protected String wrapPrimaryFragment(TreeLogger logger,
- LinkerContext context, String script, ArtifactSet artifacts) {
+ LinkerContext context, String script, ArtifactSet artifacts,
+ CompilationResult result) {
return script;
}
=======================================
---
/trunk/dev/core/src/com/google/gwt/core/linker/CrossSiteIframeLinker.java
Mon Nov 8 06:50:50 2010
+++
/trunk/dev/core/src/com/google/gwt/core/linker/CrossSiteIframeLinker.java
Tue Dec 14 13:21:45 2010
@@ -20,12 +20,15 @@
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.linker.ArtifactSet;
+import com.google.gwt.core.ext.linker.CompilationResult;
import com.google.gwt.core.ext.linker.EmittedArtifact;
import com.google.gwt.core.ext.linker.EmittedArtifact.Visibility;
import com.google.gwt.core.ext.linker.LinkerOrder;
import com.google.gwt.core.ext.linker.LinkerOrder.Order;
+import com.google.gwt.core.ext.linker.ScriptReference;
import com.google.gwt.core.ext.linker.Shardable;
import com.google.gwt.core.ext.linker.impl.PropertiesMappingArtifact;
+import com.google.gwt.core.ext.linker.impl.PropertiesUtil;
import com.google.gwt.core.ext.linker.impl.ResourceInjectionUtil;
import com.google.gwt.core.ext.linker.impl.SelectionScriptLinker;
import com.google.gwt.dev.About;
@@ -54,8 +57,8 @@
@Override
protected String fillSelectionScriptTemplate(StringBuffer ss,
- TreeLogger logger, LinkerContext context, ArtifactSet artifacts)
throws
- UnableToCompleteException {
+ TreeLogger logger, LinkerContext context, ArtifactSet artifacts,
+ CompilationResult result) throws UnableToCompleteException {
// Must do installScript before installLocation and waitForBodyLoaded
includeJs(ss, logger,
getJsInstallScript(context), "__INSTALL_SCRIPT__");
@@ -68,10 +71,21 @@
includeJs(ss, logger, getJsProcessMetas(context), "__PROCESS_METAS__");
includeJs(ss, logger,
getJsComputeScriptBase(context), "__COMPUTE_SCRIPT_BASE__");
includeJs(ss, logger,
getJsLoadExternalStylesheets(context), "__LOAD_STYLESHEETS__");
+
+ // This Linker does not support <script> tags in the gwt.xml
+ if (!artifacts.find(ScriptReference.class).isEmpty()) {
+ logger.log(TreeLogger.ERROR, "The " + getDescription() +
+ " linker does not support <script> tags in the gwt.xml files");
+ throw new UnableToCompleteException();
+ }
ss = ResourceInjectionUtil.injectStylesheets(ss, artifacts);
ss = permutationsUtil.addPermutationsJs(ss, logger, context);
-
+
+ if (result != null) {
+ replaceAll(ss, "__KNOWN_PROPERTIES__",
+ PropertiesUtil.addKnownPropertiesJs(logger, result));
+ }
replaceAll(ss, "__MODULE_FUNC__", context.getModuleFunctionName());
replaceAll(ss, "__MODULE_NAME__", context.getModuleName());
replaceAll(ss, "__HOSTED_FILENAME__", getHostedFilename());
@@ -200,22 +214,36 @@
@Override
protected void maybeAddHostedModeFile(TreeLogger logger,
- LinkerContext context, ArtifactSet artifacts)
+ LinkerContext context, ArtifactSet artifacts, CompilationResult
result)
throws UnableToCompleteException {
String filename = getHostedFilename();
if ("".equals(filename)) {
return;
}
+
+ // when we're including bootstrap in the primary fragment, we should be
+ // generating devmode files for each permutation. Otherwise, we
generate it
+ // only in the final link stage.
+ boolean isSinglePermutation = (result != null);
+ if (isSinglePermutation !=
+ shouldIncludeBootstrapInPrimaryFragment(context)) {
+ return;
+ }
long lastModified = System.currentTimeMillis();
StringBuffer buffer = readFileToStringBuffer(
"com/google/gwt/core/ext/linker/impl/" + filename, logger);
+
+ String outputFilename = filename;
+ if (result != null) {
+ outputFilename = result.getStrongName() + "." + outputFilename;
+ }
String script = generatePrimaryFragmentString(
- logger, context, "", buffer.toString(), 1, artifacts);
+ logger, context, result, buffer.toString(), 1, artifacts);
EmittedArtifact devArtifact =
- emitString(logger, script, filename, lastModified);
+ emitString(logger, script, outputFilename, lastModified);
artifacts.add(devArtifact);
}
@@ -264,11 +292,12 @@
@Override
protected String wrapPrimaryFragment(TreeLogger logger,
- LinkerContext context, String script, ArtifactSet artifacts) {
+ LinkerContext context, String script, ArtifactSet artifacts,
+ CompilationResult result) {
StringBuffer out = new StringBuffer();
if (shouldIncludeBootstrapInPrimaryFragment(context)) {
try {
- out.append(generateSelectionScript(logger, context, artifacts));
+ out.append(generateSelectionScript(logger, context, artifacts,
result));
} catch (UnableToCompleteException e) {
logger.log(TreeLogger.ERROR, "Problem setting up selection
script", e);
e.printStackTrace();
=======================================
---
/trunk/user/test/com/google/gwt/dev/jjs/CrossSiteIframeRunAsyncMetrics.gwt.xml
Tue Aug 10 07:06:57 2010
+++
/trunk/user/test/com/google/gwt/dev/jjs/CrossSiteIframeRunAsyncMetrics.gwt.xml
Tue Dec 14 13:21:45 2010
@@ -13,7 +13,9 @@
<!-- limitations under the
License. -->
<module>
- <inherits name="com.google.gwt.dev.jjs.RunAsyncMetricsIntegrationTest" />
+ <!-- We cannot inherit the RunAsyncMetricsIntegrationTest module because
+ it adds a script tag and the xsiframe linker does not support them
-->
+ <inherits name="com.google.gwt.dev.jjs.CompilerSuite"/>
<add-linker name="xsiframe" />
<public path="public" />
--
http://groups.google.com/group/Google-Web-Toolkit-Contributors