Skip to content

Commit 26e9f94

Browse files
authored
IEP-1667 support esp-idf-size 2.0 and use idf.py size command (#1372)
* feat: support esp-idf-size 2.0 * feat: using idf.py size instead of esp-idf-size script
1 parent fde15e6 commit 26e9f94

5 files changed

Lines changed: 92 additions & 79 deletions

File tree

bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/size/IDFSizeChartsComposite.java

Lines changed: 22 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,25 @@ private void plotCharts()
149149
for (var child : chartComp.getChildren())
150150
child.dispose();
151151

152+
// Defensive check: Handle unexpected empty data gracefully to prevent UI crash.
153+
if (overviewJson == null || overviewJson.isEmpty() || !overviewJson.containsKey(IDFSizeConstants.LAYOUT))
154+
{
155+
Label errorLabel = new Label(chartComp, SWT.WRAP | SWT.CENTER);
156+
errorLabel.setText(
157+
Messages.IDFSizeChartsComposite_NoMemoryDataAvailableLblMsg);
158+
errorLabel.setForeground(chartComp.getDisplay().getSystemColor(SWT.COLOR_RED));
159+
160+
// Center the error message across the 2-column grid
161+
GridData gd = new GridData(SWT.CENTER, SWT.CENTER, true, true);
162+
gd.horizontalSpan = 2;
163+
errorLabel.setLayoutData(gd);
164+
165+
// Refresh layout and return to avoid crash
166+
chartComp.layout(true, true);
167+
scrollable.setMinSize(chartComp.computeSize(SWT.DEFAULT, SWT.DEFAULT));
168+
return;
169+
}
170+
152171
JSONArray layoutArray = (JSONArray) overviewJson.get(IDFSizeConstants.LAYOUT);
153172
for (Object obj : layoutArray)
154173
{
@@ -206,7 +225,7 @@ private void createBarChart(Composite parent, String title, List<String> labels,
206225
for (int i = 0; i < dataset.getRowCount(); i++)
207226
{
208227
String rowKey = dataset.getRowKey(i).toString();
209-
if (rowKey.startsWith("Free"))
228+
if (rowKey.startsWith("Free")) //$NON-NLS-1$
210229
{
211230
labelColorMap.putIfAbsent(rowKey, Color.GREEN);
212231
}
@@ -245,7 +264,7 @@ private void createPieChart(Composite parent, String title, List<String> labels,
245264

246265
for (String key : dataset.getKeys())
247266
{
248-
if (key.startsWith("Free"))
267+
if (key.startsWith("Free")) //$NON-NLS-1$
249268
{
250269
labelColorMap.putIfAbsent(key, Color.GREEN);
251270
}
@@ -302,7 +321,7 @@ private JSONObject getIDFSizeOverviewData(IFile file, String targetName)
302321
{
303322
try
304323
{
305-
return new IDFSizeDataManager().getIDFSizeOverview(file, targetName);
324+
return new IDFSizeDataManager().getIDFSizeOverview(file);
306325
}
307326
catch (Exception e)
308327
{

bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/size/IDFSizeDataManager.java

Lines changed: 45 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ public List<LibraryMemoryComponent> getDataList(IFile mapFile) throws Exception
4646
{
4747
String pythonExecutablePath = preconditionsCheck();
4848

49-
List<String> arguments = getCommandArgsArchives(pythonExecutablePath, mapFile);
49+
List<String> arguments = getIDFSizeCommandArgs(pythonExecutablePath, mapFile, "--archives"); //$NON-NLS-1$
5050
String detailsJsonOp = getOutput(mapFile, arguments);
5151
if (!StringUtil.isEmpty(detailsJsonOp))
5252
{
@@ -57,18 +57,18 @@ public List<LibraryMemoryComponent> getDataList(IFile mapFile) throws Exception
5757
return convertToViewerModel(archivesJsonObj, symbolJsonObj);
5858
}
5959
}
60-
return Collections.EMPTY_LIST;
60+
return Collections.emptyList();
6161

6262
}
6363

64-
public JSONObject getIDFSizeOverview(IFile mapFile, String targetName) throws Exception
64+
public JSONObject getIDFSizeOverview(IFile mapFile) throws Exception
6565
{
6666
String pythonExecutablePath = preconditionsCheck();
67-
List<String> commandArgs = getCommandArgs(pythonExecutablePath, mapFile, targetName);
67+
List<String> commandArgs = getIDFSizeCommandArgs(pythonExecutablePath, mapFile);
6868
String detailsJsonOp = getOutput(mapFile, commandArgs);
69-
detailsJsonOp = detailsJsonOp.replace("NaN", "0"); //$NON-NLS-1$ //$NON-NLS-2$
7069
if (!StringUtil.isEmpty(detailsJsonOp))
7170
{
71+
detailsJsonOp = detailsJsonOp.replace("NaN", "0"); //$NON-NLS-1$ //$NON-NLS-2$
7272
return getJSON(detailsJsonOp);
7373
}
7474
return null;
@@ -107,7 +107,7 @@ private List<LibraryMemoryComponent> convertToViewerModel(JSONObject archivesJso
107107
String symbolName = symbolsKey.substring(key.length() + 1); // libnet80211.a:ieee80211_output.o
108108

109109
JSONObject symbolObj = (JSONObject) symbolJsonObj.get(symbolsKey);
110-
110+
111111
record.getChildren().add(getSizeRecord(symbolName, symbolObj));
112112
}
113113

@@ -121,44 +121,46 @@ private List<LibraryMemoryComponent> convertToViewerModel(JSONObject archivesJso
121121
protected LibraryMemoryComponent getSizeRecord(String key, JSONObject object)
122122
{
123123
LibraryMemoryComponent library = new LibraryMemoryComponent();
124-
String []keySplit = key.split("/");
125-
String nameToSet = keySplit[keySplit.length-1] + " -> " + key;
124+
String[] keySplit = key.split("/");
125+
String nameToSet = keySplit[keySplit.length - 1] + " -> " + key;
126126
library.setName(nameToSet);
127127
library.setAbbrevName((String) object.get("abbrev_name"));
128-
library.setSize(getValue(object.get("size")));
129-
library.setSizeDiff(getValue(object.get("size_diff")));
130-
Map<String, MemoryType> memoryTypesMap = new LinkedHashMap<>();
131-
JSONObject memoryTypesJson = (JSONObject) object.get("memory_types");
128+
library.setSize(getValue(object.get("size")));
129+
library.setSizeDiff(getValue(object.get("size_diff")));
130+
Map<String, MemoryType> memoryTypesMap = new LinkedHashMap<>();
131+
JSONObject memoryTypesJson = (JSONObject) object.get("memory_types");
132+
133+
for (Object memoryKeyObj : memoryTypesJson.keySet())
134+
{
135+
String memoryKey = (String) memoryKeyObj;
136+
JSONObject memoryTypeJson = (JSONObject) memoryTypesJson.get(memoryKey);
132137

133-
for (Object memoryKeyObj : memoryTypesJson.keySet()) {
134-
String memoryKey = (String) memoryKeyObj;
135-
JSONObject memoryTypeJson = (JSONObject) memoryTypesJson.get(memoryKey);
138+
MemoryType memoryType = new MemoryType();
139+
memoryType.setSize(getValue(memoryTypeJson.get("size")));
140+
memoryType.setSizeDiff(getValue(memoryTypeJson.get("size_diff")));
136141

137-
MemoryType memoryType = new MemoryType();
138-
memoryType.setSize(getValue(memoryTypeJson.get("size")));
139-
memoryType.setSizeDiff(getValue(memoryTypeJson.get("size_diff")));
142+
JSONObject sectionsJson = (JSONObject) memoryTypeJson.get("sections");
143+
Map<String, Section> sectionsMap = new LinkedHashMap<>();
140144

141-
JSONObject sectionsJson = (JSONObject) memoryTypeJson.get("sections");
142-
Map<String, Section> sectionsMap = new LinkedHashMap<>();
145+
for (Object sectionKeyObj : sectionsJson.keySet())
146+
{
147+
String sectionKey = (String) sectionKeyObj;
148+
JSONObject sectionJson = (JSONObject) sectionsJson.get(sectionKey);
143149

144-
for (Object sectionKeyObj : sectionsJson.keySet()) {
145-
String sectionKey = (String) sectionKeyObj;
146-
JSONObject sectionJson = (JSONObject) sectionsJson.get(sectionKey);
150+
Section section = new Section();
151+
section.setSize(getValue(sectionJson.get("size")));
152+
section.setSizeDiff(getValue(sectionJson.get("size_diff")));
153+
section.setAbbrevName((String) sectionJson.get("abbrev_name"));
147154

148-
Section section = new Section();
149-
section.setSize(getValue(sectionJson.get("size")));
150-
section.setSizeDiff(getValue(sectionJson.get("size_diff")));
151-
section.setAbbrevName((String) sectionJson.get("abbrev_name"));
155+
sectionsMap.put(sectionKey, section);
156+
}
152157

153-
sectionsMap.put(sectionKey, section);
154-
}
158+
memoryType.setSections(sectionsMap);
159+
memoryTypesMap.put(memoryKey, memoryType);
160+
}
155161

156-
memoryType.setSections(sectionsMap);
157-
memoryTypesMap.put(memoryKey, memoryType);
158-
}
162+
library.setMemoryTypes(memoryTypesMap);
159163

160-
library.setMemoryTypes(memoryTypesMap);
161-
162164
return library;
163165
}
164166

@@ -169,7 +171,7 @@ protected long getValue(Object object)
169171

170172
private JSONObject getSymbolDetails(String pythonExecutablePath, IFile mapFile)
171173
{
172-
List<String> arguments = getCommandArgsSymbolDetails(pythonExecutablePath, mapFile);
174+
List<String> arguments = getIDFSizeCommandArgs(pythonExecutablePath, mapFile, "--file"); //$NON-NLS-1$
173175
String symbolsJsonOp = getOutput(mapFile, arguments);
174176
if (!StringUtil.isEmpty(symbolsJsonOp))
175177
{
@@ -214,13 +216,16 @@ protected IStatus runProcess(IFile file, List<String> arguments) throws Exceptio
214216
}
215217
}
216218

217-
protected List<String> getCommandArgsArchives(String pythonExecutablenPath, IFile file)
219+
protected List<String> getIDFSizeCommandArgs(String pythonExecutablePath, IFile file, String... additionalFlags)
218220
{
219-
List<String> arguments = new ArrayList<String>();
220-
arguments.add(pythonExecutablenPath);
221+
List<String> arguments = new ArrayList<>();
222+
arguments.add(pythonExecutablePath);
221223
arguments.add(IDFUtil.getIDFSizeScriptFile().getAbsolutePath());
222224
arguments.add(file.getLocation().toOSString());
223-
arguments.add("--archives"); //$NON-NLS-1$
225+
if (additionalFlags != null)
226+
{
227+
Collections.addAll(arguments, additionalFlags);
228+
}
224229
arguments.addAll(addJsonParseCommand());
225230

226231
return arguments;
@@ -251,37 +256,12 @@ public boolean isVersionAtLeast(String currentIDFVersion, String minimumIDFVersi
251256
{
252257
return true;
253258
}
254-
259+
255260
Version currentVersion = Version.parse(currentIDFVersion);
256261
Version minVersion = Version.parse(minimumIDFVersion);
257262
return currentVersion.compareTo(minVersion) >= 0;
258263
}
259264

260-
protected List<String> getCommandArgsSymbolDetails(String pythonExecutablenPath, IFile file)
261-
{
262-
List<String> arguments = new ArrayList<String>();
263-
arguments.add(pythonExecutablenPath);
264-
arguments.add(IDFUtil.getIDFSizeScriptFile().getAbsolutePath());
265-
arguments.add(file.getLocation().toOSString());
266-
arguments.add("--file"); //$NON-NLS-1$
267-
arguments.addAll(addJsonParseCommand());
268-
269-
return arguments;
270-
}
271-
272-
protected List<String> getCommandArgs(String pythonExecutablenPath, IFile file, String targetName)
273-
{
274-
List<String> arguments = new ArrayList<String>();
275-
arguments.add(pythonExecutablenPath);
276-
arguments.add("-m"); //$NON-NLS-1$
277-
arguments.add("esp_idf_size"); //$NON-NLS-1$
278-
arguments.add("--ng"); //$NON-NLS-1$
279-
arguments.add("--format"); //$NON-NLS-1$
280-
arguments.add("json2"); //$NON-NLS-1$
281-
arguments.add(file.getLocation().toOSString());
282-
283-
return arguments;
284-
}
285265

286266
protected JSONObject getJSON(String jsonOutput)
287267
{

bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/size/IDFSizeOverviewComposite.java

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ public void createPartControl(Composite parent, IFile file, String targetName)
9999
table.setLinesVisible(true);
100100
table.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true, 2, 1));
101101

102-
String[] columns = { "Region", "Used", "Free", "Total", "Usage" };
102+
String[] columns = { "Region", "Used", "Free", "Total", "Usage" }; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
103103
for (String colName : columns)
104104
{
105105
TableColumn col = new TableColumn(table, SWT.NONE);
@@ -119,24 +119,34 @@ private void populateTable()
119119
{
120120
table.removeAll();
121121

122-
JSONArray layout = (JSONArray) overviewJson.get("layout");
122+
// Defensive check: Handle unexpected empty data gracefully to prevent UI crash.
123+
if (overviewJson == null || overviewJson.isEmpty() || !overviewJson.containsKey("layout")) //$NON-NLS-1$
124+
{
125+
TableItem errorItem = new TableItem(table, SWT.NONE);
126+
errorItem.setText(0,
127+
Messages.IDFSizeOverviewComposite_NoExpectedOutputMsg);
128+
errorItem.setForeground(0, table.getDisplay().getSystemColor(SWT.COLOR_RED));
129+
return;
130+
}
131+
132+
JSONArray layout = (JSONArray) overviewJson.get("layout"); //$NON-NLS-1$
123133
long grandUsed = 0;
124134
long grandFree = 0;
125135

126136
int rowIndex = 0;
127137
for (Object obj : layout)
128138
{
129139
JSONObject section = (JSONObject) obj;
130-
String name = (String) section.get("name");
131-
long used = (long) section.get("used");
132-
long free = (long) section.get("free");
133-
long total = (long) section.get("total");
140+
String name = (String) section.get("name"); //$NON-NLS-1$
141+
long used = (long) section.get("used"); //$NON-NLS-1$
142+
long free = (long) section.get("free"); //$NON-NLS-1$
143+
long total = (long) section.get("total"); //$NON-NLS-1$
134144

135145
grandUsed += used;
136146
grandFree += free;
137147

138148
TableItem item = new TableItem(table, SWT.NONE);
139-
item.setText(new String[] { name, formatMemory(used), formatMemory(free), formatMemory(total), "" // progress
149+
item.setText(new String[] { name, formatMemory(used), formatMemory(free), formatMemory(total), "" // progress //$NON-NLS-1$
140150
// bar
141151
// will
142152
// go
@@ -150,8 +160,8 @@ private void populateTable()
150160

151161
// Total row
152162
TableItem totalRow = new TableItem(table, SWT.NONE);
153-
totalRow.setText(new String[] { "Total:", formatMemory(grandUsed), formatMemory(grandFree),
154-
formatMemory(grandUsed + grandFree), "" });
163+
totalRow.setText(new String[] { "Total:", formatMemory(grandUsed), formatMemory(grandFree), //$NON-NLS-1$
164+
formatMemory(grandUsed + grandFree), "" }); //$NON-NLS-1$
155165
for (int i = 0; i < 5; i++)
156166
{
157167
applyBoldToColumn(totalRow, i);
@@ -206,7 +216,7 @@ private String formatMemory(long bytes)
206216
private String getUsagePercent(long used, long total)
207217
{
208218
if (total == 0)
209-
return "-";
219+
return "-"; //$NON-NLS-1$
210220
double percent = (double) used / total * 100;
211221
return String.format("%.1f%%", percent); //$NON-NLS-1$
212222
}
@@ -228,7 +238,7 @@ protected JSONObject getIDFSizeOverviewData(IFile file, String targetName)
228238
{
229239
try
230240
{
231-
return new IDFSizeDataManager().getIDFSizeOverview(file, targetName);
241+
return new IDFSizeDataManager().getIDFSizeOverview(file);
232242
}
233243
catch (Exception e)
234244
{

bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/size/Messages.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,11 +26,13 @@ public class Messages extends NLS
2626
public static String IDFSizeOverviewComposite_SwitchToPie;
2727
public static String IDFSizeOverviewComposite_SwitchToBar;
2828
public static String IDFSizeOverviewComposite_MemoryUsagePrefix;
29+
public static String IDFSizeOverviewComposite_NoExpectedOutputMsg;
2930
public static String IDFSizeEditorOverview;
3031
public static String IDFSizeEditorDetails;
3132
public static String IDFSizeEditorCharts;
3233
public static String IDFSizeChartsComposite_SizeUnit;
3334
public static String IDFSizeChartsComposite_MemoryParts;
35+
public static String IDFSizeChartsComposite_NoMemoryDataAvailableLblMsg;
3436
public static String IDFSizeChartsComposite_SizeTag;
3537
public static String IDFSizeEditorVersionError;
3638
public static String IDFSizeEditorVersionErrorDescription;

bundles/com.espressif.idf.ui/src/com/espressif/idf/ui/size/messages.properties

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ IDFSizeOverviewComposite_ChartView=Chart View:
1919
IDFSizeOverviewComposite_SwitchToPie=Switch to Pie
2020
IDFSizeOverviewComposite_SwitchToBar=Switch to Bar
2121
IDFSizeOverviewComposite_MemoryUsagePrefix=Memory Usage -
22+
IDFSizeOverviewComposite_NoExpectedOutputMsg=No memory data available.'idf.py size' output not as expected
2223

2324
IDFSizeEditorOverview=Overview
2425
IDFSizeEditorDetails=Details
@@ -27,6 +28,7 @@ IDFSizeEditorCharts=Charts
2728

2829
IDFSizeChartsComposite_SizeUnit=Size Unit:
2930
IDFSizeChartsComposite_MemoryParts=Memory Parts
31+
IDFSizeChartsComposite_NoMemoryDataAvailableLblMsg=No memory data available.\nPlease ensure the project is built successfully and 'idf.py size' works.
3032
IDFSizeChartsComposite_SizeTag=Size {0}
3133

3234
IDFSizeEditorVersionError=Memory Usage Analysis Unavailable

0 commit comments

Comments
 (0)