AssertionError unexpected type: none in TreeMaker when using hint to create private method
Apache NetBeans version
Apache NetBeans 26
What happened
Was coding a java file. File is compilable. Typing a call to a new unknown method. Hint appears to propose to create the method locally, OK => exception below (method is not created)
java.lang.AssertionError: unexpected type: none
at com.sun.tools.javac.tree.TreeMaker.Type(TreeMaker.java:888)
at org.netbeans.modules.java.source.builder.TreeFactory.Type(TreeFactory.java:895)
at org.netbeans.api.java.source.TreeMaker.Type(TreeMaker.java:1244)
at org.netbeans.modules.java.hints.errors.CreateMethodFix$1.run(CreateMethodFix.java:243)
at org.netbeans.modules.java.hints.errors.CreateMethodFix$1.run(CreateMethodFix.java:166)
at org.netbeans.api.java.source.JavaSource$1.run(JavaSource.java:671)
at org.netbeans.api.java.source.JavaSource$1.run(JavaSource.java:661)
at org.netbeans.api.java.source.JavaSource$MultiTask.run(JavaSource.java:504)
at org.netbeans.modules.parsing.impl.TaskProcessor.callUserTask(TaskProcessor.java:586)
at org.netbeans.modules.parsing.api.ParserManager$UserTaskAction.run(ParserManager.java:197)
at org.netbeans.modules.parsing.api.ParserManager$UserTaskAction.run(ParserManager.java:180)
at org.netbeans.modules.parsing.impl.TaskProcessor$2.call(TaskProcessor.java:181)
at org.netbeans.modules.parsing.impl.TaskProcessor$2.call(TaskProcessor.java:178)
at org.netbeans.modules.masterfs.filebasedfs.utils.FileChangedManager.priorityIO(FileChangedManager.java:153)
at org.netbeans.modules.masterfs.providers.ProvidedExtensions.priorityIO(ProvidedExtensions.java:335)
at org.netbeans.modules.parsing.nb.DataObjectEnvFactory.runPriorityIO(DataObjectEnvFactory.java:118)
at org.netbeans.modules.parsing.impl.Utilities.runPriorityIO(Utilities.java:67)
at org.netbeans.modules.parsing.impl.TaskProcessor.runUserTask(TaskProcessor.java:178)
at org.netbeans.modules.parsing.api.ParserManager.parse(ParserManager.java:83)
at org.netbeans.api.java.source.JavaSource.runUserActionTaskImpl(JavaSource.java:454)
at org.netbeans.api.java.source.JavaSource.runUserActionTask(JavaSource.java:425)
at org.netbeans.api.java.source.JavaSource.runModificationTask(JavaSource.java:680)
at org.netbeans.modules.java.hints.errors.CreateMethodFix.getModificationResult(CreateMethodFix.java:166)
at org.netbeans.modules.java.hints.errors.CreateMethodFix.implement(CreateMethodFix.java:154)
at org.netbeans.modules.editor.hints.HintsUI$1.run(HintsUI.java:810)
at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:1403)
at org.netbeans.modules.openide.util.GlobalLookup.execute(GlobalLookup.java:45)
at org.openide.util.lookup.Lookups.executeWith(Lookups.java:287)
[catch] at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:2018)
Language / Project Type / NetBeans Component
Netbeans RCP platform app
How to reproduce
See call to getAllSizeWbpsas(store, bar);, select hint to create method. Note that file was compilable except for this new method.
/*
*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright @2019 Jerome Lelasseux. All rights reserved.
*
* This file is part of the JJazzLab software.
*
* JJazzLab is free software: you can redistribute it and/or modify
* it under the terms of the Lesser GNU General Public License (LGPLv3)
* as published by the Free Software Foundation, either version 3 of the License,
* or (at your option) any later version.
*
* JJazzLab is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with JJazzLab. If not, see <https://www.gnu.org/licenses/>
*
* Contributor(s):
*
*/
package org.jjazz.jjswing.walkingbass;
import com.google.common.base.Preconditions;
import java.util.List;
import java.util.function.Predicate;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Tile in bar order the most compatible WbpSourceAdaptation whose WbpSource was never used or was used the furthest from current bar.
* <p>
*/
public class TilerMaxDistance implements Tiler
{
private final Predicate<Score> minScoreTester;
private static final Logger LOGGER = Logger.getLogger(TilerMaxDistance.class.getSimpleName());
/**
*
* @param minScoreTester Ignore WbpSourceAdapatations which do not satisfy this predicate
*/
public TilerMaxDistance(Predicate<Score> minScoreTester)
{
this.minScoreTester = minScoreTester;
}
@Override
public void tile(WbpTiling tiling, WbpsaStore store)
{
LOGGER.log(Level.FINE, "tile() --");
// LOGGER.log(Level.FINE, "tile() store=\n{0}", store.toDebugString(true));
var nonTiledBars = tiling.getNonTiledBars();
var itBar = nonTiledBars.iterator();
while (itBar.hasNext())
{
int bar = itBar.next();
var wbpsas = getAllSizeWbpsas(store, bar); // EXCEPTION here when selecting hint to create method
if (wbpsas.isEmpty())
{
continue;
}
var wbpsa = select(tiling, wbpsas);
if (wbpsa != null)
{
tiling.add(wbpsa);
// Advance
int wbpsaSize = wbpsa.getBarRange().size();
while (wbpsaSize-- > 1)
{
itBar.next();
}
}
}
}
// ====================================================================================================================
// Private methods
// ====================================================================================================================
/**
* Select the first WbpSourceAdaptation in wbpsas whose WbpSource was never used, or was used at the furthest bar.
*
* @param tiling
* @param wbpsas Can not be empty. All WbpSourceAdaptation must start at the same bar.
* @return Can be null
*/
private WbpSourceAdaptation select(WbpTiling tiling, List<WbpSourceAdaptation> wbpsas)
{
Preconditions.checkArgument(!wbpsas.isEmpty());
WbpSourceAdaptation res = null;
int maxMinDistance = -1;
int wbpsaBar = wbpsas.get(0).getBarRange().from;
for (var wbpsa : wbpsas)
{
var usageBars = tiling.getStartBarIndexes(wbpsa.getWbpSource(), true); // Use false for less possible redundancies
if (usageBars.isEmpty())
{
res = wbpsa; // not used before, use it now
break;
}
// Used, find the largest min distance
int minDistance = usageBars.stream()
.mapToInt(bar -> Math.abs(bar - wbpsaBar))
.min()
.orElseThrow();
if (minDistance > maxMinDistance)
{
maxMinDistance = minDistance;
res = wbpsa;
} else if (minDistance == maxMinDistance)
{
// Randomly select to avoid repetitions
var oldRes = res;
res = Math.random() > 0.5 ? oldRes : wbpsa;
} else
{
assert res != null;
}
}
return res;
}
}
Did this work correctly in an earlier version?
No / Don't know
Operating System
Win 11
JDK
Adoption JDK 23
Apache NetBeans packaging
Apache NetBeans binary zip
Anything else
No response
Are you willing to submit a pull request?
No
With the information given, I can reproduce the error.
The problem may lie in the fact that the user uses var instead of a proper type.
This means that the hints engine has no clue on what expected return type of the getAllSizeWBpsas(store, bar); should be.
Hence, it thinks the return type is unspecified (none), nor void.
The user can prevent the issue by supplying a type.
For NetBeans hints: If the return type is not known, maybe first hint to provide a type, then hint to create method. Note that NetBeans (or the compiler) cannot infer the expected type because the method does not yet exist.
Tested with NetBeans 26 on Java 21 on Ubuntu Linux 24.04
Minimal example showing the 'problem'
public class UnknownType {
public static void main(String[] args) {
new UnknownType().method(args);
}
void method(String[] args){
var whoKnows = whoKnows(args);
}
}
Select the line method whoKnows, the select hint create method 'whoKnows(String[] args);
This will produce an error bulb in the status line.
@jlahoda In javahints/org.netbeans.modules.java.hints.errors.CreateMethodFix one could test for the return type to be none and change the hint message appropriately or otherwise higher up in the call tree, produce a different hint.
Or maybe add an extra hint (if it does not already exist) to supply an explicit type, asking the user for the type.
https://github.com/apache/netbeans/blob/256edf4e977f03a02c7c8b78a3db8311779ac911/java/java.hints/src/org/netbeans/modules/java/hints/errors/CreateMethodFix.java#L115-L121
In line line 116-120 tests for return type to be null (for void methods and constructors?) or not null exist. A test for returnType == TypeKind.NONE can prevent the error, but may not provide the best user experience.
One could consider this case to be a user error to be flagged as such, avoiding further changes in the hint system. The error could say something like var types and unknown methods cannot be combined. but I have no idea if a hint could be turned into such an error.
With some guidance, I would be willing to work on a solution.
Silly me.
Maybe the simple solution is just to not propose the hint in that case.
In that case, the patch would be simple. Add a guard in the process that proposes the hints. I will give it a try.
Just now (2025-06-19 23:07) , I submitted a PR. Let us see what the experts say.