private void runBuild(final MessageHandler msgHandler, CanceledStatus cs) throws Throwable { final File dataStorageRoot = Utils.getDataStorageRoot(myProjectPath); if (dataStorageRoot == null) { msgHandler.processMessage( new CompilerMessage( "build", BuildMessage.Kind.ERROR, "Cannot determine build data storage root for project " + myProjectPath)); return; } if (!dataStorageRoot.exists()) { // invoked the very first time for this project. Force full rebuild myBuildType = BuildType.PROJECT_REBUILD; } final DataInputStream fsStateStream = createFSDataStream(dataStorageRoot); if (fsStateStream != null) { // optimization: check whether we can skip the build final boolean hasWorkToDoWithModules = fsStateStream.readBoolean(); if (myBuildType == BuildType.MAKE && !hasWorkToDoWithModules && scopeContainsModulesOnly(myBuildRunner.getScopes()) && !containsChanges(myInitialFSDelta)) { updateFsStateOnDisk(dataStorageRoot, fsStateStream, myInitialFSDelta.getOrdinal()); return; } } final BuildFSState fsState = new BuildFSState(false); try { final ProjectDescriptor pd = myBuildRunner.load(msgHandler, dataStorageRoot, fsState); myProjectDescriptor = pd; if (fsStateStream != null) { try { try { fsState.load(fsStateStream, pd.getModel(), pd.getBuildRootIndex()); applyFSEvent(pd, myInitialFSDelta); } finally { fsStateStream.close(); } } catch (Throwable e) { LOG.error(e); fsState.clearAll(); } } myLastEventOrdinal = myInitialFSDelta != null ? myInitialFSDelta.getOrdinal() : 0L; // free memory myInitialFSDelta = null; // ensure events from controller are processed after FSState initialization myEventsProcessor.startProcessing(); myBuildRunner.runBuild(pd, cs, myConstantSearch, msgHandler, myBuildType); } finally { saveData(fsState, dataStorageRoot); } }
@Nullable private DataInputStream createFSDataStream(File dataStorageRoot) { if (myInitialFSDelta == null) { // this will force FS rescan return null; } try { final File file = new File(dataStorageRoot, FS_STATE_FILE); final InputStream fs = new FileInputStream(file); byte[] bytes; try { bytes = FileUtil.loadBytes(fs, (int) file.length()); } finally { fs.close(); } final DataInputStream in = new DataInputStream(new ByteArrayInputStream(bytes)); final int version = in.readInt(); if (version != FSState.VERSION) { return null; } final long savedOrdinal = in.readLong(); if (savedOrdinal + 1L != myInitialFSDelta.getOrdinal()) { return null; } return in; } catch (FileNotFoundException ignored) { } catch (Throwable e) { LOG.error(e); } return null; }