diff --git a/php.editor/src/org/netbeans/modules/php/editor/csl/FoldingScanner.java b/php.editor/src/org/netbeans/modules/php/editor/csl/FoldingScanner.java --- a/php.editor/src/org/netbeans/modules/php/editor/csl/FoldingScanner.java +++ b/php.editor/src/org/netbeans/modules/php/editor/csl/FoldingScanner.java @@ -51,9 +51,15 @@ import javax.swing.text.Document; import org.netbeans.api.editor.fold.FoldTemplate; import org.netbeans.api.editor.fold.FoldType; +import org.netbeans.api.lexer.Token; +import org.netbeans.api.lexer.TokenSequence; +import org.netbeans.api.lexer.TokenUtilities; +import org.netbeans.editor.BaseDocument; import org.netbeans.modules.csl.api.OffsetRange; import org.netbeans.modules.csl.spi.ParserResult; import org.netbeans.modules.parsing.api.Source; +import org.netbeans.modules.php.editor.lexer.LexUtilities; +import org.netbeans.modules.php.editor.lexer.PHPTokenId; import org.netbeans.modules.php.editor.model.FileScope; import org.netbeans.modules.php.editor.model.FunctionScope; import org.netbeans.modules.php.editor.model.MethodScope; @@ -126,6 +132,18 @@ "array", Bundle.FT_Arrays(), new FoldTemplate(0, 0, "[...]")); // NOI18N + /** + * PHP tags (<?php...?> blocks). + * + * NOTE: <?=...?> blocks are not folded. + */ + @NbBundle.Messages("FT_PHPTag= blocks") + public static final FoldType TYPE_PHPTAG = FoldType.CODE_BLOCK.derive( + "phptag", // NOI18N + Bundle.FT_PHPTag(), + new FoldTemplate(0, 0, "...") // NOI18N + ); + private static final String LAST_CORRECT_FOLDING_PROPERTY = "LAST_CORRECT_FOLDING_PROPERY"; //NOI18N public static FoldingScanner create() { @@ -166,6 +184,7 @@ Source source = phpParseResult.getSnapshot().getSource(); assert source != null : "source was null"; Document doc = source.getDocument(false); + processPHPTags(folds, doc); setFoldingProperty(doc, folds); return folds; } @@ -210,6 +229,50 @@ } } + private void processPHPTags(Map> folds, Document document) { + if (document instanceof BaseDocument) { + BaseDocument doc = (BaseDocument) document; + doc.readLock(); + try { + TokenSequence ts = LexUtilities.getPHPTokenSequence(doc, 0); + if (ts == null) { + return; + } + ts.move(0); + int startOffset = -1; + int endOffset = -1; + int shortTagBalance = 0; // for + while (ts.moveNext()) { + Token token = ts.token(); + if (token != null) { + PHPTokenId id = token.id(); + switch (id) { + case PHP_OPENTAG: + startOffset = ts.offset() + token.length(); + break; + case PHP_CLOSETAG: + if (shortTagBalance == 0) { + assert startOffset != -1; + endOffset = ts.offset(); + getRanges(folds, TYPE_PHPTAG).add(new OffsetRange(startOffset, endOffset)); + } else { + shortTagBalance--; + } + break; + case T_OPEN_TAG_WITH_ECHO: + shortTagBalance++; + break; + default: + break; + } + } + } + } finally { + doc.readUnlock(); + } + } + } + private void processScopes(Map> folds, List scopes) { for (Scope scope : scopes) { OffsetRange offsetRange = scope.getBlockRange(); diff --git a/php.editor/src/org/netbeans/modules/php/editor/csl/PHPFoldingProvider.java b/php.editor/src/org/netbeans/modules/php/editor/csl/PHPFoldingProvider.java --- a/php.editor/src/org/netbeans/modules/php/editor/csl/PHPFoldingProvider.java +++ b/php.editor/src/org/netbeans/modules/php/editor/csl/PHPFoldingProvider.java @@ -53,7 +53,7 @@ */ @MimeRegistration(mimeType = "text/x-php5", service = FoldTypeProvider.class, position = 1000) public class PHPFoldingProvider implements FoldTypeProvider { - private static final Collection TYPES = new ArrayList<>(6); + private static final Collection TYPES = new ArrayList<>(7); static { TYPES.add(FoldingScanner.TYPE_CLASS); @@ -62,6 +62,7 @@ TYPES.add(FoldingScanner.TYPE_COMMENT); TYPES.add(FoldingScanner.TYPE_PHPDOC); TYPES.add(FoldingScanner.TYPE_ARRAY); + TYPES.add(FoldingScanner.TYPE_PHPTAG); } @Override diff --git a/php.editor/test/unit/data/testfiles/finally_01.php.folds b/php.editor/test/unit/data/testfiles/finally_01.php.folds --- a/php.editor/test/unit/data/testfiles/finally_01.php.folds +++ b/php.editor/test/unit/data/testfiles/finally_01.php.folds @@ -1,5 +1,5 @@ - +| +- ?> diff --git a/php.editor/test/unit/data/testfiles/finally_02.php.folds b/php.editor/test/unit/data/testfiles/finally_02.php.folds --- a/php.editor/test/unit/data/testfiles/finally_02.php.folds +++ b/php.editor/test/unit/data/testfiles/finally_02.php.folds @@ -1,9 +1,9 @@ - +| +- ?> diff --git a/php.editor/test/unit/data/testfiles/foldingConditionalStatements.php.folds b/php.editor/test/unit/data/testfiles/foldingConditionalStatements.php.folds --- a/php.editor/test/unit/data/testfiles/foldingConditionalStatements.php.folds +++ b/php.editor/test/unit/data/testfiles/foldingConditionalStatements.php.folds @@ -40,4 +40,3 @@ | - } - ?> diff --git a/php.editor/test/unit/data/testfiles/foldingConditionalStatements_1.php.folds b/php.editor/test/unit/data/testfiles/foldingConditionalStatements_1.php.folds --- a/php.editor/test/unit/data/testfiles/foldingConditionalStatements_1.php.folds +++ b/php.editor/test/unit/data/testfiles/foldingConditionalStatements_1.php.folds @@ -52,4 +52,3 @@ | - } - ?> diff --git a/php.editor/test/unit/data/testfiles/foldingCycles.php.folds b/php.editor/test/unit/data/testfiles/foldingCycles.php.folds --- a/php.editor/test/unit/data/testfiles/foldingCycles.php.folds +++ b/php.editor/test/unit/data/testfiles/foldingCycles.php.folds @@ -60,4 +60,3 @@ | - } - ?> diff --git a/php.editor/test/unit/data/testfiles/foldingCycles_1.php.folds b/php.editor/test/unit/data/testfiles/foldingCycles_1.php.folds --- a/php.editor/test/unit/data/testfiles/foldingCycles_1.php.folds +++ b/php.editor/test/unit/data/testfiles/foldingCycles_1.php.folds @@ -76,4 +76,3 @@ | - } - ?> diff --git a/php.editor/test/unit/data/testfiles/foldingMethod.php.folds b/php.editor/test/unit/data/testfiles/foldingMethod.php.folds --- a/php.editor/test/unit/data/testfiles/foldingMethod.php.folds +++ b/php.editor/test/unit/data/testfiles/foldingMethod.php.folds @@ -20,4 +20,3 @@ | - } - ?> diff --git a/php.editor/test/unit/data/testfiles/foldingMethod_1.php.folds b/php.editor/test/unit/data/testfiles/foldingMethod_1.php.folds --- a/php.editor/test/unit/data/testfiles/foldingMethod_1.php.folds +++ b/php.editor/test/unit/data/testfiles/foldingMethod_1.php.folds @@ -25,4 +25,3 @@ | - } - ?> diff --git a/php.editor/test/unit/data/testfiles/foldingPHPTags.php.folds b/php.editor/test/unit/data/testfiles/foldingPHPTags.php.folds new file mode 100644 --- /dev/null +++ b/php.editor/test/unit/data/testfiles/foldingPHPTags.php.folds @@ -0,0 +1,19 @@ + + +

