Open
Description
Describe the bug
I am using spoon to add comments to code blocks. For example when there is a "for" loop, I would add "start of for loop" to the code. I am using spoon's processor to achieve this. But when I run spoon processors on my files, I receive an error that I cannot understand. Do you have any idea what is going on?
Source code you are trying to analyze/transform
public class Temp {
public void printHeaders()
{
int nbCols = columns.size();
for( int i = 0; i < nbCols; i++ )
columns.get( i ).hdrPrintsOn.print( null, new HdrInTreeTablePrinter( table, i ) );
}
@Override
public void print( Iterable<T> data )
{
killCurrentEdit();
table.emptyTable();
if( data == null )
return;
// sort if needed
if( userComparator != null )
{
ArrayList<T> tmp = new ArrayList<T>();
for( T t : data )
{
int ins = Collections.binarySearch( tmp, t, userComparator );
if( ins >= 0 )
tmp.add( ins, t );
else
tmp.add( -ins - 1, t );
}
data = tmp;
}
// each row
for( T d : data )
{
Row row = table.addRow( null );
row.setRef( refMng.getRef( d ) );
printRow( d, row );
}
}
@Override
public void updateRow( T object )
{
// find the row associated with this object
int objectRef = refMng.getRef( object );
Row item = getRow( objectRef );
if( edition != null && refMng.getRef( edition.editedObject ) == objectRef )
killCurrentEdit();
Row insPos = userComparator != null ? getInsertPoint( object ) : item;
// insert or move the row to the right place and create a cell printer
if( item == null )
{
// new
if( insPos != null )
insPos = insPos.addBefore();
else
insPos = table.addRow( null );
insPos.setRef( refMng.getRef( object ) );
}
else
{
if( insPos != item )
{
// GWT.log( "is at row " + row + " but should be at " + insPos
// );
item.moveBefore( insPos );
insPos = item;
}
}
// print the row
printRow( object, insPos );
}
private Row getInsertPoint( T object )
{
ArrayList<Row> items = table.getItemChilds( null );
int nbRows = items.size();
int objectRef = refMng.getRef( object );
if( userComparator != null )
{
for( Row item : items )
{
int refAtRow = item.getRef();
if( userComparator.compare( object, refMng.getObject( refAtRow ) ) <= 0 )
{
if( refAtRow == objectRef )
{
// keep the same place only if lesser than the nxt item
// or if there is no next
if( items.indexOf( item ) == nbRows - 1 )
{
return item;
}
else
{
int refAtNextRow = getRefAtRow( item.getNextSiblingItem() );
if( userComparator.compare( object, refMng.getObject( refAtNextRow ) ) <= 0 )
return item;
}
}
else
{
return item;
}
}
}
}
return null;
}
@Override
public void deleteRow( int ref )
{
Row item = getRow( ref );
if( item == null )
return;
// to reset the edition state, just in case... (an only if we are
// editing on the row we delete)
if( edition != null && refMng.getRef( edition.editedObject ) == ref )
killCurrentEdit();
item.remove();
}
@Override
public void setComparator( Comparator<T> comparator )
{
userComparator = comparator;
sortAndPrint( comparator );
}
public void sortAndPrint( final Comparator<T> userComparator )
{
class It
{
Row item;
T object;
It( Row item, T object )
{
this.object = object;
this.item = item;
}
}
;
ArrayList<It> its = new ArrayList<It>();
// get all objects from the table
ArrayList<Row> childs = table.getItemChilds( null );
for( Row item : childs )
{
int ref = getRefAtRow( item );
its.add( new It( item, refMng.getObject( ref ) ) );
}
// sort them
Collections.sort( its, new Comparator<It>()
{
@Override
public int compare( It o1, It o2 )
{
return userComparator.compare( o1.object, o2.object );
}
} );
// now reorder the lines
for( int j = 0; j < its.size(); j++ )
{
// item at position j ?
Row atJ = table.getItemChilds( null ).get( j );
// needed item is its[i].item
Row neededItem = its.get( j ).item;
if( atJ != neededItem )
{
// move its[i].item before item at position i
neededItem.moveBefore( atJ );
}
}
}
private int getRefAtRow( Row item )
{
return item.getRef();
}
// return the row index of the row associated to the object referenced as
// objectRef
// returns null if the row is not found
private Row getRow( int objectRef )
{
return table.getItemForRef( objectRef );
}
// returns a printer that can be used for the next call. a new one can be
// created
// WARNING : assumes the printer item is correctly initialized
private void printRow( T object, Row row )
{
// to reset the edition state, just in case...
if( edition != null && refMng.getRef( edition.editedObject ) == refMng.getRef( object ) )
killCurrentEdit();
// writes the element reference on the corresponding row element
// note that this does not create a hard link to the referenced object
// so
// no garbage is created here
row.setRef( refMng.getRef( object ) );
// each column
for( int i = 0; i < columns.size(); i++ )
columns.get( i ).prints.print( object, new CellInTreeTablePrinter( row, i ) );
}
private boolean beginEdit( Row item, int col )
{
int ref = getRefAtRow( item );
if( edition != null && ref == refMng.getRef( edition.editedObject ) )
return true; // already began !!!
killCurrentEdit();
Edits<T> editMng = columns.get( col ).edits;
if( editMng == null )
return false;
// find the T object that has been clicked
T object = refMng.getObject( ref );
assert object != null;
if( object == null )
return false;
Element td = item.getTdElement( col );
edition = new EditionState();
// initialize and set the current edit
edition.editedCol = col;
edition.editedObject = object;
// create a Printer corresponding to this cell
edition.editedPrinter = new CellInTreeTablePrinter( item, col );
// create an editor and init it
// -2 to remove padding : HACK HACK HACK
edition.editedEditor = editMng.createEditor( edition.editedObject, edition.editedPrinter, onEdit, td.getOffsetWidth() - 2, td.getClientHeight() - 2 );
return true;
}
private static class CellPos
{
Row item;
int col;
CellPos( Row item, int col )
{
this.item = item;
this.col = col;
}
}
private final MouseDownHandler onTableMouseDown = new MouseDownHandler()
{
@Override
public void onMouseDown( MouseDownEvent event )
{
Element source = DOM.eventGetTarget( Event.as( event.getNativeEvent() ) );
// try to see if it's not on a th element
int hdr = table.getEventTargetHeaderIdx( source );
if( hdr < 0 )
return;
DragDrop.initiate( source, onDragDrop, hdr, Event.as( event.getNativeEvent() ) );
}
};
DragDrop.Callback<Integer> onDragDrop = new DragDrop.Callback<Integer>()
{
@Override
public String getGhostInnerHTML( Integer cookie, Element source )
{
class TempPrinter implements Printer
{
String html = null;
@Override
public void setWidget( Widget widget )
{
assert false;
}
@Override
public void setText( String text )
{
html = text;
}
@Override
public void setHTML( String html )
{
this.html = html;
}
}
TempPrinter printer = new TempPrinter();
columns.get( cookie ).hdrPrintsOn.print( null, printer );
// Due to asynchronism, it may be possible that the printer did not
// yet print anything, well... Too late, we use the source element
// instead !!
if( printer.html == null )
return "<div style='background-color:rgba(120,120,120,0.4);'>" + source.getInnerHTML() + "</div>";
return "<div style='background-color:rgba(120,120,120,0.4);width:20px;height:20px;'>" + printer.html + "</div>";
}
@Override
public void onDragDropFinished( Integer cookie, Element source, Element destination )
{
int newPos = table.getEventTargetHeaderIdx( destination );
if( newPos < 0 )
return;
ColumnMng<T> dum = columns.get( cookie );
columns.set( cookie, columns.get( newPos ) );
columns.set( newPos, dum );
// Redraw headers
printHeaders();
// Redraw all objects in the table
ArrayList<Row> items = table.getItemChilds( null );
for( Row item : items )
{
int ref = item.getRef();
printRow( refMng.getObject( ref ), item );
}
}
};
private final Edits.Callback onEdit = new Edits.Callback()
{
@Override
public void cancelEdition()
{
killCurrentEdit();
}
@Override
public void validateEdition( boolean fJumpNext )
{
// just forget the edition state, but don't redraw
// that means we let the client continue drawing on its cell
if( edition != null && fJumpNext )
{
CellPos next = getNextPos( getRow( refMng.getRef( edition.editedObject ) ), edition.editedCol );
edition.close();
edition = null;
beginEdit( next.item, next.col );
}
}
};
// wait a bit to avoid ui jitter...
// use refMng in case the data change during the time waited
private void killCurrentEdit()
{
if( edition == null )
return;
// reprints the cell, with uptodate data
columns.get( edition.editedCol ).prints.print( refMng.getObject( refMng.getRef( edition.editedObject ) ), edition.editedPrinter );
edition.close();
edition = null;
}
CellPos getNextPos( Row item, int col )
{
// either on the same row
for( int c = col + 1; c < columns.size(); c++ )
{
if( columns.get( c ).edits != null )
return new CellPos( item, c );
}
// or on the next
item = item.getNextSiblingItem();
for( int c = 0; c < columns.size(); c++ )
{
if( columns.get( c ).edits != null )
return new CellPos( item, c );
}
return null;
}
}
Source code for your Spoon processing
// file processors/ForProcessor.java
package spoon.processors;
import spoon.processing.AbstractProcessor;
import spoon.reflect.visitor.filter.TypeFilter;
import spoon.reflect.visitor.CtIterator;
import spoon.reflect.declaration.CtElement;
import spoon.reflect.code.CtFor;
import spoon.reflect.code.CtComment;
import spoon.reflect.factory.Factory;
import java.util.List;
import java.io.*;
public class ForProcessor extends AbstractProcessor<CtFor> {
public void process(CtFor element) {
element.addComment(element.getFactory().Code().createComment("START OF FOR LOOP STATEMENT",CtComment.CommentType.INLINE));
}
}
Actual output
Exception in thread "main" java.lang.Runtime Exception: Inconsistent Stack public static @Nonnull IMicroNode convertToMicroNode (fi
nal @Nonnull Node aNode) {
ValueEnforcer.notNull(aNode, "Node");
IMicroNode ret;
final short nNodeType=aNode.getNode Type();
case Node. DOCUMENT_NODE :
{
ret = new MicroDocument ();
break;
}
case Node. DOCUMENT_TYPE_NODE :
{
final DocumentType aDT = (DocumentType) aNode;
ret = new MicroDocument Type (aDT.getName(), aDT.getPublicId(), aDT.getSystemId());
break;
}
case Node.ELEMENT_NODE :
final Element a Element = (Element) aNode;
final String sNamespaceURI = aElement.getNamespaceURI();
final IMicroElement eElement = ((sNamespaceURI != null)? new Micro Element(sNamespaceURI, aElement.getLocalName()): new MicroE
lement (aElement.getTagName()));
}
case Node. ELEMENT_NODE :
at
at spoon.support.compiler.jdt. JDTTree Builder.endVisit(JDTTree Builder.java:541)
at org.eclipse.jdt.internal.compiler.ast.MethodDeclaration. traverse(MethodDeclaration.java:440)
at org.eclipse.jdt.internal.compiler.ast. Type Declaration. traverse (Type Declaration.java:1699)
at org.eclipse.jdt.internal.compiler.ast.CompilationUnit Declaration. traverse (Compilation Unit Declaration.java:827)
at org.eclipse.jdt.internal.compiler.ast.CompilationUnit Declaration. traverse (CompilationUnit Declaration.java:788)
at spoon.support.compiler.jdt. JDTBased SpoonCompiler.traverseUnit Declaration (JDTBased SpoonCompiler.java:481)
at spoon.support.compiler.jdt. JDTBased SpoonCompiler.lambda$buildModel$0 (JDTBased SpoonCompiler.java:438)
at spoon.support.compiler.jdt. JDTBased SpoonCompiler.forEach CompilationUnit (JDTBased SpoonCompiler.java:465)
at spoon.support.compiler.jdt.JDTBased SpoonCompiler.buildModel (JDTBased Spoon Compiler.java:436)
at spoon.support.compiler.jdt.JDTBased SpoonCompiler.build Units And Model (JDTBased SpoonCompiler.java:373)
at spoon.support.compiler.jdt.JDTBased Spoon Compiler.buildSources (JDTBased SpoonCompiler.java:336)
at spoon.support.compiler.jdt. JDTBased SpoonCompiler.build(JDTBased Spoon Compiler.java:117)
at spoon.support.compiler.jdt. JDTBased SpoonCompiler.build(JDTBased SpoonCompiler.java:100)
at spoon. Launcher.buildModel (Launcher.java:782)
at spoon. Launcher.run(Launcher.java:733)
at spoon. Launcher.run(Launcher.java:112)
at spoon. Launcher.main(Launcher.java:105)
spoon.support.compiler.jdt.ContextBuilder.exit(ContextBuilder.java:122)
Expected output
No response
Spoon Version
10.2.0
JVM Version
11
What operating system are you using?
Linux