| author | |
| committer | |
| log | 1014cfdf3b60faf9af5b062d198f4f44976cb1bc |
| tree | cfa5bff2c520b70c510e3a6ca44b35588417be38 |
| parent | 47dfaf3d175ebea63b169a373b4dec4af6af7001 |
| signature |
See #34066 files changed, 527 insertions(+), 85 deletions(-)
lib/std/hash_map.zig+2-1| ... | @@ -36,7 +36,8 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3 | ... | @@ -36,7 +36,8 @@ pub fn HashMap(comptime K: type, comptime V: type, comptime hash: fn (key: K) u3 |
| 36 | size: usize, | 36 | size: usize, |
| 37 | max_distance_from_start_index: usize, | 37 | max_distance_from_start_index: usize, |
| 38 | allocator: *Allocator, | 38 | allocator: *Allocator, |
| 39 | // this is used to detect bugs where a hashtable is edited while an iterator is running. | 39 | |
| 40 | /// This is used to detect bugs where a hashtable is edited while an iterator is running. | ||
| 40 | modification_count: debug_u32, | 41 | modification_count: debug_u32, |
| 41 | 42 | ||
| 42 | const Self = @This(); | 43 | const Self = @This(); |
lib/std/meta.zig+10| ... | @@ -542,3 +542,13 @@ pub fn intToEnum(comptime Tag: type, tag_int: var) IntToEnumError!Tag { | ... | @@ -542,3 +542,13 @@ pub fn intToEnum(comptime Tag: type, tag_int: var) IntToEnumError!Tag { |
| 542 | } | 542 | } |
| 543 | return error.InvalidEnumTag; | 543 | return error.InvalidEnumTag; |
| 544 | } | 544 | } |
| 545 | |||
| 546 | /// Given a type and a name, return the field index according to source order. | ||
| 547 | /// Returns `null` if the field is not found. | ||
| 548 | pub fn fieldIndex(comptime T: type, comptime name: []const u8) ?comptime_int { | ||
| 549 | inline for (fields(T)) |field, i| { | ||
| 550 | if (mem.eql(u8, field.name, name)) | ||
| 551 | return comptime_int(i); | ||
| 552 | } | ||
| 553 | return null; | ||
| 554 | } |
lib/std/special/docs/index.html+14-1| ... | @@ -104,6 +104,16 @@ | ... | @@ -104,6 +104,16 @@ |
| 104 | background-color: #FFBB4D; | 104 | background-color: #FFBB4D; |
| 105 | color: #000; | 105 | color: #000; |
| 106 | } | 106 | } |
| 107 | #listFnExamples { | ||
| 108 | list-style-type: none; | ||
| 109 | margin: 0; | ||
| 110 | padding: 0; | ||
| 111 | } | ||
| 112 | #listFnExamples li { | ||
| 113 | padding: 0.5em 0; | ||
| 114 | white-space: nowrap; | ||
| 115 | overflow-x: auto; | ||
| 116 | } | ||
| 107 | #logo { | 117 | #logo { |
| 108 | width: 8em; | 118 | width: 8em; |
| 109 | padding: 0.5em 1em; | 119 | padding: 0.5em 1em; |
| ... | @@ -289,7 +299,6 @@ | ... | @@ -289,7 +299,6 @@ |
| 289 | <pre id="fnProtoCode"></pre> | 299 | <pre id="fnProtoCode"></pre> |
| 290 | </div> | 300 | </div> |
| 291 | <h1 id="hdrName" class="hidden"></h1> | 301 | <h1 id="hdrName" class="hidden"></h1> |
| 292 | <div id="fnExamples" class="hidden"></div> | ||
| 293 | <div id="fnNoExamples" class="hidden"> | 302 | <div id="fnNoExamples" class="hidden"> |
| 294 | <p>This function is not tested or referenced.</p> | 303 | <p>This function is not tested or referenced.</p> |
| 295 | </div> | 304 | </div> |
| ... | @@ -357,6 +366,10 @@ | ... | @@ -357,6 +366,10 @@ |
| 357 | <ul id="listErrSets"> | 366 | <ul id="listErrSets"> |
| 358 | </ul> | 367 | </ul> |
| 359 | </div> | 368 | </div> |
| 369 | <div id="fnExamples" class="hidden"> | ||
| 370 | <h2>Examples</h2> | ||
| 371 | <ul id="listFnExamples"></ul> | ||
| 372 | </div> | ||
| 360 | </section> | 373 | </section> |
| 361 | <div id="helpDialog" class="hidden"> | 374 | <div id="helpDialog" class="hidden"> |
| 362 | <h1>Keyboard Shortcuts</h1> | 375 | <h1>Keyboard Shortcuts</h1> |
lib/std/special/docs/main.js+230-19| ... | @@ -26,6 +26,7 @@ | ... | @@ -26,6 +26,7 @@ |
| 26 | var domTableFnErrors = document.getElementById("tableFnErrors"); | 26 | var domTableFnErrors = document.getElementById("tableFnErrors"); |
| 27 | var domFnErrorsAnyError = document.getElementById("fnErrorsAnyError"); | 27 | var domFnErrorsAnyError = document.getElementById("fnErrorsAnyError"); |
| 28 | var domFnExamples = document.getElementById("fnExamples"); | 28 | var domFnExamples = document.getElementById("fnExamples"); |
| 29 | var domListFnExamples = document.getElementById("listFnExamples"); | ||
| 29 | var domFnNoExamples = document.getElementById("fnNoExamples"); | 30 | var domFnNoExamples = document.getElementById("fnNoExamples"); |
| 30 | var domDeclNoRef = document.getElementById("declNoRef"); | 31 | var domDeclNoRef = document.getElementById("declNoRef"); |
| 31 | var domSearch = document.getElementById("search"); | 32 | var domSearch = document.getElementById("search"); |
| ... | @@ -64,6 +65,9 @@ | ... | @@ -64,6 +65,9 @@ |
| 64 | declNames: [], | 65 | declNames: [], |
| 65 | // these will be all types, except the last one may be a type or a decl | 66 | // these will be all types, except the last one may be a type or a decl |
| 66 | declObjs: [], | 67 | declObjs: [], |
| 68 | |||
| 69 | // (a, b, c, d) comptime call; result is the value the docs refer to | ||
| 70 | callName: null, | ||
| 67 | }; | 71 | }; |
| 68 | var curNavSearch = ""; | 72 | var curNavSearch = ""; |
| 69 | var curSearchIndex = -1; | 73 | var curSearchIndex = -1; |
| ... | @@ -237,20 +241,29 @@ | ... | @@ -237,20 +241,29 @@ |
| 237 | renderErrorSet(errSetType); | 241 | renderErrorSet(errSetType); |
| 238 | } | 242 | } |
| 239 | 243 | ||
| 240 | var protoSrcIndex; | 244 | var fnObj = zigAnalysis.fns[fnDecl.value]; |
| 245 | var protoSrcIndex = fnObj.src; | ||
| 241 | if (typeIsGenericFn(fnDecl.type)) { | 246 | if (typeIsGenericFn(fnDecl.type)) { |
| 242 | protoSrcIndex = fnDecl.value; | ||
| 243 | |||
| 244 | var instantiations = nodesToFnsMap[protoSrcIndex]; | 247 | var instantiations = nodesToFnsMap[protoSrcIndex]; |
| 245 | var calls = nodesToCallsMap[protoSrcIndex]; | 248 | var calls = nodesToCallsMap[protoSrcIndex]; |
| 246 | if (instantiations == null && calls == null) { | 249 | if (instantiations == null && calls == null) { |
| 247 | domFnNoExamples.classList.remove("hidden"); | 250 | domFnNoExamples.classList.remove("hidden"); |
| 248 | } else { | 251 | } else if (calls != null) { |
| 249 | // TODO show examples | 252 | if (fnObj.combined === undefined) fnObj.combined = allCompTimeFnCallsResult(calls); |
| 253 | if (fnObj.combined != null) renderContainer(fnObj.combined); | ||
| 254 | |||
| 255 | resizeDomList(domListFnExamples, calls.length, '<li></li>'); | ||
| 256 | |||
| 257 | for (var callI = 0; callI < calls.length; callI += 1) { | ||
| 258 | var liDom = domListFnExamples.children[callI]; | ||
| 259 | liDom.innerHTML = getCallHtml(fnDecl, calls[callI]); | ||
| 260 | } | ||
| 261 | |||
| 250 | domFnExamples.classList.remove("hidden"); | 262 | domFnExamples.classList.remove("hidden"); |
| 263 | } else if (instantiations != null) { | ||
| 264 | // TODO | ||
| 251 | } | 265 | } |
| 252 | } else { | 266 | } else { |
| 253 | protoSrcIndex = zigAnalysis.fns[fnDecl.value].src; | ||
| 254 | 267 | ||
| 255 | domFnExamples.classList.add("hidden"); | 268 | domFnExamples.classList.add("hidden"); |
| 256 | domFnNoExamples.classList.add("hidden"); | 269 | domFnNoExamples.classList.add("hidden"); |
| ... | @@ -349,13 +362,15 @@ | ... | @@ -349,13 +362,15 @@ |
| 349 | } | 362 | } |
| 350 | } | 363 | } |
| 351 | 364 | ||
| 352 | function navLink(pkgNames, declNames) { | 365 | function navLink(pkgNames, declNames, callName) { |
| 353 | if (pkgNames.length === 0 && declNames.length === 0) { | 366 | if (pkgNames.length === 0 && declNames.length === 0) { |
| 354 | return '#'; | 367 | return '#'; |
| 355 | } else if (declNames.length === 0) { | 368 | } else if (declNames.length === 0 && callName == null) { |
| 356 | return '#' + pkgNames.join('.'); | 369 | return '#' + pkgNames.join('.'); |
| 357 | } else { | 370 | } else if (callName == null) { |
| 358 | return '#' + pkgNames.join('.') + ';' + declNames.join('.'); | 371 | return '#' + pkgNames.join('.') + ';' + declNames.join('.'); |
| 372 | } else { | ||
| 373 | return '#' + pkgNames.join('.') + ';' + declNames.join('.') + ';' + callName; | ||
| 359 | } | 374 | } |
| 360 | } | 375 | } |
| 361 | 376 | ||
| ... | @@ -367,6 +382,22 @@ | ... | @@ -367,6 +382,22 @@ |
| 367 | return navLink(curNav.pkgNames, curNav.declNames.concat([childName])); | 382 | return navLink(curNav.pkgNames, curNav.declNames.concat([childName])); |
| 368 | } | 383 | } |
| 369 | 384 | ||
| 385 | function navLinkCall(callObj) { | ||
| 386 | var declNamesCopy = curNav.declNames.concat([]); | ||
| 387 | var callName = declNamesCopy.pop(); | ||
| 388 | |||
| 389 | callName += '('; | ||
| 390 | for (var arg_i = 0; arg_i < callObj.args.length; arg_i += 1) { | ||
| 391 | if (arg_i !== 0) callName += ','; | ||
| 392 | var argObj = callObj.args[arg_i]; | ||
| 393 | callName += getValueText(argObj.type, argObj.value, false, false); | ||
| 394 | } | ||
| 395 | callName += ')'; | ||
| 396 | |||
| 397 | declNamesCopy.push(callName); | ||
| 398 | return navLink(curNav.pkgNames, declNamesCopy); | ||
| 399 | } | ||
| 400 | |||
| 370 | function resizeDomListDl(dlDom, desiredLen) { | 401 | function resizeDomListDl(dlDom, desiredLen) { |
| 371 | // add the missing dom entries | 402 | // add the missing dom entries |
| 372 | var i, ev; | 403 | var i, ev; |
| ... | @@ -426,6 +457,40 @@ | ... | @@ -426,6 +457,40 @@ |
| 426 | return (typeObj.len == null) ? pointerSizeEnum.One : typeObj.len; | 457 | return (typeObj.len == null) ? pointerSizeEnum.One : typeObj.len; |
| 427 | } | 458 | } |
| 428 | 459 | ||
| 460 | function getCallHtml(fnDecl, callIndex) { | ||
| 461 | var callObj = zigAnalysis.calls[callIndex]; | ||
| 462 | |||
| 463 | // TODO make these links work | ||
| 464 | //var html = '<a href="' + navLinkCall(callObj) + '">' + escapeHtml(fnDecl.name) + '</a>('; | ||
| 465 | var html = escapeHtml(fnDecl.name) + '('; | ||
| 466 | for (var arg_i = 0; arg_i < callObj.args.length; arg_i += 1) { | ||
| 467 | if (arg_i !== 0) html += ', '; | ||
| 468 | var argObj = callObj.args[arg_i]; | ||
| 469 | html += getValueText(argObj.type, argObj.value, true, true); | ||
| 470 | } | ||
| 471 | html += ')'; | ||
| 472 | return html; | ||
| 473 | } | ||
| 474 | |||
| 475 | function getValueText(typeIndex, value, wantHtml, wantLink) { | ||
| 476 | var typeObj = zigAnalysis.types[typeIndex]; | ||
| 477 | switch (typeObj.kind) { | ||
| 478 | case typeKinds.Type: | ||
| 479 | return typeIndexName(value, wantHtml, wantLink); | ||
| 480 | case typeKinds.Fn: | ||
| 481 | var fnObj = zigAnalysis.fns[value]; | ||
| 482 | return typeIndexName(fnObj.type, wantHtml, wantLink); | ||
| 483 | case typeKinds.Int: | ||
| 484 | if (wantHtml) { | ||
| 485 | return '<span class="tok-number">' + value + '</span>'; | ||
| 486 | } else { | ||
| 487 | return value + ""; | ||
| 488 | } | ||
| 489 | default: | ||
| 490 | throw new Error("TODO implement getValueText for this type"); | ||
| 491 | } | ||
| 492 | } | ||
| 493 | |||
| 429 | function typeName(typeObj, wantHtml, wantSubLink, fnDecl, linkFnNameDecl) { | 494 | function typeName(typeObj, wantHtml, wantSubLink, fnDecl, linkFnNameDecl) { |
| 430 | switch (typeObj.kind) { | 495 | switch (typeObj.kind) { |
| 431 | case typeKinds.Array: | 496 | case typeKinds.Array: |
| ... | @@ -544,6 +609,12 @@ | ... | @@ -544,6 +609,12 @@ |
| 544 | } else { | 609 | } else { |
| 545 | return "void"; | 610 | return "void"; |
| 546 | } | 611 | } |
| 612 | case typeKinds.EnumLiteral: | ||
| 613 | if (wantHtml) { | ||
| 614 | return '<span class="tok-type">(enum literal)</span>'; | ||
| 615 | } else { | ||
| 616 | return "(enum literal)"; | ||
| 617 | } | ||
| 547 | case typeKinds.NoReturn: | 618 | case typeKinds.NoReturn: |
| 548 | if (wantHtml) { | 619 | if (wantHtml) { |
| 549 | return '<span class="tok-type">noreturn</span>'; | 620 | return '<span class="tok-type">noreturn</span>'; |
| ... | @@ -592,6 +663,15 @@ | ... | @@ -592,6 +663,15 @@ |
| 592 | } | 663 | } |
| 593 | payloadHtml += '('; | 664 | payloadHtml += '('; |
| 594 | if (typeObj.args != null) { | 665 | if (typeObj.args != null) { |
| 666 | var fields = null; | ||
| 667 | var isVarArgs = false; | ||
| 668 | if (fnDecl != null) { | ||
| 669 | var fnObj = zigAnalysis.fns[fnDecl.value]; | ||
| 670 | var fnNode = zigAnalysis.astNodes[fnObj.src]; | ||
| 671 | fields = fnNode.fields; | ||
| 672 | isVarArgs = fnNode.varArgs; | ||
| 673 | } | ||
| 674 | |||
| 595 | for (var i = 0; i < typeObj.args.length; i += 1) { | 675 | for (var i = 0; i < typeObj.args.length; i += 1) { |
| 596 | if (i != 0) { | 676 | if (i != 0) { |
| 597 | payloadHtml += ', '; | 677 | payloadHtml += ', '; |
| ... | @@ -599,10 +679,31 @@ | ... | @@ -599,10 +679,31 @@ |
| 599 | 679 | ||
| 600 | var argTypeIndex = typeObj.args[i]; | 680 | var argTypeIndex = typeObj.args[i]; |
| 601 | 681 | ||
| 602 | if (fnDecl != null && zigAnalysis.astNodes[fnDecl.src].fields != null) { | 682 | if (fields != null) { |
| 603 | var paramDeclIndex = zigAnalysis.astNodes[fnDecl.src].fields[i]; | 683 | var paramNode = zigAnalysis.astNodes[fields[i]]; |
| 604 | var paramName = zigAnalysis.astNodes[paramDeclIndex].name; | 684 | |
| 685 | if (paramNode.varArgs) { | ||
| 686 | payloadHtml += '...'; | ||
| 687 | continue; | ||
| 688 | } | ||
| 689 | |||
| 690 | if (paramNode.noalias) { | ||
| 691 | if (wantHtml) { | ||
| 692 | payloadHtml += '<span class="tok-kw">noalias</span> '; | ||
| 693 | } else { | ||
| 694 | payloadHtml += 'noalias '; | ||
| 695 | } | ||
| 696 | } | ||
| 697 | |||
| 698 | if (paramNode.comptime) { | ||
| 699 | if (wantHtml) { | ||
| 700 | payloadHtml += '<span class="tok-kw">comptime</span> '; | ||
| 701 | } else { | ||
| 702 | payloadHtml += 'comptime '; | ||
| 703 | } | ||
| 704 | } | ||
| 605 | 705 | ||
| 706 | var paramName = paramNode.name; | ||
| 606 | if (paramName != null) { | 707 | if (paramName != null) { |
| 607 | // skip if it matches the type name | 708 | // skip if it matches the type name |
| 608 | if (argTypeIndex == null || !shouldSkipParamName(argTypeIndex, paramName)) { | 709 | if (argTypeIndex == null || !shouldSkipParamName(argTypeIndex, paramName)) { |
| ... | @@ -611,7 +712,9 @@ | ... | @@ -611,7 +712,9 @@ |
| 611 | } | 712 | } |
| 612 | } | 713 | } |
| 613 | 714 | ||
| 614 | if (argTypeIndex != null) { | 715 | if (isVarArgs && i === typeObj.args.length - 1) { |
| 716 | payloadHtml += '...'; | ||
| 717 | } else if (argTypeIndex != null) { | ||
| 615 | payloadHtml += typeIndexName(argTypeIndex, wantHtml, wantSubLink); | 718 | payloadHtml += typeIndexName(argTypeIndex, wantHtml, wantSubLink); |
| 616 | } else if (wantHtml) { | 719 | } else if (wantHtml) { |
| 617 | payloadHtml += '<span class="tok-kw">var</span>'; | 720 | payloadHtml += '<span class="tok-kw">var</span>'; |
| ... | @@ -690,7 +793,7 @@ | ... | @@ -690,7 +793,7 @@ |
| 690 | } | 793 | } |
| 691 | 794 | ||
| 692 | function allCompTimeFnCallsHaveTypeResult(typeIndex, value) { | 795 | function allCompTimeFnCallsHaveTypeResult(typeIndex, value) { |
| 693 | var srcIndex = typeIsGenericFn(typeIndex) ? value : zigAnalysis.fns[value].src; | 796 | var srcIndex = zigAnalysis.fns[value].src; |
| 694 | var calls = nodesToCallsMap[srcIndex]; | 797 | var calls = nodesToCallsMap[srcIndex]; |
| 695 | if (calls == null) return false; | 798 | if (calls == null) return false; |
| 696 | for (var i = 0; i < calls.length; i += 1) { | 799 | for (var i = 0; i < calls.length; i += 1) { |
| ... | @@ -700,6 +803,90 @@ | ... | @@ -700,6 +803,90 @@ |
| 700 | return true; | 803 | return true; |
| 701 | } | 804 | } |
| 702 | 805 | ||
| 806 | function allCompTimeFnCallsResult(calls) { | ||
| 807 | var firstTypeObj = null; | ||
| 808 | var containerObj = { | ||
| 809 | privDecls: [], | ||
| 810 | }; | ||
| 811 | for (var callI = 0; callI < calls.length; callI += 1) { | ||
| 812 | var call = zigAnalysis.calls[calls[callI]]; | ||
| 813 | if (call.result.type !== typeTypeId) return null; | ||
| 814 | var typeObj = zigAnalysis.types[call.result.value]; | ||
| 815 | if (!typeKindIsContainer(typeObj.kind)) return null; | ||
| 816 | if (firstTypeObj == null) { | ||
| 817 | firstTypeObj = typeObj; | ||
| 818 | containerObj.src = typeObj.src; | ||
| 819 | } else if (firstTypeObj.src !== typeObj.src) { | ||
| 820 | return null; | ||
| 821 | } | ||
| 822 | |||
| 823 | if (containerObj.fields == null) { | ||
| 824 | containerObj.fields = (typeObj.fields || []).concat([]); | ||
| 825 | } else for (var fieldI = 0; fieldI < typeObj.fields.length; fieldI += 1) { | ||
| 826 | var prev = containerObj.fields[fieldI]; | ||
| 827 | var next = typeObj.fields[fieldI]; | ||
| 828 | if (prev === next) continue; | ||
| 829 | if (typeof(prev) === 'object') { | ||
| 830 | if (prev[next] == null) prev[next] = typeObj; | ||
| 831 | } else { | ||
| 832 | containerObj.fields[fieldI] = {}; | ||
| 833 | containerObj.fields[fieldI][prev] = firstTypeObj; | ||
| 834 | containerObj.fields[fieldI][next] = typeObj; | ||
| 835 | } | ||
| 836 | } | ||
| 837 | |||
| 838 | if (containerObj.pubDecls == null) { | ||
| 839 | containerObj.pubDecls = (typeObj.pubDecls || []).concat([]); | ||
| 840 | } else for (var declI = 0; declI < typeObj.pubDecls.length; declI += 1) { | ||
| 841 | var prev = containerObj.pubDecls[declI]; | ||
| 842 | var next = typeObj.pubDecls[declI]; | ||
| 843 | if (prev === next) continue; | ||
| 844 | // TODO instead of showing "examples" as the public declarations, | ||
| 845 | // do logic like this: | ||
| 846 | //if (typeof(prev) !== 'object') { | ||
| 847 | // var newDeclId = zigAnalysis.decls.length; | ||
| 848 | // prev = clone(zigAnalysis.decls[prev]); | ||
| 849 | // prev.id = newDeclId; | ||
| 850 | // zigAnalysis.decls.push(prev); | ||
| 851 | // containerObj.pubDecls[declI] = prev; | ||
| 852 | //} | ||
| 853 | //mergeDecls(prev, next, firstTypeObj, typeObj); | ||
| 854 | } | ||
| 855 | } | ||
| 856 | for (var declI = 0; declI < containerObj.pubDecls.length; declI += 1) { | ||
| 857 | var decl = containerObj.pubDecls[declI]; | ||
| 858 | if (typeof(decl) === 'object') { | ||
| 859 | containerObj.pubDecls[declI] = containerObj.pubDecls[declI].id; | ||
| 860 | } | ||
| 861 | } | ||
| 862 | return containerObj; | ||
| 863 | } | ||
| 864 | |||
| 865 | function mergeDecls(declObj, nextDeclIndex, firstTypeObj, typeObj) { | ||
| 866 | var nextDeclObj = zigAnalysis.decls[nextDeclIndex]; | ||
| 867 | if (declObj.type != null && nextDeclObj.type != null && declObj.type !== nextDeclObj.type) { | ||
| 868 | if (typeof(declObj.type) !== 'object') { | ||
| 869 | var prevType = declObj.type; | ||
| 870 | declObj.type = {}; | ||
| 871 | declObj.type[prevType] = firstTypeObj; | ||
| 872 | declObj.value = null; | ||
| 873 | } | ||
| 874 | declObj.type[nextDeclObj.type] = typeObj; | ||
| 875 | } else if (declObj.type == null && nextDeclObj != null) { | ||
| 876 | declObj.type = nextDeclObj.type; | ||
| 877 | } | ||
| 878 | if (declObj.value != null && nextDeclObj.value != null && declObj.value !== nextDeclObj.value) { | ||
| 879 | if (typeof(declObj.value) !== 'object') { | ||
| 880 | var prevValue = declObj.value; | ||
| 881 | declObj.value = {}; | ||
| 882 | declObj.value[prevValue] = firstTypeObj; | ||
| 883 | } | ||
| 884 | declObj.value[nextDeclObj.value] = typeObj; | ||
| 885 | } else if (declObj.value == null && nextDeclObj.value != null) { | ||
| 886 | declObj.value = nextDeclObj.value; | ||
| 887 | } | ||
| 888 | } | ||
| 889 | |||
| 703 | function renderValue(decl) { | 890 | function renderValue(decl) { |
| 704 | domFnProtoCode.innerHTML = '<span class="tok-kw">const</span> ' + | 891 | domFnProtoCode.innerHTML = '<span class="tok-kw">const</span> ' + |
| 705 | escapeHtml(decl.name) + ': ' + typeIndexName(decl.type, true, true); | 892 | escapeHtml(decl.name) + ': ' + typeIndexName(decl.type, true, true); |
| ... | @@ -733,13 +920,15 @@ | ... | @@ -733,13 +920,15 @@ |
| 733 | var fnsList = []; | 920 | var fnsList = []; |
| 734 | var varsList = []; | 921 | var varsList = []; |
| 735 | var valsList = []; | 922 | var valsList = []; |
| 923 | |||
| 736 | for (var i = 0; i < container.pubDecls.length; i += 1) { | 924 | for (var i = 0; i < container.pubDecls.length; i += 1) { |
| 737 | var decl = zigAnalysis.decls[container.pubDecls[i]]; | 925 | var decl = zigAnalysis.decls[container.pubDecls[i]]; |
| 926 | |||
| 738 | if (decl.kind === 'var') { | 927 | if (decl.kind === 'var') { |
| 739 | varsList.push(decl); | 928 | varsList.push(decl); |
| 740 | continue; | 929 | continue; |
| 741 | } else if (decl.kind === 'const' && decl.type != null) { | 930 | } else if (decl.kind === 'const' && decl.type != null) { |
| 742 | if (decl.type == typeTypeId) { | 931 | if (decl.type === typeTypeId) { |
| 743 | if (typeIsErrSet(decl.value)) { | 932 | if (typeIsErrSet(decl.value)) { |
| 744 | errSetsList.push(decl); | 933 | errSetsList.push(decl); |
| 745 | } else if (typeIsStructWithNoFields(decl.value)) { | 934 | } else if (typeIsStructWithNoFields(decl.value)) { |
| ... | @@ -838,7 +1027,12 @@ | ... | @@ -838,7 +1027,12 @@ |
| 838 | if (container.kind === typeKinds.Enum) { | 1027 | if (container.kind === typeKinds.Enum) { |
| 839 | html += ' = <span class="tok-number">' + field + '</span>'; | 1028 | html += ' = <span class="tok-number">' + field + '</span>'; |
| 840 | } else { | 1029 | } else { |
| 841 | html += ": " + typeIndexName(field, true, true); | 1030 | html += ": "; |
| 1031 | if (typeof(field) === 'object') { | ||
| 1032 | html += '<span class="tok-kw">var</span>'; | ||
| 1033 | } else { | ||
| 1034 | html += typeIndexName(field, true, true); | ||
| 1035 | } | ||
| 842 | } | 1036 | } |
| 843 | 1037 | ||
| 844 | html += ',</pre>'; | 1038 | html += ',</pre>'; |
| ... | @@ -1042,13 +1236,16 @@ | ... | @@ -1042,13 +1236,16 @@ |
| 1042 | return list; | 1236 | return list; |
| 1043 | } | 1237 | } |
| 1044 | 1238 | ||
| 1045 | function declCanRepresentTypeKind(typeKind) { | 1239 | function typeKindIsContainer(typeKind) { |
| 1046 | return typeKind === typeKinds.ErrorSet || | 1240 | return typeKind === typeKinds.Struct || |
| 1047 | typeKind === typeKinds.Struct || | ||
| 1048 | typeKind === typeKinds.Union || | 1241 | typeKind === typeKinds.Union || |
| 1049 | typeKind === typeKinds.Enum; | 1242 | typeKind === typeKinds.Enum; |
| 1050 | } | 1243 | } |
| 1051 | 1244 | ||
| 1245 | function declCanRepresentTypeKind(typeKind) { | ||
| 1246 | return typeKind === typeKinds.ErrorSet || typeKindIsContainer(typeKind); | ||
| 1247 | } | ||
| 1248 | |||
| 1052 | function computeCanonDeclPaths() { | 1249 | function computeCanonDeclPaths() { |
| 1053 | var list = new Array(zigAnalysis.decls.length); | 1250 | var list = new Array(zigAnalysis.decls.length); |
| 1054 | canonTypeDecls = new Array(zigAnalysis.types.length); | 1251 | canonTypeDecls = new Array(zigAnalysis.types.length); |
| ... | @@ -1406,4 +1603,18 @@ | ... | @@ -1406,4 +1603,18 @@ |
| 1406 | function byNameProperty(a, b) { | 1603 | function byNameProperty(a, b) { |
| 1407 | return operatorCompare(a.name, b.name); | 1604 | return operatorCompare(a.name, b.name); |
| 1408 | } | 1605 | } |
| 1606 | |||
| 1607 | function clone(obj) { | ||
| 1608 | var res = {}; | ||
| 1609 | for (var key in obj) { | ||
| 1610 | res[key] = obj[key]; | ||
| 1611 | } | ||
| 1612 | return res; | ||
| 1613 | } | ||
| 1614 | |||
| 1615 | function firstObjectKey(obj) { | ||
| 1616 | for (var key in obj) { | ||
| 1617 | return key; | ||
| 1618 | } | ||
| 1619 | } | ||
| 1409 | })(); | 1620 | })(); |
src/dump_analysis.cpp+98-64| ... | @@ -456,6 +456,10 @@ static uint32_t anal_dump_get_fn_id(AnalDumpCtx *ctx, ZigFn *fn) { | ... | @@ -456,6 +456,10 @@ static uint32_t anal_dump_get_fn_id(AnalDumpCtx *ctx, ZigFn *fn) { |
| 456 | auto existing_entry = ctx->fn_map.put_unique(fn, fn_id); | 456 | auto existing_entry = ctx->fn_map.put_unique(fn, fn_id); |
| 457 | if (existing_entry == nullptr) { | 457 | if (existing_entry == nullptr) { |
| 458 | ctx->fn_list.append(fn); | 458 | ctx->fn_list.append(fn); |
| 459 | |||
| 460 | // poke the fn | ||
| 461 | (void)anal_dump_get_type_id(ctx, fn->type_entry); | ||
| 462 | (void)anal_dump_get_node_id(ctx, fn->proto_node); | ||
| 459 | } else { | 463 | } else { |
| 460 | fn_id = existing_entry->value; | 464 | fn_id = existing_entry->value; |
| 461 | } | 465 | } |
| ... | @@ -700,11 +704,7 @@ static void anal_dump_value(AnalDumpCtx *ctx, AstNode *source_node, ZigType *ty, | ... | @@ -700,11 +704,7 @@ static void anal_dump_value(AnalDumpCtx *ctx, AstNode *source_node, ZigType *ty, |
| 700 | case ZigTypeIdFn: { | 704 | case ZigTypeIdFn: { |
| 701 | if (value->data.x_ptr.special == ConstPtrSpecialFunction) { | 705 | if (value->data.x_ptr.special == ConstPtrSpecialFunction) { |
| 702 | ZigFn *val_fn = value->data.x_ptr.data.fn.fn_entry; | 706 | ZigFn *val_fn = value->data.x_ptr.data.fn.fn_entry; |
| 703 | if (val_fn->type_entry->data.fn.is_generic) { | 707 | anal_dump_fn_ref(ctx, val_fn); |
| 704 | anal_dump_node_ref(ctx, val_fn->proto_node); | ||
| 705 | } else { | ||
| 706 | anal_dump_fn_ref(ctx, val_fn); | ||
| 707 | } | ||
| 708 | } else { | 708 | } else { |
| 709 | jw_null(&ctx->jw); | 709 | jw_null(&ctx->jw); |
| 710 | } | 710 | } |
| ... | @@ -758,6 +758,7 @@ static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) { | ... | @@ -758,6 +758,7 @@ static void anal_dump_type(AnalDumpCtx *ctx, ZigType *ty) { |
| 758 | switch (ty->id) { | 758 | switch (ty->id) { |
| 759 | case ZigTypeIdMetaType: | 759 | case ZigTypeIdMetaType: |
| 760 | case ZigTypeIdBool: | 760 | case ZigTypeIdBool: |
| 761 | case ZigTypeIdEnumLiteral: | ||
| 761 | break; | 762 | break; |
| 762 | case ZigTypeIdStruct: { | 763 | case ZigTypeIdStruct: { |
| 763 | if (ty->data.structure.is_slice) { | 764 | if (ty->data.structure.is_slice) { |
| ... | @@ -1072,13 +1073,25 @@ static void anal_dump_node(AnalDumpCtx *ctx, const AstNode *node) { | ... | @@ -1072,13 +1073,25 @@ static void anal_dump_node(AnalDumpCtx *ctx, const AstNode *node) { |
| 1072 | jw_object_field(jw, "col"); | 1073 | jw_object_field(jw, "col"); |
| 1073 | jw_int(jw, node->column); | 1074 | jw_int(jw, node->column); |
| 1074 | 1075 | ||
| 1075 | const Buf *doc_comments_buf; | 1076 | const Buf *doc_comments_buf = nullptr; |
| 1077 | const Buf *name_buf = nullptr; | ||
| 1078 | const ZigList<AstNode *> *field_nodes = nullptr; | ||
| 1079 | bool is_var_args = false; | ||
| 1080 | bool is_noalias = false; | ||
| 1081 | bool is_comptime = false; | ||
| 1082 | |||
| 1076 | switch (node->type) { | 1083 | switch (node->type) { |
| 1077 | case NodeTypeParamDecl: | 1084 | case NodeTypeParamDecl: |
| 1078 | doc_comments_buf = &node->data.param_decl.doc_comments; | 1085 | doc_comments_buf = &node->data.param_decl.doc_comments; |
| 1086 | name_buf = node->data.param_decl.name; | ||
| 1087 | is_var_args = node->data.param_decl.is_var_args; | ||
| 1088 | is_noalias = node->data.param_decl.is_noalias; | ||
| 1089 | is_comptime = node->data.param_decl.is_comptime; | ||
| 1079 | break; | 1090 | break; |
| 1080 | case NodeTypeFnProto: | 1091 | case NodeTypeFnProto: |
| 1081 | doc_comments_buf = &node->data.fn_proto.doc_comments; | 1092 | doc_comments_buf = &node->data.fn_proto.doc_comments; |
| 1093 | field_nodes = &node->data.fn_proto.params; | ||
| 1094 | is_var_args = node->data.fn_proto.is_var_args; | ||
| 1082 | break; | 1095 | break; |
| 1083 | case NodeTypeVariableDeclaration: | 1096 | case NodeTypeVariableDeclaration: |
| 1084 | doc_comments_buf = &node->data.variable_declaration.doc_comments; | 1097 | doc_comments_buf = &node->data.variable_declaration.doc_comments; |
| ... | @@ -1088,55 +1101,50 @@ static void anal_dump_node(AnalDumpCtx *ctx, const AstNode *node) { | ... | @@ -1088,55 +1101,50 @@ static void anal_dump_node(AnalDumpCtx *ctx, const AstNode *node) { |
| 1088 | break; | 1101 | break; |
| 1089 | case NodeTypeStructField: | 1102 | case NodeTypeStructField: |
| 1090 | doc_comments_buf = &node->data.struct_field.doc_comments; | 1103 | doc_comments_buf = &node->data.struct_field.doc_comments; |
| 1104 | name_buf = node->data.struct_field.name; | ||
| 1105 | break; | ||
| 1106 | case NodeTypeContainerDecl: | ||
| 1107 | field_nodes = &node->data.container_decl.fields; | ||
| 1091 | break; | 1108 | break; |
| 1092 | default: | 1109 | default: |
| 1093 | doc_comments_buf = nullptr; | ||
| 1094 | break; | 1110 | break; |
| 1095 | } | 1111 | } |
| 1112 | |||
| 1096 | if (doc_comments_buf != nullptr && doc_comments_buf->list.length != 0) { | 1113 | if (doc_comments_buf != nullptr && doc_comments_buf->list.length != 0) { |
| 1097 | jw_object_field(jw, "docs"); | 1114 | jw_object_field(jw, "docs"); |
| 1098 | jw_string(jw, buf_ptr(doc_comments_buf)); | 1115 | jw_string(jw, buf_ptr(doc_comments_buf)); |
| 1099 | } | 1116 | } |
| 1100 | 1117 | ||
| 1101 | const Buf *name_buf; | ||
| 1102 | switch (node->type) { | ||
| 1103 | case NodeTypeStructField: | ||
| 1104 | name_buf = node->data.struct_field.name; | ||
| 1105 | break; | ||
| 1106 | case NodeTypeParamDecl: | ||
| 1107 | name_buf = node->data.param_decl.name; | ||
| 1108 | break; | ||
| 1109 | default: | ||
| 1110 | name_buf = nullptr; | ||
| 1111 | break; | ||
| 1112 | } | ||
| 1113 | if (name_buf != nullptr) { | 1118 | if (name_buf != nullptr) { |
| 1114 | jw_object_field(jw, "name"); | 1119 | jw_object_field(jw, "name"); |
| 1115 | jw_string(jw, buf_ptr(name_buf)); | 1120 | jw_string(jw, buf_ptr(name_buf)); |
| 1116 | } | 1121 | } |
| 1117 | 1122 | ||
| 1118 | const ZigList<AstNode *> *fieldNodes; | 1123 | if (field_nodes != nullptr) { |
| 1119 | switch (node->type) { | ||
| 1120 | case NodeTypeContainerDecl: | ||
| 1121 | fieldNodes = &node->data.container_decl.fields; | ||
| 1122 | break; | ||
| 1123 | case NodeTypeFnProto: | ||
| 1124 | fieldNodes = &node->data.fn_proto.params; | ||
| 1125 | break; | ||
| 1126 | default: | ||
| 1127 | fieldNodes = nullptr; | ||
| 1128 | break; | ||
| 1129 | } | ||
| 1130 | if (fieldNodes != nullptr) { | ||
| 1131 | jw_object_field(jw, "fields"); | 1124 | jw_object_field(jw, "fields"); |
| 1132 | jw_begin_array(jw); | 1125 | jw_begin_array(jw); |
| 1133 | for (size_t i = 0; i < fieldNodes->length; i += 1) { | 1126 | for (size_t i = 0; i < field_nodes->length; i += 1) { |
| 1134 | jw_array_elem(jw); | 1127 | jw_array_elem(jw); |
| 1135 | anal_dump_node_ref(ctx, fieldNodes->at(i)); | 1128 | anal_dump_node_ref(ctx, field_nodes->at(i)); |
| 1136 | } | 1129 | } |
| 1137 | jw_end_array(jw); | 1130 | jw_end_array(jw); |
| 1138 | } | 1131 | } |
| 1139 | 1132 | ||
| 1133 | if (is_var_args) { | ||
| 1134 | jw_object_field(jw, "varArgs"); | ||
| 1135 | jw_bool(jw, true); | ||
| 1136 | } | ||
| 1137 | |||
| 1138 | if (is_comptime) { | ||
| 1139 | jw_object_field(jw, "comptime"); | ||
| 1140 | jw_bool(jw, true); | ||
| 1141 | } | ||
| 1142 | |||
| 1143 | if (is_noalias) { | ||
| 1144 | jw_object_field(jw, "noalias"); | ||
| 1145 | jw_bool(jw, true); | ||
| 1146 | } | ||
| 1147 | |||
| 1140 | jw_end_object(jw); | 1148 | jw_end_object(jw); |
| 1141 | } | 1149 | } |
| 1142 | 1150 | ||
| ... | @@ -1235,59 +1243,76 @@ void zig_print_analysis_dump(CodeGen *g, FILE *f, const char *one_indent, const | ... | @@ -1235,59 +1243,76 @@ void zig_print_analysis_dump(CodeGen *g, FILE *f, const char *one_indent, const |
| 1235 | jw_object_field(jw, "calls"); | 1243 | jw_object_field(jw, "calls"); |
| 1236 | jw_begin_array(jw); | 1244 | jw_begin_array(jw); |
| 1237 | { | 1245 | { |
| 1246 | ZigList<ZigVar *> var_stack = {}; | ||
| 1247 | |||
| 1238 | auto it = g->memoized_fn_eval_table.entry_iterator(); | 1248 | auto it = g->memoized_fn_eval_table.entry_iterator(); |
| 1239 | for (;;) { | 1249 | for (;;) { |
| 1240 | auto *entry = it.next(); | 1250 | auto *entry = it.next(); |
| 1241 | if (!entry) | 1251 | if (!entry) |
| 1242 | break; | 1252 | break; |
| 1243 | 1253 | ||
| 1244 | jw_array_elem(jw); | 1254 | var_stack.resize(0); |
| 1245 | jw_begin_object(jw); | 1255 | ZigFn *fn = nullptr; |
| 1246 | |||
| 1247 | jw_object_field(jw, "args"); | ||
| 1248 | jw_begin_object(jw); | ||
| 1249 | 1256 | ||
| 1250 | Scope *scope = entry->key; | 1257 | Scope *scope = entry->key; |
| 1251 | while (scope != nullptr) { | 1258 | while (scope != nullptr) { |
| 1252 | if (scope->id == ScopeIdVarDecl) { | 1259 | if (scope->id == ScopeIdVarDecl) { |
| 1253 | ZigVar *var = reinterpret_cast<ScopeVarDecl *>(scope)->var; | 1260 | ZigVar *var = reinterpret_cast<ScopeVarDecl *>(scope)->var; |
| 1254 | jw_object_field(jw, var->name); | 1261 | var_stack.append(var); |
| 1255 | jw_begin_object(jw); | ||
| 1256 | jw_object_field(jw, "type"); | ||
| 1257 | anal_dump_type_ref(&ctx, var->var_type); | ||
| 1258 | jw_object_field(jw, "value"); | ||
| 1259 | anal_dump_value(&ctx, scope->source_node, var->var_type, var->const_value); | ||
| 1260 | jw_end_object(jw); | ||
| 1261 | } else if (scope->id == ScopeIdFnDef) { | 1262 | } else if (scope->id == ScopeIdFnDef) { |
| 1262 | jw_end_object(jw); | 1263 | fn = reinterpret_cast<ScopeFnDef *>(scope)->fn_entry; |
| 1264 | break; | ||
| 1265 | } | ||
| 1266 | scope = scope->parent; | ||
| 1267 | } | ||
| 1268 | ConstExprValue *result = entry->value; | ||
| 1269 | |||
| 1270 | assert(fn != nullptr); | ||
| 1271 | |||
| 1272 | jw_array_elem(jw); | ||
| 1273 | jw_begin_object(jw); | ||
| 1274 | |||
| 1275 | jw_object_field(jw, "fn"); | ||
| 1276 | anal_dump_fn_ref(&ctx, fn); | ||
| 1277 | |||
| 1278 | jw_object_field(jw, "result"); | ||
| 1279 | { | ||
| 1280 | jw_begin_object(jw); | ||
| 1281 | |||
| 1282 | jw_object_field(jw, "type"); | ||
| 1283 | anal_dump_type_ref(&ctx, result->type); | ||
| 1284 | |||
| 1285 | jw_object_field(jw, "value"); | ||
| 1286 | anal_dump_value(&ctx, scope->source_node, result->type, result); | ||
| 1287 | |||
| 1288 | jw_end_object(jw); | ||
| 1289 | } | ||
| 1290 | |||
| 1291 | if (var_stack.length != 0) { | ||
| 1292 | jw_object_field(jw, "args"); | ||
| 1293 | jw_begin_array(jw); | ||
| 1263 | 1294 | ||
| 1264 | jw_object_field(jw, "fn"); | 1295 | while (var_stack.length != 0) { |
| 1265 | ZigFn *fn = reinterpret_cast<ScopeFnDef *>(scope)->fn_entry; | 1296 | ZigVar *var = var_stack.pop(); |
| 1266 | anal_dump_fn_ref(&ctx, fn); | ||
| 1267 | 1297 | ||
| 1268 | ConstExprValue *result = entry->value; | 1298 | jw_array_elem(jw); |
| 1269 | jw_object_field(jw, "result"); | ||
| 1270 | jw_begin_object(jw); | 1299 | jw_begin_object(jw); |
| 1300 | |||
| 1271 | jw_object_field(jw, "type"); | 1301 | jw_object_field(jw, "type"); |
| 1272 | anal_dump_type_ref(&ctx, result->type); | 1302 | anal_dump_type_ref(&ctx, var->var_type); |
| 1303 | |||
| 1273 | jw_object_field(jw, "value"); | 1304 | jw_object_field(jw, "value"); |
| 1274 | anal_dump_value(&ctx, scope->source_node, result->type, result); | 1305 | anal_dump_value(&ctx, scope->source_node, var->var_type, var->const_value); |
| 1306 | |||
| 1275 | jw_end_object(jw); | 1307 | jw_end_object(jw); |
| 1276 | break; | ||
| 1277 | } | 1308 | } |
| 1278 | scope = scope->parent; | 1309 | jw_end_array(jw); |
| 1279 | } | 1310 | } |
| 1311 | |||
| 1280 | jw_end_object(jw); | 1312 | jw_end_object(jw); |
| 1281 | } | 1313 | } |
| 1282 | } | ||
| 1283 | jw_end_array(jw); | ||
| 1284 | 1314 | ||
| 1285 | jw_object_field(jw, "fns"); | 1315 | var_stack.deinit(); |
| 1286 | jw_begin_array(jw); | ||
| 1287 | for (uint32_t i = 0; i < ctx.fn_list.length; i += 1) { | ||
| 1288 | ZigFn *fn = ctx.fn_list.at(i); | ||
| 1289 | jw_array_elem(jw); | ||
| 1290 | anal_dump_fn(&ctx, fn); | ||
| 1291 | } | 1316 | } |
| 1292 | jw_end_array(jw); | 1317 | jw_end_array(jw); |
| 1293 | 1318 | ||
| ... | @@ -1315,6 +1340,15 @@ void zig_print_analysis_dump(CodeGen *g, FILE *f, const char *one_indent, const | ... | @@ -1315,6 +1340,15 @@ void zig_print_analysis_dump(CodeGen *g, FILE *f, const char *one_indent, const |
| 1315 | } | 1340 | } |
| 1316 | jw_end_array(jw); | 1341 | jw_end_array(jw); |
| 1317 | 1342 | ||
| 1343 | jw_object_field(jw, "fns"); | ||
| 1344 | jw_begin_array(jw); | ||
| 1345 | for (uint32_t i = 0; i < ctx.fn_list.length; i += 1) { | ||
| 1346 | ZigFn *fn = ctx.fn_list.at(i); | ||
| 1347 | jw_array_elem(jw); | ||
| 1348 | anal_dump_fn(&ctx, fn); | ||
| 1349 | } | ||
| 1350 | jw_end_array(jw); | ||
| 1351 | |||
| 1318 | jw_object_field(jw, "errors"); | 1352 | jw_object_field(jw, "errors"); |
| 1319 | jw_begin_array(jw); | 1353 | jw_begin_array(jw); |
| 1320 | for (uint32_t i = 0; i < ctx.err_list.length; i += 1) { | 1354 | for (uint32_t i = 0; i < ctx.err_list.length; i += 1) { |
tools/merge_anal_dumps.zig+173| ... | @@ -2,6 +2,8 @@ const builtin = @import("builtin"); | ... | @@ -2,6 +2,8 @@ const builtin = @import("builtin"); |
| 2 | const std = @import("std"); | 2 | const std = @import("std"); |
| 3 | const json = std.json; | 3 | const json = std.json; |
| 4 | const mem = std.mem; | 4 | const mem = std.mem; |
| 5 | const fieldIndex = std.meta.fieldIndex; | ||
| 6 | const TypeId = builtin.TypeId; | ||
| 5 | 7 | ||
| 6 | pub fn main() anyerror!void { | 8 | pub fn main() anyerror!void { |
| 7 | var arena = std.heap.ArenaAllocator.init(std.heap.direct_allocator); | 9 | var arena = std.heap.ArenaAllocator.init(std.heap.direct_allocator); |
| ... | @@ -61,6 +63,81 @@ const Error = struct { | ... | @@ -61,6 +63,81 @@ const Error = struct { |
| 61 | } | 63 | } |
| 62 | }; | 64 | }; |
| 63 | 65 | ||
| 66 | const simple_types = [_][]const u8{ | ||
| 67 | "Type", | ||
| 68 | "Void", | ||
| 69 | "Bool", | ||
| 70 | "NoReturn", | ||
| 71 | "ComptimeFloat", | ||
| 72 | "ComptimeInt", | ||
| 73 | "Undefined", | ||
| 74 | "Null", | ||
| 75 | "AnyFrame", | ||
| 76 | "EnumLiteral", | ||
| 77 | }; | ||
| 78 | |||
| 79 | const Type = union(builtin.TypeId) { | ||
| 80 | Type, | ||
| 81 | Void, | ||
| 82 | Bool, | ||
| 83 | NoReturn, | ||
| 84 | ComptimeFloat, | ||
| 85 | ComptimeInt, | ||
| 86 | Undefined, | ||
| 87 | Null, | ||
| 88 | AnyFrame, | ||
| 89 | EnumLiteral, | ||
| 90 | |||
| 91 | Int: Int, | ||
| 92 | Float: usize, // bits | ||
| 93 | |||
| 94 | Vector: Array, | ||
| 95 | Optional: usize, // payload type index | ||
| 96 | Pointer: Pointer, | ||
| 97 | Array: Array, | ||
| 98 | |||
| 99 | Struct, // TODO | ||
| 100 | ErrorUnion, // TODO | ||
| 101 | ErrorSet, // TODO | ||
| 102 | Enum, // TODO | ||
| 103 | Union, // TODO | ||
| 104 | Fn, // TODO | ||
| 105 | BoundFn, // TODO | ||
| 106 | ArgTuple, // TODO | ||
| 107 | Opaque, // TODO | ||
| 108 | Frame, // TODO | ||
| 109 | |||
| 110 | const Int = struct { | ||
| 111 | bits: usize, | ||
| 112 | signed: bool, | ||
| 113 | }; | ||
| 114 | |||
| 115 | const Pointer = struct { | ||
| 116 | elem: usize, | ||
| 117 | alignment: usize, | ||
| 118 | is_const: bool, | ||
| 119 | is_volatile: bool, | ||
| 120 | allow_zero: bool, | ||
| 121 | host_int_bytes: usize, | ||
| 122 | bit_offset_in_host: usize, | ||
| 123 | }; | ||
| 124 | |||
| 125 | const Array = struct { | ||
| 126 | elem: usize, | ||
| 127 | len: usize, | ||
| 128 | }; | ||
| 129 | |||
| 130 | fn hash(t: Type) u32 { | ||
| 131 | var hasher = std.hash.Wyhash.init(0); | ||
| 132 | std.hash.autoHash(&hasher, builtin.TypeId(t)); | ||
| 133 | return @truncate(u32, hasher.final()); | ||
| 134 | } | ||
| 135 | |||
| 136 | fn eql(a: Type, b: Type) bool { | ||
| 137 | return std.meta.eql(a, b); | ||
| 138 | } | ||
| 139 | }; | ||
| 140 | |||
| 64 | const Dump = struct { | 141 | const Dump = struct { |
| 65 | zig_id: ?[]const u8 = null, | 142 | zig_id: ?[]const u8 = null, |
| 66 | zig_version: ?[]const u8 = null, | 143 | zig_version: ?[]const u8 = null, |
| ... | @@ -79,6 +156,10 @@ const Dump = struct { | ... | @@ -79,6 +156,10 @@ const Dump = struct { |
| 79 | error_list: std.ArrayList(Error), | 156 | error_list: std.ArrayList(Error), |
| 80 | error_map: ErrorMap, | 157 | error_map: ErrorMap, |
| 81 | 158 | ||
| 159 | const TypeMap = std.HashMap(Type, usize, Type.hash, Type.eql); | ||
| 160 | type_list: std.ArrayList(Type), | ||
| 161 | type_map: TypeMap, | ||
| 162 | |||
| 82 | fn init(allocator: *mem.Allocator) Dump { | 163 | fn init(allocator: *mem.Allocator) Dump { |
| 83 | return Dump{ | 164 | return Dump{ |
| 84 | .targets = std.ArrayList([]const u8).init(allocator), | 165 | .targets = std.ArrayList([]const u8).init(allocator), |
| ... | @@ -88,6 +169,8 @@ const Dump = struct { | ... | @@ -88,6 +169,8 @@ const Dump = struct { |
| 88 | .node_map = NodeMap.init(allocator), | 169 | .node_map = NodeMap.init(allocator), |
| 89 | .error_list = std.ArrayList(Error).init(allocator), | 170 | .error_list = std.ArrayList(Error).init(allocator), |
| 90 | .error_map = ErrorMap.init(allocator), | 171 | .error_map = ErrorMap.init(allocator), |
| 172 | .type_list = std.ArrayList(Type).init(allocator), | ||
| 173 | .type_map = TypeMap.init(allocator), | ||
| 91 | }; | 174 | }; |
| 92 | } | 175 | } |
| 93 | 176 | ||
| ... | @@ -165,6 +248,66 @@ const Dump = struct { | ... | @@ -165,6 +248,66 @@ const Dump = struct { |
| 165 | } | 248 | } |
| 166 | try other_error_to_mine.putNoClobber(i, gop.kv.value); | 249 | try other_error_to_mine.putNoClobber(i, gop.kv.value); |
| 167 | } | 250 | } |
| 251 | |||
| 252 | // Merge types. Now it starts to get advanced. | ||
| 253 | // First we identify all the simple types and merge those. | ||
| 254 | // Example: void, type, noreturn | ||
| 255 | // We can also do integers and floats. | ||
| 256 | const other_types = root.Object.get("types").?.value.Array.toSliceConst(); | ||
| 257 | var other_types_to_mine = std.AutoHashMap(usize, usize).init(self.a()); | ||
| 258 | for (other_types) |other_type_json, i| { | ||
| 259 | const type_kind = jsonObjInt(other_type_json, "kind"); | ||
| 260 | switch (type_kind) { | ||
| 261 | fieldIndex(TypeId, "Int").? => { | ||
| 262 | var signed: bool = undefined; | ||
| 263 | var bits: usize = undefined; | ||
| 264 | if (other_type_json.Object.get("i")) |kv| { | ||
| 265 | signed = true; | ||
| 266 | bits = @intCast(usize, kv.value.Integer); | ||
| 267 | } else if (other_type_json.Object.get("u")) |kv| { | ||
| 268 | signed = false; | ||
| 269 | bits = @intCast(usize, kv.value.Integer); | ||
| 270 | } else { | ||
| 271 | unreachable; | ||
| 272 | } | ||
| 273 | const other_type = Type{ | ||
| 274 | .Int = Type.Int{ | ||
| 275 | .bits = bits, | ||
| 276 | .signed = signed, | ||
| 277 | }, | ||
| 278 | }; | ||
| 279 | try self.mergeOtherType(other_type, i, &other_types_to_mine); | ||
| 280 | }, | ||
| 281 | fieldIndex(TypeId, "Float").? => { | ||
| 282 | const other_type = Type{ | ||
| 283 | .Float = jsonObjInt(other_type_json, "bits"), | ||
| 284 | }; | ||
| 285 | try self.mergeOtherType(other_type, i, &other_types_to_mine); | ||
| 286 | }, | ||
| 287 | else => {}, | ||
| 288 | } | ||
| 289 | |||
| 290 | inline for (simple_types) |simple_type_name| { | ||
| 291 | if (type_kind == std.meta.fieldIndex(builtin.TypeId, simple_type_name).?) { | ||
| 292 | const other_type = @unionInit(Type, simple_type_name, {}); | ||
| 293 | try self.mergeOtherType(other_type, i, &other_types_to_mine); | ||
| 294 | } | ||
| 295 | } | ||
| 296 | } | ||
| 297 | } | ||
| 298 | |||
| 299 | fn mergeOtherType( | ||
| 300 | self: *Dump, | ||
| 301 | other_type: Type, | ||
| 302 | other_type_index: usize, | ||
| 303 | other_types_to_mine: *std.AutoHashMap(usize, usize), | ||
| 304 | ) !void { | ||
| 305 | const gop = try self.type_map.getOrPut(other_type); | ||
| 306 | if (!gop.found_existing) { | ||
| 307 | gop.kv.value = self.type_list.len; | ||
| 308 | try self.type_list.append(other_type); | ||
| 309 | } | ||
| 310 | try other_types_to_mine.putNoClobber(other_type_index, gop.kv.value); | ||
| 168 | } | 311 | } |
| 169 | 312 | ||
| 170 | fn render(self: *Dump, stream: var) !void { | 313 | fn render(self: *Dump, stream: var) !void { |
| ... | @@ -204,6 +347,36 @@ const Dump = struct { | ... | @@ -204,6 +347,36 @@ const Dump = struct { |
| 204 | 347 | ||
| 205 | try jw.endObject(); | 348 | try jw.endObject(); |
| 206 | 349 | ||
| 350 | try jw.objectField("types"); | ||
| 351 | try jw.beginArray(); | ||
| 352 | for (self.type_list.toSliceConst()) |t| { | ||
| 353 | try jw.arrayElem(); | ||
| 354 | try jw.beginObject(); | ||
| 355 | |||
| 356 | try jw.objectField("kind"); | ||
| 357 | try jw.emitNumber(@enumToInt(builtin.TypeId(t))); | ||
| 358 | |||
| 359 | switch (t) { | ||
| 360 | .Int => |int| { | ||
| 361 | if (int.signed) { | ||
| 362 | try jw.objectField("i"); | ||
| 363 | } else { | ||
| 364 | try jw.objectField("u"); | ||
| 365 | } | ||
| 366 | try jw.emitNumber(int.bits); | ||
| 367 | }, | ||
| 368 | .Float => |bits| { | ||
| 369 | try jw.objectField("bits"); | ||
| 370 | try jw.emitNumber(bits); | ||
| 371 | }, | ||
| 372 | |||
| 373 | else => {}, | ||
| 374 | } | ||
| 375 | |||
| 376 | try jw.endObject(); | ||
| 377 | } | ||
| 378 | try jw.endArray(); | ||
| 379 | |||
| 207 | try jw.objectField("errors"); | 380 | try jw.objectField("errors"); |
| 208 | try jw.beginArray(); | 381 | try jw.beginArray(); |
| 209 | for (self.error_list.toSliceConst()) |zig_error| { | 382 | for (self.error_list.toSliceConst()) |zig_error| { |