Link Here
|
10 |
*******************************************************************************/ |
10 |
*******************************************************************************/ |
11 |
package org.eclipse.jdt.core.dom; |
11 |
package org.eclipse.jdt.core.dom; |
12 |
|
12 |
|
13 |
import java.util.HashMap; |
|
|
14 |
|
15 |
import org.eclipse.jdt.core.compiler.CharOperation; |
13 |
import org.eclipse.jdt.core.compiler.CharOperation; |
16 |
import org.eclipse.jdt.core.compiler.InvalidInputException; |
14 |
import org.eclipse.jdt.core.compiler.InvalidInputException; |
17 |
import org.eclipse.jdt.internal.compiler.parser.Scanner; |
15 |
import org.eclipse.jdt.internal.compiler.parser.Scanner; |
18 |
import org.eclipse.jdt.internal.compiler.parser.TerminalTokens; |
16 |
import org.eclipse.jdt.internal.compiler.parser.TerminalTokens; |
|
|
17 |
import org.eclipse.jdt.internal.compiler.util.Util; |
19 |
|
18 |
|
20 |
/** |
19 |
/** |
21 |
* Internal class for associating comments with AST nodes. |
20 |
* Internal class for associating comments with AST nodes. |
Link Here
|
135 |
} |
134 |
} |
136 |
|
135 |
|
137 |
/* |
136 |
/* |
|
|
137 |
* Search the line number corresponding to a specific position |
138 |
* between the given line range (inclusive) |
139 |
* @param position int |
140 |
* @parem lineRange size-2 int[] |
141 |
* @return int |
142 |
*/ |
143 |
public final int getLineNumber(int position, int[] lineRange) { |
144 |
int[] lineEnds = this.scanner.lineEnds; |
145 |
int length = lineEnds.length; |
146 |
return Util.getLineNumber(position, lineEnds, (lineRange[0] > length ? length : lineRange[0]) -1, (lineRange[1] > length ? length : lineRange[1]) - 1); |
147 |
} |
148 |
|
149 |
/* |
138 |
* Returns the extended end position of the given node. |
150 |
* Returns the extended end position of the given node. |
139 |
*/ |
151 |
*/ |
140 |
public int getExtendedEnd(ASTNode node) { |
152 |
public int getExtendedEnd(ASTNode node) { |
Link Here
|
285 |
* If finally there's leading still comments, then stores indexes of the first and last one |
297 |
* If finally there's leading still comments, then stores indexes of the first and last one |
286 |
* in leading comments table. |
298 |
* in leading comments table. |
287 |
*/ |
299 |
*/ |
288 |
int storeLeadingComments(ASTNode node, int previousEnd) { |
300 |
int storeLeadingComments(ASTNode node, int previousEnd, int[] parentLineRange) { |
289 |
// Init extended position |
301 |
// Init extended position |
290 |
int nodeStart = node.getStartPosition(); |
302 |
int nodeStart = node.getStartPosition(); |
291 |
int extended = nodeStart; |
303 |
int extended = nodeStart; |
292 |
|
304 |
|
293 |
// Get line of node start position |
305 |
// Get line of node start position |
294 |
int previousEndLine = this.scanner.getLineNumber(previousEnd); |
306 |
int previousEndLine = getLineNumber(previousEnd, parentLineRange); |
295 |
int nodeStartLine = this.scanner.getLineNumber(nodeStart); |
307 |
int nodeStartLine = getLineNumber(nodeStart, parentLineRange); |
296 |
|
308 |
|
297 |
// Find first comment index |
309 |
// Find first comment index |
298 |
int idx = getCommentIndex(0, nodeStart, -1); |
310 |
int idx = getCommentIndex(0, nodeStart, -1); |
Link Here
|
309 |
Comment comment = this.comments[idx]; |
321 |
Comment comment = this.comments[idx]; |
310 |
int commentStart = comment.getStartPosition(); |
322 |
int commentStart = comment.getStartPosition(); |
311 |
int end = commentStart+comment.getLength()-1; |
323 |
int end = commentStart+comment.getLength()-1; |
312 |
int commentLine = this.scanner.getLineNumber(commentStart); |
324 |
int commentLine = getLineNumber(commentStart, parentLineRange); |
313 |
if (end <= previousEnd || (commentLine == previousEndLine && commentLine != nodeStartLine)) { |
325 |
if (end <= previousEnd || (commentLine == previousEndLine && commentLine != nodeStartLine)) { |
314 |
// stop search on condition 1) and 2) |
326 |
// stop search on condition 1) and 2) |
315 |
break; |
327 |
break; |
Link Here
|
360 |
} catch (InvalidInputException e) { |
372 |
} catch (InvalidInputException e) { |
361 |
// do nothing |
373 |
// do nothing |
362 |
} |
374 |
} |
363 |
int lastTokenLine = this.scanner.getLineNumber(lastTokenEnd); |
375 |
int lastTokenLine = getLineNumber(lastTokenEnd, parentLineRange); |
364 |
int length = this.comments.length; |
376 |
int length = this.comments.length; |
365 |
while (startIdx<length && lastTokenLine == this.scanner.getLineNumber(this.comments[startIdx].getStartPosition()) && nodeStartLine != lastTokenLine) { |
377 |
while (startIdx<length && lastTokenLine == getLineNumber(this.comments[startIdx].getStartPosition(), parentLineRange) && nodeStartLine != lastTokenLine) { |
366 |
startIdx++; |
378 |
startIdx++; |
367 |
} |
379 |
} |
368 |
} |
380 |
} |
Link Here
|
405 |
* If finally there's still trailing comments, then stores indexes of the first and last one |
417 |
* If finally there's still trailing comments, then stores indexes of the first and last one |
406 |
* in trailing comments table. |
418 |
* in trailing comments table. |
407 |
*/ |
419 |
*/ |
408 |
int storeTrailingComments(ASTNode node, int nextStart, boolean lastChild) { |
420 |
int storeTrailingComments(ASTNode node, int nextStart, boolean lastChild, int[] parentLineRange) { |
409 |
|
421 |
|
410 |
// Init extended position |
422 |
// Init extended position |
411 |
int nodeEnd = node.getStartPosition()+node.getLength()-1; |
423 |
int nodeEnd = node.getStartPosition()+node.getLength()-1; |
Link Here
|
427 |
int extended = nodeEnd; |
439 |
int extended = nodeEnd; |
428 |
|
440 |
|
429 |
// Get line number |
441 |
// Get line number |
430 |
int nodeEndLine = this.scanner.getLineNumber(nodeEnd); |
442 |
int nodeEndLine = getLineNumber(nodeEnd, parentLineRange); |
431 |
|
443 |
|
432 |
// Find comments range index |
444 |
// Find comments range index |
433 |
int idx = getCommentIndex(0, nodeEnd, 1); |
445 |
int idx = getCommentIndex(0, nodeEnd, 1); |
Link Here
|
480 |
} |
492 |
} |
481 |
} |
493 |
} |
482 |
// Store index if we're on the same line than node end |
494 |
// Store index if we're on the same line than node end |
483 |
int commentLine = this.scanner.getLineNumber(commentStart); |
495 |
int commentLine = getLineNumber(commentStart, parentLineRange); |
484 |
if (commentLine == nodeEndLine) { |
496 |
if (commentLine == nodeEndLine) { |
485 |
sameLineIdx = idx; |
497 |
sameLineIdx = idx; |
486 |
} |
498 |
} |
Link Here
|
491 |
if (endIdx != -1) { |
503 |
if (endIdx != -1) { |
492 |
// Verify that following node start is separated |
504 |
// Verify that following node start is separated |
493 |
if (!lastChild) { |
505 |
if (!lastChild) { |
494 |
int nextLine = this.scanner.getLineNumber(nextStart); |
506 |
int nextLine = getLineNumber(nextStart, parentLineRange); |
495 |
int previousLine = this.scanner.getLineNumber(previousEnd); |
507 |
int previousLine = getLineNumber(previousEnd, parentLineRange); |
496 |
if((nextLine - previousLine) <= 1) { |
508 |
if((nextLine - previousLine) <= 1) { |
497 |
if (sameLineIdx == -1) return nodeEnd; |
509 |
if (sameLineIdx == -1) return nodeEnd; |
498 |
endIdx = sameLineIdx; |
510 |
endIdx = sameLineIdx; |
Link Here
|
541 |
|
553 |
|
542 |
class CommentMapperVisitor extends DefaultASTVisitor { |
554 |
class CommentMapperVisitor extends DefaultASTVisitor { |
543 |
|
555 |
|
544 |
HashMap waitingSiblings = new HashMap(10); |
556 |
ASTNode topSiblingParent = null; |
|
|
557 |
ASTNode[] siblings = new ASTNode[10]; |
558 |
int[][] parentLineRange = new int[10][]; |
559 |
int siblingPtr = -1; |
545 |
|
560 |
|
546 |
protected boolean visitNode(ASTNode node) { |
561 |
protected boolean visitNode(ASTNode node) { |
547 |
|
562 |
|
548 |
// Get default previous end |
563 |
// Get default previous end |
549 |
ASTNode parent = node.getParent(); |
564 |
ASTNode parent = node.getParent(); |
550 |
int previousEnd = parent.getStartPosition(); |
565 |
int previousEnd = parent.getStartPosition(); |
551 |
|
566 |
|
552 |
// Look for sibling node |
567 |
// Look for sibling node |
553 |
ASTNode sibling = (ASTNode) this.waitingSiblings.get(parent); |
568 |
ASTNode sibling = parent == this.topSiblingParent ? (ASTNode) this.siblings[this.siblingPtr] : null; |
554 |
if (sibling != null) { |
569 |
if (sibling != null) { |
555 |
// Found one previous sibling, so compute its trailing comments using current node start position |
570 |
// Found one previous sibling, so compute its trailing comments using current node start position |
556 |
try { |
571 |
try { |
557 |
previousEnd = storeTrailingComments(sibling, node.getStartPosition(), false); |
572 |
previousEnd = storeTrailingComments(sibling, node.getStartPosition(), false, this.parentLineRange[this.siblingPtr]); |
558 |
} catch (Exception ex) { |
573 |
} catch (Exception ex) { |
559 |
// Give up extended ranges at this level if unexpected exception happens... |
574 |
// Give up extended ranges at this level if unexpected exception happens... |
560 |
} |
575 |
} |
Link Here
|
566 |
} |
581 |
} |
567 |
|
582 |
|
568 |
// Compute leading comments for current node |
583 |
// Compute leading comments for current node |
|
|
584 |
int[] previousLineRange = this.siblingPtr > -1 ? this.parentLineRange[this.siblingPtr] : new int[] {1, DefaultCommentMapper.this.scanner.linePtr+1}; |
569 |
try { |
585 |
try { |
570 |
storeLeadingComments(node, previousEnd); |
586 |
storeLeadingComments(node, previousEnd, previousLineRange); |
571 |
} catch (Exception ex) { |
587 |
} catch (Exception ex) { |
572 |
// Give up extended ranges at this level if unexpected exception happens... |
588 |
// Give up extended ranges at this level if unexpected exception happens... |
573 |
} |
589 |
} |
574 |
|
590 |
|
575 |
// Store current node as waiting sibling for its parent |
591 |
// Store current node as waiting sibling for its parent |
576 |
this.waitingSiblings.put(parent, node); |
592 |
if (this.topSiblingParent != parent) { |
|
|
593 |
if (this.siblings.length == ++this.siblingPtr) { |
594 |
System.arraycopy(this.siblings, 0, this.siblings = new ASTNode[this.siblingPtr*2], 0, this.siblingPtr); |
595 |
System.arraycopy(this.parentLineRange, 0, this.parentLineRange = new int[this.siblingPtr*2][], 0, this.siblingPtr); |
596 |
} |
597 |
if (this.topSiblingParent == null) { |
598 |
// node is a CompilationUnit |
599 |
this.parentLineRange[this.siblingPtr] = previousLineRange; |
600 |
} else { |
601 |
int parentStart = parent.getStartPosition(); |
602 |
int firstLine = getLineNumber(parentStart, previousLineRange); |
603 |
int lastLine = getLineNumber(parentStart + parent.getLength() - 1, previousLineRange); |
604 |
if (this.parentLineRange[this.siblingPtr] == null) { |
605 |
this.parentLineRange[this.siblingPtr] = new int[] {firstLine, lastLine}; |
606 |
} else { |
607 |
int[] lineRange = this.parentLineRange[this.siblingPtr]; |
608 |
lineRange[0] = firstLine; |
609 |
lineRange[1] = lastLine; |
610 |
} |
611 |
} |
612 |
this.topSiblingParent = parent; |
613 |
} |
614 |
this.siblings[this.siblingPtr] = node; |
577 |
|
615 |
|
578 |
// We're always ok to visit sub-levels |
616 |
// We're always ok to visit sub-levels |
579 |
return true; |
617 |
return true; |
Link Here
|
582 |
protected void endVisitNode(ASTNode node) { |
620 |
protected void endVisitNode(ASTNode node) { |
583 |
|
621 |
|
584 |
// Look if a child node is waiting for trailing comments computing |
622 |
// Look if a child node is waiting for trailing comments computing |
585 |
ASTNode sibling = (ASTNode) this.waitingSiblings.get(node); |
623 |
ASTNode sibling = this.topSiblingParent == node ? (ASTNode) this.siblings[this.siblingPtr] : null; |
586 |
if (sibling != null) { |
624 |
if (sibling != null) { |
587 |
try { |
625 |
try { |
588 |
storeTrailingComments(sibling, node.getStartPosition()+node.getLength()-1, true); |
626 |
storeTrailingComments(sibling, node.getStartPosition()+node.getLength()-1, true, this.parentLineRange[this.siblingPtr]); |
589 |
} catch (Exception ex) { |
627 |
} catch (Exception ex) { |
590 |
// Give up extended ranges at this level if unexpected exception happens... |
628 |
// Give up extended ranges at this level if unexpected exception happens... |
591 |
} |
629 |
} |
592 |
} |
630 |
} |
|
|
631 |
// Remove sibling if needed |
632 |
if (this.topSiblingParent != null /*not a CompilationUnit*/ |
633 |
&& this.topSiblingParent == node) { |
634 |
this.siblingPtr--; |
635 |
this.topSiblingParent = node.getParent(); |
636 |
} |
593 |
} |
637 |
} |
594 |
|
638 |
|
595 |
public boolean visit ( CompilationUnit node) { |
639 |
public boolean visit ( CompilationUnit node) { |