Test

+ ++ + + +

Test

++ + + diff --git a/php.editor/test/unit/data/testfiles/issue213616.php.folds b/php.editor/test/unit/data/testfiles/issue213616.php.folds --- a/php.editor/test/unit/data/testfiles/issue213616.php.folds +++ b/php.editor/test/unit/data/testfiles/issue213616.php.folds @@ -7,4 +7,3 @@ - } - } - ?> diff --git a/php.editor/test/unit/data/testfiles/issue216088.php.folds b/php.editor/test/unit/data/testfiles/issue216088.php.folds --- a/php.editor/test/unit/data/testfiles/issue216088.php.folds +++ b/php.editor/test/unit/data/testfiles/issue216088.php.folds @@ -4,4 +4,3 @@ + echo ""; else + echo ""; - ?> diff --git a/php.editor/test/unit/data/testfiles/issue232884.php.folds b/php.editor/test/unit/data/testfiles/issue232884.php.folds --- a/php.editor/test/unit/data/testfiles/issue232884.php.folds +++ b/php.editor/test/unit/data/testfiles/issue232884.php.folds @@ -3,4 +3,3 @@ if (TRUE): endif; - ?> diff --git a/php.editor/test/unit/data/testfiles/parser/foldingConditionalStatements.php b/php.editor/test/unit/data/testfiles/parser/foldingConditionalStatements.php --- a/php.editor/test/unit/data/testfiles/parser/foldingConditionalStatements.php +++ b/php.editor/test/unit/data/testfiles/parser/foldingConditionalStatements.php @@ -39,5 +39,3 @@ } else { } - -?> \ No newline at end of file diff --git a/php.editor/test/unit/data/testfiles/parser/foldingConditionalStatements_1.php b/php.editor/test/unit/data/testfiles/parser/foldingConditionalStatements_1.php --- a/php.editor/test/unit/data/testfiles/parser/foldingConditionalStatements_1.php +++ b/php.editor/test/unit/data/testfiles/parser/foldingConditionalStatements_1.php @@ -51,5 +51,3 @@ { } - -?> \ No newline at end of file diff --git a/php.editor/test/unit/data/testfiles/parser/foldingCycles.php b/php.editor/test/unit/data/testfiles/parser/foldingCycles.php --- a/php.editor/test/unit/data/testfiles/parser/foldingCycles.php +++ b/php.editor/test/unit/data/testfiles/parser/foldingCycles.php @@ -59,5 +59,3 @@ foreach ($array as $value) { } - -?> \ No newline at end of file diff --git a/php.editor/test/unit/data/testfiles/parser/foldingCycles_1.php b/php.editor/test/unit/data/testfiles/parser/foldingCycles_1.php --- a/php.editor/test/unit/data/testfiles/parser/foldingCycles_1.php +++ b/php.editor/test/unit/data/testfiles/parser/foldingCycles_1.php @@ -75,5 +75,3 @@ { } - -?> \ No newline at end of file diff --git a/php.editor/test/unit/data/testfiles/parser/foldingMethod.php b/php.editor/test/unit/data/testfiles/parser/foldingMethod.php --- a/php.editor/test/unit/data/testfiles/parser/foldingMethod.php +++ b/php.editor/test/unit/data/testfiles/parser/foldingMethod.php @@ -19,5 +19,3 @@ } } - -?> \ No newline at end of file diff --git a/php.editor/test/unit/data/testfiles/parser/foldingMethod_1.php b/php.editor/test/unit/data/testfiles/parser/foldingMethod_1.php --- a/php.editor/test/unit/data/testfiles/parser/foldingMethod_1.php +++ b/php.editor/test/unit/data/testfiles/parser/foldingMethod_1.php @@ -24,5 +24,3 @@ } } - -?> \ No newline at end of file diff --git a/php.editor/test/unit/data/testfiles/parser/foldingPHPTags.php b/php.editor/test/unit/data/testfiles/parser/foldingPHPTags.php new file mode 100644 --- /dev/null +++ b/php.editor/test/unit/data/testfiles/parser/foldingPHPTags.php @@ -0,0 +1,19 @@ + + +

