netbeans icon indicating copy to clipboard operation
netbeans copied to clipboard

Fails to parse a file with incomplete switch expression

Open SBasalaev opened this issue 2 years ago • 8 comments

Apache NetBeans version

Apache NetBeans 16

What happened

When I add a case with a block to the switch expression, exception notification appears and completion stops working. If I try to save a file after that the whole application freezes.

How to reproduce

Suppose I have a class (requires JDK 17 with preview features enabled)

class Switch {
    public boolean test(Object value) {
        return switch (value) {
            default -> false;
        }
    }
}

Then I start adding a new case. The issue happens right after I type the opening brace

class Switch {
    public boolean test(Object value) {
        return switch (value) {
            case Boolean b -> {    // <- this line added
            default -> false;
        }
    }
}

Creating file with that contents does not always cause the issue but typing the line in editor always does. This also happened in previous versions of NetBeans and with previous JDK versions.

Did this work correctly in an earlier version?

No / Don't know

Operating System

Ubuntu Linux 22.04 amd64

JDK

OpenJDK 19 (system provided)

Apache NetBeans packaging

Apache NetBeans provided installer

Anything else

Stack trace reported by NetBeans

Caused: java.lang.NullPointerException: Cannot read field "type" because "tree" is null
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scanCond(Flow.java:2145)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitYield(Flow.java:2785)
	at com.sun.tools.javac.tree.JCTree$JCYield.accept(JCTree.java:1660)
	at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
	at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:447)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:1861)
	at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scanSyntheticBreak(Flow.java:459)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.handleSwitch(Flow.java:2597)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitSwitchExpression(Flow.java:2565)
	at com.sun.tools.javac.tree.JCTree$JCSwitchExpression.accept(JCTree.java:1382)
	at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
	at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:447)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:1861)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scanExpr(Flow.java:2118)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitReturn(Flow.java:2818)
	at com.sun.tools.javac.tree.JCTree$JCReturn.accept(JCTree.java:1711)
	at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
	at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:447)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:1861)
	at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:57)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitBlock(Flow.java:2402)
	at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:1082)
	at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
	at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:447)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:1861)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitMethodDef(Flow.java:2305)
	at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:912)
	at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
	at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:447)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:1861)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitClassDef(Flow.java:2243)
	at com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:810)
	at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:49)
	at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:447)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:1861)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.analyzeTree(Flow.java:3031)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.analyzeTree(Flow.java:3013)
	at com.sun.tools.javac.comp.Flow.analyzeTree(Flow.java:224)
	at com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1377)
	at com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1341)
	at com.sun.tools.javac.api.JavacTaskImpl.analyze(JavacTaskImpl.java:404)
	at com.sun.tools.javac.api.JavacTaskImpl.lambda$analyze$1(JavacTaskImpl.java:379)
	at com.sun.tools.javac.api.JavacTaskImpl.invocationHelper(JavacTaskImpl.java:152)
	at com.sun.tools.javac.api.JavacTaskImpl.analyze(JavacTaskImpl.java:379)
Caused: java.lang.IllegalStateException
	at com.sun.tools.javac.api.JavacTaskImpl.analyze(JavacTaskImpl.java:383)
	at org.netbeans.modules.java.source.parsing.JavacParser.moveToPhase(JavacParser.java:770)
	at org.netbeans.modules.java.source.parsing.JavacParser.getResult(JavacParser.java:540)
	at org.netbeans.modules.java.source.parsing.JavacParser.getResult(JavacParser.java:141)
	at org.netbeans.modules.parsing.impl.TaskProcessor.callGetResult(TaskProcessor.java:608)
	at org.netbeans.modules.parsing.impl.SourceCache.getResult(SourceCache.java:241)
	at org.netbeans.modules.parsing.impl.TaskProcessor$RequestPerformer.run(TaskProcessor.java:775)
	at org.openide.util.lookup.Lookups.executeWith(Lookups.java:279)
	at org.netbeans.modules.parsing.impl.TaskProcessor$RequestPerformer.execute(TaskProcessor.java:702)
[catch] at org.netbeans.modules.parsing.impl.TaskProcessor$CompilationJob.run(TaskProcessor.java:663)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:577)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
	at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:1418)
	at org.netbeans.modules.openide.util.GlobalLookup.execute(GlobalLookup.java:45)
	at org.openide.util.lookup.Lookups.executeWith(Lookups.java:278)
	at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:2033)

Are you willing to submit a pull request?

No

Code of Conduct

Yes

SBasalaev avatar Dec 12 '22 16:12 SBasalaev

any on-save action enabled? Organize imports or formatting etc?

mbien avatar Dec 13 '22 18:12 mbien

Yes, "Remove unused imports". After disabling it I can save, so this is actually two separate issues.

SBasalaev avatar Dec 14 '22 16:12 SBasalaev

right, just wanted to make sure this applies here too. The other issue is tracked under #4054.

mbien avatar Dec 14 '22 16:12 mbien

Is this still a valid issue?

neilcsmith-net avatar Aug 04 '23 07:08 neilcsmith-net

