1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Fixed an infinite loop reported by Joseph Paul Cohen.

This commit is contained in:
Sergey Prigogin 2012-07-11 15:01:17 -07:00
parent c6e1d1e6ab
commit 0603a4dc4d

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2008, 2011 Institute for Software, HSR Hochschule fuer Technik * Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik
* Rapperswil, University of applied sciences and others * Rapperswil, University of applied sciences and others
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
@ -37,7 +37,6 @@ import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNodeSelector;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator; import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement; import org.eclipse.cdt.core.dom.ast.IASTPreprocessorStatement;
@ -771,10 +770,8 @@ public class ChangeGenerator extends ASTVisitor {
IASTNode sibling = siblings[i]; IASTNode sibling = siblings[i];
if (sibling == node) { if (sibling == node) {
beforeNode = true; beforeNode = true;
} else if (beforeNode) { } else if (beforeNode && getReplacementNode(sibling) != null) {
sibling = getReplacementNode(sibling); return sibling;
if (sibling != null)
return sibling;
} }
} }
return null; return null;
@ -795,18 +792,21 @@ public class ChangeGenerator extends ASTVisitor {
low = mid + 1; low = mid + 1;
} }
} }
low--; IASTNode statement = --low >= 0 ? preprocessorStatements[low] : null;
if (low >= 0) {
IASTNode statement = preprocessorStatements[low]; IASTNode originalSibling = getPreviousSiblingNode(node);
if (statement.isPartOfTranslationUnitFile()) { IASTNode sibling = originalSibling == null ? null : getReplacementNode(originalSibling);
int endOffset = endOffset(statement); if (statement == null || !statement.isPartOfTranslationUnitFile()) {
if (!doesRegionContainNode(ast, endOffset, offset - endOffset)) { return sibling;
return statement; }
} if (sibling == null) {
} IASTNode parent = node.getParent();
if (offset(parent) >= endOffset(statement))
return null;
return statement;
} }
return getPreviousSiblingNode(node); return endOffset(originalSibling) >= endOffset(statement) ? sibling : statement;
} }
private IASTNode getNextSiblingNode(IASTNode node) { private IASTNode getNextSiblingNode(IASTNode node) {
@ -823,10 +823,8 @@ public class ChangeGenerator extends ASTVisitor {
for (IASTNode sibling : siblings) { for (IASTNode sibling : siblings) {
if (sibling == node) { if (sibling == node) {
beforeNode = true; beforeNode = true;
} else if (beforeNode) { } else if (beforeNode && getReplacementNode(sibling) != null) {
sibling = getReplacementNode(sibling); return sibling;
if (sibling != null)
return sibling;
} }
} }
return null; return null;
@ -847,44 +845,21 @@ public class ChangeGenerator extends ASTVisitor {
low = mid + 1; low = mid + 1;
} }
} }
if (high < preprocessorStatements.length) { IASTNode statement = high < preprocessorStatements.length ? preprocessorStatements[high] : null;
IASTNode statement = preprocessorStatements[high];
if (statement.isPartOfTranslationUnitFile()) { IASTNode originalSibling = getNextSiblingNode(node);
int offset = offset(statement); IASTNode sibling = originalSibling == null ? null : getReplacementNode(originalSibling);
if (!doesRegionContainNode(ast, endOffset, offset - endOffset)) { if (statement == null || !statement.isPartOfTranslationUnitFile()) {
return statement; return sibling;
} }
} if (sibling == null) {
IASTNode parent = node.getParent();
if (endOffset(parent) <= offset(statement))
return null;
return statement;
} }
return getNextSiblingNode(node); return offset(originalSibling) <= offset(statement) ? sibling : statement;
}
/**
* Checks if a given region contains at least a piece of a node after rewrite.
*/
private boolean doesRegionContainNode(IASTTranslationUnit ast, int offset, int length) {
IASTNodeSelector nodeSelector = ast.getNodeSelector(ast.getFilePath());
while (length > 0) {
IASTNode node = nodeSelector.findFirstContainedNode(offset, length - 1);
if (node == null)
return false;
if (!isNodeRemoved(node))
return true;
int oldOffset = offset;
offset = endOffset(node);
length -= offset - oldOffset;
}
return false;
}
private boolean isNodeRemoved(IASTNode node) {
do {
if (getReplacementNode(node) == null)
return true;
} while ((node = node.getParent()) != null);
return false;
} }
/** /**