tsantalis / JDeodorant

JDeodorant
https://marketplace.eclipse.org/content/jdeodorant
MIT License
139 stars 59 forks source link

NPE (JFreeChart - CCFInderX) #72

Closed T45K closed 4 years ago

T45K commented 5 years ago

NPE occurred when I used jdeodorant-commandline on JFreeChart.

My Environment: Mac OS X Catalina, AdoptOpenJDK8 JDeodorant(8db9766bd84d6ef7bbe4c2e6f3dc9b6789a7cab7) JDeodorant-Commandline(latest) Target: JFreeChart ,d03e68acaff59e7ba1b3573af3c45c9b028f715d

stack trace

java.lang.NullPointerException
    at gr.uom.java.jdeodorant.refactoring.manipulators.RefactoringUtility.generateTypeFromTypeBinding(RefactoringUtility.java:110)
    at gr.uom.java.jdeodorant.refactoring.manipulators.ExtractCloneRefactoring.extractClone(ExtractCloneRefactoring.java:1141)
    at gr.uom.java.jdeodorant.refactoring.manipulators.ExtractCloneRefactoring.apply(ExtractCloneRefactoring.java:341)
    at gr.uom.java.jdeodorant.refactoring.manipulators.ExtractCloneRefactoring.checkFinalConditions(ExtractCloneRefactoring.java:5087)
    at ca.concordia.jdeodorant.eclipse.commandline.Application.testRefactoring(Application.java:632)
    at ca.concordia.jdeodorant.eclipse.commandline.Application.start(Application.java:208)
    at org.eclipse.equinox.internal.app.EclipseAppHandle.run(EclipseAppHandle.java:203)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.runApplication(EclipseAppLauncher.java:137)
    at org.eclipse.core.runtime.internal.adaptor.EclipseAppLauncher.start(EclipseAppLauncher.java:107)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:400)
    at org.eclipse.core.runtime.adaptor.EclipseStarter.run(EclipseStarter.java:255)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.eclipse.equinox.launcher.Main.invokeFramework(Main.java:660)
    at org.eclipse.equinox.launcher.Main.basicRun(Main.java:597)
    at org.eclipse.equinox.launcher.Main.run(Main.java:1468)
tsantalis commented 4 years ago

@T45K Thank you for reporting the problem. Is it possible to give the pair of clones or methods for which the bug occurred?

T45K commented 4 years ago

@tsantalis Sorry for the late reply. The code fragment is jfreechat/src/main/java/org/jfrer/chart/renderer/category/AreaRenderer.java l.323 ~ 330, and it is clone pair of org/jfrer/chart/renderer/category/BarRenderer.java l.1083 ~ 1090 and org/jfrer/chart/renderer/category/LineAndShapeRenderer.java l.835 ~ 842.

tsantalis commented 4 years ago

The three clones are the following code fragments:

// /jfreechart/src/main/java/org/jfree/chart/renderer/category/AreaRenderer.java
// submit the current data point as a crosshair candidate
int datasetIndex = plot.indexOf(dataset);
updateCrosshairValues(state.getCrosshairState(), 
        dataset.getRowKey(row), dataset.getColumnKey(column), yy1,
        datasetIndex, x1, y1, orientation);

// add an item entity, if this information is being collected
EntityCollection entities = state.getEntityCollection();
if (entities != null) {
    addItemEntity(entities, dataset, row, column, area);
}
// /jfreechart/src/main/java/org/jfree/chart/renderer/category/BarRenderer.java
// submit the current data point as a crosshair candidate
int datasetIndex = plot.indexOf(dataset);
updateCrosshairValues(state.getCrosshairState(),
        dataset.getRowKey(row), dataset.getColumnKey(column), value,
        datasetIndex, barW0, barL0, orientation);

// add an item entity, if this information is being collected
EntityCollection entities = state.getEntityCollection();
if (entities != null) {
    addItemEntity(entities, dataset, row, column, bar);
}
// /jfreechart/src/main/java/org/jfree/chart/renderer/category/LineAndShapeRenderer.java
// submit the current data point as a crosshair candidate
int datasetIndex = plot.indexOf(dataset);
updateCrosshairValues(state.getCrosshairState(),
        dataset.getRowKey(row), dataset.getColumnKey(column),
        value, datasetIndex, x1, y1, orientation);

// add an item entity, if this information is being collected
EntityCollection entities = state.getEntityCollection();
if (entities != null) {
    addItemEntity(entities, dataset, row, column, shape);
}

The clones have differences only in variable identifiers and the types of some variables (float <-> double). All clone fragments can be extracted in a separate method. Therefore, the clones should be refactorable.

There is one problem with the line range given by CCFinder. In all clone fragments, CCFinder reports the end of the clone fragments in line if (entities != null) { This makes the fragments syntactically invalid, because the if AST node is incomplete. We spent a lot of effort to correct the output of clone detection tools, so that the final clone fragments processed for refactoring are syntactically valid.