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:
parent
c6e1d1e6ab
commit
0603a4dc4d
1 changed files with 31 additions and 56 deletions
|
@ -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,9 +770,7 @@ 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);
|
|
||||||
if (sibling != null)
|
|
||||||
return sibling;
|
return sibling;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
if (sibling == null) {
|
||||||
|
IASTNode parent = node.getParent();
|
||||||
|
if (offset(parent) >= endOffset(statement))
|
||||||
|
return null;
|
||||||
return statement;
|
return statement;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return getPreviousSiblingNode(node);
|
return endOffset(originalSibling) >= endOffset(statement) ? sibling : statement;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IASTNode getNextSiblingNode(IASTNode node) {
|
private IASTNode getNextSiblingNode(IASTNode node) {
|
||||||
|
@ -823,9 +823,7 @@ 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);
|
|
||||||
if (sibling != null)
|
|
||||||
return sibling;
|
return sibling;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 sibling;
|
||||||
|
}
|
||||||
|
if (sibling == null) {
|
||||||
|
IASTNode parent = node.getParent();
|
||||||
|
if (endOffset(parent) <= offset(statement))
|
||||||
|
return null;
|
||||||
return statement;
|
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
Loading…
Add table
Reference in a new issue