/*
* Copyright 2017-present Facebook, 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.facebook.buck.jvm.java.abi.source;
import com.facebook.buck.jvm.java.plugin.adapter.BuckJavacPlugin;
import com.facebook.buck.jvm.java.plugin.adapter.BuckJavacTask;
import com.sun.source.util.TaskEvent;
import com.sun.source.util.TaskListener;
/**
* Watches the phases of the compiler and keeps our parallel symbol table in sync. Put task
* listeners that need access to our symbol tables inside this one.
*/
class EnteringPlugin implements BuckJavacPlugin {
@Override
public String getName() {
return "EnteringPlugin";
}
@Override
public void init(BuckJavacTask task, String... args) {
FrontendOnlyJavacTask frontendTask = (FrontendOnlyJavacTask) task;
task.addTaskListener(
new EnteringTaskListener(frontendTask.getElements(), frontendTask.getTrees()));
}
private static class EnteringTaskListener implements TaskListener {
private final TreeBackedElements elements;
private final TreeBackedTrees trees;
private final TreeBackedEnter enter;
private int classesEnteredThisRound = 0;
public EnteringTaskListener(TreeBackedElements elements, TreeBackedTrees trees) {
this.elements = elements;
this.trees = trees;
enter = new TreeBackedEnter(this.elements, this.trees);
}
@Override
public void started(TaskEvent e) {
if (e.getKind() == TaskEvent.Kind.ENTER && classesEnteredThisRound == 0) {
// We want to clear our tables between rounds, and leave them intact after the last enter
// phase. However, javac sends the round start after the enter phase, so we must do some
// bookkeeping to detect the first enter event *after* a round and clear the table then.
elements.clear();
trees.clear();
}
}
@Override
public void finished(TaskEvent e) {
if (e.getKind() == TaskEvent.Kind.ENTER) {
enter.enter(e.getCompilationUnit());
classesEnteredThisRound += 1;
} else if (e.getKind() == TaskEvent.Kind.ANNOTATION_PROCESSING_ROUND) {
// Reset counter for next round
classesEnteredThisRound = 0;
}
}
}
}