7777import org .eclipse .jdt .core .dom .ASTVisitor ;
7878import org .eclipse .jdt .core .dom .AnonymousClassDeclaration ;
7979import org .eclipse .jdt .core .dom .Block ;
80+ import org .eclipse .jdt .core .dom .BodyDeclaration ;
8081import org .eclipse .jdt .core .dom .BreakStatement ;
8182import org .eclipse .jdt .core .dom .CatchClause ;
8283import org .eclipse .jdt .core .dom .Comment ;
9091import org .eclipse .jdt .core .dom .Initializer ;
9192import org .eclipse .jdt .core .dom .LambdaExpression ;
9293import org .eclipse .jdt .core .dom .MethodDeclaration ;
94+ import org .eclipse .jdt .core .dom .SimpleName ;
9395import org .eclipse .jdt .core .dom .Statement ;
9496import org .eclipse .jdt .core .dom .SwitchCase ;
9597import org .eclipse .jdt .core .dom .SwitchExpression ;
@@ -338,7 +340,7 @@ void setIsComment(boolean isComment) {
338340 @ Override
339341 public String toString () {
340342 return "JavaProjectionAnnotation:\n " + //$NON-NLS-1$
341- "\t element: \t " + fJavaElement . toString () + "\n " + //$NON-NLS-1$ //$NON-NLS-2$
343+ "\t element: \t " + fJavaElement + "\n " + //$NON-NLS-1$ //$NON-NLS-2$
342344 "\t collapsed: \t " + isCollapsed () + "\n " + //$NON-NLS-1$ //$NON-NLS-2$
343345 "\t comment: \t " + isComment () + "\n " ; //$NON-NLS-1$ //$NON-NLS-2$
344346 }
@@ -357,9 +359,12 @@ private class FoldingVisitor extends ASTVisitor {
357359
358360 private FoldingStructureComputationContext ctx ;
359361 private List <Position > topLevelTypes = new ArrayList <>();
362+ private ICompilationUnit topLevelCompilationUnit ;
363+ private Deque <IRegion > currentSurroundingElemenPositions = new ArrayDeque <>();
360364
361- public FoldingVisitor (FoldingStructureComputationContext ctx ) {
365+ public FoldingVisitor (FoldingStructureComputationContext ctx , ICompilationUnit compilationUnit ) {
362366 this .ctx = ctx ;
367+ this .topLevelCompilationUnit = compilationUnit ;
363368 }
364369
365370 @ Override
@@ -377,13 +382,15 @@ public boolean visit(CompilationUnit node) {
377382
378383 @ Override
379384 public boolean visit (TypeDeclaration node ) {
385+ SimpleName name = node .getName ();
380386 if (node .isMemberTypeDeclaration () || node .isLocalTypeDeclaration ()) {
381- int start = node . getName () .getStartPosition ();
387+ int start = name .getStartPosition ();
382388 int end = node .getStartPosition () + node .getLength ();
383389 createFoldingRegion (start , end - start , ctx .collapseMembers ());
384390 } else {
385391 topLevelTypes .add (new Position (node .getStartPosition (), node .getLength ()-1 ));
386392 }
393+ addToCurrentSurroundingPositions (node , name );
387394 return true ;
388395 }
389396
@@ -392,9 +399,14 @@ public boolean visit(MethodDeclaration node) {
392399 int start = node .getName ().getStartPosition ();
393400 int end = node .getStartPosition () + node .getLength ();
394401 createFoldingRegion (start , end - start , ctx .collapseMembers ());
402+ addToCurrentSurroundingPositions (node , node .getName ());
395403 return true ;
396404 }
397405
406+ private void addToCurrentSurroundingPositions (BodyDeclaration node , SimpleName name ) {
407+ currentSurroundingElemenPositions .add (new Region (name .getStartPosition (), node .getLength () + name .getStartPosition () - node .getStartPosition ()));
408+ }
409+
398410 @ Override
399411 public boolean visit (IfStatement node ) {
400412 int start = node .getStartPosition ();
@@ -560,13 +572,46 @@ private void createFoldingRegion(ASTNode node, boolean collapse) {
560572 }
561573
562574 private void createFoldingRegion (int start , int length , boolean collapse ) {
575+ createFoldingRegion (start , length , collapse , false );
576+ }
577+
578+ private void createFoldingRegion (int start , int length , boolean collapse , boolean isComment ) {
579+ createFoldingRegion (start , length , collapse , resolveJavaElementAt (start , true ), isComment );
580+ }
581+
582+
583+ private IJavaElement resolveJavaElementAt (int offset , boolean checkSurrounding ) {
584+ IJavaElement [] elements ;
585+ try {
586+ elements = topLevelCompilationUnit .codeSelect (offset , 0 );
587+ } catch (JavaModelException e ) {
588+ JavaPlugin .log (e );
589+ return null ;
590+ }
591+ if (elements .length > 0 ) {
592+ return elements [0 ];
593+ }
594+ if (checkSurrounding ) {
595+ for (Iterator <IRegion > it = currentSurroundingElemenPositions .reversed ().iterator (); it .hasNext ();) {
596+ IRegion outer = it .next ();
597+ if (outer .getOffset () + outer .getLength () < offset ) {
598+ it .remove ();
599+ } else if (outer .getOffset () <= offset ) {
600+ return resolveJavaElementAt (outer .getOffset (), false );
601+ }
602+ }
603+ }
604+ return null ;
605+ }
606+
607+ private void createFoldingRegion (int start , int length , boolean collapse , IJavaElement element , boolean isComment ) {
563608 if (length > 0 ) {
564609 IRegion region = new Region (start , length );
565610 IRegion aligned = alignRegion (region , ctx );
566611
567612 if (aligned != null && isMultiline (aligned )) {
568613 Position position = new Position (aligned .getOffset (), aligned .getLength ());
569- JavaProjectionAnnotation annotation = new JavaProjectionAnnotation (collapse , null , false );
614+ JavaProjectionAnnotation annotation = new JavaProjectionAnnotation (collapse , element , isComment );
570615 ctx .addProjectionRange (annotation , position );
571616 }
572617 }
@@ -1399,7 +1444,7 @@ private void processCompilationUnit(ICompilationUnit unit, FoldingStructureCompu
13991444 parser .setCompilerOptions (options );
14001445
14011446 CompilationUnit ast = (CompilationUnit ) parser .createAST (null );
1402- FoldingVisitor visitor = new FoldingVisitor (ctx );
1447+ FoldingVisitor visitor = new FoldingVisitor (ctx , unit );
14031448 ast .accept (visitor );
14041449
14051450 if (fCustomFoldingRegionsEnabled ) {
@@ -1568,7 +1613,7 @@ private void checkCustomFolding(Deque<Integer> openCustomRegionStartPositions, c
15681613
15691614 private void checkIncludeLastLineAndCreateCustomFoldingRegion (char [] sourceArray , FoldingVisitor visitor , IRegion customFoldingRegion , boolean excludeEndregionComment ) {
15701615 includelastLine = includeLastLineInCustomFoldingRegion (sourceArray , customFoldingRegion .getOffset () + customFoldingRegion .getLength (), excludeEndregionComment );
1571- visitor .createFoldingRegion (customFoldingRegion .getOffset (), customFoldingRegion .getLength (), fCollapseCustomRegions );
1616+ visitor .createFoldingRegion (customFoldingRegion .getOffset (), customFoldingRegion .getLength (), fCollapseCustomRegions , true );
15721617 }
15731618
15741619 private boolean includeLastLineInCustomFoldingRegion (char [] sourceArray , int regionEnd , boolean excludeEndregionComment ) {
0 commit comments