| /* |
| * 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); |
| } |
| } |