blob: 74429cfc2d231d71266de59644d5580e73149eac [file] [log] [blame]
/*
* 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();
}