Lines 50-55
Link Here
|
50 |
import org.eclipse.ui.texteditor.IDocumentProvider; |
50 |
import org.eclipse.ui.texteditor.IDocumentProvider; |
51 |
import org.eclipse.ui.texteditor.ITextEditor; |
51 |
import org.eclipse.ui.texteditor.ITextEditor; |
52 |
|
52 |
|
|
|
53 |
import org.eclipse.cdt.core.CCorePlugin; |
54 |
import org.eclipse.cdt.core.dom.ast.ASTVisitor; |
55 |
import org.eclipse.cdt.core.dom.ast.IASTBreakStatement; |
56 |
import org.eclipse.cdt.core.dom.ast.IASTCaseStatement; |
57 |
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; |
58 |
import org.eclipse.cdt.core.dom.ast.IASTDoStatement; |
59 |
import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier; |
60 |
import org.eclipse.cdt.core.dom.ast.IASTExpression; |
61 |
import org.eclipse.cdt.core.dom.ast.IASTFileLocation; |
62 |
import org.eclipse.cdt.core.dom.ast.IASTForStatement; |
63 |
import org.eclipse.cdt.core.dom.ast.IASTWhileStatement; |
64 |
import org.eclipse.cdt.core.dom.ast.IASTIfStatement; |
65 |
import org.eclipse.cdt.core.dom.ast.IASTStatement; |
66 |
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement; |
67 |
|
53 |
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; |
68 |
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation; |
54 |
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorElifStatement; |
69 |
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorElifStatement; |
55 |
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorElseStatement; |
70 |
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorElseStatement; |
Lines 647-652
Link Here
|
647 |
|
662 |
|
648 |
private int fMinCommentLines= 1; |
663 |
private int fMinCommentLines= 1; |
649 |
private boolean fPreprocessorBranchFoldingEnabled= true; |
664 |
private boolean fPreprocessorBranchFoldingEnabled= true; |
|
|
665 |
private boolean fStatementsFoldingEnabled = false; |
650 |
private boolean fCommentFoldingEnabled= true; |
666 |
private boolean fCommentFoldingEnabled= true; |
651 |
|
667 |
|
652 |
private ICReconcilingListener fReconilingListener; |
668 |
private ICReconcilingListener fReconilingListener; |
Lines 810-815
Link Here
|
810 |
fCollapseComments= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_COMMENTS); |
826 |
fCollapseComments= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_COMMENTS); |
811 |
fCollapseInactiveCode= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_INACTIVE_CODE); |
827 |
fCollapseInactiveCode= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_INACTIVE_CODE); |
812 |
fPreprocessorBranchFoldingEnabled= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_PREPROCESSOR_BRANCHES_ENABLED); |
828 |
fPreprocessorBranchFoldingEnabled= store.getBoolean(PreferenceConstants.EDITOR_FOLDING_PREPROCESSOR_BRANCHES_ENABLED); |
|
|
829 |
fStatementsFoldingEnabled = store.getBoolean(PreferenceConstants.EDITOR_FOLDING_STATEMENTS); |
813 |
fCommentFoldingEnabled= true; |
830 |
fCommentFoldingEnabled= true; |
814 |
} |
831 |
} |
815 |
|
832 |
|
Lines 1041-1047
Link Here
|
1041 |
// ignore |
1058 |
// ignore |
1042 |
} |
1059 |
} |
1043 |
} |
1060 |
} |
1044 |
if (fPreprocessorBranchFoldingEnabled) { |
1061 |
if (fPreprocessorBranchFoldingEnabled || fStatementsFoldingEnabled) { |
1045 |
IASTTranslationUnit ast= ctx.getAST(); |
1062 |
IASTTranslationUnit ast= ctx.getAST(); |
1046 |
if (ast == null) { |
1063 |
if (ast == null) { |
1047 |
final ASTProvider astProvider= CUIPlugin.getDefault().getASTProvider(); |
1064 |
final ASTProvider astProvider= CUIPlugin.getDefault().getASTProvider(); |
Lines 1081-1088
Link Here
|
1081 |
return false; |
1098 |
return false; |
1082 |
} |
1099 |
} |
1083 |
|
1100 |
|
|
|
1101 |
class ModifiableRegionExtra extends ModifiableRegion { |
1102 |
/* A modifiable region with extra information about the |
1103 |
* region it holds. It tells us whether or not to include |
1104 |
* the last line of the region */ |
1105 |
public boolean inclusive; |
1106 |
} |
1107 |
|
1084 |
/** |
1108 |
/** |
1085 |
* Compute folding structure of the preprocessor branches for the given AST. |
1109 |
* Computes folding structure for preprocessor branches for the given AST. |
|
|
1110 |
* |
1111 |
* @param ast |
1112 |
* @param ctx |
1113 |
*/ |
1114 |
private void computeStatementFoldingStructure(IASTTranslationUnit ast, FoldingStructureComputationContext ctx) { |
1115 |
final Stack<ModifiableRegionExtra> iral = new Stack<ModifiableRegionExtra>(); |
1116 |
ast.accept(new ASTVisitor() { |
1117 |
{ |
1118 |
shouldVisitStatements = true; |
1119 |
} |
1120 |
|
1121 |
public int visit(IASTStatement statement) { |
1122 |
// if it's not part of the displayed - file, we don't need it |
1123 |
if (!statement.isPartOfTranslationUnitFile()) |
1124 |
return PROCESS_SKIP;//we neither need its descendants |
1125 |
try { |
1126 |
ModifiableRegionExtra mr; |
1127 |
IASTFileLocation fl; |
1128 |
if (statement instanceof IASTIfStatement) { |
1129 |
IASTIfStatement ifstmt = (IASTIfStatement) statement; |
1130 |
IASTStatement tmp; |
1131 |
mr = new ModifiableRegionExtra(); |
1132 |
tmp = ifstmt.getThenClause(); |
1133 |
if (tmp==null) return PROCESS_CONTINUE; |
1134 |
fl = tmp.getFileLocation(); |
1135 |
mr.setLength(fl.getNodeLength()); |
1136 |
mr.setOffset(fl.getNodeOffset()); |
1137 |
mr.inclusive = false; |
1138 |
tmp = ifstmt.getElseClause(); |
1139 |
if (tmp==null) { |
1140 |
mr.inclusive = true; |
1141 |
iral.push(mr); |
1142 |
return PROCESS_CONTINUE; |
1143 |
} |
1144 |
iral.push(mr); |
1145 |
mr = new ModifiableRegionExtra(); |
1146 |
fl = tmp.getFileLocation(); |
1147 |
mr.setLength(fl.getNodeLength()); |
1148 |
mr.setOffset(fl.getNodeOffset()); |
1149 |
mr.inclusive = true; |
1150 |
iral.push(mr); |
1151 |
} |
1152 |
mr = new ModifiableRegionExtra(); |
1153 |
mr.inclusive = true; |
1154 |
if (statement instanceof IASTDoStatement) |
1155 |
mr.inclusive = false; |
1156 |
//if (statement instanceof IASTSwitchStatement) { |
1157 |
/* The following code should visit any case statements within the |
1158 |
* switch statement, and add folding to each case statement. |
1159 |
* For some unknown reason, it fails to even visit a single child statement |
1160 |
* of the switch statement, the visit function in the anonymous class is never |
1161 |
* visited. |
1162 |
* I leave the code commented in case anyone wish to fix it. |
1163 |
statement.accept(new ASTVisitor() { |
1164 |
{ |
1165 |
shouldVisitStatements = true; |
1166 |
} |
1167 |
boolean pushedMR = false; |
1168 |
//did we pushed a ModifiableRegion to iral stack? If we did we might need to update it |
1169 |
public int visit(IASTStatement stmt) { |
1170 |
ModifiableRegionExtra tmpmr; |
1171 |
if (!(stmt instanceof IASTCaseStatement)) { |
1172 |
if (!pushedMR) return PROCESS_SKIP; |
1173 |
tmpmr = iral.peek(); |
1174 |
tmpmr.setLength(tmpmr.getLength()+stmt.getFileLocation().getNodeLength()); |
1175 |
System.out.printf("%d is good\n", tmpmr.getLength()+stmt.getFileLocation().getNodeLength()); //$NON-NLS-1$ |
1176 |
if (stmt instanceof IASTBreakStatement) pushedMR = false; |
1177 |
return PROCESS_SKIP; |
1178 |
} |
1179 |
IASTCaseStatement casestmt = (IASTCaseStatement) stmt; |
1180 |
tmpmr = new ModifiableRegionExtra(); |
1181 |
IASTFileLocation tmpfl = casestmt.getExpression().getFileLocation(); |
1182 |
tmpmr.setOffset(tmpfl.getNodeOffset()); |
1183 |
tmpmr.setLength(tmpfl.getNodeLength()); |
1184 |
iral.push(tmpmr); |
1185 |
pushedMR = true; |
1186 |
|
1187 |
return PROCESS_SKIP; |
1188 |
} |
1189 |
});*/ |
1190 |
//} |
1191 |
if (statement instanceof IASTForStatement || |
1192 |
statement instanceof IASTWhileStatement || |
1193 |
statement instanceof IASTDoStatement || |
1194 |
statement instanceof IASTSwitchStatement) { |
1195 |
fl = statement.getFileLocation(); |
1196 |
mr.setLength(fl.getNodeLength()); |
1197 |
mr.setOffset(fl.getNodeOffset()); |
1198 |
iral.push(mr); |
1199 |
} |
1200 |
return PROCESS_CONTINUE; |
1201 |
} catch (Throwable e) { |
1202 |
CCorePlugin.log(e); |
1203 |
return PROCESS_CONTINUE; |
1204 |
} |
1205 |
} |
1206 |
}); |
1207 |
while (!iral.empty()) { |
1208 |
ModifiableRegionExtra mr = iral.pop(); |
1209 |
IRegion aligned = alignRegion(mr, ctx,mr.inclusive); |
1210 |
if (aligned != null) { |
1211 |
Position alignedPos= new Position(aligned.getOffset(), aligned.getLength()); |
1212 |
ctx.addProjectionRange(new CProjectionAnnotation(false, computeKey(mr, ctx), false), alignedPos); |
1213 |
} |
1214 |
} |
1215 |
} |
1216 |
|
1217 |
/** |
1218 |
* Compute folding structure of things related to the AST tree. |
1219 |
* Currently it computes the folding structure for: |
1220 |
* preprocessor branches for the given AST. |
1221 |
* Also, it computes statements folding (if/else do/while for and switch) |
1086 |
* |
1222 |
* |
1087 |
* @param ast |
1223 |
* @param ast |
1088 |
* @param ctx |
1224 |
* @param ctx |
Lines 1095-1102
Link Here
|
1095 |
if (fileName == null) { |
1231 |
if (fileName == null) { |
1096 |
return; |
1232 |
return; |
1097 |
} |
1233 |
} |
|
|
1234 |
|
1235 |
if (fStatementsFoldingEnabled) computeStatementFoldingStructure(ast, ctx); |
1236 |
|
1237 |
if (fPreprocessorBranchFoldingEnabled) computePreprocessorFoldingStructure(ast, ctx, fileName); |
1238 |
} |
1239 |
|
1240 |
/** |
1241 |
* Computes folding structure for preprocessor branches for the given AST. |
1242 |
* |
1243 |
* @param ast |
1244 |
* @param ctx |
1245 |
* @param fileName |
1246 |
*/ |
1247 |
private void computePreprocessorFoldingStructure(IASTTranslationUnit ast, |
1248 |
FoldingStructureComputationContext ctx, String fileName) { |
1098 |
List branches= new ArrayList(); |
1249 |
List branches= new ArrayList(); |
1099 |
Stack branchStack = new Stack(); |
1250 |
Stack<Branch> branchStack = new Stack<Branch>(); |
|
|
1251 |
|
1252 |
|
1100 |
|
1253 |
|
1101 |
IASTPreprocessorStatement[] preprocStmts = ast.getAllPreprocessorStatements(); |
1254 |
IASTPreprocessorStatement[] preprocStmts = ast.getAllPreprocessorStatements(); |
1102 |
|
1255 |
|