Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions .github/scripts/generate-quality-report.py
Original file line number Diff line number Diff line change
Expand Up @@ -754,6 +754,23 @@ def main() -> None:
if not generate_html_only:
REPORT_PATH.write_text(report + "\n", encoding="utf-8")

# Enforce quality gates
spotbugs, _, _ = parse_spotbugs()
if spotbugs:
forbidden_rules = {
"RCN_REDUNDANT_NULLCHECK_OF_NONNULL_VALUE",
"RCN_REDUNDANT_NULLCHECK_OF_NULL_VALUE"
}
violations = [
f for f in spotbugs.findings
if f.rule in forbidden_rules
]
if violations:
print("\n❌ Build failed due to forbidden SpotBugs violations:")
for v in violations:
print(f" - {v.rule}: {v.location} - {v.message}")
exit(1)


if __name__ == "__main__":
main()
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public static boolean equals(Object a, Object b) {
if (a == b) {
return true;
}
return a == null ? b == null : a.equals(b);
return a != null && a.equals(b);
}

/**
Expand Down
6 changes: 0 additions & 6 deletions CodenameOne/src/com/codename1/io/ConnectionRequest.java
Original file line number Diff line number Diff line change
Expand Up @@ -2747,9 +2747,6 @@ public void run() {
if (fs.exists(file)) {
try {
EncodedImage img = EncodedImage.create(fs.openInputStream(file), (int) fs.getLength(file));
if (img == null) {
throw new IOException("Failed to load image at " + file);
}
CallbackDispatcher.dispatchSuccess(onSuccess, img);
} catch (Exception ex) {
CallbackDispatcher.dispatchError(onFail, ex);
Expand All @@ -2763,9 +2760,6 @@ public void run() {
if (fs.exists(file)) {
try {
EncodedImage img = EncodedImage.create(fs.createInputStream(file), fs.entrySize(file));
if (img == null) {
throw new IOException("Failed to load image at " + file);
}
CallbackDispatcher.dispatchSuccess(onSuccess, img);
} catch (Exception ex) {
CallbackDispatcher.dispatchError(onFail, ex);
Expand Down
4 changes: 0 additions & 4 deletions CodenameOne/src/com/codename1/io/gzip/Inflate.java
Original file line number Diff line number Diff line change
Expand Up @@ -151,10 +151,6 @@ int inflateInit(int w) {
inflateEnd();
return Z_STREAM_ERROR;
}
if (blocks != null && wbits != w) {
blocks.free();
blocks = null;
}

// set window size
wbits = w;
Expand Down
7 changes: 3 additions & 4 deletions CodenameOne/src/com/codename1/l10n/SimpleDateFormat.java
Original file line number Diff line number Diff line change
Expand Up @@ -521,9 +521,7 @@ public Date parse(String source) throws ParseException {

throwInvalid("timezone", startIndex);
}
if (res != null) {
parsedTimeZone = res.timeZone;
}
parsedTimeZone = res.timeZone;
tzMinutes = ((tzMinutes == -1) ? 0 : tzMinutes) + v;
break;
case YEAR_LETTER:
Expand Down Expand Up @@ -844,10 +842,11 @@ String readAmPmMarker(String source, int ofs) {
if (i == -1) {
i = source.length();
}
String fragment = readSubstring(source, ofs, i).toLowerCase();
String fragment = readSubstring(source, ofs, i);
if (fragment == null) {
return null;
}
fragment = fragment.toLowerCase();
DateFormatSymbols ds = getDateFormatSymbols();
String[] markers = ds.getAmPmStrings();
for (String marker : markers) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,6 @@ private String[] _getLeftValue(StructuredContent element, String lvalue) {
*/
protected Object evaluateLeftContainsRight(StructuredContent element, String lvalue, String rvalue) {
String[] lvalues = _getLeftValue(element, lvalue);
if (lvalues == null) {
return null;
}
// if the rvalue is wrapped with "()", the caller explicitly expects the lvalue to be an array of values,
// otherwise try to do a "string contains" match first if there's only one lvalue
if (rvalue.indexOf("(") == -1 && lvalues.length == 1) {
Expand Down
9 changes: 0 additions & 9 deletions CodenameOne/src/com/codename1/processing/TextEvaluator.java
Original file line number Diff line number Diff line change
Expand Up @@ -80,9 +80,6 @@ private String[] _getLeftValue(StructuredContent element, String lvalue) {
protected Object evaluateLeftLessRight(StructuredContent element,
String lvalue, String rvalue) {
String[] v = _getLeftValue(element, lvalue);
if (v == null) {
return null;
}
int vlen = v.length;
for (int i = 0; i < vlen; i++) {
if (isNumeric(rvalue) && isNumeric(v[i])) {
Expand Down Expand Up @@ -112,9 +109,6 @@ protected Object evaluateLeftLessRight(StructuredContent element,
protected Object evaluateLeftGreaterRight(StructuredContent element,
String lvalue, String rvalue) {
String[] v = _getLeftValue(element, lvalue);
if (v == null) {
return null;
}
int vlen = v.length;
for (int i = 0; i < vlen; i++) {
if (isNumeric(rvalue) && isNumeric(v[i])) {
Expand Down Expand Up @@ -144,9 +138,6 @@ protected Object evaluateLeftGreaterRight(StructuredContent element,
protected Object evaluateLeftEqualsRight(StructuredContent element,
String lvalue, String rvalue) {
String[] v = _getLeftValue(element, lvalue);
if (v == null) {
return null;
}
int vlen = v.length;
for (int i = 0; i < vlen; i++) {
if (isNumeric(rvalue) && isNumeric(v[i])) {
Expand Down
4 changes: 1 addition & 3 deletions CodenameOne/src/com/codename1/properties/PropertyIndex.java
Original file line number Diff line number Diff line change
Expand Up @@ -372,9 +372,7 @@ public void populateFromMap(Map<String, Object> m, Class<? extends PropertyBusin
if (val instanceof List) {
if (p instanceof CollectionProperty) {
if (recursiveType != null) {
if (p != null) {
((CollectionProperty) p).clear();
}
((CollectionProperty) p).clear();
for (Object e : (Collection) val) {
if (e instanceof Map) {
Class eType = p.getGenericType();
Expand Down
37 changes: 15 additions & 22 deletions CodenameOne/src/com/codename1/properties/PropertyXMLElement.java
Original file line number Diff line number Diff line change
Expand Up @@ -61,15 +61,13 @@ public boolean contains(Element element) {
return true;
}
Vector children = getChildren();
if (children != null) {
int i = 0;
while (i < children.size()) {
Element child = (Element) children.get(i);
if (child.contains(element)) {
return true;
}
i++;
int i = 0;
while (i < children.size()) {
Element child = (Element) children.get(i);
if (child.contains(element)) {
return true;
}
i++;
}
return false;
}
Expand Down Expand Up @@ -193,17 +191,14 @@ public Element getElementById(String id) {
return this;
}
Vector children = getChildren();
if (children != null) {
int i = 0;
while (i < children.size()) {
Element child = (Element) children.get(i);
Element match = child.getElementById(id);
if (match != null) {
return match;
}
i++;
int i = 0;
while (i < children.size()) {
Element child = (Element) children.get(i);
Element match = child.getElementById(id);
if (match != null) {
return match;
}

i++;
}
return null;
}
Expand Down Expand Up @@ -389,10 +384,8 @@ public String toString(String spacing) {
}
str += ">\n";
Vector children = getChildren();
if (children != null) {
for (int i = 0; i < children.size(); i++) {
str += ((Element) children.get(i)).toString(spacing + ' ');
}
for (int i = 0; i < children.size(); i++) {
str += ((Element) children.get(i)).toString(spacing + ' ');
}
str += spacing + "</" + getTagName() + ">\n";
return str;
Expand Down
14 changes: 6 additions & 8 deletions CodenameOne/src/com/codename1/ui/BrowserComponent.java
Original file line number Diff line number Diff line change
Expand Up @@ -1263,14 +1263,12 @@ public void execute(String js, Object[] params) {
* @return the string returned from the Javascript call
*/
public String executeAndReturnString(String javaScript) {
if (internal == null) {
while (internal == null) {
CN.invokeAndBlock(new Runnable() {
public void run() {
Util.sleep(50);
}
});
}
while (internal == null) {
CN.invokeAndBlock(new Runnable() {
public void run() {
Util.sleep(50);
}
});
}
if (Display.impl.supportsBrowserExecuteAndReturnString(internal)) {
return Display.impl.browserExecuteAndReturnString(internal, javaScript);
Expand Down
4 changes: 2 additions & 2 deletions CodenameOne/src/com/codename1/ui/Command.java
Original file line number Diff line number Diff line change
Expand Up @@ -273,12 +273,12 @@ public boolean equals(Object obj) {
return false;
}
if (((Command) obj).command == null) {
return (obj != null) && obj.getClass() == getClass() && command == null &&
return obj.getClass() == getClass() && command == null &&
((Command) obj).icon == icon && ((Command) obj).commandId == commandId &&
((Command) obj).materialIcon == materialIcon && ((Command) obj).materialIconSize == materialIconSize &&
(Objects.equals(clientProperties, ((Command) obj).clientProperties));
} else {
return (obj != null) && obj.getClass() == getClass() && ((Command) obj).command.equals(command) &&
return obj.getClass() == getClass() && ((Command) obj).command.equals(command) &&
((Command) obj).icon == icon && ((Command) obj).commandId == commandId &&
((Command) obj).materialIcon == materialIcon && ((Command) obj).materialIconSize == materialIconSize &&
(Objects.equals(clientProperties, ((Command) obj).clientProperties));
Expand Down
4 changes: 3 additions & 1 deletion CodenameOne/src/com/codename1/ui/Component.java
Original file line number Diff line number Diff line change
Expand Up @@ -2028,7 +2028,9 @@ public boolean containsOrOwns(int x, int y) {
Form f = getComponentForm();
if (f != null) {
Component cmp = f.getComponentAt(x, y);
return cmp != null && cmp.isOwnedBy(this);
if (cmp.isOwnedBy(this)) {
Copy link

Copilot AI Dec 22, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The redundant null check 'cmp != null' was removed, but cmp.isOwnedBy(this) is now called without null validation. If getComponentAt returns null, this will throw NullPointerException.

Suggested change
if (cmp.isOwnedBy(this)) {
if (cmp != null && cmp.isOwnedBy(this)) {

Copilot uses AI. Check for mistakes.
return true;
}
}
return false;

Expand Down
34 changes: 14 additions & 20 deletions CodenameOne/src/com/codename1/ui/ComponentSelector.java
Original file line number Diff line number Diff line change
Expand Up @@ -914,22 +914,19 @@ public void run() {


}
if (mgr != null) {
final AnimationManager fmgr = mgr;
$(new Runnable() {
public void run() {
fmgr.addAnimation(ComponentAnimation.compoundAnimation(animations2.toArray(new ComponentAnimation[animations2.size()])), new Runnable() {
public void run() {
if (callback != null) {
callback.onSucess(ComponentSelector.this);
}
final AnimationManager fmgr = mgr;
$(new Runnable() {
public void run() {
fmgr.addAnimation(ComponentAnimation.compoundAnimation(animations2.toArray(new ComponentAnimation[animations2.size()])), new Runnable() {
public void run() {
if (callback != null) {
callback.onSucess(ComponentSelector.this);
}
}

});
}
});

}
});
}
});


}
Expand Down Expand Up @@ -1018,12 +1015,9 @@ public ComponentSelector fadeInAndWait(final int duration) {


}
if (mgr != null) {
mgr.addAnimationAndBlock(
ComponentAnimation.compoundAnimation(animations2.toArray(new ComponentAnimation[animations2.size()]))
);

}
mgr.addAnimationAndBlock(
ComponentAnimation.compoundAnimation(animations2.toArray(new ComponentAnimation[animations2.size()]))
);
}

return this;
Expand Down
4 changes: 1 addition & 3 deletions CodenameOne/src/com/codename1/ui/Container.java
Original file line number Diff line number Diff line change
Expand Up @@ -4258,9 +4258,7 @@ public void destroy() {
if (current != null) {
current.setLightweightMode(false);
}
if (next != null) {
next.setLightweightMode(false);
}
next.setLightweightMode(false);
if (thisContainer.cmpTransitions != null && thisContainer.cmpTransitions.size() == 0 && growSpeed > -1) {
if (growSpeed > 0) {
current.growShrink(growSpeed);
Expand Down
7 changes: 3 additions & 4 deletions CodenameOne/src/com/codename1/ui/CustomFont.java
Original file line number Diff line number Diff line change
Expand Up @@ -133,17 +133,16 @@ private boolean checkCacheCurrentColor(int newColor) {
Object newCache = colorCache.get(newColorKey);
if (newCache != null) {
Image i = (Image) newCache;
if (i != null) {
cache = i;
if (colorCache.size() > COLOR_CACHE_SIZE) {
cache = i;
if (colorCache.size() > COLOR_CACHE_SIZE) {
// remove a random cache element
colorCache.remove(colorCache.keys().nextElement());
}
return true;
} else {
colorCache.remove(newColorKey);
}
}

if (colorCache.size() > COLOR_CACHE_SIZE) {
// remove a random cache element
colorCache.remove(colorCache.keys().nextElement());
Expand Down
8 changes: 3 additions & 5 deletions CodenameOne/src/com/codename1/ui/Display.java
Original file line number Diff line number Diff line change
Expand Up @@ -1608,7 +1608,7 @@ void setCurrent(final Form newForm, boolean reverse) {
// transitions which are a bit sensitive
if (current != null && (!(newForm instanceof Dialog))) {
Transition t = current.getTransitionOutAnimator();
if (current != null && t != null) {
if (t != null) {
transitionExists = initTransition(t.copy(reverse), current, newForm);
}
}
Expand Down Expand Up @@ -1647,9 +1647,7 @@ private boolean initTransition(Transition transition, Form source, Form dest) {
if (source != null) {
source.setLightweightMode(true);
}
if (dest != null) {
dest.setLightweightMode(true);
}
dest.setLightweightMode(true);

// if a native transition implementation exists then substitute it into place
transition = impl.getNativeTransition(transition);
Expand Down Expand Up @@ -2360,7 +2358,7 @@ private int handleEvent(int offset, int[] inputEventStackTmp) {

// make sure the released event is sent to the same Form that got a
// pressed event
if (xy == f || (f != null && f.shouldSendPointerReleaseToOtherForm())) {
if (xy == f || f.shouldSendPointerReleaseToOtherForm()) {
int[] array1 = readArrayStackArgument(offset);
offset += array1.length + 1;
int[] array2 = readArrayStackArgument(offset);
Expand Down
11 changes: 2 additions & 9 deletions CodenameOne/src/com/codename1/ui/Form.java
Original file line number Diff line number Diff line change
Expand Up @@ -2967,10 +2967,6 @@ public void keyPressed(int keyCode) {
if (focused.isEnabled()) {
focused.keyPressed(keyCode);
}
if (focused == null) {
initFocused();
return;
}
if (focused.handlesInput()) {
return;
}
Expand Down Expand Up @@ -3083,7 +3079,7 @@ public void keyRepeated(int keyCode) {
int game = Display.getInstance().getGameAction(keyCode);
// this has issues in the WTK
// Fix for issue 433: the focus might be changed by the key repeated method in a way that can turn it to null
if (focused != null && !focused.handlesInput()
if (!focused.handlesInput()
&& (game == Display.GAME_DOWN || game == Display.GAME_UP || game == Display.GAME_LEFT || game == Display.GAME_RIGHT)) {
keyPressed(keyCode);
keyReleased(keyCode);
Expand Down Expand Up @@ -3326,10 +3322,7 @@ public void clearComponentsAwaitingRelease() {
private void autoRelease(int x, int y) {
if (componentsAwaitingRelease != null && componentsAwaitingRelease.size() == 1) {
// special case allowing drag within a button
Component atXY = getComponentAt(x, y);
if (atXY != null) {
atXY = LeadUtil.leadParentImpl(atXY);
}
Component atXY = LeadUtil.leadParentImpl(getComponentAt(x, y));
Component pendingC = componentsAwaitingRelease.get(0);
if (pendingC != null) {
pendingC = LeadUtil.leadParentImpl(pendingC);
Expand Down
3 changes: 0 additions & 3 deletions CodenameOne/src/com/codename1/ui/Sheet.java
Original file line number Diff line number Diff line change
Expand Up @@ -176,9 +176,6 @@ public void actionPerformed(ActionEvent evt) {
return;
}
Component cmp = f.getComponentAt(evt.getX(), evt.getY());
if (cmp == null) {
return;
}
if (Sheet.this.contains(cmp) || Sheet.this == cmp || cmp.isOwnedBy(Sheet.this)) {
// do nothing.
} else {
Expand Down
Loading
Loading