Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
Copyright (c) 2004, 2013 IBM Corporation and others. All rights reserved. This program and the accompanying materials are made available under the terms of the Eclipse Public License v1.0 which accompanies this distribution, and is available at http://www.eclipse.org/legal/epl-v10.html Contributors: IBM Corporation - initial API and implementation /
 
 package org.eclipse.jdt.core.dom.rewrite;
 
 import java.util.List;
 import java.util.Map;
 
 import  org.eclipse.jface.text.IDocument;
 import  org.eclipse.jface.text.TextUtilities;
 import  org.eclipse.text.edits.MultiTextEdit;
 import  org.eclipse.text.edits.TextEdit;
 import  org.eclipse.text.edits.TextEditGroup;

Infrastructure for modifying code by describing changes to AST nodes. The AST rewriter collects descriptions of modifications to nodes and translates these descriptions into text edits that can then be applied to the original source. The key thing is that this is all done without actually modifying the original AST, which has the virtue of allowing one to entertain several alternate sets of changes on the same AST (e.g., for calculating quick fix proposals). The rewrite infrastructure tries to generate minimal text changes, preserve existing comments and indentation, and follow code formatter settings. If the freedom to explore multiple alternate changes is not required, consider using the AST's built-in rewriter (see org.eclipse.jdt.core.dom.CompilationUnit.rewrite(IDocument, Map)).

The following code snippet illustrated usage of this class:

 Document document = new Document("import java.util.List;\nclass X {}\n");
 ASTParser parser = ASTParser.newParser(AST.JLS3);
 parser.setSource(document.get().toCharArray());
 CompilationUnit cu = (CompilationUnit) parser.createAST(null);
 AST ast = cu.getAST();
 ImportDeclaration id = ast.newImportDeclaration();
 id.setName(ast.newName(new String[] {"java", "util", "Set"}));
 ASTRewrite rewriter = ASTRewrite.create(ast);
 TypeDeclaration td = (TypeDeclaration) cu.types().get(0);
 ITrackedNodePosition tdLocation = rewriter.track(td);
 ListRewrite lrw = rewriter.getListRewrite(cu, CompilationUnit.IMPORTS_PROPERTY);
 lrw.insertLast(id, null);
 TextEdit edits = rewriter.rewriteAST(document, null);
 UndoEdit undo = null;
 try {
     undo = edits.apply(document);
 } catch(MalformedTreeException e) {
     e.printStackTrace();
 } catch(BadLocationException e) {
     e.printStackTrace();
 }
 assert "import java.util.List;\nimport java.util.Set;\nclass X {}\n".equals(document.get());
 // tdLocation.getStartPosition() and tdLocation.getLength()
 // are new source range for "class X {}" in document.get()
 

This class is not intended to be subclassed.

Since:
3.0
Noinstantiate:
This class is not intended to be instantiated by clients.
Noextend:
This class is not intended to be subclassed by clients.
 
 public class ASTRewrite {
root node for the rewrite: Only nodes under this root are accepted
 
 	private final AST ast;
 
 	private final RewriteEventStore eventStore;
	private final NodeInfoStore nodeStore;

Target source range computer; null means uninitialized; lazy initialized to new TargetSourceRangeComputer().

Since:
3.1
Primary field used in representing rewrite properties efficiently. If null, this rewrite has no properties. If a String, this is the name of this rewrite's sole property, and property2 contains its value. If a Map, this is the table of property name-value mappings. Initially null.

See also:
property2
	private Object property1 = null;

Auxiliary field used in representing rewrite properties efficiently.

See also:
property1
	private Object property2 = null;

Creates a new instance for describing manipulations of the given AST.

Parameters:
ast the AST whose nodes will be rewritten
Returns:
the new rewriter instance
	public static ASTRewrite create(AST ast) {
		return new ASTRewrite(ast);
	}

Internal constructor. Creates a new instance for the given AST. Clients should use create(AST) to create instances.

Parameters:
ast the AST being rewritten
	protected ASTRewrite(AST ast) {
		this.ast;
		this.new NodeInfoStore(ast);
	}

Returns the AST the rewrite was set up on.

Returns:
the AST the rewrite was set up on
	public final AST getAST() {
		return this.;
	}

Internal method. Returns the internal event store. Clients should not use.

Returns:
Returns the internal event store. Clients should not use.
		return this.;
	}