Yes, it's still a valid issue. I get exactly the same stack trace as SBasalaev. NetBeans 18 (binary from zip), Debian Bookworm (12.1), OpenJDK-17 (Debian supplied). LXDE desktop. Peter

Knusende-Ro avatar Aug 07 '23 18:08 Knusende-Ro

i am wondering why issues like this don't show up when javac is ran from CLI. NPEs in javac seem to be more common now. Going to start using the https://github.com/apache/netbeans/labels/nb-javac label for issues like this. The good thing here is that we have a simple reproducer which other filed issues lack.

cc @lahodaj

mbien avatar Oct 07 '23 11:10 mbien

checked and this is still reproducible with 22-rc1

updated trace since the line numbers moved:

Caused: java.lang.NullPointerException: Cannot read field "type" because "tree" is null
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scanCond(Flow.java:2293)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitYield(Flow.java:2913)
	at com.sun.tools.javac.tree.JCTree$JCYield.accept(JCTree.java:1677)
	at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:50)
	at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:463)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:2013)
	at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scanSyntheticBreak(Flow.java:475)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.handleSwitch(Flow.java:2725)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitSwitchExpression(Flow.java:2700)
	at com.sun.tools.javac.tree.JCTree$JCSwitchExpression.accept(JCTree.java:1399)
	at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:50)
	at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:463)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:2013)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scanExpr(Flow.java:2270)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitReturn(Flow.java:2946)
	at com.sun.tools.javac.tree.JCTree$JCReturn.accept(JCTree.java:1728)
	at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:50)
	at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:463)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:2013)
	at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:58)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitBlock(Flow.java:2537)
	at com.sun.tools.javac.tree.JCTree$JCBlock.accept(JCTree.java:1092)
	at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:50)
	at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:463)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:2013)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitMethodDef(Flow.java:2440)
	at com.sun.tools.javac.tree.JCTree$JCMethodDecl.accept(JCTree.java:916)
	at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:50)
	at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:463)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:2013)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.visitClassDef(Flow.java:2384)
	at com.sun.tools.javac.tree.JCTree$JCClassDecl.accept(JCTree.java:814)
	at com.sun.tools.javac.tree.TreeScanner.scan(TreeScanner.java:50)
	at com.sun.tools.javac.comp.Flow$BaseAnalyzer.scan(Flow.java:463)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.scan(Flow.java:2013)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.analyzeTree(Flow.java:3174)
	at com.sun.tools.javac.comp.Flow$AssignAnalyzer.analyzeTree(Flow.java:3156)
	at com.sun.tools.javac.comp.Flow.analyzeTree(Flow.java:231)
	at com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1426)
	at com.sun.tools.javac.main.JavaCompiler.flow(JavaCompiler.java:1390)
	at com.sun.tools.javac.api.JavacTaskImpl.analyze(JavacTaskImpl.java:404)
	at com.sun.tools.javac.api.JavacTaskImpl.lambda$analyze$1(JavacTaskImpl.java:379)
	at com.sun.tools.javac.api.JavacTaskImpl.invocationHelper(JavacTaskImpl.java:152)
	at com.sun.tools.javac.api.JavacTaskImpl.analyze(JavacTaskImpl.java:379)
Caused: java.lang.IllegalStateException
	at com.sun.tools.javac.api.JavacTaskImpl.analyze(JavacTaskImpl.java:383)
	at org.netbeans.modules.java.source.parsing.JavacParser.moveToPhase(JavacParser.java:765)
	at org.netbeans.modules.java.source.parsing.JavacParser.getResult(JavacParser.java:536)
	at org.netbeans.modules.java.source.parsing.JavacParser.getResult(JavacParser.java:140)
	at org.netbeans.modules.parsing.impl.TaskProcessor.callGetResult(TaskProcessor.java:608)
	at org.netbeans.modules.parsing.impl.SourceCache.getResult(SourceCache.java:241)
	at org.netbeans.modules.parsing.impl.TaskProcessor$RequestPerformer.run(TaskProcessor.java:775)
	at org.openide.util.lookup.Lookups.executeWith(Lookups.java:288)
	at org.netbeans.modules.parsing.impl.TaskProcessor$RequestPerformer.execute(TaskProcessor.java:702)
[catch] at org.netbeans.modules.parsing.impl.TaskProcessor$CompilationJob.run(TaskProcessor.java:663)
	at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:572)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:317)
	at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:1420)
	at org.netbeans.modules.openide.util.GlobalLookup.execute(GlobalLookup.java:45)
	at org.openide.util.lookup.Lookups.executeWith(Lookups.java:287)
	at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:2035)

mbien avatar Apr 26 '24 10:04 mbien

FWIW, I've filled: https://bugs.openjdk.org/browse/JDK-8331212 have a (potential) fix, will open a PR sometime soon.

lahodaj avatar Apr 26 '24 20:04 lahodaj

the nb-javac update https://github.com/apache/netbeans/pull/7484 fixed this and is already testable in NB23rc1. There is no longer an exception and the errors are annotated as expected: image

closing

mbien avatar Aug 05 '24 17:08 mbien