Skip to content

Commit 7d87667

Browse files
authored
Merge pull request #165 from Ackee-Blockchain/ver/1.19.2
Ver/1.19.2
2 parents 6391664 + 7fc0a0c commit 7d87667

File tree

15 files changed

+257
-59
lines changed

15 files changed

+257
-59
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,4 +6,5 @@ node_modules
66
env.ts
77
.DS_Store
88
.todo
9-
.vscode
9+
.vscode
10+
.wake

CHANGELOG.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,20 @@
11
# Changelog
22

3+
## [1.19.2]
4+
### Fixes
5+
- Fixed compilation issues caused by unreliable `remappings.txt` files in Foundry projects
6+
7+
## [1.19.1]
8+
### Features
9+
- Added Wake version information to the bottom status bar
10+
- Implemented filtering for ignored detections in the detections UI
11+
12+
### Improvements
13+
- Store ignored detections toggle setting in workspace storage for better persistence
14+
15+
### Fixes
16+
- Fixed state loading issues and disabled autosave by default
17+
318
## [1.19.0]
419
### Features
520
- Introduced pre-configured chains, such as Ethereum Mainnet and popular L2 networks (Optimism, Arbitrum, Base, Polygon, etc.), significantly streamlining the forking process

package.json

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,16 @@
639639
"command": "Tools-for-Solidity.sake.copyFromResults",
640640
"title": "Solidity: Copy From Results",
641641
"icon": "$(copy)"
642+
},
643+
{
644+
"command": "Tools-for-Solidity.detections.toggle_show_ignored",
645+
"title": "Show Ignored Detections",
646+
"icon": "$(eye)"
647+
},
648+
{
649+
"command": "Tools-for-Solidity.detections.toggle_hide_ignored",
650+
"title": "Hide Ignored Detections",
651+
"icon": "$(eye-closed)"
642652
}
643653
],
644654
"viewsContainers": {
@@ -694,6 +704,16 @@
694704
"when": "view == wake-detections",
695705
"group": "navigation@3"
696706
},
707+
{
708+
"command": "Tools-for-Solidity.detections.toggle_show_ignored",
709+
"when": "view == wake-detections && !wake.detections.showIgnored",
710+
"group": "navigation@4"
711+
},
712+
{
713+
"command": "Tools-for-Solidity.detections.toggle_hide_ignored",
714+
"when": "view == wake-detections && wake.detections.showIgnored",
715+
"group": "navigation@4"
716+
},
697717
{
698718
"submenu": "tools-for-solidity.detections.group",
699719
"when": "view == wake-detections",

resources/walkthrough/sake.png

-420 KB
Loading

src/commands.ts

Lines changed: 18 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,14 @@ export async function importFoundryRemappings(out: vscode.OutputChannel, silent:
9292
let remappings: string[] = [];
9393

9494
try {
95-
// First, try to read from remappings.txt
96-
remappings = fs
97-
.readFileSync(cwd + '/remappings.txt')
95+
// First, try to execute forge from PATH
96+
remappings = execFileSync('forge', ['remappings'], {
97+
cwd: cwd
98+
})
9899
.toString('utf8')
99100
.split(/\r?\n/);
100101
} catch (e) {
101-
// If remappings.txt doesn't exist or can't be read, try using forge
102+
// If forge is not in PATH, try specific locations
102103
try {
103104
remappings = execFileSync(os.homedir() + '/.foundry/bin/forge', ['remappings'], {
104105
cwd: cwd
@@ -113,12 +114,20 @@ export async function importFoundryRemappings(out: vscode.OutputChannel, silent:
113114
.toString('utf8')
114115
.split(/\r?\n/);
115116
} catch (e) {
116-
if (!silent) {
117-
vscode.window.showErrorMessage(
118-
'Failed to find `remappings.txt` file or `forge` executable.'
119-
);
117+
// Fall back to reading remappings.txt
118+
try {
119+
remappings = fs
120+
.readFileSync(cwd + '/remappings.txt')
121+
.toString('utf8')
122+
.split(/\r?\n/);
123+
} catch (e) {
124+
if (!silent) {
125+
vscode.window.showErrorMessage(
126+
'Failed to find `forge` executable or `remappings.txt` file.'
127+
);
128+
}
129+
return;
120130
}
121-
return;
122131
}
123132
}
124133
}

src/detections/WakeTreeDataProvider.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ export class WakeTreeDataProvider extends BaseTreeProvider {
1212
groupBy: GroupBy = GroupBy.IMPACT;
1313
filterImpact: Impact = Impact.INFO;
1414
filterConfidence: Confidence = Confidence.LOW;
15+
showIgnored: boolean = false;
1516

1617
constructor(context : vscode.ExtensionContext){
1718
super(context);
@@ -22,14 +23,17 @@ export class WakeTreeDataProvider extends BaseTreeProvider {
2223
let groupByConfig = this.context.workspaceState.get("detections.groupBy")
2324
let filterImpactConfig = this.context.workspaceState.get("detections.filterImpact")
2425
let filterConfidenceConfig = this.context.workspaceState.get("detections.filterConfidence")
26+
let showIgnoredConfig = this.context.workspaceState.get("detections.showIgnored", false)
2527

2628
if (groupByConfig !== undefined) this.groupBy = GroupBy[groupByConfig as keyof typeof GroupBy];
2729
if (filterImpactConfig !== undefined) this.filterImpact = Impact[filterImpactConfig as keyof typeof Impact];
2830
if (filterConfidenceConfig !== undefined) this.filterConfidence = Confidence[filterConfidenceConfig as keyof typeof Confidence];
31+
this.showIgnored = showIgnoredConfig;
2932

3033
vscode.commands.executeCommand('setContext', 'detections.group', GroupBy[this.groupBy]);
3134
vscode.commands.executeCommand('setContext', 'detections.filterImpact', Impact[this.filterImpact]);
3235
vscode.commands.executeCommand('setContext', 'detections.filterConfidence', Confidence[this.filterConfidence]);
36+
vscode.commands.executeCommand('setContext', 'wake.detections.showIgnored', this.showIgnored);
3337
}
3438

3539
getRoot(diagnostic: WakeDiagnostic): string {
@@ -147,6 +151,11 @@ export class WakeTreeDataProvider extends BaseTreeProvider {
147151
}
148152

149153
filterDetections(detection: WakeDetection): boolean {
154+
// Filter out ignored detections unless showIgnored is true
155+
if (!this.showIgnored && detection.diagnostic.data.ignored) {
156+
return false;
157+
}
158+
150159
var filterImpact = true;
151160
var filterConfidence = true;
152161

@@ -204,6 +213,11 @@ export class WakeTreeDataProvider extends BaseTreeProvider {
204213
this.context.workspaceState.update("detections.filterConfidence", Confidence[minConfidence]).then(() => this.refresh());
205214
vscode.commands.executeCommand('setContext', 'detections.filterConfidence', Confidence[minConfidence]);
206215
}
216+
217+
setShowIgnored(showIgnored: boolean) {
218+
this.showIgnored = showIgnored;
219+
this.context.workspaceState.update("detections.showIgnored", showIgnored).then(() => this.refresh());
220+
}
207221
}
208222

209223
export enum GroupBy {

src/extension.ts

Lines changed: 75 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ import waitPort = require('wait-port');
3838
import { GroupBy, Impact, Confidence } from './detections/WakeTreeDataProvider';
3939
import { SolcTreeDataProvider } from './detections/SolcTreeDataProvider';
4040
import { WakeTreeDataProvider } from './detections/WakeTreeDataProvider';
41-
import { Detector, WakeDetection } from './detections/model/WakeDetection';
41+
import { Detector, WakeDetection, WakeDiagnostic } from './detections/model/WakeDetection';
4242
import { convertDiagnostics } from './detections/util';
4343
import { DetectorItem } from './detections/model/DetectorItem';
4444
import { ClientMiddleware } from './ClientMiddleware';
@@ -65,6 +65,8 @@ let errorHandler: ClientErrorHandler;
6565
let printers: PrintersHandler;
6666
let crashlog: string[] = [];
6767
let graphvizGenerator: GraphvizPreviewGenerator;
68+
let showIgnoredDetections = false;
69+
let extensionContext: vscode.ExtensionContext;
6870

6971
//export let log: Log
7072

@@ -75,20 +77,28 @@ interface DiagnosticNotification {
7577
diagnostics: Diagnostic[];
7678
}
7779

80+
// Store all diagnostics globally so we can refresh visibility
81+
let allDiagnosticsMap: Map<string, WakeDiagnostic[]> = new Map();
82+
7883
function onNotification(outputChannel: vscode.OutputChannel, detection: DiagnosticNotification) {
79-
let diags = detection.diagnostics
80-
.map((it) => convertDiagnostics(it))
81-
.filter((item) => !item.data.ignored);
82-
diagnosticCollection.set(vscode.Uri.parse(detection.uri), diags);
84+
let diags = detection.diagnostics.map((it) => convertDiagnostics(it));
85+
86+
// Store all diagnostics for later filtering
87+
allDiagnosticsMap.set(detection.uri, diags);
88+
89+
// Store filtered diagnostics for VS Code diagnostics panel
90+
let visibleDiags = diags.filter((item) => showIgnoredDetections || !item.data.ignored);
91+
diagnosticCollection.set(vscode.Uri.parse(detection.uri), visibleDiags);
8392

8493
try {
8594
let uri = vscode.Uri.parse(detection.uri);
95+
// Pass all detections to providers (including ignored ones)
8696
let wakeDetections = diags
87-
.filter((item) => item.source == 'Wake')
97+
.filter((item) => item.source === 'Wake')
8898
.map((it) => new WakeDetection(uri, it));
8999
wakeProvider?.add(uri, wakeDetections);
90100
let solcDetections = diags
91-
.filter((item) => item.source == 'Wake(solc)')
101+
.filter((item) => item.source === 'Wake(solc)')
92102
.map((it) => new WakeDetection(uri, it));
93103
solcProvider?.add(uri, solcDetections);
94104
} catch (err) {
@@ -98,9 +108,18 @@ function onNotification(outputChannel: vscode.OutputChannel, detection: Diagnost
98108
}
99109
}
100110

111+
function refreshDiagnosticsVisibility() {
112+
// Re-filter all stored diagnostics based on current showIgnoredDetections state
113+
for (const [uri, diags] of allDiagnosticsMap) {
114+
let visibleDiags = diags.filter((item) => showIgnoredDetections || !item.data.ignored);
115+
diagnosticCollection.set(vscode.Uri.parse(uri), visibleDiags);
116+
}
117+
}
118+
101119
// this method is called when your extension is activated
102120
// your extension is activated the very first time the command is executed
103121
export async function activate(context: vscode.ExtensionContext) {
122+
extensionContext = context;
104123
const outputChannel = vscode.window.createOutputChannel(
105124
'Solidity: Output',
106125
'tools-for-solidity-output'
@@ -236,6 +255,9 @@ export async function activate(context: vscode.ExtensionContext) {
236255
wakeProvider = new WakeTreeDataProvider(context);
237256
solcProvider = new SolcTreeDataProvider(context);
238257

258+
// Initialize showIgnoredDetections from workspace state (already loaded by WakeTreeDataProvider)
259+
showIgnoredDetections = context.workspaceState.get('detections.showIgnored', false);
260+
239261
const clientOptions: LanguageClientOptions = {
240262
documentSelector: [{ scheme: 'file', language: 'solidity' }],
241263
synchronize: { configurationSection: 'wake' },
@@ -325,7 +347,7 @@ export async function activate(context: vscode.ExtensionContext) {
325347
client.start();
326348

327349
// Create the Wake status bar item
328-
const statusBarProvider = new WakeStatusBarProvider(client);
350+
const statusBarProvider = new WakeStatusBarProvider(client, analytics);
329351

330352
analytics.logActivate();
331353

@@ -542,6 +564,7 @@ function registerCommands(outputChannel: vscode.OutputChannel, context: vscode.E
542564
'Tools-for-Solidity.detections.force_rerun_detectors',
543565
async () => {
544566
wakeProvider?.clear();
567+
allDiagnosticsMap.clear();
545568
vscode.commands.executeCommand('wake.lsp.force_rerun_detectors');
546569
}
547570
)
@@ -552,6 +575,7 @@ function registerCommands(outputChannel: vscode.OutputChannel, context: vscode.E
552575
async () => {
553576
solcProvider?.clear();
554577
wakeProvider?.clear();
578+
allDiagnosticsMap.clear();
555579
vscode.commands.executeCommand('wake.lsp.force_recompile');
556580
}
557581
)
@@ -652,6 +676,39 @@ function registerCommands(outputChannel: vscode.OutputChannel, context: vscode.E
652676
);
653677
})
654678
);
679+
680+
// Register commands for toggling ignored detections
681+
context.subscriptions.push(
682+
vscode.commands.registerCommand('Tools-for-Solidity.detections.toggle_show_ignored', () => {
683+
showIgnoredDetections = true;
684+
vscode.commands.executeCommand('setContext', 'wake.detections.showIgnored', true);
685+
686+
// Update tree provider (which also saves to workspaceState)
687+
wakeProvider?.setShowIgnored(true);
688+
689+
// Refresh diagnostics panel by re-processing existing detections
690+
refreshDiagnosticsVisibility();
691+
})
692+
);
693+
694+
context.subscriptions.push(
695+
vscode.commands.registerCommand('Tools-for-Solidity.detections.toggle_hide_ignored', () => {
696+
showIgnoredDetections = false;
697+
vscode.commands.executeCommand('setContext', 'wake.detections.showIgnored', false);
698+
699+
// Update tree provider (which also saves to workspaceState)
700+
wakeProvider?.setShowIgnored(false);
701+
702+
// Refresh diagnostics panel by re-processing existing detections
703+
refreshDiagnosticsVisibility();
704+
})
705+
);
706+
}
707+
708+
function registerFormatter(context: vscode.ExtensionContext) {
709+
context.subscriptions.push(
710+
vscode.languages.registerDocumentFormattingEditProvider('solidity', new PrettierFormatter())
711+
);
655712
}
656713

657714
function registerFormatter(context: vscode.ExtensionContext) {
@@ -668,7 +725,7 @@ function watchFoundryRemappings() {
668725

669726
const workspace = workspaces[0];
670727
const fileWatcher = vscode.workspace.createFileSystemWatcher(
671-
new vscode.RelativePattern(workspace, 'remappings.txt')
728+
new vscode.RelativePattern(workspace, '.gitmodules')
672729
);
673730

674731
let configWatcher: vscode.Disposable;
@@ -704,6 +761,14 @@ function watchFoundryRemappings() {
704761
return;
705762
}
706763

764+
// Check if this is a Foundry project by looking for .gitmodules or foundry.toml
765+
// const gitmodulesPath = path.join(workspace.uri.fsPath, '.gitmodules');
766+
// const foundryTomlPath = path.join(workspace.uri.fsPath, 'foundry.toml');
767+
768+
// if (!fs.existsSync(gitmodulesPath) && !fs.existsSync(foundryTomlPath)) {
769+
// return;
770+
// }
771+
707772
// start file system watcher
708773
fileWatcher.onDidChange(async () => {
709774
vscode.commands.executeCommand('Tools-for-Solidity.foundry.import_remappings_silent');
@@ -712,6 +777,7 @@ function watchFoundryRemappings() {
712777
vscode.commands.executeCommand('Tools-for-Solidity.foundry.import_remappings_silent');
713778
});
714779
fileWatcher.onDidDelete(async () => {
780+
// When .gitmodules is deleted, clear remappings since dependencies are gone
715781
vscode.workspace
716782
.getConfiguration('wake.compiler.solc')
717783
.update('remappings', undefined, vscode.ConfigurationTarget.Workspace);

src/helpers/WakeStatusProvider.ts

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,16 @@ import { SakeContext } from '../sake/context';
33
import { LanguageClient, State } from 'vscode-languageclient/node';
44
import { restartWakeClient } from '../commands';
55
import { MarkdownString } from 'vscode';
6+
import { Analytics } from '../Analytics';
67

78
export class WakeStatusBarProvider {
89
// private static instance: WakeStatusBarProvider;
910
private _statusBarItem!: vscode.StatusBarItem;
1011

11-
constructor(private client: LanguageClient) {
12+
constructor(
13+
private client: LanguageClient,
14+
private analytics: Analytics
15+
) {
1216
this._initializeStatusBar();
1317
this._initializeCommands();
1418
this.client.onDidChangeState((state) => {
@@ -35,24 +39,26 @@ export class WakeStatusBarProvider {
3539
this._statusBarItem.command = undefined;
3640
this._statusBarItem.show();
3741

42+
const version = this.analytics.wakeVersion || '';
43+
const versionText = version ? ` v${version}` : '';
44+
3845
switch (this.client.state) {
3946
case State.Running:
4047
// this._statusBarItem.hide()
41-
this._statusBarItem.text = '$(check-all) Wake';
42-
this._statusBarItem.tooltip = 'Wake LSP is running';
48+
this._statusBarItem.text = `$(check-all) Wake${versionText}`;
49+
this._statusBarItem.tooltip = `Wake LSP is running${version ? ` (version ${version})` : ''}`;
4350
break;
4451
case State.Stopped:
45-
this._statusBarItem.text = '$(refresh) Wake';
46-
this._statusBarItem.tooltip =
47-
'Cannot connect to Wake LSP required by Solidity (Wake).\nClick to restart client.';
52+
this._statusBarItem.text = `$(refresh) Wake${versionText}`;
53+
this._statusBarItem.tooltip = `Cannot connect to Wake LSP required by Solidity (Wake)${version ? ` (version ${version})` : ''}.\nClick to restart client.`;
4854
this._statusBarItem.backgroundColor = new vscode.ThemeColor(
4955
'statusBarItem.errorBackground'
5056
);
5157
this._statusBarItem.command = 'Tools-for-Solidity.wake.restart_client';
5258
break;
5359
case State.Starting:
54-
this._statusBarItem.text = '$(sync~spin) Wake';
55-
this._statusBarItem.tooltip = 'Connecting to Wake LSP...';
60+
this._statusBarItem.text = `$(sync~spin) Wake${versionText}`;
61+
this._statusBarItem.tooltip = `Connecting to Wake LSP...${version ? ` (version ${version})` : ''}`;
5662
break;
5763
default:
5864
this._statusBarItem.hide();

0 commit comments

Comments
 (0)