Internal method. Returns the internal node info store. Clients should not use.

Returns:
Returns the internal info store. Clients should not use.
	protected final NodeInfoStore getNodeStore() {
		return this.;
	}

Converts all modifications recorded by this rewriter into an object representing the corresponding text edits to the given document containing the original source code. The document itself is not modified.

For nodes in the original that are being replaced or deleted, this rewriter computes the adjusted source ranges by calling getExtendedSourceRangeComputer().computeSourceRange(node).

Calling this methods does not discard the modifications on record. Subsequence modifications are added to the ones already on record. If this method is called again later, the resulting text edit object will accurately reflect the net cumulative effect of all those changes.

Parameters:
document original document containing source code
options the table of formatter options (key type: String; value type: String); or null to use the standard global options JavaCore.getOptions()
Returns:
text edit object describing the changes to the document corresponding to the changes recorded by this rewriter
Throws:
IllegalArgumentException An IllegalArgumentException is thrown if the document passed does not correspond to the AST that is rewritten.
	public TextEdit rewriteAST(IDocument documentMap optionsthrows IllegalArgumentException {
		if (document == null) {
		}
		ASTNode rootNodegetRootNode();
		if (rootNode == null) {
			return new MultiTextEdit(); // no changes
		}
		char[] contentdocument.get().toCharArray();
		LineInformation lineInfo= LineInformation.create(document);
		String lineDelim= TextUtilities.getDefaultLineDelimiter(document);
		ASTNode astRootrootNode.getRoot();
		List commentNodesastRoot instanceof CompilationUnit ? ((CompilationUnitastRoot).getCommentList() : null;
		Map currentOptions = options == null ? JavaCore.getOptions() : options;
		return internalRewriteAST(contentlineInfolineDelimcommentNodescurrentOptionsrootNode, (RecoveryScannerData)((CompilationUnitastRoot).getStatementsRecoveryData());
	}

Converts all modifications recorded by this rewriter into an object representing the the corresponding text edits to the source of a ITypeRoot from which the AST was created from. The type root's source itself is not modified by this method call.

Important: This API can only be used if the modified AST has been created from a ITypeRoot with source. That means ASTParser.setSource(ICompilationUnit), ASTParser.setSource(IClassFile) or ASTParser.setSource(ITypeRoot) has been used when initializing the ASTParser. A IllegalArgumentException is thrown otherwise. An IllegalArgumentException is also thrown when the type roots buffer does not correspond anymore to the AST. Use rewriteAST(IDocument, Map) for all ASTs created from other content.

For nodes in the original that are being replaced or deleted, this rewriter computes the adjusted source ranges by calling getExtendedSourceRangeComputer().computeSourceRange(node).

Calling this methods does not discard the modifications on record. Subsequence modifications are added to the ones already on record. If this method is called again later, the resulting text edit object will accurately reflect the net cumulative effect of all those changes.

Returns:
text edit object describing the changes to the document corresponding to the changes recorded by this rewriter
Throws:
JavaModelException A JavaModelException is thrown when the underlying compilation units buffer could not be accessed.
IllegalArgumentException An IllegalArgumentException is thrown if the document passed does not correspond to the AST that is rewritten.
Since:
3.2
	public TextEdit rewriteAST() throws JavaModelExceptionIllegalArgumentException {
		ASTNode rootNodegetRootNode();
		if (rootNode == null) {
			return new MultiTextEdit(); // no changes
		}
		ASTNode rootrootNode.getRoot();
		if (!(root instanceof CompilationUnit)) {
			throw new IllegalArgumentException("This API can only be used if the AST is created from a compilation unit or class file"); //$NON-NLS-1$
		}
		CompilationUnit astRoot= (CompilationUnitroot;
		ITypeRoot typeRoot = astRoot.getTypeRoot();
		if (typeRoot == null || typeRoot.getBuffer() == null) {
			throw new IllegalArgumentException("This API can only be used if the AST is created from a compilation unit or class file"); //$NON-NLS-1$
		}
		char[] contenttypeRoot.getBuffer().getCharacters();
		LineInformation lineInfo= LineInformation.create(astRoot);
		String lineDelimtypeRoot.findRecommendedLineSeparator();
		Map optionstypeRoot.getJavaProject().getOptions(true);
		return internalRewriteAST(contentlineInfolineDelimastRoot.getCommentList(), optionsrootNode, (RecoveryScannerData)astRoot.getStatementsRecoveryData());
	}
	private TextEdit internalRewriteAST(char[] contentLineInformation lineInfoString lineDelimList commentNodesMap optionsASTNode rootNodeRecoveryScannerData recoveryScannerData) {
		TextEdit resultnew MultiTextEdit();
		//validateASTNotModified(rootNode);
		this..prepareMovedNodes(sourceRangeComputer);
		ASTRewriteAnalyzer visitornew ASTRewriteAnalyzer(contentlineInfolineDelimresultthis.this.commentNodesoptionssourceRangeComputerrecoveryScannerData);
		rootNode.accept(visitor); // throws IllegalArgumentException
		return result;
	}
	private ASTNode getRootNode() {
		ASTNode nodenull;
		int start= -1;
		int end= -1;
			ASTNode curr= (ASTNodeiter.next();
			if (!RewriteEventStore.isNewNode(curr)) {
				int currStartcurr.getStartPosition();
				int currEndcurrStart + curr.getLength();
				if (node == null || currStart < start && currEnd > end) {
					startcurrStart;
					endcurrEnd;
					nodecurr;
else if (currStart < start) {
					startcurrStart;
else if (currEnd > end) {
					endcurrEnd;
				}
			}
		}
		if (node != null) {
			int currStartnode.getStartPosition();
			int currEndcurrStart + node.getLength();
			while (start < currStart || end > currEnd) { // go up until a node covers all
				nodenode.getParent();
				currStartnode.getStartPosition();
				currEndcurrStart + node.getLength();
			}
			ASTNode parentnode.getParent(); // go up until a parent has different range
			while (parent != null && parent.getStartPosition() == node.getStartPosition() && parent.getLength() == node.getLength()) {
				nodeparent;
				parentnode.getParent();
			}
		}
		return node;
	}
	/*
	private void validateASTNotModified(ASTNode root) throws IllegalArgumentException {
		GenericVisitor isModifiedVisitor= new GenericVisitor() {
			protected boolean visitNode(ASTNode node) {
				if ((node.getFlags() & ASTNode.ORIGINAL) == 0) {
					throw new IllegalArgumentException("The AST that is rewritten must not be modified."); //$NON-NLS-1$
				}
				return true;
			}
		};
		root.accept(isModifiedVisitor);
	}
	*/

Removes the given node from its parent in this rewriter. The AST itself is not actually modified in any way; rather, the rewriter just records a note that this node should not be there.

Parameters:
node the node being removed. The node can either be an original node in the AST or (since 3.4) a new node already inserted or used as replacement in this AST rewriter.
editGroup the edit group in which to collect the corresponding text edits, or null if ungrouped
Throws:
IllegalArgumentException if the node is null, or if the node is not part of this rewriter's AST, or if the described modification is invalid (such as removing a required node)
	public final void remove(ASTNode node, TextEditGroup editGroup) {
		if (node == null) {
		}
		ASTNode parent;
		if (RewriteEventStore.isNewNode(node)) { // remove a new node, bug 164862
			if (location != null) {
				propertylocation.getProperty();
				parentlocation.getParent();
else {
				throw new IllegalArgumentException("Node is not part of the rewriter's AST"); //$NON-NLS-1$
			}
else {
			propertynode.getLocationInParent();
			parentnode.getParent();
		}
		if (property.isChildListProperty()) {
			getListRewrite(parent, (ChildListPropertyDescriptorproperty).remove(nodeeditGroup);
else {
			set(parentpropertynulleditGroup);
		}
	}

Replaces the given node in this rewriter. The replacement node must either be brand new (not part of the original AST) or a placeholder node (for example, one created by createCopyTarget(ASTNode) or createStringPlaceholder(String, int)). The AST itself is not actually modified in any way; rather, the rewriter just records a note that this node has been replaced.

Parameters:
node the node being replaced. The node can either be an original node in the AST or (since 3.4) a new node already inserted or used as replacement in this AST rewriter.
replacement the replacement node, or null if no replacement
editGroup the edit group in which to collect the corresponding text edits, or null if ungrouped
Throws:
IllegalArgumentException if the node is null, or if the node is not part of this rewriter's AST, or if the replacement node is not a new node (or placeholder), or if the described modification is otherwise invalid
	public final void replace(ASTNode nodeASTNode replacement, TextEditGroup editGroup) {
		if (node == null) {
		}
		ASTNode parent;
		if (RewriteEventStore.isNewNode(node)) { // replace a new node, bug 164862
			if (location != null) {
				propertylocation.getProperty();
				parentlocation.getParent();
else {
				throw new IllegalArgumentException("Node is not part of the rewriter's AST"); //$NON-NLS-1$
			}
else {
			propertynode.getLocationInParent();
			parentnode.getParent();
		}
		if (property.isChildListProperty()) {
			getListRewrite(parent, (ChildListPropertyDescriptorproperty).replace(nodereplacementeditGroup);
else {
			set(parentpropertyreplacementeditGroup);
		}
	}

Sets the given property of the given node. If the given property is a child property, the value must be a replacement node that is either be brand new (not part of the original AST) or a placeholder node (for example, one created by createCopyTarget(ASTNode) or createStringPlaceholder(String, int)); or it must be null, indicating that the child should be deleted. If the given property is a simple property, the value must be the new value (primitive types must be boxed) or null. The AST itself is not actually modified in any way; rather, the rewriter just records a note that this node has been changed in the specified way.

Parameters:
node the node
property the node's property; either a simple property or a child property
value the replacement child or new value, or null if none
editGroup the edit group in which to collect the corresponding text edits, or null if ungrouped
Throws:
IllegalArgumentException if the node or property is null, or if the node is not part of this rewriter's AST, or if the property is not a node property, or if the described modification is invalid
	public final void set(ASTNode nodeStructuralPropertyDescriptor propertyObject value, TextEditGroup editGroup) {
		if (node == null || property == null) {
		}
		validatePropertyType(propertyvalue);
		validateIsPropertyOfNode(propertynode);
		NodeRewriteEvent nodeEventthis..getNodeEvent(nodepropertytrue);
		nodeEvent.setNewValue(value);
		if (editGroup != null) {
			this..setEventEditGroup(nodeEventeditGroup);
		}
	}

Returns the value of the given property as managed by this rewriter. If the property has been removed, null is returned. If it has been replaced, the replacing value is returned. If the property has not been changed yet, the original value is returned.

For child list properties use ListRewrite.getRewrittenList() to get access to the rewritten nodes in a list.

Parameters:
node the node
property the node's property
Returns:
the value of the given property as managed by this rewriter
Since:
3.2
	public Object get(ASTNode nodeStructuralPropertyDescriptor property) {
		if (node == null || property == null) {
		}
		if (property.isChildListProperty()) {
			throw new IllegalArgumentException("Use the list rewriter to access nodes in a list"); //$NON-NLS-1$
		}
		return this..getNewValue(nodeproperty);
	}

Creates and returns a new rewriter for describing modifications to the given list property of the given node.

Parameters:
node the node
property the node's property; the child list property
Returns:
a new list rewriter object
Throws:
IllegalArgumentException if the node or property is null, or if the node is not part of this rewriter's AST, or if the property is not a node property, or if the described modification is invalid
	public final ListRewrite getListRewrite(ASTNode nodeChildListPropertyDescriptor property) {
		if (node == null || property == null) {
		}
		validateIsPropertyOfNode(propertynode);
		return new ListRewrite(thisnodeproperty);
	}

Returns the value of the named property of this rewrite, or null if none.

Parameters:
propertyName the property name
Returns:
the property value, or null if none
Throws:
IllegalArgumentException if the given property name is null
Since:
3.7
See also:
setProperty(String,Object)
	public final Object getProperty(String propertyName) {
		if (propertyName == null) {
		}
		if (this. == null) {
			// rewrite has no properties at all
			return null;
		}
		if (this. instanceof String) {
			// rewrite has only a single property
			if (propertyName.equals(this.)) {
				return this.;
else {
				return null;
			}
		}
		// otherwise rewrite has table of properties
		Map m = (Mapthis.;
		return m.get(propertyName);
	}

Returns an object that tracks the source range of the given node across the rewrite to its AST. Upon return, the result object reflects the given node's current source range in the AST. After rewrite is called, the result object is updated to reflect the given node's source range in the rewritten AST.

Parameters:
node the node to track
Returns:
an object that tracks the source range of node
Throws:
IllegalArgumentException if the node is null, or if the node is not part of this rewriter's AST, or if the node is already being tracked
	public final ITrackedNodePosition track(ASTNode node) {
		if (node == null) {
		}
		TextEditGroup groupthis..getTrackedNodeData(node);
		if (group == null) {
			groupnew TextEditGroup("internal"); //$NON-NLS-1$
			this..setTrackedNodeData(nodegroup);
		}
		return new TrackedNodePosition(groupnode);
	}
	private void validateIsExistingNode(ASTNode node) {
		if (node.getStartPosition() == -1) {
			throw new IllegalArgumentException("Node is not an existing node"); //$NON-NLS-1$
		}
	}
	private void validateIsCorrectAST(ASTNode node) {
		if (node.getAST() != getAST()) {
			throw new IllegalArgumentException("Node is not inside the AST"); //$NON-NLS-1$
		}
	}
		if (!property.isChildListProperty()) {
			String messageproperty.getId() + " is not a list property"//$NON-NLS-1$
			throw new IllegalArgumentException(message);
		}
	}
		if (!property.getNodeClass().isInstance(node)) {
			String messageproperty.getId() + " is not a property of type " + node.getClass().getName(); //$NON-NLS-1$
			throw new IllegalArgumentException(message);
		}
	}
		if (prop.isChildListProperty()) {
			String message = "Can not modify a list property, use getListRewrite()"//$NON-NLS-1$
			throw new IllegalArgumentException(message);
		}
			return;
		}
		if (value == null) {
					|| prop.isChildProperty() && ((ChildPropertyDescriptorprop).isMandatory()) {
				String message = "Can not remove property " + prop.getId(); //$NON-NLS-1$
				throw new IllegalArgumentException(message);
			}
else {
			Class valueType;
			if (prop.isSimpleProperty()) {
				valueType = p.getValueType();
				if (valueType == int.class) {
					valueType = Integer.class;
else if (valueType == boolean.class) {
					valueType = Boolean.class;
				}
else {
				valueType = p.getChildType();
			}
			if (!valueType.isAssignableFrom(value.getClass())) {
				String message = value.getClass().getName() + " is not a valid type for " + prop.getNodeClass().getName() //$NON-NLS-1$
" property '" + prop.getId() + '\''//$NON-NLS-1$
				throw new IllegalArgumentException(message);
			}
		}
	}

Creates and returns a placeholder node for a source string that is to be inserted into the output document at the position corresponding to the placeholder. The string will be inserted without being reformatted beyond correcting the indentation level. The placeholder node can either be inserted as new or used to replace an existing node.

Parameters:
code the string to be inserted; lines should should not have extra indentation
nodeType the ASTNode type that corresponds to the passed code.
Returns:
the new placeholder node
Throws:
IllegalArgumentException if the code is null, or if the node type is invalid
	public final ASTNode createStringPlaceholder(String codeint nodeType) {
		if (code == null) {
		}
		ASTNode placeholdergetNodeStore().newPlaceholderNode(nodeType);
		if (placeholder == null) {
			throw new IllegalArgumentException("String placeholder is not supported for type" + nodeType); //$NON-NLS-1$
		}
		return placeholder;
	}

Creates and returns a node that represents a sequence of nodes. Each of the given nodes must be either be brand new (not part of the original AST), or a placeholder node (for example, one created by createCopyTarget(ASTNode) or createStringPlaceholder(String, int)), or another group node. The type of the returned node is unspecified. The returned node can be used to replace an existing node (or as an element of another group node). When the document is rewritten, the source code for each of the given nodes is inserted, in order, into the output document at the position corresponding to the group (indentation is adjusted).

Parameters:
targetNodes the nodes to go in the group
Returns:
the new group node
Throws:
IllegalArgumentException if the targetNodes is null or empty
Since:
3.1
	public final ASTNode createGroupNode(ASTNode[] targetNodes) {
		if (targetNodes == null || targetNodes.length == 0) {
		}
		for (int i= 0; i < targetNodes.lengthi++) {
			listRewrite.insertLast(targetNodes[i], null);
		}
		return res;
	}
	private ASTNode createTargetNode(ASTNode nodeboolean isMove) {
		if (node == null) {
		}
		if (placeholder == null) {
			throw new IllegalArgumentException("Creating a target node is not supported for nodes of type" + node.getClass().getName()); //$NON-NLS-1$
		}
		getNodeStore().markAsCopyTarget(placeholderinfo);
		return placeholder;
	}

Creates and returns a placeholder node for a true copy of the given node. The placeholder node can either be inserted as new or used to replace an existing node. When the document is rewritten, a copy of the source code for the given node is inserted into the output document at the position corresponding to the placeholder (indentation is adjusted).

Parameters:
node the node to create a copy placeholder for
Returns:
the new placeholder node
Throws:
IllegalArgumentException if the node is null, or if the node is not part of this rewriter's AST
	public final ASTNode createCopyTarget(ASTNode node) {
		return createTargetNode(nodefalse);
	}

Creates and returns a placeholder node for the new locations of the given node. After obtaining a placeholder, the node must be removed or replaced. The placeholder node can either be inserted as new or used to replace an existing node. The placeholder must be used somewhere in the AST and must not be dropped by subsequent modifications. When the document is rewritten, the source code for the given node is inserted into the output document at the position corresponding to the placeholder (indentation is adjusted).

Parameters:
node the node to create a move placeholder for
Returns:
the new placeholder node
Throws:
IllegalArgumentException if the node is null, or if the node is not part of this rewriter's AST
	public final ASTNode createMoveTarget(ASTNode node) {
		return createTargetNode(nodetrue);
	}

Returns the extended source range computer for this AST rewriter. The default value is a new TargetSourceRangeComputer().

Returns:
an extended source range computer
Since:
3.1
See also:
setTargetSourceRangeComputer(TargetSourceRangeComputer)
		if (this. == null) {
			// lazy initialize
		}
	}

Sets the named property of this rewrite to the given value, or to null to clear it.

Clients should employ property names that are sufficiently unique to avoid inadvertent conflicts with other clients that might also be setting properties on the same rewrite.

Note that modifying a property is not considered a modification to the AST itself. This is to allow clients to decorate existing rewrites with their own properties without jeopardizing certain things (like the validity of bindings), which rely on the underlying tree remaining static.

Parameters:
propertyName the property name
data the new property value, or null if none
Throws:
IllegalArgumentException if the given property name is null
Since:
3.7
See also:
getProperty(String)
	public final void setProperty(String propertyNameObject data) {
		if (propertyName == null) {
		}
		if (this. == null) {
			// rewrite has no properties at all
			if (data == null) {
				// rewrite already knows this
				return;
			}
			// rewrite gets its fist property
			this. = propertyName;
			this. = data;
			return;
		}
		if (this. instanceof String) {
			// rewrite has only a single property
			if (propertyName.equals(this.)) {
				// we're in luck
				if (data == null) {
					// just delete last property
					this. = null;
					this. = null;
else {
					this. = data;
				}
				return;
			}
			if (data == null) {
				// we already know this
				return;
			}
			// rewrite already has one property - getting its second
			// convert to more flexible representation
			Map m = new HashMap(3);
			m.put(this.this.);
			m.put(propertyNamedata);
			this. = m;
			this. = null;
			return;
		}
		// rewrite has two or more properties
		Map m = (Mapthis.;
		if (data == null) {
			m.remove(propertyName);
			// check for just one property left
			if (m.size() == 1) {
				// convert to more efficient representation
				Map.Entry[] entries = (Map.Entry[]) m.entrySet().toArray(new Map.Entry[1]);
				this. = entries[0].getKey();
				this. = entries[0].getValue();
			}
			return;
else {
			m.put(propertyNamedata);
			// still has two or more properties
			return;
		}
	}

Sets a custom target source range computer for this AST rewriter. This is advanced feature to modify how comments are associated with nodes, which should be done only in special cases.

Parameters:
computer a target source range computer, or null to restore the default value of new TargetSourceRangeComputer()
Since:
3.1
See also:
getExtendedSourceRangeComputer()
		// if computer==null, rely on lazy init code in getExtendedSourceRangeComputer()
		this. = computer;
	}

Returns a string suitable for debugging purposes (only).

Returns:
a debug string
	public String toString() {
		buf.append("Events:\n"); //$NON-NLS-1$
		// be extra careful of uninitialized or mangled instances
		if (this. != null) {
		}
		return buf.toString();
	}
New to GrepCode? Check out our FAQ X