| /* |
| * Copyright 2010 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.core.ext.linker.impl; |
| |
| import com.google.gwt.core.ext.LinkerContext; |
| import com.google.gwt.core.ext.TreeLogger; |
| import com.google.gwt.core.ext.UnableToCompleteException; |
| import com.google.gwt.core.ext.linker.CompilationResult; |
| import com.google.gwt.core.ext.linker.ConfigurationProperty; |
| import com.google.gwt.core.ext.linker.SelectionProperty; |
| import com.google.gwt.dev.cfg.ModuleDef; |
| import com.google.gwt.dev.jjs.JsOutputOption; |
| |
| import java.util.Map.Entry; |
| import java.util.SortedSet; |
| |
| /** |
| * A utility class to fill in the properties javascript in linker templates. |
| */ |
| public class PropertiesUtil { |
| public static String addKnownPropertiesJs(TreeLogger logger, |
| CompilationResult result) { |
| StringBuilder propertiesJs = new StringBuilder(); |
| |
| // 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) |
| throws UnableToCompleteException { |
| int startPos; |
| |
| // Add property providers |
| startPos = selectionScript.indexOf("// __PROPERTIES_END__"); |
| if (startPos == -1) { |
| return selectionScript; |
| } |
| selectionScript.insert(startPos, generatePropertyProviders(logger, context)); |
| return selectionScript; |
| } |
| |
| /** |
| * Returns JavaScript that declares and initializes the "providers" and "values" variables. |
| * |
| * <p>Requires $doc and $wnd variables to be defined. (And possibly others; this is unclear.) |
| * |
| * <p>Provides "providers" and "values" variables.</p>. |
| * |
| * <ul> |
| * <li>"providers" is a mapping from each binding property (string) to a no-argument function |
| * that determines its value.</li> |
| * <li>"values" is a mapping from each binding property (string) to the set of allowed values |
| * (represented as a mapping with the value as key). |
| * </li> |
| * </ul> |
| */ |
| public static String generatePropertiesSnippet(ModuleDef module, TreeLogger compileLogger) |
| throws UnableToCompleteException { |
| |
| // TODO: PropertyProviderGenerator should specify the JavaScript environment that a |
| // property provider can assume so the caller of this function knows what it should provide. |
| |
| LinkerContext linkerContext = new StandardLinkerContext(compileLogger, module, |
| module.getPublicResourceOracle(), JsOutputOption.PRETTY); |
| |
| String initProvidersJs = |
| generatePropertyProviders(compileLogger, linkerContext); |
| |
| return "var providers = {};\nvar values = {};\n" + initProvidersJs + "\n"; |
| } |
| |
| /** |
| * Generates JavaScript to create a property provider for each non-derived binding property |
| * in the given linker. The JavaScript mutates the "providers" and "values" variables which |
| * must already exist. |
| */ |
| private static String generatePropertyProviders(TreeLogger logger, LinkerContext context) |
| throws UnableToCompleteException { |
| StringBuilder out = new StringBuilder(); |
| for (SelectionProperty p : context.getProperties()) { |
| out.append(generatePropertyProvider(logger, p, context.getConfigurationProperties())); |
| } |
| return out.toString(); |
| } |
| |
| private static String generatePropertyProvider(TreeLogger logger, |
| SelectionProperty prop, SortedSet<ConfigurationProperty> configurationProperties) |
| throws UnableToCompleteException { |
| StringBuilder toReturn = new StringBuilder(); |
| |
| if (prop.tryGetValue() == null && !prop.isDerived()) { |
| toReturn.append("providers['" + prop.getName() + "'] = function()"); |
| toReturn.append(prop.getPropertyProvider(logger, configurationProperties)); |
| toReturn.append(";"); |
| |
| toReturn.append("values['" + prop.getName() + "'] = {"); |
| boolean needsComma = false; |
| int counter = 0; |
| for (String value : prop.getPossibleValues()) { |
| if (needsComma) { |
| toReturn.append(","); |
| } else { |
| needsComma = true; |
| } |
| toReturn.append("'" + value + "':"); |
| toReturn.append(counter++); |
| } |
| toReturn.append("};"); |
| } |
| |
| return toReturn.toString(); |
| } |
| } |