1 11 package org.eclipse.jdt.internal.compiler.parser; 12 13 import org.eclipse.jdt.core.compiler.*; 14 import org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration; 15 import org.eclipse.jdt.internal.compiler.ast.Argument; 16 import org.eclipse.jdt.internal.compiler.ast.ASTNode; 17 import org.eclipse.jdt.internal.compiler.ast.Block; 18 import org.eclipse.jdt.internal.compiler.ast.FieldDeclaration; 19 import org.eclipse.jdt.internal.compiler.ast.LocalDeclaration; 20 import org.eclipse.jdt.internal.compiler.ast.Statement; 21 import org.eclipse.jdt.internal.compiler.ast.TypeDeclaration; 22 import org.eclipse.jdt.internal.compiler.classfmt.ClassFileConstants; 23 import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; 24 25 public class RecoveredBlock extends RecoveredStatement implements TerminalTokens { 26 27 public Block blockDeclaration; 28 public RecoveredStatement[] statements; 29 public int statementCount; 30 public boolean preserveContent = false; 31 public RecoveredLocalVariable pendingArgument; 32 33 public RecoveredBlock(Block block, RecoveredElement parent, int bracketBalance){ 34 super(block, parent, bracketBalance); 35 this.blockDeclaration = block; 36 this.foundOpeningBrace = true; 37 38 this.preserveContent = this.parser().methodRecoveryActivated || this.parser().statementRecoveryActivated; 39 } 40 public RecoveredElement add(AbstractMethodDeclaration methodDeclaration, int bracketBalanceValue) { 41 if (this.parent != null && this.parent instanceof RecoveredMethod) { 42 RecoveredMethod enclosingRecoveredMethod = (RecoveredMethod) this.parent; 43 if (enclosingRecoveredMethod.methodBody == this && enclosingRecoveredMethod.parent == null) { 44 return this; } 47 } 48 return super.add(methodDeclaration, bracketBalanceValue); 49 } 50 53 public RecoveredElement add(Block nestedBlockDeclaration, int bracketBalanceValue) { 54 55 57 if (this.blockDeclaration.sourceEnd != 0 58 && nestedBlockDeclaration.sourceStart > this.blockDeclaration.sourceEnd){ 59 return this.parent.add(nestedBlockDeclaration, bracketBalanceValue); 60 } 61 62 RecoveredBlock element = new RecoveredBlock(nestedBlockDeclaration, this, bracketBalanceValue); 63 64 if (this.pendingArgument != null){ 66 element.attach(this.pendingArgument); 67 this.pendingArgument = null; 68 } 69 if(this.parser().statementRecoveryActivated) { 70 this.addBlockStatement(element); 71 } 72 this.attach(element); 73 if (nestedBlockDeclaration.sourceEnd == 0) return element; 74 return this; 75 } 76 79 public RecoveredElement add(LocalDeclaration localDeclaration, int bracketBalanceValue) { 80 return this.add(localDeclaration, bracketBalanceValue, false); 81 } 82 85 public RecoveredElement add(LocalDeclaration localDeclaration, int bracketBalanceValue, boolean delegatedByParent) { 86 87 88 103 105 if (this.blockDeclaration.sourceEnd != 0 106 && localDeclaration.declarationSourceStart > this.blockDeclaration.sourceEnd){ 107 if (delegatedByParent) return this; return this.parent.add(localDeclaration, bracketBalanceValue); 109 } 110 111 RecoveredLocalVariable element = new RecoveredLocalVariable(localDeclaration, this, bracketBalanceValue); 112 113 if (localDeclaration instanceof Argument){ 114 this.pendingArgument = element; 115 return this; 116 } 117 118 this.attach(element); 119 if (localDeclaration.declarationSourceEnd == 0) return element; 120 return this; 121 } 122 125 public RecoveredElement add(Statement stmt, int bracketBalanceValue) { 126 return this.add(stmt, bracketBalanceValue, false); 127 } 128 129 132 public RecoveredElement add(Statement stmt, int bracketBalanceValue, boolean delegatedByParent) { 133 134 136 if (this.blockDeclaration.sourceEnd != 0 137 && stmt.sourceStart > this.blockDeclaration.sourceEnd){ 138 if (delegatedByParent) return this; return this.parent.add(stmt, bracketBalanceValue); 140 } 141 142 RecoveredStatement element = new RecoveredStatement(stmt, this, bracketBalanceValue); 143 this.attach(element); 144 if (stmt.sourceEnd == 0) return element; 145 return this; 146 } 147 150 public RecoveredElement add(TypeDeclaration typeDeclaration, int bracketBalanceValue) { 151 return this.add(typeDeclaration, bracketBalanceValue, false); 152 } 153 156 public RecoveredElement add(TypeDeclaration typeDeclaration, int bracketBalanceValue, boolean delegatedByParent) { 157 158 160 if (this.blockDeclaration.sourceEnd != 0 161 && typeDeclaration.declarationSourceStart > this.blockDeclaration.sourceEnd){ 162 if (delegatedByParent) return this; return this.parent.add(typeDeclaration, bracketBalanceValue); 164 } 165 166 RecoveredStatement element = new RecoveredType(typeDeclaration, this, bracketBalanceValue); 167 this.attach(element); 168 if (typeDeclaration.declarationSourceEnd == 0) return element; 169 return this; 170 } 171 174 void attach(RecoveredStatement recoveredStatement) { 175 176 if (this.statements == null) { 177 this.statements = new RecoveredStatement[5]; 178 this.statementCount = 0; 179 } else { 180 if (this.statementCount == this.statements.length) { 181 System.arraycopy( 182 this.statements, 183 0, 184 (this.statements = new RecoveredStatement[2 * this.statementCount]), 185 0, 186 this.statementCount); 187 } 188 } 189 this.statements[this.statementCount++] = recoveredStatement; 190 } 191 194 public ASTNode parseTree(){ 195 return this.blockDeclaration; 196 } 197 public String toString(int tab) { 198 StringBuffer result = new StringBuffer (tabString(tab)); 199 result.append("Recovered block:\n"); this.blockDeclaration.print(tab + 1, result); 201 if (this.statements != null) { 202 for (int i = 0; i < this.statementCount; i++) { 203 result.append("\n"); result.append(this.statements[i].toString(tab + 1)); 205 } 206 } 207 return result.toString(); 208 } 209 212 public Block updatedBlock(){ 213 214 if (!this.preserveContent || this.statementCount == 0) return null; 216 217 Statement[] updatedStatements = new Statement[this.statementCount]; 218 int updatedCount = 0; 219 220 221 RecoveredStatement lastStatement = statements[statementCount - 1]; 223 RecoveredMethod enclosingMethod = this.enclosingMethod(); 224 RecoveredInitializer enclosingIntializer = this.enclosingInitializer(); 225 int bodyEndValue = 0; 226 if(enclosingMethod != null) { 227 bodyEndValue = enclosingMethod.methodDeclaration.bodyEnd; 228 if(enclosingIntializer != null && enclosingMethod.methodDeclaration.sourceStart < enclosingIntializer.fieldDeclaration.sourceStart) { 229 bodyEndValue = enclosingIntializer.fieldDeclaration.declarationSourceEnd; 230 } 231 } else if(enclosingIntializer != null) { 232 bodyEndValue = enclosingIntializer.fieldDeclaration.declarationSourceEnd; 233 } else { 234 bodyEndValue = this.blockDeclaration.sourceEnd - 1; 235 } 236 237 if(lastStatement instanceof RecoveredLocalVariable) { 238 RecoveredLocalVariable lastLocalVariable = (RecoveredLocalVariable) lastStatement; 239 if(lastLocalVariable.localDeclaration.declarationSourceEnd == 0) { 240 lastLocalVariable.localDeclaration.declarationSourceEnd = bodyEndValue; 241 lastLocalVariable.localDeclaration.declarationEnd = bodyEndValue; 242 } 243 } else if(lastStatement instanceof RecoveredBlock) { 244 RecoveredBlock lastBlock = (RecoveredBlock) lastStatement; 245 if(lastBlock.blockDeclaration.sourceEnd == 0) { 246 lastBlock.blockDeclaration.sourceEnd = bodyEndValue; 247 } 248 } else if(!(lastStatement instanceof RecoveredType)){ 249 if(lastStatement.statement.sourceEnd == 0) { 250 lastStatement.statement.sourceEnd = bodyEndValue; 251 } 252 } 253 254 int lastEnd = blockDeclaration.sourceStart; 255 256 for (int i = 0; i < this.statementCount; i++){ 258 Statement updatedStatement = this.statements[i].updatedStatement(); 259 if (updatedStatement != null){ 260 updatedStatements[updatedCount++] = updatedStatement; 261 262 if (updatedStatement instanceof LocalDeclaration) { 263 LocalDeclaration localDeclaration = (LocalDeclaration) updatedStatement; 264 if(localDeclaration.declarationSourceEnd > lastEnd) { 265 lastEnd = localDeclaration.declarationSourceEnd; 266 } 267 } else if (updatedStatement instanceof TypeDeclaration) { 268 TypeDeclaration typeDeclaration = (TypeDeclaration) updatedStatement; 269 if(typeDeclaration.declarationSourceEnd > lastEnd) { 270 lastEnd = typeDeclaration.declarationSourceEnd; 271 } 272 } else { 273 if (updatedStatement.sourceEnd > lastEnd) { 274 lastEnd = updatedStatement.sourceEnd; 275 } 276 } 277 } 278 } 279 if (updatedCount == 0) return null; 281 if (updatedCount != this.statementCount){ 283 this.blockDeclaration.statements = new Statement[updatedCount]; 284 System.arraycopy(updatedStatements, 0, this.blockDeclaration.statements, 0, updatedCount); 285 } else { 286 this.blockDeclaration.statements = updatedStatements; 287 } 288 289 if (this.blockDeclaration.sourceEnd == 0) { 290 if(lastEnd < bodyEndValue) { 291 this.blockDeclaration.sourceEnd = bodyEndValue; 292 } else { 293 this.blockDeclaration.sourceEnd = lastEnd; 294 } 295 } 296 297 return this.blockDeclaration; 298 } 299 302 public Statement updatedStatement(){ 303 304 return this.updatedBlock(); 305 } 306 310 public RecoveredElement updateOnClosingBrace(int braceStart, int braceEnd){ 311 if ((--this.bracketBalance <= 0) && (this.parent != null)){ 312 this.updateSourceEndIfNecessary(braceStart, braceEnd); 313 314 315 RecoveredMethod method = enclosingMethod(); 316 if (method != null && method.methodBody == this){ 317 return this.parent.updateOnClosingBrace(braceStart, braceEnd); 318 } 319 RecoveredInitializer initializer = enclosingInitializer(); 320 if (initializer != null && initializer.initializerBody == this){ 321 return this.parent.updateOnClosingBrace(braceStart, braceEnd); 322 } 323 return this.parent; 324 } 325 return this; 326 } 327 331 public RecoveredElement updateOnOpeningBrace(int braceStart, int braceEnd){ 332 333 Block block = new Block(0); 335 block.sourceStart = parser().scanner.startPosition; 336 return this.add(block, 1); 337 } 338 341 public void updateParseTree(){ 342 343 this.updatedBlock(); 344 } 345 348 public Statement updateStatement(){ 349 350 if (this.blockDeclaration.sourceEnd != 0 || this.statementCount == 0) return null; 352 353 Statement[] updatedStatements = new Statement[this.statementCount]; 354 int updatedCount = 0; 355 356 for (int i = 0; i < this.statementCount; i++){ 358 Statement updatedStatement = this.statements[i].updatedStatement(); 359 if (updatedStatement != null){ 360 updatedStatements[updatedCount++] = updatedStatement; 361 } 362 } 363 if (updatedCount == 0) return null; 365 if (updatedCount != this.statementCount){ 367 this.blockDeclaration.statements = new Statement[updatedCount]; 368 System.arraycopy(updatedStatements, 0, this.blockDeclaration.statements, 0, updatedCount); 369 } else { 370 this.blockDeclaration.statements = updatedStatements; 371 } 372 373 return this.blockDeclaration; 374 } 375 376 379 public RecoveredElement add(FieldDeclaration fieldDeclaration, int bracketBalanceValue) { 380 381 382 char[][] fieldTypeName; 383 if ((fieldDeclaration.modifiers & ~ClassFileConstants.AccFinal) != 0 || (fieldDeclaration.type == null) || ((fieldTypeName = fieldDeclaration.type.getTypeName()).length == 1 && CharOperation.equals(fieldTypeName[0], TypeBinding.VOID.sourceName()))){ 387 this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(fieldDeclaration.declarationSourceStart - 1)); 388 return this.parent.add(fieldDeclaration, bracketBalanceValue); 389 } 390 391 393 if (this.blockDeclaration.sourceEnd != 0 394 && fieldDeclaration.declarationSourceStart > this.blockDeclaration.sourceEnd){ 395 return this.parent.add(fieldDeclaration, bracketBalanceValue); 396 } 397 398 return this; 402 } 403 } 404 | Popular Tags |