INRIA / INRIA/spoon

[Bug]: Cannot invoke "String.isEmpty()" because "sourceCode" is null

Open
#5,082 5 comments 0 reactions 0 assignees View on GitHub
bug
Dominant language
Java
Stars
2k
Forks
392
Avg merge
11h 24m
Merged PRs (30d)
36

Description

### Describe the bug

``` java
String sourceCode = getOriginalSourceCode();
if (sourceCode.isEmpty()) {
return;
}
```

If `sourceCode` is null, an NPE is thrown.

I'd recommend running [SpotBugs](https://spotbugs.github.io/) on your software to find additional problems, rather than waiting for reports. At that point you can probably more efficiently and effectively clean up (and find) such issues.

``` java
package com.whitemagicsoftware.rename;

import spoon.Launcher;
import spoon.refactoring.Refactoring;
import spoon.support.sniper.SniperJavaPrettyPrinter;

import java.io.File;
import java.util.regex.Pattern;

public class App {
public static void main( final String[] args ) {
Launcher spoon = new Launcher();
spoon.addInputResource( "/tmp/nts/app/src/main/java/nts/app" );
spoon.addInputResource( "/tmp/nts/dvi/src/main/java/nts/dvi" );
spoon.addInputResource( "/tmp/nts/png/src/main/java/nts/png" );
spoon.addInputResource( "/tmp/nts/svg/src/main/java/nts/svg" );
spoon.addInputResource( "/tmp/nts/tex/src/main/java/nts/align" );
spoon.addInputResource( "/tmp/nts/tex/src/main/java/nts/base" );
spoon.addInputResource( "/tmp/nts/tex/src/main/java/nts/builder" );
spoon.addInputResource( "/tmp/nts/tex/src/main/java/nts/command" );
spoon.addInputResource( "/tmp/nts/tex/src/main/java/nts/hyph" );
spoon.addInputResource( "/tmp/nts/tex/src/main/java/nts/io" );
spoon.addInputResource( "/tmp/nts/tex/src/main/java/nts/math" );
spoon.addInputResource( "/tmp/nts/tex/src/main/java/nts/noad" );
spoon.addInputResource( "/tmp/nts/tex/src/main/java/nts/node" );
spoon.addInputResource( "/tmp/nts/tex/src/main/java/nts/render" );
spoon.addInputResource( "/tmp/nts/tex/src/main/java/nts/tex" );
spoon.addInputResource( "/tmp/nts/tex/src/main/java/nts/tfm" );
spoon.addInputResource( "/tmp/nts/tex/src/main/java/nts/typo" );
spoon.addInputResource( "/tmp/nts/tex/src/test/java/nts/io" );

final var env = spoon.getEnvironment();
env.setPrettyPrinterCreator(
() -> new SniperJavaPrettyPrinter( env )
);
env.setAutoImports( true );

final var model = spoon.buildModel();
final var p = Pattern.compile( "^(?!Kt).*" );

for( final var clazz : model.getAllTypes() ) {
final var name = clazz.getSimpleName();
final var m = p.matcher( name );

if( m.matches() ) {
final var newName = "Kt" + name;

System.out.println( "rename " + name + " to " + newName );
Refactoring.changeTypeName( clazz, newName );
}
}

final var outputDir = new File( "/tmp/nts-new" );

if( outputDir.exists() || outputDir.mkdirs() ) {
spoon.setSourceOutputDirectory( outputDir );
spoon.prettyprint();
}
}
}
```

Exception

```
Exception in thread "main" spoon.SpoonException: java.lang.NullPointerException: Cannot invoke "String.isEmpty()" because "sourceCode" is null
at spoon.Launcher.prettyprint(Launcher.java:804)
at com.whitemagicsoftware.rename.App.main(App.java:60)
Caused by: java.lang.NullPointerException: Cannot invoke "String.isEmpty()" because "sourceCode" is null
at spoon.support.sniper.internal.ElementSourceFragment.forEachConstantFragment(ElementSourceFragment.java:669)
at spoon.support.sniper.internal.ElementSourceFragment.getChildrenFragments(ElementSourceFragment.java:473)
at spoon.support.sniper.internal.ElementSourceFragment.getGroupedChildrenFragments(ElementSourceFragment.java:492)
at spoon.support.sniper.internal.IndentationDetector.detectIndentation(IndentationDetector.java:35)
at spoon.support.sniper.SniperJavaPrettyPrinter.calculate(SniperJavaPrettyPrinter.java:150)
at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.getCompilationUnitInputStream(JDTBasedSpoonCompiler.java:674)
at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.generateProcessedSourceFilesUsingCUs(JDTBasedSpoonCompiler.java:547)
at spoon.support.compiler.jdt.JDTBasedSpoonCompiler.generateProcessedSourceFiles(JDTBasedSpoonCompiler.java:212)
at spoon.Launcher.prettyprint(Launcher.java:799)
... 1 more
```

Contributor guide

Open the contributing guide

Research direction

Start at spoon.support.sniper.internal.ElementSourceFragment.forEachConstantFragment, reported at line 669, and trace how it is reached through IndentationDetector and SniperJavaPrettyPrinter during Launcher.prettyprint. Reproduce the supplied Spoon transformation example and verify that prettyprinting no longer throws when sourceCode is null.

Written by the indexing model from the issue text.

Assessment

Tech stack
java
Domain
devtools
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
38/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.