mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-04 14:55:41 +02:00
[Bug 273471] Child nodes on C++ class disappear on PE on an Undo action
This commit is contained in:
parent
09f3368f3e
commit
66ff1f285c
2 changed files with 63 additions and 45 deletions
|
@ -15,6 +15,7 @@ import java.util.Collections;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Stack;
|
import java.util.Stack;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.CCorePlugin;
|
import org.eclipse.cdt.core.CCorePlugin;
|
||||||
|
@ -94,6 +95,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
||||||
private final static boolean DEBUG= Util.isActive(DebugLogConstants.MODEL);
|
private final static boolean DEBUG= Util.isActive(DebugLogConstants.MODEL);
|
||||||
|
|
||||||
private final TranslationUnit fTranslationUnit;
|
private final TranslationUnit fTranslationUnit;
|
||||||
|
private final Map<ICElement, CElementInfo> fNewElements;
|
||||||
private final IProgressMonitor fProgressMonitor;
|
private final IProgressMonitor fProgressMonitor;
|
||||||
|
|
||||||
private ASTAccessVisibility fCurrentVisibility;
|
private ASTAccessVisibility fCurrentVisibility;
|
||||||
|
@ -104,10 +106,12 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
||||||
* Create a model builder for the given translation unit.
|
* Create a model builder for the given translation unit.
|
||||||
*
|
*
|
||||||
* @param tu the translation unit (must be a {@link TranslationUnit}
|
* @param tu the translation unit (must be a {@link TranslationUnit}
|
||||||
|
* @param newElements element cache
|
||||||
* @param monitor the progress monitor
|
* @param monitor the progress monitor
|
||||||
*/
|
*/
|
||||||
public CModelBuilder2(ITranslationUnit tu, IProgressMonitor monitor) {
|
public CModelBuilder2(ITranslationUnit tu, Map<ICElement, CElementInfo> newElements, IProgressMonitor monitor) {
|
||||||
fTranslationUnit= (TranslationUnit)tu;
|
fTranslationUnit= (TranslationUnit)tu;
|
||||||
|
fNewElements= newElements;
|
||||||
fProgressMonitor= monitor;
|
fProgressMonitor= monitor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,7 +132,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
||||||
}
|
}
|
||||||
checkCanceled();
|
checkCanceled();
|
||||||
long startTime= System.currentTimeMillis();
|
long startTime= System.currentTimeMillis();
|
||||||
final CElementInfo elementInfo= fTranslationUnit.getElementInfo();
|
final CElementInfo elementInfo= getElementInfo(fTranslationUnit);
|
||||||
int parseFlags= quickParseMode ? ITranslationUnit.AST_SKIP_ALL_HEADERS : ITranslationUnit.AST_SKIP_INDEXED_HEADERS;
|
int parseFlags= quickParseMode ? ITranslationUnit.AST_SKIP_ALL_HEADERS : ITranslationUnit.AST_SKIP_INDEXED_HEADERS;
|
||||||
if (!(elementInfo instanceof ASTHolderTUInfo)) {
|
if (!(elementInfo instanceof ASTHolderTUInfo)) {
|
||||||
parseFlags |= ITranslationUnit.AST_SKIP_FUNCTION_BODIES;
|
parseFlags |= ITranslationUnit.AST_SKIP_FUNCTION_BODIES;
|
||||||
|
@ -158,7 +162,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
||||||
buildModel(ast);
|
buildModel(ast);
|
||||||
elementInfo.setIsStructureKnown(true);
|
elementInfo.setIsStructureKnown(true);
|
||||||
if (DEBUG) Util.debugLog("CModelBuilder2: building " //$NON-NLS-1$
|
if (DEBUG) Util.debugLog("CModelBuilder2: building " //$NON-NLS-1$
|
||||||
+"children="+ fTranslationUnit.getElementInfo().internalGetChildren().size() //$NON-NLS-1$
|
+"children="+ elementInfo.internalGetChildren().size() //$NON-NLS-1$
|
||||||
+" time="+ (System.currentTimeMillis() - startTime) + "ms", //$NON-NLS-1$ //$NON-NLS-2$
|
+" time="+ (System.currentTimeMillis() - startTime) + "ms", //$NON-NLS-1$ //$NON-NLS-2$
|
||||||
DebugLogConstants.MODEL, false);
|
DebugLogConstants.MODEL, false);
|
||||||
|
|
||||||
|
@ -219,20 +223,16 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
||||||
fEqualElements.clear();
|
fEqualElements.clear();
|
||||||
|
|
||||||
// sort by offset
|
// sort by offset
|
||||||
final List<ICElement> children= fTranslationUnit.getElementInfo().internalGetChildren();
|
final List<ICElement> children= getElementInfo(fTranslationUnit).internalGetChildren();
|
||||||
Collections.sort(children, new Comparator<ICElement>() {
|
Collections.sort(children, new Comparator<ICElement>() {
|
||||||
public int compare(ICElement o1, ICElement o2) {
|
public int compare(ICElement o1, ICElement o2) {
|
||||||
try {
|
final SourceManipulationInfo info1= getSourceManipulationInfo((SourceManipulation) o1);
|
||||||
final SourceManipulationInfo info1= ((SourceManipulation) o1).getSourceManipulationInfo();
|
final SourceManipulationInfo info2= getSourceManipulationInfo((SourceManipulation) o2);
|
||||||
final SourceManipulationInfo info2= ((SourceManipulation) o2).getSourceManipulationInfo();
|
|
||||||
int delta= info1.getStartPos() - info2.getStartPos();
|
int delta= info1.getStartPos() - info2.getStartPos();
|
||||||
if (delta == 0) {
|
if (delta == 0) {
|
||||||
delta= info1.getIdStartPos() - info2.getIdStartPos();
|
delta= info1.getIdStartPos() - info2.getIdStartPos();
|
||||||
}
|
}
|
||||||
return delta;
|
return delta;
|
||||||
} catch (CModelException exc) {
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}});
|
}});
|
||||||
|
|
||||||
if (isCanceled()) {
|
if (isCanceled()) {
|
||||||
|
@ -553,21 +553,22 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
||||||
}
|
}
|
||||||
setIndex(element);
|
setIndex(element);
|
||||||
element.setActive(elaboratedTypeSpecifier.isActive());
|
element.setActive(elaboratedTypeSpecifier.isActive());
|
||||||
element.setTypeName(type);
|
StructureInfo info= (StructureInfo) getElementInfo(element);
|
||||||
|
info.setTypeName(type);
|
||||||
|
|
||||||
// add to parent
|
// add to parent
|
||||||
parent.addChild(element);
|
parent.addChild(element);
|
||||||
|
|
||||||
// set positions
|
// set positions
|
||||||
if (className.length() > 0) {
|
if (className.length() > 0) {
|
||||||
setIdentifierPosition(element, astClassName);
|
setIdentifierPosition(info, astClassName);
|
||||||
} else {
|
} else {
|
||||||
final IASTFileLocation classLocation= getMinFileLocation(elaboratedTypeSpecifier.getNodeLocations());
|
final IASTFileLocation classLocation= getMinFileLocation(elaboratedTypeSpecifier.getNodeLocations());
|
||||||
if (classLocation != null) {
|
if (classLocation != null) {
|
||||||
element.setIdPos(classLocation.getNodeOffset(), type.length());
|
info.setIdPos(classLocation.getNodeOffset(), type.length());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setBodyPosition(element, elaboratedTypeSpecifier);
|
setBodyPosition(info, elaboratedTypeSpecifier);
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -586,15 +587,16 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
||||||
for (final IASTEnumerator enumerator : enumerators) {
|
for (final IASTEnumerator enumerator : enumerators) {
|
||||||
createEnumerator(element, enumerator);
|
createEnumerator(element, enumerator);
|
||||||
}
|
}
|
||||||
|
EnumerationInfo info= (EnumerationInfo) getElementInfo(element);
|
||||||
// set enumeration position
|
// set enumeration position
|
||||||
if (astEnumName != null && enumName.length() > 0) {
|
if (astEnumName != null && enumName.length() > 0) {
|
||||||
setIdentifierPosition(element, astEnumName);
|
setIdentifierPosition(info, astEnumName);
|
||||||
} else {
|
} else {
|
||||||
final IASTFileLocation enumLocation= enumSpecifier.getFileLocation();
|
final IASTFileLocation enumLocation= enumSpecifier.getFileLocation();
|
||||||
element.setIdPos(enumLocation.getNodeOffset(), type.length());
|
info.setIdPos(enumLocation.getNodeOffset(), type.length());
|
||||||
}
|
}
|
||||||
setBodyPosition(element, enumSpecifier);
|
setBodyPosition(info, enumSpecifier);
|
||||||
element.setTypeName(type);
|
info.setTypeName(type);
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -682,20 +684,21 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
element.setTypeName(type);
|
StructureInfo info= (StructureInfo) getElementInfo(element);
|
||||||
|
info.setTypeName(type);
|
||||||
|
|
||||||
// add to parent
|
// add to parent
|
||||||
parent.addChild(element);
|
parent.addChild(element);
|
||||||
// set positions
|
// set positions
|
||||||
if(!isTemplate){
|
if(!isTemplate){
|
||||||
setBodyPosition(element, compositeTypeSpecifier);
|
setBodyPosition(info, compositeTypeSpecifier);
|
||||||
}
|
}
|
||||||
if (className.length() > 0) {
|
if (className.length() > 0) {
|
||||||
setIdentifierPosition(element, astClassName);
|
setIdentifierPosition(info, astClassName);
|
||||||
} else {
|
} else {
|
||||||
final IASTFileLocation classLocation= getMinFileLocation(compositeTypeSpecifier.getNodeLocations());
|
final IASTFileLocation classLocation= getMinFileLocation(compositeTypeSpecifier.getNodeLocations());
|
||||||
if (classLocation != null) {
|
if (classLocation != null) {
|
||||||
element.setIdPos(classLocation.getNodeOffset(), type.length());
|
info.setIdPos(classLocation.getNodeOffset(), type.length());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// add members
|
// add members
|
||||||
|
@ -736,7 +739,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
||||||
parent.addChild(element);
|
parent.addChild(element);
|
||||||
|
|
||||||
// set positions
|
// set positions
|
||||||
final SourceManipulationInfo info= element.getSourceManipulationInfo();
|
final SourceManipulationInfo info= getSourceManipulationInfo(element);
|
||||||
if (name.length() > 0) {
|
if (name.length() > 0) {
|
||||||
setIdentifierPosition(info, astTypedefName);
|
setIdentifierPosition(info, astTypedefName);
|
||||||
} else {
|
} else {
|
||||||
|
@ -773,8 +776,8 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
||||||
final ICPPASTDeclSpecifier cppSpecifier= (ICPPASTDeclSpecifier)specifier;
|
final ICPPASTDeclSpecifier cppSpecifier= (ICPPASTDeclSpecifier)specifier;
|
||||||
newElement.setMutable(cppSpecifier.getStorageClass() == ICPPASTDeclSpecifier.sc_mutable);
|
newElement.setMutable(cppSpecifier.getStorageClass() == ICPPASTDeclSpecifier.sc_mutable);
|
||||||
}
|
}
|
||||||
newElement.setTypeName(ASTStringUtil.getSignatureString(specifier, declarator));
|
final FieldInfo fieldInfo= (FieldInfo)getElementInfo(newElement);
|
||||||
final FieldInfo fieldInfo= (FieldInfo)newElement.getElementInfo();
|
fieldInfo.setTypeName(ASTStringUtil.getSignatureString(specifier, declarator));
|
||||||
fieldInfo.setVisibility(getCurrentVisibility());
|
fieldInfo.setVisibility(getCurrentVisibility());
|
||||||
element= newElement;
|
element= newElement;
|
||||||
info= fieldInfo;
|
info= fieldInfo;
|
||||||
|
@ -795,8 +798,9 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setIndex(element);
|
setIndex(element);
|
||||||
element.setTypeName(ASTStringUtil.getSignatureString(specifier, declarator));
|
VariableInfo varInfo= (VariableInfo) getElementInfo(element);
|
||||||
info= element.getSourceManipulationInfo();
|
varInfo.setTypeName(ASTStringUtil.getSignatureString(specifier, declarator));
|
||||||
|
info= varInfo;
|
||||||
}
|
}
|
||||||
element.setActive(declarator.isActive());
|
element.setActive(declarator.isActive());
|
||||||
element.setConst(specifier.isConst());
|
element.setConst(specifier.isConst());
|
||||||
|
@ -888,7 +892,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
||||||
methodElement.setConst(cppFunctionDeclarator.isConst());
|
methodElement.setConst(cppFunctionDeclarator.isConst());
|
||||||
setIndex(element);
|
setIndex(element);
|
||||||
|
|
||||||
final MethodInfo methodInfo= methodElement.getMethodInfo();
|
final MethodInfo methodInfo= (MethodInfo) getElementInfo(methodElement);
|
||||||
info= methodInfo;
|
info= methodInfo;
|
||||||
ICPPMethod methodBinding= null;
|
ICPPMethod methodBinding= null;
|
||||||
if (scope != null) {
|
if (scope != null) {
|
||||||
|
@ -952,7 +956,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
||||||
element.setReturnType(returnType);
|
element.setReturnType(returnType);
|
||||||
setIndex(element);
|
setIndex(element);
|
||||||
|
|
||||||
info= element.getFunctionInfo();
|
info= (FunctionInfo) getElementInfo(element);
|
||||||
info.setConst(cppFunctionDeclarator.isConst());
|
info.setConst(cppFunctionDeclarator.isConst());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -963,7 +967,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
||||||
element.setReturnType(returnType);
|
element.setReturnType(returnType);
|
||||||
setIndex(element);
|
setIndex(element);
|
||||||
|
|
||||||
info= element.getFunctionInfo();
|
info= (FunctionInfo) getElementInfo(element);
|
||||||
}
|
}
|
||||||
element.setActive(functionDeclaration.isActive());
|
element.setActive(functionDeclaration.isActive());
|
||||||
|
|
||||||
|
@ -1015,7 +1019,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
||||||
methodElement.setReturnType(returnType);
|
methodElement.setReturnType(returnType);
|
||||||
methodElement.setConst(cppFunctionDeclarator.isConst());
|
methodElement.setConst(cppFunctionDeclarator.isConst());
|
||||||
setIndex(element);
|
setIndex(element);
|
||||||
final MethodInfo methodInfo= methodElement.getMethodInfo();
|
final MethodInfo methodInfo= (MethodInfo) getElementInfo(methodElement);
|
||||||
info= methodInfo;
|
info= methodInfo;
|
||||||
if (declSpecifier instanceof ICPPASTDeclSpecifier) {
|
if (declSpecifier instanceof ICPPASTDeclSpecifier) {
|
||||||
final ICPPASTDeclSpecifier cppDeclSpecifier= (ICPPASTDeclSpecifier)declSpecifier;
|
final ICPPASTDeclSpecifier cppDeclSpecifier= (ICPPASTDeclSpecifier)declSpecifier;
|
||||||
|
@ -1038,7 +1042,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
||||||
element.setReturnType(returnType);
|
element.setReturnType(returnType);
|
||||||
setIndex(element);
|
setIndex(element);
|
||||||
|
|
||||||
info= (FunctionInfo)element.getElementInfo();
|
info= (FunctionInfo)getElementInfo(element);
|
||||||
info.setConst(cppFunctionDeclarator.isConst());
|
info.setConst(cppFunctionDeclarator.isConst());
|
||||||
}
|
}
|
||||||
} else if (declarator instanceof IASTStandardFunctionDeclarator) {
|
} else if (declarator instanceof IASTStandardFunctionDeclarator) {
|
||||||
|
@ -1051,7 +1055,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
||||||
element.setReturnType(returnType);
|
element.setReturnType(returnType);
|
||||||
setIndex(element);
|
setIndex(element);
|
||||||
|
|
||||||
info= (FunctionInfo)element.getElementInfo();
|
info= (FunctionInfo)getElementInfo(element);
|
||||||
} else {
|
} else {
|
||||||
assert false;
|
assert false;
|
||||||
return null;
|
return null;
|
||||||
|
@ -1103,6 +1107,19 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private CElementInfo getElementInfo(CElement cElement) {
|
||||||
|
CElementInfo info = fNewElements.get(cElement);
|
||||||
|
if (info == null) {
|
||||||
|
info = cElement.createElementInfo();
|
||||||
|
fNewElements.put(cElement, info);
|
||||||
|
}
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
private SourceManipulationInfo getSourceManipulationInfo(SourceManipulation cElement) {
|
||||||
|
return (SourceManipulationInfo) getElementInfo(cElement);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility method to set the body position of an element from an AST node.
|
* Utility method to set the body position of an element from an AST node.
|
||||||
*
|
*
|
||||||
|
@ -1111,7 +1128,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
||||||
* @throws CModelException
|
* @throws CModelException
|
||||||
*/
|
*/
|
||||||
private void setBodyPosition(SourceManipulation element, IASTNode astNode) throws CModelException {
|
private void setBodyPosition(SourceManipulation element, IASTNode astNode) throws CModelException {
|
||||||
setBodyPosition(element.getSourceManipulationInfo(), astNode);
|
setBodyPosition(getSourceManipulationInfo(element), astNode);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1150,7 +1167,7 @@ public class CModelBuilder2 implements IContributedModelBuilder {
|
||||||
* @throws CModelException
|
* @throws CModelException
|
||||||
*/
|
*/
|
||||||
private void setIdentifierPosition(SourceManipulation element, IASTName astName) throws CModelException {
|
private void setIdentifierPosition(SourceManipulation element, IASTName astName) throws CModelException {
|
||||||
setIdentifierPosition(element.getSourceManipulationInfo(), astName);
|
setIdentifierPosition(getSourceManipulationInfo(element), astName);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -429,11 +429,6 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
|
||||||
protected boolean buildStructure(OpenableInfo info, IProgressMonitor pm, Map<ICElement, CElementInfo> newElements, IResource underlyingResource) throws CModelException {
|
protected boolean buildStructure(OpenableInfo info, IProgressMonitor pm, Map<ICElement, CElementInfo> newElements, IResource underlyingResource) throws CModelException {
|
||||||
TranslationUnitInfo unitInfo = (TranslationUnitInfo) info;
|
TranslationUnitInfo unitInfo = (TranslationUnitInfo) info;
|
||||||
|
|
||||||
// We reuse the general info cache in the CModelBuilder, We should not do this
|
|
||||||
// and instead create the info explicitly(see JDT).
|
|
||||||
// So to get by we need to remove in the LRU all the info of this handle
|
|
||||||
CModelManager.getDefault().removeChildrenInfo(this);
|
|
||||||
|
|
||||||
// generate structure
|
// generate structure
|
||||||
this.parse(newElements, pm);
|
this.parse(newElements, pm);
|
||||||
|
|
||||||
|
@ -665,7 +660,7 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
|
||||||
*/
|
*/
|
||||||
private void parseUsingCModelBuilder(Map<ICElement, CElementInfo> newElements, boolean quickParseMode, IProgressMonitor monitor) {
|
private void parseUsingCModelBuilder(Map<ICElement, CElementInfo> newElements, boolean quickParseMode, IProgressMonitor monitor) {
|
||||||
try {
|
try {
|
||||||
new CModelBuilder2(this, monitor).parse(quickParseMode);
|
new CModelBuilder2(this, newElements, monitor).parse(quickParseMode);
|
||||||
} catch (OperationCanceledException oce) {
|
} catch (OperationCanceledException oce) {
|
||||||
if (isWorkingCopy()) {
|
if (isWorkingCopy()) {
|
||||||
throw oce;
|
throw oce;
|
||||||
|
@ -677,6 +672,12 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseUsingContributedModelBuilder(IContributedModelBuilder mb, boolean quickParseMode, IProgressMonitor monitor) {
|
private void parseUsingContributedModelBuilder(IContributedModelBuilder mb, boolean quickParseMode, IProgressMonitor monitor) {
|
||||||
|
// We did reuse the shared info cache in the internal model builder.
|
||||||
|
// This has been fixed (bug 273471).
|
||||||
|
// Contributed model builders cannot apply the same fix.
|
||||||
|
// So to get by we need to remove in the LRU all the info of this handle.
|
||||||
|
// This might result in a race condition as observed in bug 273471.
|
||||||
|
CModelManager.getDefault().removeChildrenInfo(this);
|
||||||
try {
|
try {
|
||||||
mb.parse(quickParseMode);
|
mb.parse(quickParseMode);
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|
Loading…
Add table
Reference in a new issue