Test

+ + + + +

Test

+ + + diff --git a/php.editor/test/unit/data/testfiles/parser/issue213616.php b/php.editor/test/unit/data/testfiles/parser/issue213616.php --- a/php.editor/test/unit/data/testfiles/parser/issue213616.php +++ b/php.editor/test/unit/data/testfiles/parser/issue213616.php @@ -6,5 +6,3 @@ } } - -?> \ No newline at end of file diff --git a/php.editor/test/unit/data/testfiles/parser/issue216088.php b/php.editor/test/unit/data/testfiles/parser/issue216088.php --- a/php.editor/test/unit/data/testfiles/parser/issue216088.php +++ b/php.editor/test/unit/data/testfiles/parser/issue216088.php @@ -4,4 +4,3 @@ echo ""; else echo ""; -?> \ No newline at end of file diff --git a/php.editor/test/unit/data/testfiles/parser/issue232884.php b/php.editor/test/unit/data/testfiles/parser/issue232884.php --- a/php.editor/test/unit/data/testfiles/parser/issue232884.php +++ b/php.editor/test/unit/data/testfiles/parser/issue232884.php @@ -3,4 +3,3 @@ if (TRUE): endif; -?> \ No newline at end of file diff --git a/php.editor/test/unit/src/org/netbeans/modules/php/editor/csl/FoldingTest.java b/php.editor/test/unit/src/org/netbeans/modules/php/editor/csl/FoldingTest.java --- a/php.editor/test/unit/src/org/netbeans/modules/php/editor/csl/FoldingTest.java +++ b/php.editor/test/unit/src/org/netbeans/modules/php/editor/csl/FoldingTest.java @@ -106,4 +106,9 @@ checkFolds("testfiles/parser/foldingArrays.php"); } + // #232600 + public void testPHPTags() throws Exception { + checkFolds("testfiles/parser/foldingPHPTags.php"); + } + }