public RecoveredElement addAnnotationName( int identifierPtr, int identifierLengthPtr, int annotationStart, int bracketBalanceValue) { if (pendingAnnotations == null) { pendingAnnotations = new RecoveredAnnotation[5]; pendingAnnotationCount = 0; } else { if (pendingAnnotationCount == pendingAnnotations.length) { System.arraycopy( pendingAnnotations, 0, (pendingAnnotations = new RecoveredAnnotation[2 * pendingAnnotationCount]), 0, pendingAnnotationCount); } } RecoveredAnnotation element = new RecoveredAnnotation( identifierPtr, identifierLengthPtr, annotationStart, this, bracketBalanceValue); pendingAnnotations[pendingAnnotationCount++] = element; return element; }
public AbstractMethodDeclaration updatedMethodDeclaration() { /* update annotations */ if (modifiers != 0) { this.methodDeclaration.modifiers |= modifiers; if (this.modifiersStart < this.methodDeclaration.declarationSourceStart) { this.methodDeclaration.declarationSourceStart = modifiersStart; } } /* update annotations */ if (annotationCount > 0) { int existingCount = methodDeclaration.annotations == null ? 0 : methodDeclaration.annotations.length; Annotation[] annotationReferences = new Annotation[existingCount + annotationCount]; if (existingCount > 0) { System.arraycopy( methodDeclaration.annotations, 0, annotationReferences, annotationCount, existingCount); } for (int i = 0; i < annotationCount; i++) { annotationReferences[i] = annotations[i].updatedAnnotationReference(); } methodDeclaration.annotations = annotationReferences; int start = this.annotations[0].annotation.sourceStart; if (start < this.methodDeclaration.declarationSourceStart) { this.methodDeclaration.declarationSourceStart = start; } } if (methodBody != null) { Block block = methodBody.updatedBlock(); if (block != null) { methodDeclaration.statements = block.statements; if (methodDeclaration.declarationSourceEnd == 0) { methodDeclaration.declarationSourceEnd = block.sourceEnd; methodDeclaration.bodyEnd = block.sourceEnd; } /* first statement might be an explict constructor call destinated to a special slot */ if (methodDeclaration.isConstructor()) { ConstructorDeclaration constructor = (ConstructorDeclaration) methodDeclaration; if (methodDeclaration.statements != null && methodDeclaration.statements[0] instanceof ExplicitConstructorCall) { constructor.constructorCall = (ExplicitConstructorCall) methodDeclaration.statements[0]; int length = methodDeclaration.statements.length; System.arraycopy( methodDeclaration.statements, 1, (methodDeclaration.statements = new Statement[length - 1]), 0, length - 1); } if (constructor.constructorCall == null) { // add implicit constructor call constructor.constructorCall = SuperReference.implicitSuperConstructorCall(); } } } } else { if (methodDeclaration.declarationSourceEnd == 0) { if (methodDeclaration.sourceEnd + 1 == methodDeclaration.bodyStart) { // right brace is missing methodDeclaration.declarationSourceEnd = methodDeclaration.sourceEnd; methodDeclaration.bodyStart = methodDeclaration.sourceEnd; methodDeclaration.bodyEnd = methodDeclaration.sourceEnd; } else { methodDeclaration.declarationSourceEnd = methodDeclaration.bodyStart; methodDeclaration.bodyEnd = methodDeclaration.bodyStart; } } } if (localTypeCount > 0) methodDeclaration.bits |= ASTNode.HasLocalType; return methodDeclaration; }
/* * Update the corresponding parse node from parser state which * is about to disappear because of restarting recovery */ public void updateFromParserState() { // if parent is null then recovery already occured in diet parser. if (this.bodyStartsAtHeaderEnd() && this.parent != null) { Parser parser = this.parser(); /* might want to recover arguments or thrown exceptions */ if (parser.listLength > 0 && parser.astLengthPtr > 0) { // awaiting interface type references /* has consumed the arguments - listed elements must be thrown exceptions */ if (methodDeclaration.sourceEnd == parser.rParenPos) { // protection for bugs 15142 int length = parser.astLengthStack[parser.astLengthPtr]; int astPtr = parser.astPtr - length; boolean canConsume = astPtr >= 0; if (canConsume) { if ((!(parser.astStack[astPtr] instanceof AbstractMethodDeclaration))) { canConsume = false; } for (int i = 1, max = length + 1; i < max; i++) { if (!(parser.astStack[astPtr + i] instanceof TypeReference)) { canConsume = false; } } } if (canConsume) { parser.consumeMethodHeaderThrowsClause(); // will reset typeListLength to zero // thus this check will only be performed on first errorCheck after void foo() throws X, // Y, } else { parser.listLength = 0; } } else { /* has not consumed arguments yet, listed elements must be arguments */ if (parser.currentToken == TokenNameLPAREN || parser.currentToken == TokenNameSEMICOLON) { /* if currentToken is parenthesis this last argument is a method/field signature */ parser.astLengthStack[parser.astLengthPtr]--; parser.astPtr--; parser.listLength--; parser.currentToken = 0; } int argLength = parser.astLengthStack[parser.astLengthPtr]; int argStart = parser.astPtr - argLength + 1; boolean needUpdateRParenPos = parser.rParenPos < parser.lParenPos; // 12387 : rParenPos will be used // remove unfinished annotation nodes MemberValuePair[] memberValuePairs = null; while (argLength > 0 && parser.astStack[parser.astPtr] instanceof MemberValuePair) { System.arraycopy( parser.astStack, argStart, memberValuePairs = new MemberValuePair[argLength], 0, argLength); parser.astLengthPtr--; parser.astPtr -= argLength; argLength = parser.astLengthStack[parser.astLengthPtr]; argStart = parser.astPtr - argLength + 1; needUpdateRParenPos = true; } // to compute bodyStart, and thus used to set next checkpoint. int count; for (count = 0; count < argLength; count++) { ASTNode aNode = parser.astStack[argStart + count]; if (aNode instanceof Argument) { Argument argument = (Argument) aNode; /* cannot be an argument if non final */ char[][] argTypeName = argument.type.getTypeName(); if ((argument.modifiers & ~ClassFileConstants.AccFinal) != 0 || (argTypeName.length == 1 && CharOperation.equals(argTypeName[0], TypeBinding.VOID.sourceName()))) { parser.astLengthStack[parser.astLengthPtr] = count; parser.astPtr = argStart + count - 1; parser.listLength = count; parser.currentToken = 0; break; } if (needUpdateRParenPos) parser.rParenPos = argument.sourceEnd + 1; } else { parser.astLengthStack[parser.astLengthPtr] = count; parser.astPtr = argStart + count - 1; parser.listLength = count; parser.currentToken = 0; break; } } if (parser.listLength > 0 && parser.astLengthPtr > 0) { // protection for bugs 15142 int length = parser.astLengthStack[parser.astLengthPtr]; int astPtr = parser.astPtr - length; boolean canConsume = astPtr >= 0; if (canConsume) { if ((!(parser.astStack[astPtr] instanceof AbstractMethodDeclaration))) { canConsume = false; } for (int i = 1, max = length + 1; i < max; i++) { if (!(parser.astStack[astPtr + i] instanceof Argument)) { canConsume = false; } } } if (canConsume) { parser.consumeMethodHeaderRightParen(); /* fix-up positions, given they were updated against rParenPos, which did not get set */ if (parser.currentElement == this) { // parameter addition might have added an awaiting (no return type) // method - see 1FVXQZ4 */ methodDeclaration.sourceEnd = methodDeclaration.arguments[methodDeclaration.arguments.length - 1].sourceEnd; methodDeclaration.bodyStart = methodDeclaration.sourceEnd + 1; parser.lastCheckPoint = methodDeclaration.bodyStart; } } } if (memberValuePairs != null) { System.arraycopy( memberValuePairs, 0, parser.astStack, parser.astPtr + 1, memberValuePairs.length); parser.astPtr += memberValuePairs.length; parser.astLengthStack[++parser.astLengthPtr] = memberValuePairs.length; } } } } }
public RecoveredElement add(TypeDeclaration typeDeclaration, int bracketBalanceValue) { /* do not consider a type starting passed the type end (if set) it must be belonging to an enclosing type */ if (methodDeclaration.declarationSourceEnd != 0 && typeDeclaration.declarationSourceStart > methodDeclaration.declarationSourceEnd) { if (this.parent == null) { return this; // ignore } return this.parent.add(typeDeclaration, bracketBalanceValue); } if ((typeDeclaration.bits & ASTNode.IsLocalType) != 0 || this.parser().methodRecoveryActivated || this.parser().statementRecoveryActivated) { if (methodBody == null) { Block block = new Block(0); block.sourceStart = methodDeclaration.bodyStart; this.add(block, 1); } methodBody.attachPendingModifiers( this.pendingAnnotations, this.pendingAnnotationCount, this.pendingModifiers, this.pendingModifersSourceStart); this.resetPendingModifiers(); return methodBody.add(typeDeclaration, bracketBalanceValue, true); } switch (TypeDeclaration.kind(typeDeclaration.modifiers)) { case TypeDeclaration.INTERFACE_DECL: case TypeDeclaration.ANNOTATION_TYPE_DECL: resetPendingModifiers(); this.updateSourceEndIfNecessary( this.previousAvailableLineEnd(typeDeclaration.declarationSourceStart - 1)); if (this.parent == null) { return this; // ignore } // close the constructor return this.parent.add(typeDeclaration, bracketBalanceValue); } if (localTypes == null) { localTypes = new RecoveredType[5]; localTypeCount = 0; } else { if (localTypeCount == localTypes.length) { System.arraycopy( localTypes, 0, (localTypes = new RecoveredType[2 * localTypeCount]), 0, localTypeCount); } } RecoveredType element = new RecoveredType(typeDeclaration, this, bracketBalanceValue); localTypes[localTypeCount++] = element; if (this.pendingAnnotationCount > 0) { element.attach( pendingAnnotations, pendingAnnotationCount, pendingModifiers, pendingModifersSourceStart); } this.resetPendingModifiers(); /* consider that if the opening brace was not found, it is there */ if (!foundOpeningBrace) { foundOpeningBrace = true; this.bracketBalance++; } return element; }