diff --git a/IDE/src/Compiler/BfCompiler.bf b/IDE/src/Compiler/BfCompiler.bf index 4933ef06..b8a54fd0 100644 --- a/IDE/src/Compiler/BfCompiler.bf +++ b/IDE/src/Compiler/BfCompiler.bf @@ -55,6 +55,12 @@ namespace IDE.Compiler [CallingConvention(.Stdcall), CLink] static extern char8* BfCompiler_GetAutocompleteInfo(void* bfCompiler); + [CallingConvention(.Stdcall), CLink] + static extern char8* BfCompiler_GetRebuildFileSet(void* bfCompiler); + + [CallingConvention(.Stdcall), CLink] + static extern void BfCompiler_FileChanged(void* bfCompiler, char8* str); + [CallingConvention(.Stdcall), CLink] static extern char8* BfCompiler_GetSymbolReferences(void* bfCompiler, void* bfPassInstance, void* bfResolvePassData); @@ -200,10 +206,17 @@ namespace IDE.Compiler public int32 mHotIdx; } + class RebuildFileChangedCommand : Command + { + public String mDir = new .() ~ delete _; + } + + public void* mNativeBfCompiler; public bool mIsResolveOnly; public BfSystem mBfSystem; bool mWantsRemoveOldData; + public Dictionary mRebuildWatchingFiles = new .() ~ delete _; public this(void* nativeBfCompiler) { @@ -214,6 +227,13 @@ namespace IDE.Compiler { BfCompiler_Delete(mNativeBfCompiler); mNativeBfCompiler = null; + + for (var kv in mRebuildWatchingFiles) + { + gApp.mFileWatcher.RemoveWatch(kv.key, kv.value); + delete kv.key; + delete kv.value; + } } public bool Compile(BfPassInstance passInstance, String outputDirectory) @@ -249,6 +269,12 @@ namespace IDE.Compiler outAutocompleteInfo.Append(StringView(result)); } + public void GetRebuildFileSet(String outDirInfo) + { + char8* result = BfCompiler_GetRebuildFileSet(mNativeBfCompiler); + outDirInfo.Append(StringView(result)); + } + public void GetSymbolReferences(BfPassInstance passInstance, BfResolvePassData resolvePassData, String outSymbolReferences) { char8* result = BfCompiler_GetSymbolReferences(mNativeBfCompiler, passInstance.mNativeBfPassInstance, resolvePassData.mNativeResolvePassData); @@ -531,6 +557,7 @@ namespace IDE.Compiler { var compileCommand = (CompileCommand)command; Compile(passInstance, compileCommand.mOutputDirectory); + UpdateRebuildFileWatches(); mBfSystem.RemoveOldParsers(); mBfSystem.RemoveOldData(); } @@ -547,7 +574,8 @@ namespace IDE.Compiler // If we get canceled then try again after waiting a couple updates if (!ClassifySource(passInstance, null, resolvePassData, null)) QueueDeferredResolveAll(); - + UpdateRebuildFileWatches(); + delete resolvePassData; wantsRemoveOldData = true; passKind = .Classify; @@ -570,6 +598,11 @@ namespace IDE.Compiler { mWantsActiveViewRefresh = true; } + + if (var dirChangedCommand = command as RebuildFileChangedCommand) + { + BfCompiler_FileChanged(mNativeBfCompiler, dirChangedCommand.mDir); + } } mBfSystem.Unlock(); @@ -842,5 +875,54 @@ namespace IDE.Compiler { return BfCompiler_GetLastHadComptimeRebuilds(mNativeBfCompiler); } + + void UpdateRebuildFileWatches() + { + HashSet curWatches = scope .(); + + var rebuildDirStr = GetRebuildFileSet(.. scope .()); + for (var dir in rebuildDirStr.Split('\n', .RemoveEmptyEntries)) + { + curWatches.Add(dir); + if (mRebuildWatchingFiles.TryAddAlt(dir, var keyPtr, var valuePtr)) + { + *keyPtr = new String(dir); + String watchFile = *valuePtr = new .(); + watchFile.Append(dir); + if ((watchFile.EndsWith(Path.DirectorySeparatorChar)) || (watchFile.EndsWith(Path.AltDirectorySeparatorChar))) + watchFile.Append("*"); + gApp.mFileWatcher.WatchFile(watchFile, watchFile); + } + } + + List oldKeys = scope .(); + for (var kv in mRebuildWatchingFiles) + { + if (!curWatches.Contains(kv.key)) + { + gApp.mFileWatcher.RemoveWatch(kv.key, kv.value); + oldKeys.Add(kv.key); + } + } + + for (var key in oldKeys) + { + var kv = mRebuildWatchingFiles.GetAndRemove(key).Value; + delete kv.key; + delete kv.value; + } + } + + public bool HasRebuildFileWatches() + { + return !mRebuildWatchingFiles.IsEmpty; + } + + public void AddChangedDirectory(StringView str) + { + var dirChangedCommand = new RebuildFileChangedCommand(); + dirChangedCommand.mDir.Set(str); + QueueCommand(dirChangedCommand); + } } } diff --git a/IDE/src/FileWatcher.bf b/IDE/src/FileWatcher.bf index 90aaf15f..d068839f 100644 --- a/IDE/src/FileWatcher.bf +++ b/IDE/src/FileWatcher.bf @@ -55,7 +55,8 @@ namespace IDE Dictionary mWatchedFiles = new Dictionary() ~ DeleteDictionaryAndKeysAndValues!(_); // Including ref count List mChangeList = new .() ~ DeleteContainerAndItems!(_); Dictionary mChangeMap = new .() ~ delete _; - List mDependencyChangeList = new List() ~ delete _; + HashSet mDependencyChangeSet = new .() ~ delete _; + List mDependencyChangeList = new .() ~ delete _; List mQueuedRefreshWatcherEntries = new List() ~ delete _; public Monitor mMonitor = new Monitor() ~ delete _; List mQueuedFileChanges = new List() ~ DeleteContainerAndItems!(_); @@ -86,6 +87,14 @@ namespace IDE { bool isDirectory = filePath.EndsWith(Path.DirectorySeparatorChar); + if (!filePath.EndsWith('*')) + { + String starPath = Path.GetDirectoryPath(filePath, .. scope .()); + starPath.Append(Path.DirectorySeparatorChar); + starPath.Append('*'); + FileChanged(starPath, null, .Changed); + } + var newPath; if (isDirectory) { @@ -194,9 +203,10 @@ namespace IDE { if (var tryProjectItem = dep as ProjectItem) projectItem = tryProjectItem; - if ((dep != null) && (!mDependencyChangeList.Contains(dep))) - { - mDependencyChangeList.Add(dep); + if (dep != null) + { + if (mDependencyChangeSet.Add(dep)) + mDependencyChangeList.Add(dep); } } @@ -535,7 +545,8 @@ namespace IDE String outKey; if (!mWatchedFiles.TryGet(fixedFilePath, out outKey, out depInfo)) return; - depInfo.mDependentObjects.Remove(dependentObject); + if (dependentObject != null) + depInfo.mDependentObjects.Remove(dependentObject); if (depInfo.mDependentObjects.Count == 0) { @@ -553,7 +564,8 @@ namespace IDE delete depInfo; } - mDependencyChangeList.Remove(dependentObject); + if (dependentObject != null) + mDependencyChangeSet.Remove(dependentObject); } #endif } @@ -644,10 +656,10 @@ namespace IDE { using (mMonitor.Enter()) { - if (mDependencyChangeList.Count == 0) + if (mDependencyChangeList.IsEmpty) return null; - Object dep = mDependencyChangeList[0]; - mDependencyChangeList.RemoveAt(0); + Object dep = mDependencyChangeList.PopFront(); + mDependencyChangeSet.Remove(dep); return dep; } } @@ -656,7 +668,7 @@ namespace IDE { using (mMonitor.Enter()) { - mDependencyChangeList.Add(obj); + mDependencyChangeSet.Add(obj); } } } diff --git a/IDE/src/IDEApp.bf b/IDE/src/IDEApp.bf index 138410ee..182f77c5 100644 --- a/IDE/src/IDEApp.bf +++ b/IDE/src/IDEApp.bf @@ -13032,6 +13032,14 @@ namespace IDE } else if (changeType == .Failed) { + if (mBfResolveCompiler?.HasRebuildFileWatches() == true) + { + mBfResolveCompiler.AddChangedDirectory("*"); + mBfResolveCompiler.QueueDeferredResolveAll(); + } + if (mBfBuildCompiler?.HasRebuildFileWatches() == true) + mBfBuildCompiler.AddChangedDirectory("*"); + if (mProjectPanel != null) { if (let projectFolder = projectItem as ProjectFolder) @@ -13115,13 +13123,29 @@ namespace IDE while (true) { - var dep = mFileWatcher.PopChangedDependency(); - if (dep == null) - break; - var projectSourceDep = dep as ProjectSource; - if (projectSourceDep != null) + using (mFileWatcher.mMonitor.Enter()) { - // We process these projectSources directly from the filename below + var dep = mFileWatcher.PopChangedDependency(); + if (dep == null) + break; + var projectSourceDep = dep as ProjectSource; + if (projectSourceDep != null) + { + // We process these projectSources directly from the filename below + } + if (var path = dep as String) + { + StringView usePath = path; + if (usePath.EndsWith('*')) + usePath.RemoveFromEnd(1); + if (mBfResolveCompiler != null) + { + mBfResolveCompiler.AddChangedDirectory(usePath); + mBfResolveCompiler.QueueDeferredResolveAll(); + } + if (mBfBuildCompiler != null) + mBfBuildCompiler.AddChangedDirectory(usePath); + } } } diff --git a/IDEHelper/Compiler/BfCompiler.cpp b/IDEHelper/Compiler/BfCompiler.cpp index 41b8863d..b32e4579 100644 --- a/IDEHelper/Compiler/BfCompiler.cpp +++ b/IDEHelper/Compiler/BfCompiler.cpp @@ -6565,6 +6565,8 @@ bool BfCompiler::DoCompile(const StringImpl& outputDirectory) } } + mRebuildFileSet.Clear(); + // Inc revision for next run through Compile mRevision++; mHasComptimeRebuilds = false; @@ -8149,7 +8151,7 @@ String BfCompiler::GetGeneratorString(BfTypeDef* typeDef, BfTypeInstance* typeIn SetAndRestoreValue prevTypeInstance(mContext->mUnreifiedModule->mCurTypeInstance, typeInst); BfExprEvaluator exprEvaluator(mContext->mUnreifiedModule); - exprEvaluator.mBfEvalExprFlags = BfEvalExprFlags_Comptime; + exprEvaluator.mBfEvalExprFlags = (BfEvalExprFlags)(BfEvalExprFlags_Comptime | BfEvalExprFlags_NoCeRebuildFlags); SizedArray irArgs; if (args != NULL) @@ -8189,7 +8191,7 @@ String BfCompiler::GetGeneratorTypeDefList() BfProject* curProject = NULL; Dictionary projectIds; - BfResolvePassData resolvePassData; + BfResolvePassData resolvePassData; SetAndRestoreValue prevResolvePassData(mResolvePassData, &resolvePassData); BfPassInstance passInstance(mSystem); SetAndRestoreValue prevPassInstance(mPassInstance, &passInstance); @@ -8226,7 +8228,7 @@ String BfCompiler::GetGeneratorTypeDefList() String BfCompiler::GetGeneratorInitData(const StringImpl& typeName, const StringImpl& args) { - BfResolvePassData resolvePassData; + BfResolvePassData resolvePassData; SetAndRestoreValue prevResolvePassData(mResolvePassData, &resolvePassData); BfPassInstance passInstance(mSystem); SetAndRestoreValue prevPassInstance(mPassInstance, &passInstance); @@ -9444,6 +9446,22 @@ BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetAutocompleteInfo(BfCompiler* bfC return autoCompleteResultString.c_str(); } +BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetRebuildFileSet(BfCompiler* bfCompiler) +{ + String& autoCompleteResultString = *gTLStrReturn.Get(); + for (auto& val : bfCompiler->mRebuildFileSet) + { + autoCompleteResultString += val; + autoCompleteResultString += "\n"; + } + return autoCompleteResultString.c_str(); +} + +BF_EXPORT void BF_CALLTYPE BfCompiler_FileChanged(BfCompiler* bfCompiler, const char* dirPath) +{ + bfCompiler->mRebuildChangedFileSet.Add(dirPath); +} + BF_EXPORT const char* BF_CALLTYPE BfCompiler_GetSymbolReferences(BfCompiler* bfCompiler, BfPassInstance* bfPassInstance, BfResolvePassData* resolvePassData) { BP_ZONE("BfCompiler_GetSymbolReferences"); diff --git a/IDEHelper/Compiler/BfCompiler.h b/IDEHelper/Compiler/BfCompiler.h index 4c79b85c..b748ce50 100644 --- a/IDEHelper/Compiler/BfCompiler.h +++ b/IDEHelper/Compiler/BfCompiler.h @@ -336,6 +336,8 @@ public: int mHSPreserveIdx; BfModule* mLastAutocompleteModule; CompileState mCompileState; + HashSet mRebuildFileSet; + HashSet mRebuildChangedFileSet; // Files we had actual changes from Array mVDataModules; diff --git a/IDEHelper/Compiler/BfContext.cpp b/IDEHelper/Compiler/BfContext.cpp index 477fd2ce..3d10da23 100644 --- a/IDEHelper/Compiler/BfContext.cpp +++ b/IDEHelper/Compiler/BfContext.cpp @@ -1061,6 +1061,9 @@ void BfContext::RebuildType(BfType* type, bool deleteOnDemandTypes, bool rebuild delete typeInst->mTypeInfoEx; typeInst->mTypeInfoEx = NULL; + if (typeInst->mCeTypeInfo != NULL) + typeInst->mCeTypeInfo->mRebuildMap.Clear(); + if (typeInst->mTypeDef->mEmitParent != NULL) { auto emitTypeDef = typeInst->mTypeDef; @@ -1895,9 +1898,11 @@ void BfContext::UpdateRevisedTypes() Dictionary lastWriteTimeMap; + bool rebuildAllFilesChanged = mCompiler->mRebuildChangedFileSet.Contains("*"); + // Do primary 'rebuild' scan for (auto type : mResolvedTypes) - { + { auto typeInst = type->ToTypeInstance(); if (type == NULL) { @@ -1958,6 +1963,14 @@ void BfContext::UpdateRevisedTypes() } if (*valuePtr != kv.mValue.mInt) changed = true; + mCompiler->mRebuildFileSet.Add(kv.mKey.mString); + } + + if ((kv.mKey.mKind == CeRebuildKey::Kind_File) || (kv.mKey.mKind == CeRebuildKey::Kind_Directory)) + { + if ((rebuildAllFilesChanged) || (mCompiler->mRebuildChangedFileSet.Contains(kv.mKey.mString))) + changed = true; + mCompiler->mRebuildFileSet.Add(kv.mKey.mString); } } @@ -1984,20 +1997,15 @@ void BfContext::UpdateRevisedTypes() continue; } -// if ((mCompiler->mResolvePassData != NULL) && (mCompiler->mResolvePassData->mParser != NULL) && (!typeInst->IsSpecializedType())) -// { -// if (typeDef->HasSource(mCompiler->mResolvePassData->mParser)) -// { -// HandleChangedTypeDef(typeDef); -// } -// } - if (typeDef->mDefState != BfTypeDef::DefState_New) { defStateChangedQueue.Add(typeInst); } } + // We consumed this above + mCompiler->mRebuildChangedFileSet.Clear(); + for (auto typeInst : defStateChangedQueue) { BP_ZONE("BfContext::UpdateRevisedTypes defStateChangedQueue"); diff --git a/IDEHelper/Compiler/BfExprEvaluator.cpp b/IDEHelper/Compiler/BfExprEvaluator.cpp index 06c51aa1..5c9954fd 100644 --- a/IDEHelper/Compiler/BfExprEvaluator.cpp +++ b/IDEHelper/Compiler/BfExprEvaluator.cpp @@ -5541,7 +5541,9 @@ BfTypedValue BfExprEvaluator::CreateCall(BfAstNode* targetSrc, BfMethodInstance* } else { - CeEvalFlags evalFlags = CeEvalFlags_None; + CeEvalFlags evalFlags = CeEvalFlags_None; + if ((mBfEvalExprFlags & BfEvalExprFlags_NoCeRebuildFlags) != 0) + evalFlags = (CeEvalFlags)(evalFlags | CeEvalFlags_NoRebuild); auto constRet = mModule->mCompiler->mCEMachine->Call(targetSrc, mModule, methodInstance, irArgs, evalFlags, mExpectingType); if (constRet) { diff --git a/IDEHelper/Compiler/BfModule.h b/IDEHelper/Compiler/BfModule.h index 0be8a8b2..5f721261 100644 --- a/IDEHelper/Compiler/BfModule.h +++ b/IDEHelper/Compiler/BfModule.h @@ -79,6 +79,7 @@ enum BfEvalExprFlags BfEvalExprFlags_WasMethodRef = 0x800000, BfEvalExprFlags_DeclType = 0x1000000, BfEvalExprFlags_AllowBase = 0x2000000, + BfEvalExprFlags_NoCeRebuildFlags = 0x4000000, BfEvalExprFlags_InheritFlags = BfEvalExprFlags_NoAutoComplete | BfEvalExprFlags_Comptime | BfEvalExprFlags_DeclType }; diff --git a/IDEHelper/Compiler/CeMachine.cpp b/IDEHelper/Compiler/CeMachine.cpp index 78468f72..023c4097 100644 --- a/IDEHelper/Compiler/CeMachine.cpp +++ b/IDEHelper/Compiler/CeMachine.cpp @@ -3028,16 +3028,38 @@ BfError* CeContext::Fail(const CeFrame& curFrame, const StringImpl& str) ////////////////////////////////////////////////////////////////////////// -void CeContext::AddRebuild(const CeRebuildKey& key, const CeRebuildValue& value) +bool CeContext::AddRebuild(const CeRebuildKey& key, const CeRebuildValue& value) { if (mCurModule == NULL) - return; + return false; if (mCurModule->mCurTypeInstance == NULL) - return; + return false; + if ((mCurEvalFlags & CeEvalFlags_NoRebuild) != 0) + return false; if (mCurModule->mCurTypeInstance->mCeTypeInfo == NULL) mCurModule->mCurTypeInstance->mCeTypeInfo = new BfCeTypeInfo(); mCurModule->mCurTypeInstance->mCeTypeInfo->mRebuildMap[key] = value; mCurModule->mCompiler->mHasComptimeRebuilds = true; + return true; +} + +void CeContext::AddFileRebuild(const StringImpl& path) +{ + auto timeStamp = BfpFile_GetTime_LastWrite(path.c_str()); + if (timeStamp != 0) + { + String fixedPath = FixPathAndCase(path); + + CeRebuildKey rebuildKey; + rebuildKey.mKind = CeRebuildKey::Kind_File; + rebuildKey.mString = fixedPath; + + CeRebuildValue rebuildValue; + rebuildValue.mInt = timeStamp; + + if (AddRebuild(rebuildKey, rebuildValue)) + mCurModule->mCompiler->mRebuildFileSet.Add(fixedPath); + } } uint8* CeContext::CeMalloc(int size) @@ -5243,21 +5265,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* if (bfpFile != NULL) { if ((createKind == BfpFileCreateKind_OpenExisting) || (createKind == BfpFileCreateKind_OpenAlways)) - { - auto timeStamp = BfpFile_GetTime_LastWrite(path.c_str()); - if (timeStamp != 0) - { - CeRebuildKey rebuildKey; - rebuildKey.mKind = CeRebuildKey::Kind_File; - rebuildKey.mString = path; - - CeRebuildValue rebuildValue; - rebuildValue.mInt = timeStamp; - - AddRebuild(rebuildKey, rebuildValue); - } - } - + AddFileRebuild(path); CeInternalData* internalData = new CeInternalData(); internalData->mKind = CeInternalData::Kind_File; internalData->mFile = bfpFile; @@ -5351,6 +5359,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* addr_ce nameAddr = *(addr_ce*)((uint8*)stackPtr + 8); String path; CE_CHECKADDR_STR(path, nameAddr); + AddFileRebuild(path); result = BfpFile_GetTime_LastWrite(path.c_str()); } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_GetAttributes) @@ -5363,7 +5372,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* String path; CE_CHECKADDR_STR(path, nameAddr); - + AddFileRebuild(path); result = BfpFile_GetAttributes(path.c_str(), (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr)); } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_SetAttributes) @@ -5425,6 +5434,7 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* String path; CE_CHECKADDR_STR(path, nameAddr); + AddFileRebuild(path); result = BfpFile_Exists(path.c_str()); } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpFile_GetTempPath) @@ -5551,9 +5561,12 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* addr_ce outStdOutAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize); addr_ce outStdErrAddr = *(addr_ce*)((uint8*)stackPtr + ptrSize + ptrSize + ptrSize); - CE_CHECKADDR(outStdInAddr, ptrSize); - CE_CHECKADDR(outStdOutAddr, ptrSize); - CE_CHECKADDR(outStdErrAddr, ptrSize); + if (outStdInAddr != 0) + CE_CHECKADDR(outStdInAddr, ptrSize); + if (outStdOutAddr != 0) + CE_CHECKADDR(outStdOutAddr, ptrSize); + if (outStdErrAddr != NULL) + CE_CHECKADDR(outStdErrAddr, ptrSize); BfpFile* outStdIn = NULL; BfpFile* outStdOut = NULL; @@ -5580,9 +5593,12 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* } }; - _SetHandle(outStdInAddr, outStdIn); - _SetHandle(outStdOutAddr, outStdOut); - _SetHandle(outStdErrAddr, outStdErr); + if (outStdInAddr != NULL) + _SetHandle(outStdInAddr, outStdIn); + if (outStdOutAddr != NULL) + _SetHandle(outStdOutAddr, outStdOut); + if (outStdErrAddr != NULL) + _SetHandle(outStdErrAddr, outStdErr); } else if (checkFunction->mFunctionKind == CeFunctionKind_BfpSpawn_Kill) { @@ -5665,19 +5681,17 @@ bool CeContext::Execute(CeFunction* startFunction, uint8* startStackPtr, uint8* auto bfpFindFileData = BfpFindFileData_FindFirstFile(path.c_str(), (BfpFindFileFlags)flags, (outResultAddr == 0) ? NULL : (BfpFileResult*)(memStart + outResultAddr)); if (bfpFindFileData != NULL) - { -// auto timeStamp = BfpFile_GetTime_LastWrite(path.c_str()); -// if (timeStamp != 0) -// { -// CeRebuildKey rebuildKey; -// rebuildKey.mKind = CeRebuildKey::Kind_File; -// rebuildKey.mString = path; -// -// CeRebuildValue rebuildValue; -// rebuildValue.mInt = timeStamp; -// -// AddRebuild(rebuildKey, rebuildValue); -// } + { + String dir = GetFileDir(path); + dir = FixPathAndCase(dir); + dir.Append(DIR_SEP_CHAR); + + CeRebuildKey rebuildKey; + rebuildKey.mKind = CeRebuildKey::Kind_Directory; + rebuildKey.mString = dir; + CeRebuildValue rebuildValue; + if (AddRebuild(rebuildKey, rebuildValue)) + mCurModule->mCompiler->mRebuildFileSet.Add(dir); CeInternalData* internalData = new CeInternalData(); internalData->mKind = CeInternalData::Kind_FindFileData; diff --git a/IDEHelper/Compiler/CeMachine.h b/IDEHelper/Compiler/CeMachine.h index 2f16f7b6..7fd444f4 100644 --- a/IDEHelper/Compiler/CeMachine.h +++ b/IDEHelper/Compiler/CeMachine.h @@ -530,6 +530,7 @@ enum CeEvalFlags CeEvalFlags_Cascade = 1, CeEvalFlags_PersistantError = 2, CeEvalFlags_DeferIfNotOnlyError = 4, + CeEvalFlags_NoRebuild = 8 }; enum CeOperandKind @@ -766,7 +767,8 @@ public: enum Kind { Kind_None, - Kind_File + Kind_File, + Kind_Directory }; public: @@ -866,7 +868,8 @@ public: BfError* Fail(const StringImpl& error); BfError* Fail(const CeFrame& curFrame, const StringImpl& error); - void AddRebuild(const CeRebuildKey& key, const CeRebuildValue& value); + bool AddRebuild(const CeRebuildKey& key, const CeRebuildValue& value); + void AddFileRebuild(const StringImpl& filePath); uint8* CeMalloc(int size); bool CeFree(addr_ce addr); addr_ce CeAllocArray(BfArrayType* arrayType, int count, addr_ce& elemsAddr);