From 80ee66d6bd451f22ba487f7c9b6d29954278017f Mon Sep 17 00:00:00 2001 From: Kuba3105 Date: Fri, 26 Jul 2024 10:12:44 +0200 Subject: [PATCH] Added more Folding Region --- .../DefaultJavaFoldingStructureProvider.java | 200 ++++++++++++------ 1 file changed, 141 insertions(+), 59 deletions(-) diff --git a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/text/folding/DefaultJavaFoldingStructureProvider.java b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/text/folding/DefaultJavaFoldingStructureProvider.java index e212f37c39a..ca9b6fc3a3b 100755 --- a/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/text/folding/DefaultJavaFoldingStructureProvider.java +++ b/org.eclipse.jdt.ui/ui/org/eclipse/jdt/ui/text/folding/DefaultJavaFoldingStructureProvider.java @@ -68,7 +68,23 @@ import org.eclipse.jdt.core.compiler.IScanner; import org.eclipse.jdt.core.compiler.ITerminalSymbols; import org.eclipse.jdt.core.compiler.InvalidInputException; +import org.eclipse.jdt.core.dom.AST; +import org.eclipse.jdt.core.dom.ASTParser; +import org.eclipse.jdt.core.dom.ASTVisitor; +import org.eclipse.jdt.core.dom.Block; +import org.eclipse.jdt.core.dom.CatchClause; import org.eclipse.jdt.core.dom.CompilationUnit; +import org.eclipse.jdt.core.dom.DoStatement; +import org.eclipse.jdt.core.dom.EnhancedForStatement; +import org.eclipse.jdt.core.dom.ForStatement; +import org.eclipse.jdt.core.dom.IfStatement; +import org.eclipse.jdt.core.dom.LabeledStatement; +import org.eclipse.jdt.core.dom.LambdaExpression; +import org.eclipse.jdt.core.dom.Statement; +import org.eclipse.jdt.core.dom.SwitchStatement; +import org.eclipse.jdt.core.dom.SynchronizedStatement; +import org.eclipse.jdt.core.dom.TryStatement; +import org.eclipse.jdt.core.dom.WhileStatement; import org.eclipse.jdt.ui.PreferenceConstants; @@ -497,7 +513,6 @@ public IRegion[] computeProjectionRegions(IDocument document) throws BadLocation IRegion preRegion; if (firstLine < captionLine) { -// preRegion= new Region(offset + prefixEnd, contentStart - prefixEnd); int preOffset= document.getLineOffset(firstLine); IRegion preEndLineInfo= document.getLineInformation(captionLine); int preEnd= preEndLineInfo.getOffset(); @@ -541,33 +556,6 @@ private int findFirstContent(final CharSequence content, int prefixEnd) { return 0; } -// /** -// * Finds the offset of the first identifier part within content. -// * Returns 0 if none is found. -// * -// * @param content the content to search -// * @return the first index of a unicode identifier part, or zero if none can -// * be found -// */ -// private int findPrefixEnd(final CharSequence content) { -// // return the index after the leading '/*' or '/**' -// int len= content.length(); -// int i= 0; -// while (i < len && isWhiteSpace(content.charAt(i))) -// i++; -// if (len >= i + 2 && content.charAt(i) == '/' && content.charAt(i + 1) == '*') -// if (len >= i + 3 && content.charAt(i + 2) == '*') -// return i + 3; -// else -// return i + 2; -// else -// return i; -// } -// -// private boolean isWhiteSpace(char c) { -// return c == ' ' || c == '\t'; -// } - /* * @see org.eclipse.jface.text.source.projection.IProjectionPosition#computeCaptionOffset(org.eclipse.jface.text.IDocument) */ @@ -990,18 +978,117 @@ private void update(FoldingStructureComputationContext ctx) { } private void computeFoldingStructure(FoldingStructureComputationContext ctx) { - IParent parent= (IParent) fInput; - try { - if (!(fInput instanceof ISourceReference)) - return; - String source= ((ISourceReference)fInput).getSource(); - if (source == null) - return; + ICompilationUnit unit = (ICompilationUnit) fInput; + ASTParser parser = ASTParser.newParser(AST.JLS_Latest); + parser.setSource(unit); + parser.setResolveBindings(true); + CompilationUnit ast = (CompilationUnit) parser.createAST(null); + + try { + if (!(fInput instanceof ISourceReference)) + return; + String source = ((ISourceReference) fInput).getSource(); + if (source == null) + return; + + ctx.getScanner().setSource(source.toCharArray()); + + IParent parent = (IParent) fInput; + computeFoldingStructure(parent.getChildren(), ctx); + + ast.accept(new ASTVisitor() { + @Override + public boolean visit(IfStatement node) { + processStatement(node, ctx); + Statement elseStatement = node.getElseStatement(); + if (elseStatement != null) { + processStatement(elseStatement, ctx); + } + + return super.visit(node); + } + + @Override + public boolean visit(WhileStatement node) { + processStatement(node, ctx); + return super.visit(node); + } + + @Override + public boolean visit(DoStatement node) { + processStatement(node, ctx); + return super.visit(node); + } + + @Override + public boolean visit(ForStatement node) { + processStatement(node, ctx); + return super.visit(node); + } + + @Override + public boolean visit(EnhancedForStatement node) { + processStatement(node, ctx); + return super.visit(node); + } + + @Override + public boolean visit(SwitchStatement node) { + processStatement(node, ctx); + return super.visit(node); + } + + @Override + public boolean visit(TryStatement node) { + processStatement(node.getBody(), ctx); + for (Object catchClauseObj : node.catchClauses()) { + CatchClause catchClause = (CatchClause) catchClauseObj; + processStatement(catchClause.getBody(), ctx); + } + Block finallyBlock = node.getFinally(); + if (finallyBlock != null) { + processStatement(finallyBlock, ctx); + } + return super.visit(node); + } + + @Override + public boolean visit(LambdaExpression node) { + if (node.getBody() instanceof Block) { + processStatement((Block) node.getBody(), ctx); + } + return super.visit(node); + } + + @Override + public boolean visit(SynchronizedStatement node) { + processStatement(node, ctx); + return super.visit(node); + } + + @Override + public boolean visit(LabeledStatement node) { + processStatement(node, ctx); + return super.visit(node); + } + + + }); + } catch (JavaModelException e) { + } + } - ctx.getScanner().setSource(source.toCharArray()); - computeFoldingStructure(parent.getChildren(), ctx); - } catch (JavaModelException x) { - } + + private void processStatement(Statement node, FoldingStructureComputationContext ctx) { + int start = node.getStartPosition(); + int length = node.getLength(); + + IRegion aligned = alignRegion(new Region(start, length), ctx); + if (aligned != null) { + Position position = new Position(aligned.getOffset(), aligned.getLength()); + JavaProjectionAnnotation annotation = new JavaProjectionAnnotation(ctx.collapseMembers(), null, false); + ctx.addProjectionRange(annotation, position); + } } private void computeFoldingStructure(IJavaElement[] elements, FoldingStructureComputationContext ctx) throws JavaModelException { @@ -1273,33 +1360,28 @@ protected final Position createMemberPosition(IRegion aligned, IMember member) { * only one line) */ protected final IRegion alignRegion(IRegion region, FoldingStructureComputationContext ctx) { - if (region == null) - return null; + if (region == null) + return null; - IDocument document= ctx.getDocument(); - - try { + IDocument document = ctx.getDocument(); - int start= document.getLineOfOffset(region.getOffset()); - int end= document.getLineOfOffset(region.getOffset() + region.getLength()); - if (start >= end) - return null; + try { + int start = document.getLineOfOffset(region.getOffset()); + int end = document.getLineOfOffset(region.getOffset() + region.getLength()); - int offset= document.getLineOffset(start); - int endOffset; - if (document.getNumberOfLines() > end + 1) - endOffset= document.getLineOffset(end + 1); - else - endOffset= document.getLineOffset(end) + document.getLineLength(end); + if (start >= end) + return null; - return new Region(offset, endOffset - offset); + int offset = document.getLineOffset(start); + int endOffset = document.getLineOffset(end) + document.getLineLength(end); - } catch (BadLocationException x) { - // concurrent modification - return null; - } + return new Region(offset, endOffset - offset); + } catch (BadLocationException e) { + return null; + } } + private ProjectionAnnotationModel getModel() { return fEditor.getAdapter(ProjectionAnnotationModel.class); }