/* * Copyright 2013 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.dev.jjs.impl.codesplitter; import com.google.gwt.dev.jjs.ast.JRunAsync; import com.google.gwt.dev.js.ast.JsStatement; import com.google.gwt.thirdparty.guava.common.base.Preconditions; import com.google.gwt.thirdparty.guava.common.collect.Sets; import java.util.Collection; import java.util.List; import java.util.Set; /** * Describes a fragment and its contents. * * <p>A fragment contains one or more runAsyncs (split points). Each runAsync in the program is * assigned to exactly one fragment.</p> */ class Fragment { /** * Types of fragments: * <ul> * <li>- INITIAL fragments are the ones that from part of the initial download.</li> * <li>- EXCLUSIVE fragments are the ones that contain atoms that are only live when runAsyncs * contained in the fragment are activated</li> * <li>- NOT_EXCLUSIVE fragments (only one at this stage) contains all the atoms that are not * part of INITIAL or EXCLUSIVE fragments</li> * </ul> */ enum Type { INITIAL, EXCLUSIVE, NOT_EXCLUSIVE } public Fragment(Type type, Fragment... ancestorFragments) { this.type = type; this.addImmediateAncestors(ancestorFragments); } /** * Assign a runAsync to this fragment. */ public void addRunAsync(JRunAsync runAsync) { Preconditions.checkArgument(!this.runAsyncs.contains(runAsync), "Fragment %n already contains " + "runAsync %n", runAsync.getRunAsyncId()); runAsyncs.add(runAsync); } public void addRunAsyncs(Collection<JRunAsync> runAsyncs) { this.runAsyncs.addAll(runAsyncs); } public void addImmediateAncestors(Fragment... ancestorFragments) { for (Fragment ancestorFragment : ancestorFragments) { this.immediateAncestors.add(ancestorFragment); } } public void addStatements(List<JsStatement> statements) { this.statements.addAll(statements); } public int getFragmentId() { assert fragmentId >= 0; return fragmentId; } /** * Splitpoints contained in this fragment. */ public Set<JRunAsync> getRunAsyncs() { return runAsyncs; } public List<JsStatement> getStatements() { return statements; } public Type getType() { return type; } public boolean isExclusive() { return type == Type.EXCLUSIVE; } public boolean isInitial() { return type == Type.INITIAL; } public void setFragmentId(int fragmentId) { Preconditions.checkArgument(fragmentId >= 0, "Fragment id %s is not >= 0", fragmentId); Preconditions.checkArgument(fragmentId > 0 || type == Type.INITIAL, "Fragment 0 is not INITIAL"); this.fragmentId = fragmentId; } public void setStatements(List<JsStatement> statements) { this.statements = statements; } private int fragmentId = -1; private Set<JRunAsync> runAsyncs = Sets.newHashSet(); private List<JsStatement> statements; private Type type; private Set<Fragment> immediateAncestors = Sets.newHashSet(); }