@@ -63,6 +63,12 @@ export function activate(context: vscode.ExtensionContext) {
6363 } )
6464 ) ;
6565
66+ context . subscriptions . push (
67+ vscode . commands . registerCommand ( 'goMemoryVisualizer.analyzeWorkspace' , ( ) => {
68+ analyzeWorkspaceCommand ( parser , optimizer ) ;
69+ } )
70+ ) ;
71+
6672 // Register providers
6773 context . subscriptions . push (
6874 vscode . languages . registerHoverProvider ( 'go' , new MemoryLayoutHoverProvider ( parser ) )
@@ -454,6 +460,179 @@ function generateCSVReport(data: ExportFormat): string {
454460 return csv ;
455461}
456462
463+ interface WorkspaceAnalysisResult {
464+ file : string ;
465+ structName : string ;
466+ totalSize : number ;
467+ totalPadding : number ;
468+ paddingPercentage : number ;
469+ bytesSaveable : number ;
470+ cacheLinesCrossed : number ;
471+ hotFields : string [ ] ;
472+ }
473+
474+ async function analyzeWorkspaceCommand ( parser : GoParser , optimizer : StructOptimizer ) {
475+ const workspaceFolders = vscode . workspace . workspaceFolders ;
476+ if ( ! workspaceFolders ) {
477+ vscode . window . showErrorMessage ( 'No workspace folder open' ) ;
478+ return ;
479+ }
480+
481+ const results : WorkspaceAnalysisResult [ ] = [ ] ;
482+
483+ await vscode . window . withProgress ( {
484+ location : vscode . ProgressLocation . Notification ,
485+ title : 'Analyzing Go structs in workspace...' ,
486+ cancellable : true
487+ } , async ( progress , token ) => {
488+ const goFiles = await vscode . workspace . findFiles ( '**/*.go' , '**/vendor/**' ) ;
489+
490+ let processed = 0 ;
491+ for ( const file of goFiles ) {
492+ if ( token . isCancellationRequested ) {
493+ break ;
494+ }
495+
496+ progress . report ( {
497+ increment : ( 100 / goFiles . length ) ,
498+ message : `${ path . basename ( file . fsPath ) } `
499+ } ) ;
500+
501+ try {
502+ const content = fs . readFileSync ( file . fsPath , 'utf8' ) ;
503+ const structs = parser . parseStructs ( content ) ;
504+
505+ for ( const struct of structs ) {
506+ const optimization = optimizer . optimizeStruct ( struct ) ;
507+ const paddingPct = struct . totalSize > 0 ? ( struct . totalPadding / struct . totalSize ) * 100 : 0 ;
508+
509+ // Only include structs with issues
510+ if ( optimization . bytesSaved > 0 || paddingPct > 10 || struct . hotFields . length > 0 ) {
511+ results . push ( {
512+ file : vscode . workspace . asRelativePath ( file ) ,
513+ structName : struct . name ,
514+ totalSize : struct . totalSize ,
515+ totalPadding : struct . totalPadding ,
516+ paddingPercentage : paddingPct ,
517+ bytesSaveable : optimization . bytesSaved ,
518+ cacheLinesCrossed : struct . cacheLinesCrossed ,
519+ hotFields : struct . hotFields
520+ } ) ;
521+ }
522+ }
523+ } catch ( e ) {
524+ // Skip files that can't be read
525+ }
526+
527+ processed ++ ;
528+ }
529+ } ) ;
530+
531+ if ( results . length === 0 ) {
532+ vscode . window . showInformationMessage ( 'All structs in workspace are optimally aligned!' ) ;
533+ return ;
534+ }
535+
536+ // Sort by bytes saveable (most impactful first)
537+ results . sort ( ( a , b ) => b . bytesSaveable - a . bytesSaveable ) ;
538+
539+ // Create report panel
540+ const panel = vscode . window . createWebviewPanel (
541+ 'workspaceAnalysis' ,
542+ 'Workspace Memory Analysis' ,
543+ vscode . ViewColumn . One ,
544+ { enableScripts : true }
545+ ) ;
546+
547+ const totalSaveable = results . reduce ( ( sum , r ) => sum + r . bytesSaveable , 0 ) ;
548+ const totalPadding = results . reduce ( ( sum , r ) => sum + r . totalPadding , 0 ) ;
549+ const structsWithCacheIssues = results . filter ( r => r . hotFields . length > 0 ) . length ;
550+
551+ let html = `
552+ <!DOCTYPE html>
553+ <html>
554+ <head>
555+ <style>
556+ body { font-family: var(--vscode-font-family); padding: 20px; color: var(--vscode-foreground); }
557+ h1, h2, h3 { color: var(--vscode-foreground); }
558+ .summary { background: var(--vscode-editor-background); padding: 15px; border-radius: 5px; margin-bottom: 20px; }
559+ .stat { display: inline-block; margin-right: 30px; }
560+ .stat-value { font-size: 24px; font-weight: bold; color: var(--vscode-textLink-foreground); }
561+ .stat-label { font-size: 12px; color: var(--vscode-descriptionForeground); }
562+ table { border-collapse: collapse; width: 100%; margin-top: 20px; }
563+ th, td { border: 1px solid var(--vscode-panel-border); padding: 8px; text-align: left; }
564+ th { background-color: var(--vscode-editor-background); }
565+ .warning { color: #ff6b6b; }
566+ .saveable { color: #4caf50; font-weight: bold; }
567+ tr:hover { background: var(--vscode-list-hoverBackground); }
568+ </style>
569+ </head>
570+ <body>
571+ <h1>📊 Workspace Memory Analysis</h1>
572+ <p>Architecture: <strong>${ currentArch } </strong></p>
573+
574+ <div class="summary">
575+ <div class="stat">
576+ <div class="stat-value">${ results . length } </div>
577+ <div class="stat-label">Structs with issues</div>
578+ </div>
579+ <div class="stat">
580+ <div class="stat-value saveable">${ totalSaveable } B</div>
581+ <div class="stat-label">Total bytes saveable</div>
582+ </div>
583+ <div class="stat">
584+ <div class="stat-value">${ totalPadding } B</div>
585+ <div class="stat-label">Total padding</div>
586+ </div>
587+ <div class="stat">
588+ <div class="stat-value warning">${ structsWithCacheIssues } </div>
589+ <div class="stat-label">Cache line issues</div>
590+ </div>
591+ </div>
592+
593+ <h2>Optimization Opportunities</h2>
594+ <table>
595+ <tr>
596+ <th>File</th>
597+ <th>Struct</th>
598+ <th>Size</th>
599+ <th>Padding</th>
600+ <th>Saveable</th>
601+ <th>Cache Lines</th>
602+ <th>Hot Fields</th>
603+ </tr>
604+ ` ;
605+
606+ for ( const r of results ) {
607+ const hotFieldsStr = r . hotFields . length > 0
608+ ? `<span class="warning">${ r . hotFields . join ( ', ' ) } </span>`
609+ : '-' ;
610+ const saveableStr = r . bytesSaveable > 0
611+ ? `<span class="saveable">${ r . bytesSaveable } B</span>`
612+ : '-' ;
613+
614+ html += `
615+ <tr>
616+ <td>${ r . file } </td>
617+ <td><strong>${ r . structName } </strong></td>
618+ <td>${ r . totalSize } B</td>
619+ <td>${ r . totalPadding } B (${ r . paddingPercentage . toFixed ( 1 ) } %)</td>
620+ <td>${ saveableStr } </td>
621+ <td>${ r . cacheLinesCrossed } </td>
622+ <td>${ hotFieldsStr } </td>
623+ </tr>
624+ ` ;
625+ }
626+
627+ html += `
628+ </table>
629+ </body>
630+ </html>
631+ ` ;
632+
633+ panel . webview . html = html ;
634+ }
635+
457636class MemoryLayoutHoverProvider implements vscode . HoverProvider {
458637 constructor ( private parser : GoParser ) { }
459638
0 commit comments