| /* |
| * Copyright 2014-present Facebook, 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.facebook.buck.gwt; |
| |
| import com.facebook.buck.graph.AbstractBreadthFirstTraversal; |
| import com.facebook.buck.java.JavaLibrary; |
| import com.facebook.buck.model.BuildTarget; |
| import com.facebook.buck.model.BuildTargets; |
| import com.facebook.buck.rules.BuildRule; |
| import com.facebook.buck.rules.BuildRuleParams; |
| import com.facebook.buck.rules.BuildRuleResolver; |
| import com.facebook.buck.rules.BuildRuleType; |
| import com.facebook.buck.rules.Description; |
| import com.facebook.buck.rules.ImmutableBuildRuleType; |
| import com.facebook.buck.rules.SourcePathResolver; |
| import com.facebook.infer.annotation.SuppressFieldNotInitialized; |
| import com.google.common.base.Optional; |
| import com.google.common.base.Preconditions; |
| import com.google.common.base.Suppliers; |
| import com.google.common.collect.ImmutableList; |
| import com.google.common.collect.ImmutableSet; |
| import com.google.common.collect.ImmutableSortedSet; |
| |
| import java.nio.file.Path; |
| |
| public class GwtBinaryDescription implements Description<GwtBinaryDescription.Arg> { |
| |
| public static final BuildRuleType TYPE = ImmutableBuildRuleType.of("gwt_binary"); |
| |
| /** Default value for {@link Arg#style}. */ |
| private static final String DEFAULT_STYLE = GwtBinary.Style.OBF.name(); |
| |
| /** Default value for {@link Arg#localWorkers}. */ |
| private static final Integer DEFAULT_NUM_LOCAL_WORKERS = Integer.valueOf(2); |
| |
| /** Default value for {@link Arg#draftCompile}. */ |
| private static final Boolean DEFAULT_DRAFT_COMPILE = Boolean.FALSE; |
| |
| /** Default value for {@link Arg#strict}. */ |
| private static final Boolean DEFAULT_STRICT = Boolean.FALSE; |
| |
| /** |
| * This value is taken from GWT's source code: http://bit.ly/1nZtmMv |
| */ |
| private static final Integer DEFAULT_OPTIMIZE = Integer.valueOf(9); |
| |
| @SuppressFieldNotInitialized |
| public static class Arg { |
| public Optional<ImmutableSortedSet<String>> modules; |
| public Optional<ImmutableSortedSet<BuildTarget>> moduleDeps; |
| public Optional<ImmutableSortedSet<BuildTarget>> deps; |
| |
| /** |
| * In practice, these may be values such as {@code -Xmx512m}. |
| */ |
| public Optional<ImmutableList<String>> vmArgs; |
| |
| /** This will be passed to the GWT Compiler's {@code -style} flag. */ |
| // TODO(simons): t4058780 Introduce an EnumTypeCoercer so we can make this Optional<Style>. |
| public Optional<String> style; |
| |
| /** If {@code true}, the GWT Compiler's {@code -draftCompile} flag will be set. */ |
| public Optional<Boolean> draftCompile; |
| |
| /** This will be passed to the GWT Compiler's {@code -optimize} flag. */ |
| public Optional<Integer> optimize; |
| |
| /** This will be passed to the GWT Compiler's {@code -localWorkers} flag. */ |
| public Optional<Integer> localWorkers; |
| |
| /** If {@code true}, the GWT Compiler's {@code -strict} flag will be set. */ |
| public Optional<Boolean> strict; |
| |
| /** |
| * In practice, these may be values such as {@code -XenableClosureCompiler}, |
| * {@code -XdisableClassMetadata}, {@code -XdisableCastChecking}, or {@code -XfragmentMerge}. |
| */ |
| public Optional<ImmutableList<String>> experimentalArgs; |
| } |
| |
| @Override |
| public BuildRuleType getBuildRuleType() { |
| return TYPE; |
| } |
| |
| @Override |
| public Arg createUnpopulatedConstructorArg() { |
| return new Arg(); |
| } |
| |
| @Override |
| public <A extends Arg> BuildRule createBuildRule( |
| BuildRuleParams params, |
| final BuildRuleResolver resolver, |
| A args) { |
| |
| final ImmutableSortedSet.Builder<BuildRule> extraDeps = ImmutableSortedSet.naturalOrder(); |
| |
| // Find all of the reachable JavaLibrary rules and grab their associated GwtModules. |
| final ImmutableSortedSet.Builder<Path> gwtModuleJarsBuilder = |
| ImmutableSortedSet.naturalOrder(); |
| ImmutableSortedSet<BuildRule> moduleDependencies = resolver.getAllRules(args.moduleDeps.get()); |
| new AbstractBreadthFirstTraversal<BuildRule>(moduleDependencies) { |
| @Override |
| public ImmutableSet<BuildRule> visit(BuildRule rule) { |
| if (!(rule instanceof JavaLibrary)) { |
| return ImmutableSet.of(); |
| } |
| |
| JavaLibrary javaLibrary = (JavaLibrary) rule; |
| BuildTarget gwtModuleTarget = BuildTargets.createFlavoredBuildTarget( |
| javaLibrary.getBuildTarget().checkUnflavored(), |
| JavaLibrary.GWT_MODULE_FLAVOR); |
| Optional<BuildRule> gwtModule = resolver.getRuleOptional(gwtModuleTarget); |
| |
| // Note that gwtModule could be absent if javaLibrary is a rule with no srcs of its own, |
| // but a rule that exists only as a collection of deps. |
| if (gwtModule.isPresent()) { |
| extraDeps.add(gwtModule.get()); |
| gwtModuleJarsBuilder.add( |
| Preconditions.checkNotNull(gwtModule.get().getPathToOutputFile())); |
| } |
| |
| // Traverse all of the deps of this rule. |
| return rule.getDeps(); |
| } |
| }.start(); |
| |
| return new GwtBinary( |
| params.copyWithExtraDeps(Suppliers.ofInstance(extraDeps.build())), |
| new SourcePathResolver(resolver), |
| args.modules.get(), |
| args.vmArgs.get(), |
| GwtBinary.Style.valueOf(args.style.or(DEFAULT_STYLE)), |
| args.draftCompile.or(DEFAULT_DRAFT_COMPILE), |
| args.optimize.or(DEFAULT_OPTIMIZE), |
| args.localWorkers.or(DEFAULT_NUM_LOCAL_WORKERS), |
| args.strict.or(DEFAULT_STRICT), |
| args.experimentalArgs.get(), |
| moduleDependencies, |
| gwtModuleJarsBuilder.build()); |
| } |
| } |