1
0
Fork 0
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:
Anton Leherbauer 2009-04-28 12:07:18 +00:00
parent 09f3368f3e
commit 66ff1f285c
2 changed files with 63 additions and 45 deletions

View file

@ -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);
} }
/** /**

View file

@ -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) {