public boolean forFriendship() { if (astName == null) return false; IASTNode node = astName.getParent(); while (node instanceof IASTName) node = node.getParent(); IASTDeclaration decl = null; IASTDeclarator dtor = null; if (node instanceof ICPPASTDeclSpecifier && node.getParent() instanceof IASTDeclaration) { decl = (IASTDeclaration) node.getParent(); } else if (node instanceof IASTDeclarator) { dtor = (IASTDeclarator) node; while (dtor.getParent() instanceof IASTDeclarator) dtor = (IASTDeclarator) dtor.getParent(); if (!(dtor.getParent() instanceof IASTDeclaration)) return false; decl = (IASTDeclaration) dtor.getParent(); } else { return false; } if (decl instanceof IASTSimpleDeclaration) { IASTSimpleDeclaration simple = (IASTSimpleDeclaration) decl; if (!((ICPPASTDeclSpecifier) simple.getDeclSpecifier()).isFriend()) return false; if (dtor != null) return true; return simple.getDeclarators().length == 0; } else if (decl instanceof IASTFunctionDefinition) { IASTFunctionDefinition fnDef = (IASTFunctionDefinition) decl; if (!((ICPPASTDeclSpecifier) fnDef.getDeclSpecifier()).isFriend()) return false; return (dtor != null); } return false; }
@Override public int getAdditionalNameFlags(int standardFlags, IASTName name) { if ((standardFlags & PDOMName.IS_REFERENCE) == PDOMName.IS_REFERENCE) { IASTNode parent = name.getParent(); if (parent instanceof ICPPASTQualifiedName) { // When taking the address of a method it will be called without suppressing // the virtual mechanism parent = parent.getParent(); if (parent instanceof IASTIdExpression) { parent = parent.getParent(); if (parent instanceof IASTUnaryExpression) { if (((IASTUnaryExpression) parent).getOperator() == IASTUnaryExpression.op_amper) return PDOMName.COULD_BE_POLYMORPHIC_METHOD_CALL; } } } else if (parent instanceof ICPPASTFieldReference) { // The name is not qualified ICPPASTFieldReference fr = (ICPPASTFieldReference) parent; parent = parent.getParent(); if (parent instanceof IASTFunctionCallExpression) { // v->member() if (fr.isPointerDereference()) { return PDOMName.COULD_BE_POLYMORPHIC_METHOD_CALL; } // v.member() IASTExpression fieldOwner = fr.getFieldOwner(); if (fieldOwner.getValueCategory().isGLValue()) { while (fieldOwner instanceof IASTUnaryExpression && ((IASTUnaryExpression) fieldOwner).getOperator() == IASTUnaryExpression.op_bracketedPrimary) fieldOwner = ((IASTUnaryExpression) fieldOwner).getOperand(); if (fieldOwner instanceof IASTIdExpression) { IBinding b = ((IASTIdExpression) fieldOwner).getName().resolveBinding(); if (b instanceof IVariable) { IType t = ((IVariable) b).getType(); if (!(t instanceof ICPPReferenceType)) { return 0; } } } return PDOMName.COULD_BE_POLYMORPHIC_METHOD_CALL; } } } else if (parent instanceof IASTIdExpression) { // Calling a member from within a member if (parent.getParent() instanceof IASTFunctionCallExpression) { return PDOMName.COULD_BE_POLYMORPHIC_METHOD_CALL; } } } return 0; }
/** * Returns the list of nodes the given node is part of, for example function parameters if the * node is a parameter. * * @param node the node possibly belonging to a list. * @return the list of nodes containing the given node, or <code>null</code> if the node does not * belong to a list */ private IASTNode[] getContainingNodeList(IASTNode node) { if (node.getPropertyInParent() == IASTStandardFunctionDeclarator.FUNCTION_PARAMETER) { return ((IASTStandardFunctionDeclarator) node.getParent()).getParameters(); } else if (node.getPropertyInParent() == IASTExpressionList.NESTED_EXPRESSION) { return ((IASTExpressionList) node.getParent()).getExpressions(); } else if (node.getPropertyInParent() == ICPPASTFunctionDefinition.MEMBER_INITIALIZER) { return ((ICPPASTFunctionDefinition) node.getParent()).getMemberInitializers(); } else if (node.getPropertyInParent() == ICPPASTFunctionDeclarator.EXCEPTION_TYPEID) { return ((ICPPASTFunctionDeclarator) node.getParent()).getExceptionSpecification(); } return null; }
private boolean isNodeRemoved(IASTNode node) { do { if (getReplacementNode(node) == null) return true; } while ((node = node.getParent()) != null); return false; }
public void replace(IASTNode child, IASTNode other) { if (child == declarator) { other.setPropertyInParent(child.getPropertyInParent()); other.setParent(child.getParent()); declarator = (IASTDeclarator) other; } }
private IASTCompositeTypeSpecifier getCompositeTypeSpecifier(IASTName selectedName) { IASTNode node = selectedName; while (node != null && !(node instanceof IASTCompositeTypeSpecifier)) { node = node.getParent(); } return (IASTCompositeTypeSpecifier) node; }
/** * return null if the algorithm should stop (monitor was cancelled) return DOMASTNodeLeafContinue * if the algorithm should continue but no valid DOMASTNodeLeaf was added (i.e. node was null * return the DOMASTNodeLeaf added to the DOM AST View's model otherwise * * @param node * @return */ private DOMASTNodeLeaf addRoot(IASTNode node) { if (monitor != null && monitor.isCanceled()) return null; if (node == null) return new DOMASTNodeLeafContinue(null); // only do length check for ASTNode (getNodeLocations on PreprocessorStatements is very // expensive) if (node instanceof ASTNode && ((ASTNode) node).getLength() <= 0) return new DOMASTNodeLeafContinue(null); DOMASTNodeParent parent = null; // if it's a preprocessor statement being merged then do a special search for parent (no search) if (node instanceof IASTPreprocessorStatement) { parent = root; } else { IASTNode tempParent = node.getParent(); if (tempParent instanceof IASTPreprocessorStatement) { parent = root.findTreeParentForMergedNode(node); } else { parent = root.findTreeParentForNode(node); } } if (parent == null) parent = root; return createNode(parent, node); }
@Override protected int rwAnyNode(IASTNode node, int indirection) { final IASTNode parent = node.getParent(); if (parent instanceof ICPPASTConstructorInitializer) { return rwInCtorInitializer(node, indirection, (ICPPASTConstructorInitializer) parent); } return super.rwAnyNode(node, indirection); }
@Override public void replace(IASTNode child, IASTNode other) { if (child == nested) { other.setPropertyInParent(child.getPropertyInParent()); other.setParent(child.getParent()); nested = (IASTDeclarator) other; } }
public boolean isFunctionCall() { if (astName == null) return false; if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false; IASTNode p1 = astName.getParent(); if (p1 instanceof ICPPASTQualifiedName) p1 = p1.getParent(); return (p1 instanceof IASTIdExpression && p1.getPropertyInParent() == IASTFunctionCallExpression.FUNCTION_NAME); }
@Override public void replace(IASTNode child, IASTNode other) { if (child == operand) { other.setPropertyInParent(child.getPropertyInParent()); other.setParent(child.getParent()); operand = (IASTExpression) other; } }
private void handleReplace(IASTNode node) { List<ASTModification> modifications = getModifications(node, ModificationKind.REPLACE); String source = node.getTranslationUnit().getRawSignature(); TextEdit edit; ChangeGeneratorWriterVisitor writer = new ChangeGeneratorWriterVisitor(modificationStore, commentMap); IASTFileLocation fileLocation = node.getFileLocation(); Integer val = sourceOffsets.get(fileLocation.getFileName()); int processedOffset = val != null ? val.intValue() : 0; if (modifications.size() == 1 && modifications.get(0).getNewNode() == null) { int offset = getOffsetIncludingComments(node); int endOffset = getEndOffsetIncludingComments(node); offset = Math.max(skipPrecedingBlankLines(source, offset), processedOffset); endOffset = skipTrailingBlankLines(source, endOffset); IASTNode[] siblingsList = getContainingNodeList(node); if (siblingsList != null) { if (siblingsList.length > 1) { if (node == siblingsList[0]) { endOffset = skipToTrailingDelimiter(source, ',', endOffset); } else { offset = skipToPrecedingDelimiter(source, ',', offset); } } else if (node.getPropertyInParent() == ICPPASTFunctionDefinition.MEMBER_INITIALIZER) { offset = skipToPrecedingDelimiter(source, ':', offset); } } IASTNode prevNode = getPreviousSiblingOrPreprocessorNode(node); IASTNode nextNode = getNextSiblingOrPreprocessorNode(node); if (prevNode != null && nextNode != null) { if (ASTWriter.requireBlankLineInBetween(prevNode, nextNode)) { writer.newLine(); } } else if (node.getParent() instanceof ICPPASTNamespaceDefinition) { writer.newLine(); } String code = writer.toString(); edit = new ReplaceEdit(offset, endOffset - offset, code); } else { node.accept(writer); String code = writer.toString(); int offset = fileLocation.getNodeOffset(); int endOffset = offset + fileLocation.getNodeLength(); if (node instanceof IASTStatement || node instanceof IASTDeclaration) { // Include trailing comments in the area to be replaced. endOffset = Math.max(endOffset, getEndOffsetIncludingTrailingComments(node)); } String lineSeparator = writer.getScribe().getLineSeparator(); if (code.endsWith(lineSeparator)) { code = code.substring(0, code.length() - lineSeparator.length()); } edit = new ReplaceEdit(offset, endOffset - offset, code); } IFile file = FileHelper.getFileFromNode(node); MultiTextEdit parentEdit = getEdit(node, file); parentEdit.addChild(edit); sourceOffsets.put(fileLocation.getFileName(), edit.getExclusiveEnd()); }
private void checkBelongsToAST(IASTNode node) { while (node != null) { node = node.getParent(); if (node == fRoot) { return; } } throw new IllegalArgumentException(); }
@Override public void replace(IASTNode child, IASTNode other) { if (thenClause == child) { other.setParent(child.getParent()); other.setPropertyInParent(child.getPropertyInParent()); thenClause = (IASTStatement) other; } else if (elseClause == child) { other.setParent(child.getParent()); other.setPropertyInParent(child.getPropertyInParent()); elseClause = (IASTStatement) other; } else if (condition == child || condDecl == child) { if (other instanceof IASTExpression) { setConditionExpression((IASTExpression) other); } else if (other instanceof IASTDeclaration) { setConditionDeclaration((IASTDeclaration) other); } } }
/** Returns whether the name belongs to a simple declaration or function definition. */ public IASTDeclaration forDeclaration() { IASTNode node = getDeclarator(); while (node instanceof IASTDeclarator) node = node.getParent(); if (node instanceof IASTSimpleDeclaration || node instanceof IASTFunctionDefinition) return (IASTDeclaration) node; return null; }
public boolean checkAssociatedScopes() { IASTName name = astName; if (name == null || name instanceof ICPPASTQualifiedName) return false; IASTNode parent = name.getParent(); if (name.getPropertyInParent() == ICPPASTTemplateId.TEMPLATE_NAME) parent = parent.getParent(); if (parent instanceof ICPPASTQualifiedName) { return false; } return isFunctionCall(); }
private IASTFunctionDeclarator findDeclaratorInAncestors(IASTNode node) { while (node != null) { IASTFunctionDeclarator declarator = extractDeclarator(node); if (node instanceof ICPPASTTemplateDeclaration) { declarator = extractDeclarator(((ICPPASTTemplateDeclaration) node).getDeclaration()); } if (declarator != null) { return declarator; } node = node.getParent(); } return null; }
@Override public void replace(IASTNode child, IASTNode other) { assert child.isActive() == other.isActive(); for (int i = 0; i <= fLastDeclaration; ++i) { if (fAllDeclarations[i] == child) { other.setParent(child.getParent()); other.setPropertyInParent(child.getPropertyInParent()); fAllDeclarations[i] = (IASTDeclaration) other; fActiveDeclarations = null; break; } } }
@Override public void replace(IASTNode child, IASTNode other) { if (body == child) { other.setPropertyInParent(child.getPropertyInParent()); other.setParent(child.getParent()); body = (IASTStatement) other; } if (child == init) { other.setPropertyInParent(child.getPropertyInParent()); other.setParent(child.getParent()); init = (IASTStatement) other; } if (child == iterationExpression) { other.setPropertyInParent(child.getPropertyInParent()); other.setParent(child.getParent()); iterationExpression = (IASTExpression) other; } if (child == condition) { other.setPropertyInParent(child.getPropertyInParent()); other.setParent(child.getParent()); condition = (IASTExpression) other; } }
public boolean forUsingDeclaration() { if (astName == null) return false; if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false; IASTNode p1 = astName.getParent(); if (p1 instanceof ICPPASTUsingDeclaration) return true; if (p1 instanceof ICPPASTQualifiedName) { IASTNode p2 = p1.getParent(); if (p2 instanceof ICPPASTUsingDeclaration) { IASTName[] ns = ((ICPPASTQualifiedName) p1).getNames(); return (ns[ns.length - 1] == astName); } } return false; }
public IASTDeclarator getDeclarator() { IASTName name = astName; if (name == null || name.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return null; if (name.getParent() instanceof ICPPASTTemplateId) name = (IASTName) name.getParent(); IASTNode node = name.getParent(); if (node instanceof ICPPASTQualifiedName) { if (((ICPPASTQualifiedName) node).getLastName() != name) return null; node = node.getParent(); } if (node instanceof IASTDeclarator) return (IASTDeclarator) node; return null; }
private void handleInserts(IASTNode anchorNode) { List<ASTModification> modifications = getModifications(anchorNode, ModificationKind.INSERT_BEFORE); if (modifications.isEmpty()) return; ChangeGeneratorWriterVisitor writer = new ChangeGeneratorWriterVisitor(modificationStore, commentMap); IASTNode newNode = null; for (ASTModification modification : modifications) { boolean first = newNode == null; newNode = modification.getNewNode(); if (first) { IASTNode prevNode = getPreviousSiblingOrPreprocessorNode(anchorNode); if (prevNode != null) { if (ASTWriter.requireBlankLineInBetween(prevNode, newNode)) { writer.newLine(); } } else if (anchorNode.getParent() instanceof ICPPASTNamespaceDefinition) { writer.newLine(); } } newNode.accept(writer); if (getContainingNodeList(anchorNode) != null) { writer.getScribe().print(", "); // $NON-NLS-1$ } } if (ASTWriter.requireBlankLineInBetween(newNode, anchorNode)) { writer.newLine(); } int insertPos = getOffsetIncludingComments(anchorNode); int length = 0; if (writer.getScribe().isAtBeginningOfLine()) { String tuCode = anchorNode.getTranslationUnit().getRawSignature(); insertPos = skipPrecedingWhitespace(tuCode, insertPos); length = insertPos; insertPos = skipPrecedingBlankLines(tuCode, insertPos); length -= insertPos; } String code = writer.toString(); ReplaceEdit edit = new ReplaceEdit(insertPos, length, code); IFile file = FileHelper.getFileFromNode(anchorNode); MultiTextEdit parentEdit = getEdit(anchorNode, file); parentEdit.addChild(edit); sourceOffsets.put(file.getName(), edit.getOffset()); }
public boolean qualified() { if (forceQualified) return true; IASTName n = astName; if (n == null || n.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false; IASTNode p = n.getParent(); if (p instanceof ICPPASTTemplateId) { n = (IASTName) p; p = p.getParent(); } if (p instanceof ICPPASTQualifiedName) { final ICPPASTQualifiedName qname = (ICPPASTQualifiedName) p; if (qname.isFullyQualified()) return true; final IASTName[] qnames = qname.getNames(); if (qnames.length > 0 && qnames[0] != n) return true; } return p instanceof ICPPASTFieldReference; }
public boolean checkClassContainingFriend() { if (astName == null || astName instanceof ICPPASTQualifiedName) return false; IASTNode p = astName.getParent(); ASTNodeProperty prop = null; while (p != null) { prop = p.getPropertyInParent(); if (prop == ICPPASTTemplateId.TEMPLATE_ID_ARGUMENT || prop == IASTDeclarator.DECLARATOR_NAME) return false; if (p instanceof IASTDeclarator && !(((IASTDeclarator) p).getName() instanceof ICPPASTQualifiedName)) return false; if (p instanceof IASTDeclaration) { if (prop == IASTCompositeTypeSpecifier.MEMBER_DECLARATION) { return CPPVisitor.isFriendDeclaration(p); } else { return false; } } p = p.getParent(); } return false; }
private IASTNode getNextSiblingNode(IASTNode node) { IASTNode parent = node.getParent(); IASTNode[] siblings; if (parent instanceof ICPPASTNamespaceDefinition) { siblings = ((ICPPASTNamespaceDefinition) parent).getDeclarations(true); } else if (parent instanceof IASTCompositeTypeSpecifier) { siblings = ((IASTCompositeTypeSpecifier) parent).getDeclarations(true); } else { siblings = parent.getChildren(); } boolean beforeNode = false; for (int i = 0; i < siblings.length; i++) { IASTNode sibling = siblings[i]; if (sibling == node) { beforeNode = true; } else if (beforeNode) { sibling = getReplacementNode(sibling); if (sibling != null) return sibling; } } return null; }
/** * Inserts the given node in this rewriter. The ast is not modified, the rewriter just records the * insertion. The new node can be part of a translation-unit or it is a synthetic (newly created) * node. * * @param parent the parent the new node is added to. * @param insertionPoint the node before which the insertion shall be done, or <code>null</code> * for inserting after the last child. * @param newNode the node being inserted * @param editGroup the edit group in which to collect the corresponding text edits, or <code>null * </code> * @return a rewriter for further rewriting the inserted node. * @throws IllegalArgumentException if the parent or the newNode is null, or if the parent is not * part of this rewriter's AST, or the insertionPoint is not a child of the parent. */ public final ASTRewrite insertBefore( IASTNode parent, IASTNode insertionPoint, IASTNode newNode, TextEditGroup editGroup) { if (parent != fRoot) { checkBelongsToAST(parent); } if (newNode == null) { throw new IllegalArgumentException(); } checkSupportedNode(parent, Operation.insertBefore); checkSupportedNode(insertionPoint, Operation.insertBefore); checkSupportedNode(newNode, Operation.insertBefore); ASTModification mod; if (insertionPoint == null) { mod = new ASTModification(ModificationKind.APPEND_CHILD, parent, newNode, editGroup); } else { if (insertionPoint.getParent() != parent) { throw new IllegalArgumentException(); } mod = new ASTModification(ModificationKind.INSERT_BEFORE, insertionPoint, newNode, editGroup); } fModificationStore.storeModification(fParentMod, mod); return new ASTRewrite(newNode, fModificationStore, mod, fCommentMap); }
public void setFunctionArguments(boolean containsImpliedObject, IASTInitializerClause... exprs) { argsContainImpliedObject = containsImpliedObject; functionArgs = exprs; if (exprs.length != 0) { IASTNode node = exprs[0]; boolean checkForDependentName = false; while (node != null) { if (node instanceof ICPPASTTemplateDeclaration) { checkForDependentName = true; break; } node = node.getParent(); } if (checkForDependentName) { IType[] types = getFunctionArgumentTypes(); for (IType type : types) { if (CPPTemplates.isDependentType(type)) { checkPointOfDecl = false; break; } } } } }
private static IASTDeclaration getEnclosingTemplateDeclaration(IASTNode node) { while (node != null && !(node instanceof ICPPASTTemplateDeclaration)) { node = node.getParent(); } return (IASTDeclaration) node; }
private static IASTDeclaration getEnclosingFunctionDefinition(IASTNode node) { while (node != null && !(node instanceof IASTFunctionDefinition)) { node = node.getParent(); } return (IASTDeclaration) node; }
public static boolean checkWholeClassScope(IASTName name) { if (name == null) return false; if (name.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return true; IASTNode node = name.getParent(); while (node instanceof IASTName) { name = (IASTName) node; node = name.getParent(); } final ASTNodeProperty nameProp = name.getPropertyInParent(); if (nameProp == IASTIdExpression.ID_NAME || nameProp == IASTFieldReference.FIELD_NAME || nameProp == ICASTFieldDesignator.FIELD_NAME || nameProp == ICPPASTUsingDirective.QUALIFIED_NAME || nameProp == ICPPASTUsingDeclaration.NAME || nameProp == IASTFunctionCallExpression.FUNCTION_NAME || nameProp == IASTNamedTypeSpecifier.NAME || nameProp == ICPPASTConstructorChainInitializer.MEMBER_ID) { // Potentially we need to consider the entire class scope } else { return false; } for (; node != null; node = node.getParent()) { // 3.3.7-5 if (node.getParent() instanceof IASTFunctionDefinition) { // In a function body final ASTNodeProperty prop = node.getPropertyInParent(); if (prop == IASTFunctionDefinition.DECL_SPECIFIER || prop == IASTFunctionDefinition.DECLARATOR) { return false; } IASTNode parent = node.getParent(); while (parent != null) { if (parent instanceof ICPPASTCompositeTypeSpecifier) return true; parent = parent.getParent(); } // No inline method. return false; } if (node instanceof IASTInitializerList || node instanceof IASTEqualsInitializer) { if (node.getPropertyInParent() == IASTDeclarator.INITIALIZER) { IASTNode decl = node.getParent(); while (decl instanceof IASTDeclarator) { decl = decl.getParent(); } if (decl instanceof IASTParameterDeclaration) { // Default argument IASTNode parent = decl.getParent(); while (parent != null) { if (parent instanceof ICPPASTCompositeTypeSpecifier) return true; parent = parent.getParent(); } // Not within a class definition return false; } if (decl instanceof IASTSimpleDeclaration && decl.getPropertyInParent() == IASTCompositeTypeSpecifier.MEMBER_DECLARATION) { // Initializer of non-static data member IASTDeclSpecifier declSpec = ((IASTSimpleDeclaration) decl).getDeclSpecifier(); if (declSpec.getStorageClass() != IASTDeclSpecifier.sc_static) { return true; } // Continue search, we could still be in a method. } } } } return false; }