blob: 2979a4ab35c7eced5840d213c9f3d3778ccf8f10 [file] [log] [blame]
/*
* Copyright 2008 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.javac;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.dev.CompilerContext;
import com.google.gwt.dev.javac.CompilationStateBuilder.CompileMoreLater;
import com.google.gwt.dev.javac.typemodel.TypeOracle;
import com.google.gwt.dev.util.log.speedtracer.DevModeEventType;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger;
import com.google.gwt.dev.util.log.speedtracer.SpeedTracerLogger.Event;
import com.google.gwt.thirdparty.guava.common.annotations.VisibleForTesting;
import com.google.gwt.thirdparty.guava.common.base.Function;
import com.google.gwt.thirdparty.guava.common.base.Predicates;
import com.google.gwt.thirdparty.guava.common.collect.FluentIterable;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
/**
* Encapsulates the state of active compilation units in a particular module.
* State is accumulated throughout the life cycle of the containing module and
* may be invalidated at certain times and recomputed.
*/
public class CompilationState {
/**
* Classes mapped by internal name.
*/
protected final Map<String, CompiledClass> classFileMap = new HashMap<String, CompiledClass>();
/**
* Classes mapped by source name.
*/
protected final Map<String, CompiledClass> classFileMapBySource =
new HashMap<String, CompiledClass>();
/**
* All my compilation units.
*/
protected final Map<String, CompilationUnit> unitMap = new HashMap<String, CompilationUnit>();
private int cachedGeneratedSourceCount = 0;
private int cachedStaticSourceCount = 0;
private final CompileMoreLater compileMoreLater;
private CompilerContext compilerContext;
/**
* Unmodifiable view of {@link #classFileMap}.
*/
private final Map<String, CompiledClass> exposedClassFileMap =
Collections.unmodifiableMap(classFileMap);
/**
* Unmodifiable view of {@link #classFileMapBySource}.
*/
private final Map<String, CompiledClass> exposedClassFileMapBySource =
Collections.unmodifiableMap(classFileMapBySource);
/**
* Unmodifiable view of {@link #unitMap}.
*/
private final Map<String, CompilationUnit> exposedUnitMap = Collections.unmodifiableMap(unitMap);
/**
* Unmodifiable view of all units.
*/
private final Collection<CompilationUnit> exposedUnits =
Collections.unmodifiableCollection(unitMap.values());
private int generatedSourceCount = 0;
private int staticSourceCount = 0;
/**
* Our type oracle.
*/
private final TypeOracle typeOracle;
/**
* Updates our type oracle.
*/
private final CompilationUnitTypeOracleUpdater typeOracleUpdater;
CompilationState(TreeLogger logger, CompilerContext compilerContext,
TypeOracle typeOracle, CompilationUnitTypeOracleUpdater typeOracleUpdater,
Collection<CompilationUnit> units, CompileMoreLater compileMoreLater) {
this.compileMoreLater = compileMoreLater;
this.compilerContext = compilerContext;
this.typeOracle = typeOracle;
this.typeOracleUpdater = typeOracleUpdater;
assimilateUnits(logger, units);
}
/**
* Compiles the given source files (unless cached) and adds them to the
* CompilationState.
* If the compiler aborts, logs the error and throws UnableToCompleteException.
*/
public void addGeneratedCompilationUnits(TreeLogger logger,
Collection<GeneratedUnit> generatedUnits) throws UnableToCompleteException {
Event generatedUnitsAddEvent = SpeedTracerLogger.start(
DevModeEventType.COMP_STATE_ADD_GENERATED_UNITS);
try {
logger = logger.branch(TreeLogger.DEBUG, "Adding '"
+ generatedUnits.size() + "' new generated units");
generatedUnitsAddEvent.addData("# new generated units", "" + generatedUnits.size());
Collection<CompilationUnit> newUnits = compileMoreLater.addGeneratedTypes(
logger, generatedUnits, this);
assimilateUnits(logger, newUnits);
} finally {
generatedUnitsAddEvent.end();
}
}
public int getCachedGeneratedSourceCount() {
return cachedGeneratedSourceCount;
}
public int getCachedStaticSourceCount() {
return cachedStaticSourceCount;
}
/**
* Returns a map of all compiled classes by internal name.
*/
public Map<String, CompiledClass> getClassFileMap() {
return exposedClassFileMap;
}
/**
* Returns a map of all compiled classes by source name.
*/
public Map<String, CompiledClass> getClassFileMapBySource() {
return exposedClassFileMapBySource;
}
/**
* Returns an unmodifiable view of the set of compilation units, mapped by the
* main type's qualified source name.
*/
public Map<String, CompilationUnit> getCompilationUnitMap() {
return exposedUnitMap;
}
/**
* Returns an unmodifiable view of the set of compilation units.
*/
public Collection<CompilationUnit> getCompilationUnits() {
return exposedUnits;
}
public Iterable<String> getQualifiedJsInteropRootTypesNames() {
Function<CompilationUnit, String> toRootTypeName = new Function<CompilationUnit, String>() {
@Override
public String apply(CompilationUnit compilationUnit) {
return compilationUnit.hasJsInteropRootType() ? compilationUnit.getTypeName() : null;
}
};
return FluentIterable.from(unitMap.values())
.transform(toRootTypeName)
.filter(Predicates.notNull());
}
public CompilerContext getCompilerContext() {
return compilerContext;
}
public int getGeneratedSourceCount() {
return generatedSourceCount;
}
public int getStaticSourceCount() {
return staticSourceCount;
}
public TypeOracle getTypeOracle() {
return typeOracle;
}
@VisibleForTesting
public Map<String, CompiledClass> getValidClasses() {
return compileMoreLater.getValidClasses();
}
/**
* Whether any errors were encountered while building this compilation state.
*/
public boolean hasErrors() {
for (CompilationUnit unit : unitMap.values()) {
if (unit.isError()) {
return true;
}
}
return false;
}
public void incrementCachedGeneratedSourceCount(int extraCachedGeneratedSourceCount) {
cachedGeneratedSourceCount += extraCachedGeneratedSourceCount;
}
public void incrementCachedStaticSourceCount(int extraCachedStaticSourceCount) {
cachedStaticSourceCount += extraCachedStaticSourceCount;
}
public void incrementGeneratedSourceCount(int extraGeneratedSourceCount) {
generatedSourceCount += extraGeneratedSourceCount;
}
public void incrementStaticSourceCount(int extraStaticSourceCount) {
staticSourceCount += extraStaticSourceCount;
}
/**
* For testing.
*/
CompilationUnitTypeOracleUpdater getTypeOracleUpdater() {
return typeOracleUpdater;
}
private void assimilateUnits(TreeLogger logger, Collection<CompilationUnit> units) {
for (CompilationUnit unit : units) {
unitMap.put(unit.getTypeName(), unit);
for (CompiledClass compiledClass : unit.getCompiledClasses()) {
classFileMap.put(compiledClass.getInternalName(), compiledClass);
classFileMapBySource.put(compiledClass.getSourceName(), compiledClass);
}
}
CompilationUnitInvalidator.retainValidUnits(logger, units, compileMoreLater.getValidClasses(),
compilerContext.getCompilationErrorsIndex());
typeOracleUpdater.addNewUnits(logger, units);
}
}