Workspace.bf 45 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Text;
  4. using System.Threading.Tasks;
  5. using Beefy;
  6. using Beefy.utils;
  7. using System.Diagnostics;
  8. using System.Threading;
  9. using IDE.Util;
  10. namespace IDE
  11. {
  12. [Reflect(.StaticFields | .NonStaticFields | .ApplyToInnerTypes)]
  13. public class Workspace
  14. {
  15. public enum IntermediateType
  16. {
  17. Object,
  18. IRCode,
  19. ObjectAndIRCode
  20. }
  21. public enum MachineType
  22. {
  23. case x86;
  24. case x64;
  25. public int32 PtrSize
  26. {
  27. get
  28. {
  29. switch (this)
  30. {
  31. case .x86:
  32. return 4;
  33. case .x64:
  34. return 8;
  35. }
  36. }
  37. }
  38. }
  39. public enum PlatformType
  40. {
  41. case Unknown;
  42. case Windows;
  43. case Linux;
  44. public static PlatformType GetFromName(String name)
  45. {
  46. switch (name)
  47. {
  48. case "Win32", "Win64": return .Windows;
  49. case "Linux32", "Linux64": return .Linux;
  50. default: return .Unknown;
  51. }
  52. }
  53. public static PlatformType GetHostPlatform()
  54. {
  55. #if BF_PLATFORM_WINDOWS
  56. return .Windows;
  57. #endif
  58. #if BF_PLATFORM_LINUX
  59. return .Linux;
  60. #endif
  61. #unwarn
  62. return .Unknown;
  63. }
  64. public static int GetPtrSizeByName(String name)
  65. {
  66. if (name.EndsWith("32"))
  67. return 4;
  68. return 8;
  69. }
  70. public static bool GetTargetTripleByName(String name, ToolsetType toolsetType, String outTriple)
  71. {
  72. switch (name)
  73. {
  74. case "Win32":
  75. outTriple.Append((toolsetType == .GNU) ? "i686-pc-windows-gnu" : "i686-pc-windows-msvc");
  76. case "Win64":
  77. outTriple.Append((toolsetType == .GNU) ? "x86_64-pc-windows-gnu" : "x86_64-pc-windows-msvc");
  78. case "Linux32":
  79. outTriple.Append("i686-unknown-linux-gnu");
  80. case "Linux64":
  81. outTriple.Append("x86_64-unknown-linux-gnu");
  82. case "macOS":
  83. outTriple.Append("x86_64-apple-macosx10.14.0");
  84. case "iOS":
  85. outTriple.Append("arm64-apple-ios13.1");
  86. default:
  87. return false;
  88. }
  89. return true;
  90. }
  91. }
  92. public enum ToolsetType
  93. {
  94. case GNU;
  95. case Microsoft;
  96. case LLVM;
  97. public static ToolsetType Default
  98. {
  99. get
  100. {
  101. #if BF_PLATFORM_WINDOWS
  102. return Microsoft;
  103. #else
  104. return .GNU;
  105. #endif
  106. }
  107. }
  108. }
  109. public enum BuildKind
  110. {
  111. case Normal;
  112. case Test;
  113. }
  114. public enum COptimizationLevel
  115. {
  116. O0,
  117. O1,
  118. O2,
  119. O3,
  120. Ofast,
  121. Og,
  122. }
  123. public class ConfigSelection : IHashable, IEquatable
  124. {
  125. public bool mEnabled = true;
  126. public String mConfig ~ delete _;
  127. public String mPlatform ~ delete _;
  128. public ConfigSelection Duplicate()
  129. {
  130. ConfigSelection cs = new ConfigSelection();
  131. cs.mEnabled = mEnabled;
  132. cs.mConfig = new String(mConfig);
  133. cs.mPlatform = new String(mPlatform);
  134. return cs;
  135. }
  136. public bool Equals(Object value)
  137. {
  138. ConfigSelection other = value as ConfigSelection;
  139. if (other == null)
  140. return false;
  141. return (mEnabled == other.mEnabled) &&
  142. (mConfig == other.mConfig) &&
  143. (mPlatform == other.mPlatform);
  144. }
  145. public int GetHashCode()
  146. {
  147. return mConfig.GetHashCode();
  148. }
  149. }
  150. public enum AllocType
  151. {
  152. Debug,
  153. CRT,
  154. JEMalloc,
  155. TCMalloc,
  156. Custom
  157. }
  158. public class BeefGlobalOptions
  159. {
  160. [Reflect]
  161. public List<String> mPreprocessorMacros = new List<String>() ~ DeleteContainerAndItems!(_);
  162. [Reflect]
  163. public List<DistinctBuildOptions> mDistinctBuildOptions = new List<DistinctBuildOptions>() ~ DeleteContainerAndItems!(_);
  164. }
  165. public class Options
  166. {
  167. [Reflect]
  168. public ToolsetType mToolsetType;
  169. [Reflect]
  170. public BuildKind mBuildKind;
  171. [Reflect]
  172. public bool mIncrementalBuild = true;
  173. [Reflect]
  174. public IntermediateType mIntermediateType;
  175. [Reflect]
  176. public BuildOptions.SIMDSetting mBfSIMDSetting = .SSE2;
  177. [Reflect]
  178. public BuildOptions.BfOptimizationLevel mBfOptimizationLevel;
  179. [Reflect]
  180. public BuildOptions.SIMDSetting mCSIMDSetting = .SSE2;
  181. [Reflect]
  182. public COptimizationLevel mCOptimizationLevel;
  183. [Reflect]
  184. public BuildOptions.LTOType mLTOType;
  185. [Reflect]
  186. public bool mNoOmitFramePointers;
  187. [Reflect]
  188. public bool mLargeStrings;
  189. [Reflect]
  190. public bool mLargeCollections;
  191. [Reflect]
  192. public AllocType mAllocType = .CRT;
  193. [Reflect]
  194. public String mAllocMalloc = new String() ~ delete _;
  195. [Reflect]
  196. public String mAllocFree = new String() ~ delete _;
  197. [Reflect]
  198. public BuildOptions.EmitDebugInfo mEmitDebugInfo;
  199. [Reflect]
  200. public bool mInitLocalVariables;
  201. //public bool mAllowStructByVal;
  202. [Reflect]
  203. public bool mRuntimeChecks;
  204. [Reflect]
  205. public bool mEmitDynamicCastCheck;
  206. [Reflect]
  207. public bool mEnableObjectDebugFlags;
  208. [Reflect]
  209. public bool mEmitObjectAccessCheck; // Only valid with mObjectHasDebugFlags
  210. [Reflect]
  211. public bool mEnableRealtimeLeakCheck;
  212. [Reflect]
  213. public bool mEnableSideStack;
  214. [Reflect]
  215. public bool mAllowHotSwapping;
  216. [Reflect]
  217. public int32 mAllocStackTraceDepth;
  218. [Reflect]
  219. public List<String> mPreprocessorMacros = new List<String>() ~ DeleteContainerAndItems!(_);
  220. [Reflect]
  221. public List<DistinctBuildOptions> mDistinctBuildOptions = new List<DistinctBuildOptions>() ~ DeleteContainerAndItems!(_);
  222. public Dictionary<Project, ConfigSelection> mConfigSelections = new Dictionary<Project, ConfigSelection>() ~ delete _;
  223. public ~this()
  224. {
  225. for (var configSel in mConfigSelections.Values)
  226. delete configSel;
  227. }
  228. public bool IsTestProject(Project project)
  229. {
  230. return ((mBuildKind == .Test) &&
  231. ((project.mGeneralOptions.mTargetType == .BeefConsoleApplication) ||
  232. (project.mGeneralOptions.mTargetType == .BeefWindowsApplication) ||
  233. (project.mGeneralOptions.mTargetType == .BeefConsoleApplication)));
  234. }
  235. public void CopyFrom(Workspace.Options prev)
  236. {
  237. mToolsetType = prev.mToolsetType;
  238. mBuildKind = prev.mBuildKind;
  239. mIncrementalBuild = prev.mIncrementalBuild;
  240. mIntermediateType = prev.mIntermediateType;
  241. mBfSIMDSetting = prev.mBfSIMDSetting;
  242. mBfOptimizationLevel = prev.mBfOptimizationLevel;
  243. mCSIMDSetting = prev.mCSIMDSetting;
  244. mCOptimizationLevel = prev.mCOptimizationLevel;
  245. mLTOType = prev.mLTOType;
  246. mNoOmitFramePointers = prev.mNoOmitFramePointers;
  247. mLargeStrings = prev.mLargeStrings;
  248. mLargeCollections = prev.mLargeCollections;
  249. mAllocType = prev.mAllocType;
  250. mAllocMalloc.Set(prev.mAllocMalloc);
  251. mAllocFree.Set(prev.mAllocFree);
  252. mEmitDebugInfo = prev.mEmitDebugInfo;
  253. mInitLocalVariables = prev.mInitLocalVariables;
  254. mRuntimeChecks = prev.mRuntimeChecks;
  255. mEmitDynamicCastCheck = prev.mEmitDynamicCastCheck;
  256. mEnableObjectDebugFlags = prev.mEnableObjectDebugFlags;
  257. mEmitObjectAccessCheck = prev.mEmitObjectAccessCheck;
  258. mEnableRealtimeLeakCheck = prev.mEnableRealtimeLeakCheck;
  259. mEnableSideStack = prev.mEnableSideStack;
  260. mAllowHotSwapping = prev.mAllowHotSwapping;
  261. mAllocStackTraceDepth = prev.mAllocStackTraceDepth;
  262. for (var preProc in prev.mPreprocessorMacros)
  263. mPreprocessorMacros.Add(new String(preProc));
  264. for (var typeOptionKV in prev.mConfigSelections)
  265. {
  266. let prevConfig = typeOptionKV.value;
  267. let newConfig = prevConfig.Duplicate();
  268. mConfigSelections[typeOptionKV.key] = newConfig;
  269. }
  270. for (var typeOption in prev.mDistinctBuildOptions)
  271. {
  272. var newTypeOption = typeOption.Duplicate();
  273. mDistinctBuildOptions.Add(newTypeOption);
  274. }
  275. }
  276. }
  277. public class Config
  278. {
  279. public Dictionary<String, Options> mPlatforms = new Dictionary<String, Options>() ~ DeleteDictionyAndKeysAndItems!(_);
  280. }
  281. public BeefGlobalOptions mBeefGlobalOptions = new BeefGlobalOptions() ~ delete _;
  282. public Dictionary<String, Config> mConfigs = new Dictionary<String, Config>() ~ DeleteDictionyAndKeysAndItems!(_);
  283. public class ProjectSourceCompileInstance
  284. {
  285. public String mSource ~ delete _;
  286. public IdSpan mSourceCharIdData ~ _.Dispose();
  287. public int32 mRefCount = 1;
  288. public this()
  289. {
  290. }
  291. public void Deref()
  292. {
  293. if (--mRefCount == 0)
  294. delete this;
  295. }
  296. public ~this()
  297. {
  298. }
  299. }
  300. public class CompileInstance
  301. {
  302. public enum CompileResult
  303. {
  304. Compiling,
  305. Success,
  306. PendingHotLoad,
  307. Failure,
  308. }
  309. public Dictionary<ProjectItem, ProjectSourceCompileInstance> mProjectItemCompileInstances = new Dictionary<ProjectItem, ProjectSourceCompileInstance>() ~ delete _;
  310. public CompileResult mCompileResult = .Compiling;
  311. public bool mIsReused;
  312. public ~this()
  313. {
  314. for (var compileInstance in mProjectItemCompileInstances.Values)
  315. if (compileInstance != null)
  316. compileInstance.Deref();
  317. }
  318. }
  319. public class ProjectSpec
  320. {
  321. public String mProjectName ~ delete _;
  322. public VerSpecRecord mVerSpec ~ delete _;
  323. }
  324. public Monitor mMonitor = new Monitor() ~ delete _;
  325. public String mName ~ delete _;
  326. public String mDir ~ delete _;
  327. public CompositeFile mCompositeFile ~ delete _;
  328. public List<Project> mProjects = new List<Project>() ~ DeleteContainerAndItems!(_);
  329. public List<ProjectSpec> mProjectSpecs = new .() ~ DeleteContainerAndItems!(_);
  330. public Dictionary<String, Project> mProjectNameMap = new .() ~ DeleteDictionyAndKeys!(_);
  331. public Project mStartupProject;
  332. public bool mNeedsCreate;
  333. public bool mHasChanged;
  334. public bool mHadHotCompileSinceLastFullCompile;
  335. public bool mForceNextCompile;
  336. public List<CompileInstance> mCompileInstanceList = new List<CompileInstance>() ~ DeleteContainerAndItems!(_); // First item is primary compile, secondaries are hot reloads
  337. public List<String> mPlatforms = new List<String>() ~ DeleteContainerAndItems!(_);
  338. public List<String> mUserPlatforms = new List<String>() ~ DeleteContainerAndItems!(_);
  339. public bool mIsDebugSession;
  340. public int32 HotCompileIdx
  341. {
  342. get
  343. {
  344. return (.)mCompileInstanceList.Count - 1;
  345. }
  346. }
  347. public bool IsSingleFileWorkspace
  348. {
  349. get
  350. {
  351. return mCompositeFile != null;
  352. }
  353. }
  354. public bool IsDebugSession
  355. {
  356. get
  357. {
  358. return mIsDebugSession;
  359. }
  360. }
  361. public this()
  362. {
  363. }
  364. public bool IsInitialized
  365. {
  366. get
  367. {
  368. return (mName != null) || (IsDebugSession);
  369. }
  370. }
  371. public void SetChanged()
  372. {
  373. mHasChanged = true;
  374. }
  375. public void MarkPlatformNamesDirty()
  376. {
  377. ClearAndDeleteItems(mPlatforms);
  378. }
  379. public void GetPlatformList(List<String> outList)
  380. {
  381. if (mPlatforms.IsEmpty)
  382. {
  383. HashSet<String> platformSet = scope .();
  384. void Add(String str)
  385. {
  386. if (platformSet.Add(str))
  387. mPlatforms.Add(new String(str));
  388. }
  389. Add(IDEApp.sPlatform32Name);
  390. Add(IDEApp.sPlatform64Name);
  391. for (let config in mConfigs.Values)
  392. {
  393. for (let platform in config.mPlatforms.Keys)
  394. Add(platform);
  395. }
  396. /*for (let project in mProjects)
  397. {
  398. for (let config in project.mConfigs.Values)
  399. {
  400. for (let platform in config.mPlatforms.Keys)
  401. Add(platform);
  402. }
  403. }*/
  404. mPlatforms.Sort(scope (a, b) => String.Compare(a, b, true));
  405. }
  406. for (let str in mPlatforms)
  407. outList.Add(str);
  408. }
  409. public Options GetOptions(String configName, String platformName)
  410. {
  411. Config config;
  412. mConfigs.TryGetValue(configName, out config);
  413. if (config == null)
  414. return null;
  415. Options options;
  416. config.mPlatforms.TryGetValue(platformName, out options);
  417. return options;
  418. }
  419. public void Serialize(StructuredData data)
  420. {
  421. void WriteStrings(String name, List<String> strs)
  422. {
  423. if (!strs.IsEmpty)
  424. {
  425. using (data.CreateArray(name))
  426. {
  427. for (var str in strs)
  428. data.Add(str);
  429. }
  430. }
  431. }
  432. void WriteDistinctOptions(List<DistinctBuildOptions> distinctBuildOptions)
  433. {
  434. if (distinctBuildOptions.IsEmpty)
  435. return;
  436. using (data.CreateArray("DistinctOptions"))
  437. {
  438. for (let typeOptions in distinctBuildOptions)
  439. {
  440. // This '.Deleted' can only happen if we're editing the properties but haven't committed yet
  441. if (typeOptions.mCreateState == .Deleted)
  442. continue;
  443. using (data.CreateObject())
  444. typeOptions.Serialize(data);
  445. }
  446. data.RemoveIfEmpty();
  447. }
  448. }
  449. if (!IsSingleFileWorkspace)
  450. data.Add("FileVersion", 1);
  451. using (data.CreateObject("Workspace"))
  452. {
  453. if (mStartupProject != null)
  454. data.Add("StartupProject", mStartupProject.mProjectName);
  455. WriteStrings("PreprocessorMacros", mBeefGlobalOptions.mPreprocessorMacros);
  456. WriteDistinctOptions(mBeefGlobalOptions.mDistinctBuildOptions);
  457. data.RemoveIfEmpty();
  458. }
  459. if (!mProjectSpecs.IsEmpty)
  460. {
  461. using (data.CreateObject("Projects", true))
  462. {
  463. for (var projSpec in mProjectSpecs)
  464. {
  465. projSpec.mVerSpec.Serialize(projSpec.mProjectName, data);
  466. }
  467. }
  468. }
  469. //
  470. {
  471. List<Project> unlockedProject = scope .();
  472. List<Project> lockedProject = scope .();
  473. for (var project in mProjects)
  474. {
  475. if (project.mLocked != project.mLockedDefault)
  476. {
  477. if (project.mLocked)
  478. lockedProject.Add(project);
  479. else
  480. unlockedProject.Add(project);
  481. }
  482. }
  483. if (!lockedProject.IsEmpty)
  484. {
  485. using (data.CreateArray("Locked"))
  486. {
  487. for (let project in lockedProject)
  488. data.Add(project.mProjectName);
  489. }
  490. }
  491. if (!unlockedProject.IsEmpty)
  492. {
  493. using (data.CreateArray("Unlocked"))
  494. {
  495. for (let project in unlockedProject)
  496. data.Add(project.mProjectName);
  497. }
  498. }
  499. }
  500. using (data.CreateObject("Configs"))
  501. {
  502. for (var configKeyValue in mConfigs)
  503. {
  504. var configName = configKeyValue.key;
  505. //bool isRelease = configName.Contains("Release");
  506. #unwarn
  507. bool isDebug = configName.Contains("Debug");
  508. bool isRelease = configName.Contains("Release");
  509. bool isParanoid = configName.Contains("Paranoid");
  510. bool isTest = configName.Contains("Test");
  511. var config = configKeyValue.value;
  512. using (data.CreateObject(configName))
  513. {
  514. for (var platformKeyValue in config.mPlatforms)
  515. {
  516. var options = platformKeyValue.value;
  517. var platformName = platformKeyValue.key;
  518. using (data.CreateObject(platformName))
  519. {
  520. using (data.CreateArray("PreprocessorMacros"))
  521. {
  522. for (var macro in options.mPreprocessorMacros)
  523. data.Add(macro);
  524. data.RemoveIfEmpty();
  525. }
  526. data.ConditionalAdd("Toolset", options.mToolsetType, ToolsetType.Default);
  527. data.ConditionalAdd("BuildKind", options.mBuildKind, isTest ? .Test : .Normal);
  528. data.ConditionalAdd("BfSIMDSetting", options.mBfSIMDSetting, .SSE2);
  529. #if BF_PLATFORM_WINDOWS
  530. data.ConditionalAdd("BfOptimizationLevel", options.mBfOptimizationLevel, isRelease ? .O2 : (platformName == "Win64") ? .OgPlus : .O0);
  531. #else
  532. data.ConditionalAdd("BfOptimizationLevel", options.mBfOptimizationLevel, isRelease ? .O2 : .O0);
  533. #endif
  534. data.ConditionalAdd("LTOType", options.mLTOType, .None);
  535. data.ConditionalAdd("AllocType", options.mAllocType, isRelease ? .CRT : .Debug);
  536. data.ConditionalAdd("AllocMalloc", options.mAllocMalloc, "");
  537. data.ConditionalAdd("AllocFree", options.mAllocFree, "");
  538. data.ConditionalAdd("EmitDebugInfo", options.mEmitDebugInfo, .Yes);
  539. data.ConditionalAdd("NoOmitFramePointers", options.mNoOmitFramePointers, false);
  540. data.ConditionalAdd("LargeStrings", options.mLargeStrings, false);
  541. data.ConditionalAdd("LargeCollections", options.mLargeCollections, false);
  542. data.ConditionalAdd("InitLocalVariables", options.mInitLocalVariables, false);
  543. data.ConditionalAdd("RuntimeChecks", options.mRuntimeChecks, !isRelease);
  544. data.ConditionalAdd("EmitDynamicCastCheck", options.mEmitDynamicCastCheck, !isRelease);
  545. data.ConditionalAdd("EnableObjectDebugFlags", options.mEnableObjectDebugFlags, !isRelease);
  546. data.ConditionalAdd("EmitObjectAccessCheck", options.mEmitObjectAccessCheck, !isRelease);
  547. data.ConditionalAdd("EnableRealtimeLeakCheck", options.mEnableRealtimeLeakCheck, !isRelease);
  548. data.ConditionalAdd("EnableSideStack", options.mEnableSideStack, isParanoid);
  549. data.ConditionalAdd("AllowHotSwapping", options.mAllowHotSwapping, !isRelease);
  550. data.ConditionalAdd("AllocStackTraceDepth", options.mAllocStackTraceDepth, 1);
  551. data.ConditionalAdd("IncrementalBuild", options.mIncrementalBuild, !isRelease);
  552. data.ConditionalAdd("IntermediateType", options.mIntermediateType, .Object);
  553. data.ConditionalAdd("CSIMDSetting", options.mCSIMDSetting, .SSE2);
  554. data.ConditionalAdd("COptimizationLevel", options.mCOptimizationLevel, isRelease ? .O2 : .O0);
  555. using (data.CreateObject("ConfigSelections", true))
  556. {
  557. for (var configPair in options.mConfigSelections)
  558. {
  559. let projectName = configPair.key.mProjectName;
  560. using (data.CreateObject(projectName))
  561. {
  562. String expectConfig = configName;
  563. if (isTest)
  564. {
  565. if (projectName != mProjects[0].mProjectName)
  566. expectConfig = "Debug";
  567. }
  568. var configSelection = configPair.value;
  569. data.ConditionalAdd("Enabled", configSelection.mEnabled, true);
  570. data.ConditionalAdd("Config", configSelection.mConfig, expectConfig);
  571. data.ConditionalAdd("Platform", configSelection.mPlatform, platformName);
  572. data.RemoveIfEmpty();
  573. }
  574. }
  575. data.RemoveIfEmpty();
  576. }
  577. WriteDistinctOptions(options.mDistinctBuildOptions);
  578. }
  579. }
  580. }
  581. }
  582. }
  583. }
  584. public void ClearProjectNameCache()
  585. {
  586. for (var key in mProjectNameMap.Keys)
  587. delete key;
  588. mProjectNameMap.Clear();
  589. }
  590. public Project FindProject(StringView projectName)
  591. {
  592. if (mProjectNameMap.IsEmpty)
  593. {
  594. void Add(String name, Project project)
  595. {
  596. bool added = mProjectNameMap.TryAdd(name, var keyPtr, var valuePtr);
  597. if (!added)
  598. return;
  599. *keyPtr = new String(name);
  600. *valuePtr = project;
  601. }
  602. for (var project in mProjects)
  603. Add(project.mProjectName, project);;
  604. for (var project in mProjects)
  605. {
  606. for (var alias in project.mGeneralOptions.mAliases)
  607. Add(alias, project);
  608. }
  609. }
  610. if (mProjectNameMap.TryGetWith(projectName, var matchKey, var value))
  611. {
  612. return value;
  613. }
  614. return null;
  615. }
  616. public void SetupDefault(Options options, String configName, String platformName)
  617. {
  618. #unwarn
  619. //bool isDebug = configName.Contains("Debug");
  620. #unwarn
  621. bool isRelease = configName.Contains("Release");
  622. #unwarn
  623. bool isParanoid = configName.Contains("Paranoid");
  624. bool isTest = configName.Contains("Test");
  625. options.mBfSIMDSetting = .SSE2;
  626. #if BF_PLATFORM_WINDOWS
  627. options.mBfOptimizationLevel = isRelease ? .O2 : (platformName == "Win64") ? .OgPlus : .O0;
  628. options.mToolsetType = .Microsoft;
  629. #else
  630. options.mBfOptimizationLevel = isRelease ? .O2 : .O0;
  631. options.mToolsetType = .GNU;
  632. #endif
  633. options.mAllocType = isRelease ? .CRT : .Debug;
  634. options.mEmitDebugInfo = .Yes;
  635. options.mNoOmitFramePointers = false;
  636. options.mLargeStrings = false;
  637. options.mLargeCollections = false;
  638. options.mInitLocalVariables = false;
  639. options.mRuntimeChecks = !isRelease;
  640. options.mEmitDynamicCastCheck = !isRelease;
  641. options.mEnableObjectDebugFlags = !isRelease;
  642. options.mEmitObjectAccessCheck = !isRelease;
  643. #if BF_PLATFORM_WINDOWS
  644. options.mEnableRealtimeLeakCheck = !isRelease;
  645. options.mEnableSideStack = isParanoid;
  646. #else
  647. options.mEnableRealtimeLeakCheck = false;
  648. options.mEnableSideStack = false;
  649. #endif
  650. options.mAllowHotSwapping = !isRelease;
  651. options.mIncrementalBuild = !isRelease;
  652. options.mAllocStackTraceDepth = 1;
  653. options.mIntermediateType = .Object;
  654. options.mCSIMDSetting = .SSE2;
  655. options.mCOptimizationLevel = isRelease ? .O2 : .O0;
  656. options.mBuildKind = isTest ? .Test : .Normal;
  657. //TODO:
  658. //options.mIntermediateType = .ObjectAndIRCode;
  659. }
  660. public void Deserialize(StructuredData data)
  661. {
  662. DeleteDictionyAndKeysAndItems!(mConfigs);
  663. mConfigs = new Dictionary<String, Config>();
  664. using (data.Open("Workspace"))
  665. {
  666. for (data.Enumerate("PreprocessorMacros"))
  667. {
  668. var str = new String();
  669. data.GetCurString(str);
  670. mBeefGlobalOptions.mPreprocessorMacros.Add(str);
  671. }
  672. for (data.Enumerate("DistinctOptions"))
  673. {
  674. var typeOptions = new DistinctBuildOptions();
  675. typeOptions.Deserialize(data);
  676. mBeefGlobalOptions.mDistinctBuildOptions.Add(typeOptions);
  677. }
  678. }
  679. for (var configNameKey in data.Enumerate("Configs"))
  680. {
  681. Config config = new Config();
  682. //let configName = new String(data.Keys[configIdx]);
  683. let configName = new String(configNameKey);
  684. bool isDebug = configName.Contains("Debug");
  685. bool isRelease = configName.Contains("Release");
  686. bool isParanoid = configName.Contains("Paranoid");
  687. bool isTest = configName.Contains("Test");
  688. mConfigs[configName] = config;
  689. for (var platformNameKey in data.Enumerate())
  690. {
  691. Options options = new Options();
  692. let platformName = new String(platformNameKey);
  693. config.mPlatforms[platformName] = options;
  694. SetupDefault(options, configName, platformName);
  695. for (data.Enumerate("PreprocessorMacros"))
  696. {
  697. var str = new String();
  698. data.GetCurString(str);
  699. options.mPreprocessorMacros.Add(str);
  700. }
  701. options.mToolsetType = data.GetEnum<ToolsetType>("Toolset", ToolsetType.Default);
  702. options.mBuildKind = data.GetEnum<BuildKind>("BuildKind", isTest ? .Test : .Normal);
  703. options.mBfSIMDSetting = data.GetEnum<BuildOptions.SIMDSetting>("BfSIMDSetting", .SSE2);
  704. #if BF_PLATFORM_WINDOWS
  705. options.mBfOptimizationLevel = data.GetEnum<BuildOptions.BfOptimizationLevel>("BfOptimizationLevel", isRelease ? .O2 : (platformName == "Win64") ? .OgPlus : .O0);
  706. #else
  707. options.mBfOptimizationLevel = data.GetEnum<BuildOptions.BfOptimizationLevel>("BfOptimizationLevel", isRelease ? .O2 : .O0);
  708. #endif
  709. options.mLTOType = data.GetEnum<BuildOptions.LTOType>("LTOType", .None);
  710. options.mAllocType = data.GetEnum<AllocType>("AllocType", isRelease ? .CRT : .Debug);
  711. data.GetString("AllocMalloc", options.mAllocMalloc);
  712. data.GetString("AllocFree", options.mAllocFree);
  713. options.mEmitDebugInfo = data.GetEnum<BuildOptions.EmitDebugInfo>("EmitDebugInfo", .Yes);
  714. options.mNoOmitFramePointers = data.GetBool("NoOmitFramePointers", false);
  715. options.mLargeStrings = data.GetBool("LargeStrings", false);
  716. options.mLargeCollections = data.GetBool("LargeCollections", false);
  717. options.mInitLocalVariables = data.GetBool("InitLocalVariables", false);
  718. options.mRuntimeChecks = data.GetBool("RuntimeChecks", !isRelease);
  719. options.mEmitDynamicCastCheck = data.GetBool("EmitDynamicCastCheck", !isRelease);
  720. options.mEnableObjectDebugFlags = data.GetBool("EnableObjectDebugFlags", !isRelease);
  721. options.mEmitObjectAccessCheck = data.GetBool("EmitObjectAccessCheck", !isRelease);
  722. options.mEnableRealtimeLeakCheck = data.GetBool("EnableRealtimeLeakCheck", !isRelease);
  723. options.mEnableSideStack = data.GetBool("EnableSideStack", isParanoid);
  724. options.mAllowHotSwapping = data.GetBool("AllowHotSwapping", !isRelease);
  725. options.mAllocStackTraceDepth = data.GetInt("AllocStackTraceDepth", 1);
  726. options.mIncrementalBuild = data.GetBool("IncrementalBuild", !isRelease);
  727. options.mIntermediateType = data.GetEnum<IntermediateType>("IntermediateType", .Object);
  728. options.mCSIMDSetting = data.GetEnum<BuildOptions.SIMDSetting>("CSIMDSetting", .SSE2);
  729. options.mCOptimizationLevel = data.GetEnum<COptimizationLevel>("COptimizationLevel", isDebug ? .O0 : .O2);
  730. for (var projectName in data.Enumerate("ConfigSelections"))
  731. {
  732. Project project = FindProject(scope String(projectName));
  733. if (project != null)
  734. {
  735. String expectConfig = configName;
  736. if (isTest)
  737. {
  738. if (project != mProjects[0])
  739. expectConfig = "Debug";
  740. }
  741. var configSelection = new ConfigSelection();
  742. configSelection.mEnabled = data.GetBool("Enabled", true);
  743. configSelection.mConfig = new String();
  744. data.GetString("Config", configSelection.mConfig, expectConfig);
  745. configSelection.mPlatform = new String();
  746. data.GetString("Platform", configSelection.mPlatform, platformName);
  747. options.mConfigSelections[project] = configSelection;
  748. }
  749. }
  750. for (data.Enumerate("DistinctOptions"))
  751. {
  752. var typeOptions = new DistinctBuildOptions();
  753. typeOptions.Deserialize(data);
  754. options.mDistinctBuildOptions.Add(typeOptions);
  755. }
  756. }
  757. }
  758. }
  759. public void FinishDeserialize(StructuredData data)
  760. {
  761. for (data.Enumerate("Locked"))
  762. {
  763. String projName = scope .();
  764. data.GetCurString(projName);
  765. let project = FindProject(projName);
  766. if (project != null)
  767. project.mLocked = true;
  768. }
  769. for (data.Enumerate("Unlocked"))
  770. {
  771. String projName = scope .();
  772. data.GetCurString(projName);
  773. let project = FindProject(projName);
  774. if (project != null)
  775. project.mLocked = false;
  776. }
  777. }
  778. public void FixOptions()
  779. {
  780. for (var configKV in mConfigs)
  781. {
  782. for (var platformName in configKV.value.mPlatforms.Keys)
  783. {
  784. FixOptions(configKV.key, platformName);
  785. }
  786. }
  787. }
  788. public void FixOptionsForPlatform(String platformName)
  789. {
  790. for (var configKV in mConfigs)
  791. {
  792. FixOptions(configKV.key, platformName);
  793. }
  794. }
  795. public void FixOptions(String configName, String platformName)
  796. {
  797. bool isTest = configName.Contains("Test");
  798. Config configVal;
  799. switch (mConfigs.TryAdd(configName))
  800. {
  801. case .Added(let keyPtr, let configPtr):
  802. *keyPtr = new String(configName);
  803. configVal = new Config();
  804. *configPtr = configVal;
  805. case .Exists(?, let configPtr):
  806. configVal = *configPtr;
  807. }
  808. Options options;
  809. switch (configVal.mPlatforms.TryAdd(platformName))
  810. {
  811. case .Added(let keyPtr, let optionsPtr):
  812. *keyPtr = new String(platformName);
  813. options = new Options();
  814. *optionsPtr = options;
  815. SetupDefault(options, configName, platformName);
  816. case .Exists(?, let optionsPtr):
  817. options = *optionsPtr;
  818. }
  819. var removeList = scope List<Project>();
  820. for (var project in options.mConfigSelections.Keys)
  821. {
  822. if (!mProjects.Contains(project))
  823. {
  824. // This project is no longer in the workspace
  825. removeList.Add(project);
  826. }
  827. }
  828. for (var project in removeList)
  829. {
  830. var value = options.mConfigSelections.GetValue(project);
  831. if (value case .Ok)
  832. {
  833. delete value.Get();
  834. options.mConfigSelections.Remove(project);
  835. }
  836. }
  837. for (var project in mProjects)
  838. {
  839. ConfigSelection configSelection;
  840. options.mConfigSelections.TryGetValue(project, out configSelection);
  841. String findConfig = configName;
  842. String findPlatform = platformName;
  843. bool hadConfig = false;
  844. bool hadPlatform = false;
  845. if (isTest)
  846. {
  847. if (project != mProjects[0])
  848. {
  849. findConfig = "Debug";
  850. }
  851. }
  852. if (configSelection != null)
  853. {
  854. hadConfig = project.mConfigs.ContainsKey(configSelection.mConfig);
  855. if (hadConfig)
  856. {
  857. findConfig = configSelection.mConfig;
  858. hadPlatform = project.mConfigs[configSelection.mConfig].mPlatforms.ContainsKey(configSelection.mPlatform);
  859. }
  860. }
  861. if ((!hadConfig) || (!hadPlatform))
  862. {
  863. if (configSelection == null)
  864. {
  865. configSelection = new ConfigSelection();
  866. configSelection.mConfig = new String(findConfig);
  867. configSelection.mPlatform = new String(findPlatform);
  868. options.mConfigSelections[project] = configSelection;
  869. }
  870. project.CreateConfig(findConfig, findPlatform);
  871. configSelection.mEnabled = true;
  872. }
  873. }
  874. }
  875. public void WithProjectItems(Action<ProjectItem> func)
  876. {
  877. for (var project in mProjects)
  878. {
  879. project.WithProjectItems(scope (projectItem) =>
  880. {
  881. func(projectItem);
  882. });
  883. }
  884. }
  885. void FlattenCompileInstanceList()
  886. {
  887. if (mCompileInstanceList.Count == 0)
  888. return;
  889. var headCompileInstance = mCompileInstanceList[0];
  890. headCompileInstance.mIsReused = true;
  891. if (mCompileInstanceList.Count > 1)
  892. {
  893. for (var pair in headCompileInstance.mProjectItemCompileInstances)
  894. {
  895. var projectSource = pair.key;
  896. ProjectSourceCompileInstance bestEntry = null;
  897. for (int checkIdx = mCompileInstanceList.Count - 1; checkIdx >= 1; checkIdx--)
  898. {
  899. mCompileInstanceList[checkIdx].mProjectItemCompileInstances.TryGetValue(projectSource, out bestEntry);
  900. if (bestEntry != null)
  901. break;
  902. }
  903. if (bestEntry != null)
  904. {
  905. pair.value.Deref();
  906. bestEntry.mRefCount++;
  907. @pair.SetValue(bestEntry);
  908. }
  909. }
  910. while (mCompileInstanceList.Count > 1)
  911. {
  912. var compileInstanceList = mCompileInstanceList.PopBack();
  913. delete compileInstanceList;
  914. }
  915. for (var pair in headCompileInstance.mProjectItemCompileInstances)
  916. {
  917. Debug.Assert(pair.value.mRefCount == 1);
  918. }
  919. }
  920. }
  921. public void SetupProjectCompileInstance(bool isHotReload)
  922. {
  923. using (mMonitor.Enter())
  924. {
  925. if ((!isHotReload) && (mCompileInstanceList.Count > 0))
  926. {
  927. // Only keep the most recent one if we're just doing a normal compile
  928. FlattenCompileInstanceList();
  929. return;
  930. }
  931. CompileInstance compileInstance = new CompileInstance();
  932. mCompileInstanceList.Add(compileInstance);
  933. }
  934. }
  935. public int GetHighestSuccessfulCompileIdx()
  936. {
  937. using (mMonitor.Enter())
  938. {
  939. int checkIdx = mCompileInstanceList.Count - 1;
  940. while (checkIdx >= 0)
  941. {
  942. CompileInstance compileInstance = mCompileInstanceList[checkIdx];
  943. if (compileInstance.mCompileResult == .Success)
  944. return checkIdx;
  945. checkIdx--;
  946. }
  947. return -1;
  948. }
  949. }
  950. public int GetHighestCompileIdx()
  951. {
  952. using (mMonitor.Enter())
  953. {
  954. return mCompileInstanceList.Count - 1;
  955. }
  956. }
  957. public void ProjectSourceRemoved(ProjectSource projectSource)
  958. {
  959. for (var compileInstance in mCompileInstanceList)
  960. {
  961. if (compileInstance.mProjectItemCompileInstances.GetAndRemove(projectSource) case .Ok((?, let compileInstance)))
  962. {
  963. compileInstance.Deref();
  964. }
  965. }
  966. }
  967. public void ProjectSourceCompiled(ProjectSource projectSource, String source, IdSpan sourceCharIdData, bool canMoveSourceString = false)
  968. {
  969. using (mMonitor.Enter())
  970. {
  971. if (mCompileInstanceList.Count == 0)
  972. return;
  973. var compileInstance = mCompileInstanceList[mCompileInstanceList.Count - 1];
  974. Debug.Assert(sourceCharIdData.mLength > 0);
  975. var projectSourceCompileInstance = new ProjectSourceCompileInstance();
  976. projectSourceCompileInstance.mSource = new String();
  977. if (canMoveSourceString)
  978. source.MoveTo(projectSourceCompileInstance.mSource, true);
  979. else
  980. projectSourceCompileInstance.mSource.Set(source);
  981. projectSourceCompileInstance.mSourceCharIdData = sourceCharIdData.Duplicate();
  982. ProjectItem* keyPtr;
  983. ProjectSourceCompileInstance* compileInstancePtr;
  984. if (compileInstance.mProjectItemCompileInstances.TryAdd(projectSource, out keyPtr, out compileInstancePtr))
  985. {
  986. *keyPtr = projectSource;
  987. *compileInstancePtr = projectSourceCompileInstance;
  988. }
  989. else
  990. {
  991. (*compileInstancePtr).Deref();
  992. *compileInstancePtr = projectSourceCompileInstance;
  993. }
  994. }
  995. }
  996. public ProjectSourceCompileInstance GetProjectSourceCompileInstance(ProjectSource projectSource, int compileInstanceIdx)
  997. {
  998. int useCompileInstanceIdx = compileInstanceIdx;
  999. using (mMonitor.Enter())
  1000. {
  1001. if (mCompileInstanceList.Count == 0)
  1002. return null;
  1003. if (useCompileInstanceIdx == -1)
  1004. useCompileInstanceIdx = GetHighestCompileIdx();
  1005. var compileInstance = mCompileInstanceList[useCompileInstanceIdx];
  1006. ProjectSourceCompileInstance projectSourceCompileInstance;
  1007. if ((!compileInstance.mProjectItemCompileInstances.TryGetValue(projectSource, out projectSourceCompileInstance)) && (useCompileInstanceIdx > 0))
  1008. {
  1009. for (int checkIdx = useCompileInstanceIdx - 1; checkIdx >= 0; checkIdx--)
  1010. {
  1011. var checkCompileInstance = mCompileInstanceList[checkIdx];
  1012. if (checkCompileInstance.mProjectItemCompileInstances.TryGetValue(projectSource, out projectSourceCompileInstance))
  1013. break;
  1014. }
  1015. // Add it to the index we were looking at for faster lookup next time (even if nothing was found)
  1016. if (projectSourceCompileInstance != null)
  1017. projectSourceCompileInstance.mRefCount++;
  1018. compileInstance.mProjectItemCompileInstances[projectSource] = projectSourceCompileInstance;
  1019. }
  1020. return projectSourceCompileInstance;
  1021. }
  1022. }
  1023. public int32 GetProjectSourceCharId(ProjectSource projectSource, int compileInstanceIdx, int line, int column)
  1024. {
  1025. using (mMonitor.Enter())
  1026. {
  1027. if (mCompileInstanceList.Count == 0)
  1028. return -1;
  1029. ProjectSourceCompileInstance projectSourceCompileInstance = GetProjectSourceCompileInstance(projectSource, compileInstanceIdx);
  1030. if (projectSourceCompileInstance != null)
  1031. {
  1032. projectSourceCompileInstance.mSourceCharIdData.Prepare();
  1033. int encodeIdx = 0;
  1034. int spanLeft = 0;
  1035. int32 charId = 1;
  1036. int curLine = 0;
  1037. int curColumn = 0;
  1038. int charIdx = 0;
  1039. while (true)
  1040. {
  1041. while (spanLeft == 0)
  1042. {
  1043. if (projectSourceCompileInstance.mSourceCharIdData.IsEmpty)
  1044. {
  1045. spanLeft = (int32)projectSourceCompileInstance.mSource.Length;
  1046. continue;
  1047. }
  1048. int32 cmd = Utils.DecodeInt(projectSourceCompileInstance.mSourceCharIdData.mData, ref encodeIdx);
  1049. if (cmd > 0)
  1050. charId = cmd;
  1051. else
  1052. spanLeft = -cmd;
  1053. if (cmd == 0)
  1054. return 0;
  1055. }
  1056. char8 c = projectSourceCompileInstance.mSource[charIdx++];
  1057. if (curLine == line)
  1058. {
  1059. if (curColumn == column)
  1060. return charId;
  1061. // For column == -1, use first non-whitespace char8
  1062. if ((column == -1) && (!c.IsWhiteSpace))
  1063. return charId;
  1064. }
  1065. if (c == '\n')
  1066. {
  1067. if (curLine == line)
  1068. return charId;
  1069. curLine++;
  1070. curColumn = 0;
  1071. }
  1072. else
  1073. curColumn++;
  1074. spanLeft--;
  1075. charId++;
  1076. }
  1077. }
  1078. return -1;
  1079. }
  1080. }
  1081. public IdSpan GetProjectSourceSelectionCharIds(ProjectSource projectSource, int compileInstanceIdx, int defLineStart, int defLineEnd, out int32 charIdStart, out int32 charIdEnd)
  1082. {
  1083. using (mMonitor.Enter())
  1084. {
  1085. int useCompileInstanceIdx = compileInstanceIdx;
  1086. charIdStart = -1;
  1087. charIdEnd = -1;
  1088. if (mCompileInstanceList.Count == 0)
  1089. return IdSpan();
  1090. if (useCompileInstanceIdx == -1)
  1091. useCompileInstanceIdx = GetHighestCompileIdx();
  1092. ProjectSourceCompileInstance projectSourceCompileInstance = GetProjectSourceCompileInstance(projectSource, compileInstanceIdx);
  1093. if (projectSourceCompileInstance != null)
  1094. {
  1095. projectSourceCompileInstance.mSourceCharIdData.Prepare();
  1096. int encodeIdx = 0;
  1097. int spanLeft = 0;
  1098. int32 charId = 0;
  1099. int curLine = 0;
  1100. int charIdx = 0;
  1101. while (true)
  1102. {
  1103. while (spanLeft == 0)
  1104. {
  1105. if (projectSourceCompileInstance.mSourceCharIdData.mData == null)
  1106. {
  1107. spanLeft = (int32)projectSourceCompileInstance.mSource.Length;
  1108. continue;
  1109. }
  1110. int32 cmd = Utils.DecodeInt(projectSourceCompileInstance.mSourceCharIdData.mData, ref encodeIdx);
  1111. if (cmd > 0)
  1112. charId = cmd;
  1113. else
  1114. spanLeft = -cmd;
  1115. if (cmd == 0)
  1116. break;
  1117. }
  1118. if (charIdx >= projectSourceCompileInstance.mSource.Length)
  1119. return IdSpan();
  1120. char8 c = projectSourceCompileInstance.mSource[charIdx++];
  1121. if (curLine == defLineStart)
  1122. {
  1123. if (!c.IsWhiteSpace)
  1124. {
  1125. if (charIdStart == -1)
  1126. charIdStart = charId;
  1127. }
  1128. }
  1129. else if (curLine == defLineEnd)
  1130. {
  1131. charIdEnd = charId;
  1132. }
  1133. else if (curLine > defLineEnd)
  1134. {
  1135. break;
  1136. }
  1137. if (c == '\n')
  1138. curLine++;
  1139. spanLeft--;
  1140. charId++;
  1141. }
  1142. }
  1143. if ((charIdStart != -1) && (charIdEnd != -1))
  1144. return projectSourceCompileInstance.mSourceCharIdData;
  1145. return IdSpan();
  1146. }
  1147. }
  1148. public Result<void> GetProjectSourceSection(ProjectSource projectSource, int32 compileInstanceIdx, int32 defLineStart, int32 defLineEnd, String outSourceSection)
  1149. {
  1150. var projectSourceCompileInstance = GetProjectSourceCompileInstance(projectSource, compileInstanceIdx);
  1151. if (projectSourceCompileInstance == null)
  1152. return .Err;
  1153. int32 startIdx = -1;
  1154. int32 curLine = 0;
  1155. int32 charIdx = 0;
  1156. while (charIdx < projectSourceCompileInstance.mSource.Length)
  1157. {
  1158. char8 c = projectSourceCompileInstance.mSource[charIdx++];
  1159. if (c == '\n')
  1160. {
  1161. if (curLine == defLineStart)
  1162. startIdx = charIdx;
  1163. if (curLine == defLineEnd + 1)
  1164. {
  1165. charIdx--;
  1166. break;
  1167. }
  1168. curLine++;
  1169. }
  1170. }
  1171. if (startIdx == -1)
  1172. return .Err;
  1173. outSourceSection.Append(projectSourceCompileInstance.mSource, startIdx, charIdx - startIdx);
  1174. return .Ok;
  1175. }
  1176. public bool GetProjectSourceCharIdPosition(ProjectSource projectSource, int compileInstanceIdx, int findCharId, ref int line, ref int column)
  1177. {
  1178. using (mMonitor.Enter())
  1179. {
  1180. if (mCompileInstanceList.Count == 0)
  1181. return true; // Allow it through - for the run-without-compiling case
  1182. ProjectSourceCompileInstance projectSourceCompileInstance = GetProjectSourceCompileInstance(projectSource, compileInstanceIdx);
  1183. if (projectSourceCompileInstance != null)
  1184. {
  1185. projectSourceCompileInstance.mSourceCharIdData.Prepare();
  1186. int curLine = 0;
  1187. int curColumn = 0;
  1188. int encodeIdx = 0;
  1189. int spanLeft = 0;
  1190. int charId = 0;
  1191. int charIdx = 0;
  1192. while (true)
  1193. {
  1194. while (spanLeft == 0)
  1195. {
  1196. if (projectSourceCompileInstance.mSourceCharIdData.mData == null)
  1197. {
  1198. spanLeft = (int32)projectSourceCompileInstance.mSource.Length;
  1199. continue;
  1200. }
  1201. int cmd = Utils.DecodeInt(projectSourceCompileInstance.mSourceCharIdData.mData, ref encodeIdx);
  1202. if (cmd > 0)
  1203. charId = cmd;
  1204. else
  1205. spanLeft = -cmd;
  1206. if (cmd == 0)
  1207. return false;
  1208. }
  1209. if (charId == findCharId)
  1210. {
  1211. line = curLine;
  1212. column = curColumn;
  1213. return true;
  1214. }
  1215. char8 c = projectSourceCompileInstance.mSource[charIdx++];
  1216. if (c == '\n')
  1217. {
  1218. curLine++;
  1219. curColumn = 0;
  1220. }
  1221. else
  1222. curColumn++;
  1223. spanLeft--;
  1224. charId++;
  1225. }
  1226. }
  1227. return false;
  1228. }
  1229. }
  1230. public void StoppedRunning()
  1231. {
  1232. FlattenCompileInstanceList();
  1233. }
  1234. }
  1235. }