*/
@Override
public void process(CompilationUnitBuilder builder, CompilationUnitDeclaration cud,
List<ImportReference> cudOriginaImports,
List<CompiledClass> compiledClasses) {
Event event = SpeedTracerLogger.start(DevModeEventType.CSB_PROCESS);
try {
// Collect parameter method names event when the compilation unit has errors.
List<JDeclaredType> types = ImmutableList.of();
final Set<String> jsniDeps = Sets.newHashSet();
final Map<String, Binding> jsniRefs = Maps.newHashMap();
Map<MethodDeclaration, JsniMethod> jsniMethods = ImmutableMap.of();
List<String> apiRefs = ImmutableList.of();
MethodArgNamesLookup methodArgs = new MethodArgNamesLookup();
if (!cud.compilationResult().hasErrors()) {
// Only collect jsniMethods, etc if the compilation unit does not have errors.
jsniMethods =
JsniMethodCollector.collectJsniMethods(cud, builder.getSourceMapPath(),
builder.getSource(), JsRootScope.INSTANCE, DummyCorrelationFactory.INSTANCE);
JSORestrictionsChecker.check(jsoState, cud);
// JSNI check + collect dependencies.
JsniReferenceResolver
.resolve(cud, cudOriginaImports, jsniMethods, jsniRefs,
new JsniReferenceResolver.TypeResolver() {
@Override
public ReferenceBinding resolveType(String sourceOrBinaryName) {
ReferenceBinding resolveType = compiler.resolveType(sourceOrBinaryName);
if (resolveType != null) {
jsniDeps.add(String.valueOf(resolveType.qualifiedSourceName()));
}
return resolveType;
}
});
if (compilerContext.shouldCompileMonolithic()) {
// GWT drives JDT in a way that allows missing references in the source to be
// resolved to precompiled bytecode on disk (see INameEnvironment). This is
// done so that annotations can be supplied in bytecode form only. But since no
// AST is available for these types it creates the danger that some functional
// class (not just an annotation) gets filled in but is missing AST. This would
// cause later compiler stages to fail.
//
// Library compilation needs to ignore this check since it is expected behavior
// for the source being compiled in a library to make references to other types
// which are only available as bytecode coming out of dependency libraries.
//
// But if the referenced bytecode did not come from a dependency library but
// instead was free floating in the classpath, then there is no guarantee that
// AST for it was ever seen and translated to JS anywhere in the dependency tree.
// This would be a mistake.
//
// TODO(stalcup): add a more specific check for library compiles such that binary
// types can be referenced but only if they are an Annotation or if the binary
// type comes from a dependency library.
BinaryTypeReferenceRestrictionsChecker.check(cud);
}
if (!cud.compilationResult().hasErrors()) {
// The above checks might have recorded errors; so we need to check here again.
// So only construct the GWT AST if no JDT errors and no errors from our checks.
types = astBuilder.process(cud, builder.getSourceMapPath(), jsniMethods, jsniRefs,
compilerContext);
}
// Only run this pass if JDT was able to compile the unit with no errors, otherwise
// the JDT AST traversal might throw exceptions.
methodArgs = MethodParamCollector.collect(cud, builder.getSourceMapPath());
}
apiRefs = compiler.collectApiRefs(cud);
final Interner<String> interner = StringInterner.get();
String packageName = interner.intern(Shared.getPackageName(builder.getTypeName()));
List<String> unresolvedSimple = Lists.newArrayList();
for (char[] simpleRef : cud.compilationResult().simpleNameReferences) {
unresolvedSimple.add(interner.intern(String.valueOf(simpleRef)));
}
List<String> unresolvedQualified = Lists.newArrayList();
for (char[][] qualifiedRef : cud.compilationResult().qualifiedReferences) {
unresolvedQualified.add(interner.intern(CharOperation.toString(qualifiedRef)));
}
for (String jsniDep : jsniDeps) {
unresolvedQualified.add(interner.intern(jsniDep));
}
for (int i = 0; i < apiRefs.size(); ++i) {
apiRefs.set(i, interner.intern(apiRefs.get(i)));
}
// Dependencies need to be included even when the {@code cud} has errors as the unit might
// be saved as a cached unit and its dependencies might be used to further invalidate
// other units. See {@link
// CompilationStateBuilder#removeInvalidCachedUnitsAndRescheduleCorrespondingBuilders}.
Dependencies dependencies =
new Dependencies(packageName, unresolvedQualified, unresolvedSimple, apiRefs);
for (CompiledClass cc : compiledClasses) {
allValidClasses.put(cc.getSourceName(), cc);
}
// Even when compilation units have errors, return a consistent builder.
builder
.setTypes(types)
.setDependencies(dependencies)
.setJsniMethods(jsniMethods.values())
.setMethodArgs(methodArgs)
.setClasses(compiledClasses)
.setProblems(cud.compilationResult().getProblems());
buildQueue.add(builder);
} finally {
event.end();
}
}