@Override protected final IASTNode doResolveAmbiguity(ASTVisitor visitor) { final IASTAmbiguityParent owner = (IASTAmbiguityParent) getParent(); IASTNode nodeToReplace = this; // handle nested ambiguities first owner.replace(nodeToReplace, fCastExpression); nodeToReplace = fCastExpression; fCastExpression.getTypeId().accept(visitor); owner.replace(nodeToReplace, fBinaryExpression); nodeToReplace = fBinaryExpression; fBinaryExpression.accept(visitor); // find nested names final NameCollector nameCollector = new NameCollector(); fCastExpression.getTypeId().accept(nameCollector); final IASTName[] names = nameCollector.getNames(); // resolve names boolean hasIssue = false; for (IASTName name : names) { try { IBinding b = name.resolveBinding(); if (b instanceof IProblemBinding) { hasIssue = true; break; } } catch (Exception t) { hasIssue = true; break; } } if (hasIssue) { return nodeToReplace; } final IASTExpression left = fBinaryExpression.getOperand1(); final IASTExpression right = fBinaryExpression.getOperand2(); left.setParent(null); right.setParent(null); IASTUnaryExpression primaryInParenthesis = findTrailingBracketedPrimaryExpression(left); IASTExpression leadingCastExpression = findLeadingCastExpression(right); IASTExpression castedUnary = fCastExpression.getOperand(); if (primaryInParenthesis != null && leadingCastExpression != null && castedUnary instanceof IASTUnaryExpression) { IASTExpression lp = (IASTExpression) primaryInParenthesis.getParent(); IASTBinaryExpression rp = (IASTBinaryExpression) leadingCastExpression.getParent(); ((IASTUnaryExpression) castedUnary).setOperand(leadingCastExpression); setEnd(castedUnary, leadingCastExpression); setRange(fCastExpression, primaryInParenthesis, leadingCastExpression); IASTExpression root = joinExpressions(lp, fCastExpression, rp); if (root != null) { owner.replace(nodeToReplace, root); return root; } } return nodeToReplace; }
/** * @param l unary, cast or binary expression to the left, all parents are unary, cast or binary * expressions. * @param middle initially a cast-expression, always suitable to put into l or r * @param r a binary expression to the right, all parents are binary expressions. */ private IASTExpression joinExpressions( IASTExpression l, IASTExpression middle, IASTBinaryExpression r) { while (true) { if (l == null) { if (r == null) { return middle; } r.setOperand1(middle); setStart(r, middle); middle = r; r = (IASTBinaryExpression) r.getParent(); } else if (l instanceof IASTCastExpression) { // cast binds stronger than binary operator ((IASTCastExpression) l).setOperand(middle); setEnd(l, middle); middle = l; // middle becomes cast-expr, can be put into r (a binary-expr) l = (IASTExpression) l.getParent(); } else if (l instanceof IASTUnaryExpression) { // // unary operator binds stronger than binary operator ((IASTUnaryExpression) l).setOperand(middle); setEnd(l, middle); middle = l; // middle becomes unary-expr, can be put into r (a binary-expr) l = (IASTExpression) l.getParent(); } else { if (r == null || getPrecendence((IASTBinaryExpression) l) >= getPrecendence(r)) { ((IASTBinaryExpression) l).setOperand2(middle); setEnd(l, middle); middle = l; // middle becomes binary, can be put into r because precedence is greater or equal. l = (IASTExpression) l.getParent(); } else { r.setOperand1(middle); setStart(r, middle); middle = r; // middle becomes binary, can be put into r because precedence is greater. r = (IASTBinaryExpression) r.getParent(); } } } }