X-Git-Url: http://git.phpeclipse.com diff --git a/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/RecoveredElement.java b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/RecoveredElement.java new file mode 100644 index 0000000..38ba5e5 --- /dev/null +++ b/net.sourceforge.phpeclipse/src/net/sourceforge/phpdt/internal/compiler/parser/RecoveredElement.java @@ -0,0 +1,319 @@ +/******************************************************************************* + * Copyright (c) 2000, 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package net.sourceforge.phpdt.internal.compiler.parser; + +import net.sourceforge.phpeclipse.internal.compiler.ast.AstNode; +import net.sourceforge.phpeclipse.internal.compiler.ast.Block; +import net.sourceforge.phpeclipse.internal.compiler.ast.FieldDeclaration; +import net.sourceforge.phpeclipse.internal.compiler.ast.Statement; + +/** + * Internal structure for parsing recovery + */ + +public class RecoveredElement { + + public RecoveredElement parent; + public int bracketBalance; + public boolean foundOpeningBrace; + protected Parser recoveringParser; +public RecoveredElement(RecoveredElement parent, int bracketBalance){ + this(parent, bracketBalance, null); +} +public RecoveredElement(RecoveredElement parent, int bracketBalance, Parser parser){ + this.parent = parent; + this.bracketBalance = bracketBalance; + this.recoveringParser = parser; +} +/* + * Record a method declaration + */ +//public RecoveredElement add(AbstractMethodDeclaration methodDeclaration, int bracketBalance) { +// +// /* default behavior is to delegate recording to parent if any */ +// if (parent == null) { +// return this; // ignore +// } else { +// this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(methodDeclaration.declarationSourceStart - 1)); +// return this.parent.add(methodDeclaration, bracketBalance); +// } +//} +/* + * Record a nested block declaration + */ +public RecoveredElement add(Block nestedBlockDeclaration, int bracketBalance) { + + /* default behavior is to delegate recording to parent if any */ + if (parent == null) { + return this; // ignore + } else { + this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(nestedBlockDeclaration.sourceStart - 1)); + return this.parent.add(nestedBlockDeclaration, bracketBalance); + } +} +/* + * Record a field declaration + */ +//public RecoveredElement add(FieldDeclaration fieldDeclaration, int bracketBalance) { +// +// /* default behavior is to delegate recording to parent if any */ +// if (parent == null) { +// return this; // ignore +// } else { +// this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(fieldDeclaration.declarationSourceStart - 1)); +// return this.parent.add(fieldDeclaration, bracketBalance); +// } +//} +///* +// * Record an import reference +// */ +//public RecoveredElement add(ImportReference importReference, int bracketBalance){ +// +// /* default behavior is to delegate recording to parent if any */ +// if (parent == null) { +// return this; // ignore +// } else { +// this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(importReference.declarationSourceStart - 1)); +// return this.parent.add(importReference, bracketBalance); +// } +//} +///* +// * Record a local declaration +// */ +//public RecoveredElement add(LocalDeclaration localDeclaration, int bracketBalance) { +// +// /* default behavior is to delegate recording to parent if any */ +// if (parent == null) { +// return this; // ignore +// } else { +// this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(localDeclaration.declarationSourceStart - 1)); +// return this.parent.add(localDeclaration, bracketBalance); +// } +//} +/* + * Record a statement + */ +public RecoveredElement add(Statement statement, int bracketBalance) { + + /* default behavior is to delegate recording to parent if any */ + if (parent == null) { + return this; // ignore + } else { + this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(statement.sourceStart - 1)); + return this.parent.add(statement, bracketBalance); + } +} +/* + * Record a type declaration + */ +//public RecoveredElement add(TypeDeclaration typeDeclaration, int bracketBalance){ +// +// /* default behavior is to delegate recording to parent if any */ +// if (parent == null) { +// return this; // ignore +// } else { +// this.updateSourceEndIfNecessary(this.previousAvailableLineEnd(typeDeclaration.declarationSourceStart - 1)); +// return this.parent.add(typeDeclaration, bracketBalance); +// } +//} +/* + * Answer the depth of this element, considering the parent link. + */ +public int depth(){ + int depth = 0; + RecoveredElement current = this; + while ((current = current.parent) != null) depth++; + return depth; +} +/* + * Answer the enclosing method node, or null if none + */ +//public RecoveredInitializer enclosingInitializer(){ +// RecoveredElement current = this; +// while (current != null){ +// if (current instanceof RecoveredInitializer){ +// return (RecoveredInitializer) current; +// } +// current = current.parent; +// } +// return null; +//} +/* + * Answer the enclosing method node, or null if none + */ +//public RecoveredMethod enclosingMethod(){ +// RecoveredElement current = this; +// while (current != null){ +// if (current instanceof RecoveredMethod){ +// return (RecoveredMethod) current; +// } +// current = current.parent; +// } +// return null; +//} +/* + * Answer the enclosing type node, or null if none + */ +//public RecoveredType enclosingType(){ +// RecoveredElement current = this; +// while (current != null){ +// if (current instanceof RecoveredType){ +// return (RecoveredType) current; +// } +// current = current.parent; +// } +// return null; +//} +/* + * Answer the closest specified parser + */ +public Parser parser(){ + RecoveredElement current = this; + while (current != null){ + if (current.recoveringParser != null){ + return current.recoveringParser; + } + current = current.parent; + } + return null; +} +/* + * Answer the associated parsed structure + */ +public AstNode parseTree(){ + return null; +} +/* + * Iterate the enclosing blocks and tag them so as to preserve their content + */ +//public void preserveEnclosingBlocks(){ +// RecoveredElement current = this; +// while (current != null){ +// if (current instanceof RecoveredBlock){ +// ((RecoveredBlock)current).preserveContent = true; +// } +// if (current instanceof RecoveredType){ // for anonymous types +// ((RecoveredType)current).preserveContent = true; +// } +// current = current.parent; +// } +//} +/* + * Answer the position of the previous line end if + * there is nothing but spaces in between it and the + * line end. Used to trim spaces on unclosed elements. + */ +public int previousAvailableLineEnd(int position){ + + Parser parser = this.parser(); + if (parser == null) return position; + + Scanner scanner = parser.scanner; + if (scanner.lineEnds == null) return position; + + int index = scanner.getLineNumber(position); + if (index < 2) return position; + int previousLineEnd = scanner.lineEnds[index-2]; + + char[] source = scanner.source; + for (int i = previousLineEnd+1; i < position; i++){ + if (!(source[i] == ' ' || source[i] == '\t')) return position; + } + return previousLineEnd; +} +/* + * Answer the very source end of the corresponding parse node + */ +public int sourceEnd(){ + return 0; +} +protected String tabString(int tab) { + StringBuffer result = new StringBuffer(); + for (int i = tab; i > 0; i--) { + result.append(" "); //$NON-NLS-1$ + } + return result.toString(); +} +/* + * Answer the top node + */ +public RecoveredElement topElement(){ + RecoveredElement current = this; + while (current.parent != null){ + current = current.parent; + } + return current; +} +public String toString() { + return toString(0); +} +public String toString(int tab) { + return super.toString(); +} +/* + * Answer the enclosing type node, or null if none + */ +//public RecoveredType type(){ +// RecoveredElement current = this; +// while (current != null){ +// if (current instanceof RecoveredType){ +// return (RecoveredType) current; +// } +// current = current.parent; +// } +// return null; +//} +/* + * Update the bodyStart of the corresponding parse node + */ +public void updateBodyStart(int bodyStart){ + this.foundOpeningBrace = true; +} +/* + * Update the corresponding parse node from parser state which + * is about to disappear because of restarting recovery + */ +public void updateFromParserState(){ +} +/* + * A closing brace got consumed, might have closed the current element, + * in which case both the currentElement is exited + */ +public RecoveredElement updateOnClosingBrace(int braceStart, int braceEnd){ + if ((--bracketBalance <= 0) && (parent != null)){ + this.updateSourceEndIfNecessary(braceEnd); + return parent; + } + return this; +} +/* + * An opening brace got consumed, might be the expected opening one of the current element, + * in which case the bodyStart is updated. + */ +public RecoveredElement updateOnOpeningBrace(int braceEnd){ + + if (bracketBalance++ == 0){ + this.updateBodyStart(braceEnd + 1); + return this; + } + return null; // no update is necessary +} +/* + * Final update the corresponding parse node + */ +public void updateParseTree(){ +} +/* + * Update the declarationSourceEnd of the corresponding parse node + */ +public void updateSourceEndIfNecessary(int sourceEnd){ +} +}