in src/org/intellij/grammar/actions/GenerateAction.java [87:197]
public void doGenerate(@NotNull Project project, @NotNull List<VirtualFile> bnfFiles) {
Map<VirtualFile, VirtualFile> rootMap = new LinkedHashMap<>();
Map<VirtualFile, String> packageMap = new LinkedHashMap<>();
PsiManager psiManager = PsiManager.getInstance(project);
PackageIndex packageIndex = PackageIndex.getInstance(project);
WriteAction.run(() -> {
for (VirtualFile file : bnfFiles) {
if (!file.isValid()) continue;
PsiFile bnfFile = getBnfFile(file, psiManager);
if (!(bnfFile instanceof BnfFile)) continue;
String parserClass = getRootAttribute(bnfFile, KnownAttribute.PARSER_CLASS);
VirtualFile target =
getTargetDirectoryFor(project, file,
StringUtil.getShortName(parserClass) + ".java",
StringUtil.getPackageName(parserClass), true);
rootMap.put(file, target);
packageMap.put(target, StringUtil.notNullize(packageIndex.getPackageNameByDirectory(target)));
}
});
ProgressManager.getInstance().run(new Task.Backgroundable(project, "Parser generation", true, PerformInBackgroundOption.ALWAYS_BACKGROUND) {
final List<File> files = new ArrayList<>();
final Set<VirtualFile> targets = new LinkedHashSet<>();
int filesProcessed = 0;
long totalWritten = 0;
@Override
public void run(@NotNull ProgressIndicator indicator) {
long startTime = System.currentTimeMillis();
indicator.setIndeterminate(true);
try {
runInner(indicator);
}
finally {
String report = String.format("%d grammars: %d files generated (%s) in %s",
filesProcessed,
files.size(),
StringUtil.formatFileSize(totalWritten),
StringUtil.formatDuration(System.currentTimeMillis() - startTime));
if (bnfFiles.size() > 3) {
Notifications.Bus.notify(new Notification(
BnfConstants.GENERATION_GROUP,
"", report, NotificationType.INFORMATION), project);
}
VfsUtil.markDirtyAndRefresh(true, true, true, targets.toArray(VirtualFile.EMPTY_ARRAY));
}
}
private void runInner(ProgressIndicator indicator) {
for (int i = 0, l = bnfFiles.size(); i < l; i++) {
VirtualFile file = bnfFiles.get(i);
indicator.setFraction((double)i / l);
indicator.setText2(file.getPath());
String sourcePath = file.isInLocalFileSystem() ? FileUtil.toSystemDependentName(
FileUtil.toCanonicalPath(file.getParent().getPath())) : "";
VirtualFile target = rootMap.get(file);
if (target == null) return;
targets.add(target);
File genDir = new File(VfsUtilCore.virtualToIoFile(target).getAbsolutePath());
String packagePrefix = packageMap.get(target);
long time = System.currentTimeMillis();
int filesCount = files.size();
Ref<Exception> exRef = Ref.create();
try {
DumbService.getInstance(project).runReadActionInSmartMode(() -> {
if (!file.isValid()) return;
PsiFile bnfFile = getBnfFile(file, psiManager);
if (!(bnfFile instanceof BnfFile)) return;
ParserGenerator generator = new ParserGenerator((BnfFile)bnfFile, sourcePath, genDir.getPath(), packagePrefix) {
@Override
protected PrintWriter openOutputInner(String className, File file) throws IOException {
files.add(file);
return super.openOutputInner(className, file);
}
};
try {
generator.generate();
}
catch (Exception ex) {
exRef.set(ex);
}
});
if (!exRef.isNull()) throw exRef.get();
long millis = System.currentTimeMillis() - time;
String duration = millis < 1000 ? null : StringUtil.formatDuration(millis);
long written = 0;
for (File f : files.subList(filesCount, files.size())) {
written += f.length();
}
filesProcessed ++;
totalWritten += written;
Notifications.Bus.notify(new Notification(
BnfConstants.GENERATION_GROUP,
String.format("%s generated (%s)", file.getName(), StringUtil.formatFileSize(written)),
"to " + genDir + (duration == null ? "" : " in " + duration), NotificationType.INFORMATION), project);
}
catch (ProcessCanceledException ignored) {
}
catch (Exception ex) {
Notifications.Bus.notify(new Notification(
BnfConstants.GENERATION_GROUP,
file.getName() + " generation failed",
ExceptionUtil.getUserStackTrace(ex, ParserGenerator.LOG), NotificationType.ERROR), project);
LOG.warn(ex);
}
}
}
});
}