Find the corresponding > to close a template. Args: clean_lines: A CleansedLines instance containing the file. linenum: Current line number. init_suffix: Remainder of the current line after the initial <. Returns: True if a matching bracket exists.
(clean_lines, linenum, init_suffix)
| 2519 | |
| 2520 | |
| 2521 | def FindNextMatchingAngleBracket(clean_lines, linenum, init_suffix): |
| 2522 | """Find the corresponding > to close a template. |
| 2523 | |
| 2524 | Args: |
| 2525 | clean_lines: A CleansedLines instance containing the file. |
| 2526 | linenum: Current line number. |
| 2527 | init_suffix: Remainder of the current line after the initial <. |
| 2528 | |
| 2529 | Returns: |
| 2530 | True if a matching bracket exists. |
| 2531 | """ |
| 2532 | line = init_suffix |
| 2533 | nesting_stack = ['<'] |
| 2534 | while True: |
| 2535 | # Find the next operator that can tell us whether < is used as an |
| 2536 | # opening bracket or as a less-than operator. We only want to |
| 2537 | # warn on the latter case. |
| 2538 | # |
| 2539 | # We could also check all other operators and terminate the search |
| 2540 | # early, e.g. if we got something like this "a<b+c", the "<" is |
| 2541 | # most likely a less-than operator, but then we will get false |
| 2542 | # positives for default arguments and other template expressions. |
| 2543 | match = Search(r'^[^<>(),;\[\]]*([<>(),;\[\]])(.*)$', line) |
| 2544 | if match: |
| 2545 | # Found an operator, update nesting stack |
| 2546 | operator = match.group(1) |
| 2547 | line = match.group(2) |
| 2548 | |
| 2549 | if nesting_stack[-1] == '<': |
| 2550 | # Expecting closing angle bracket |
| 2551 | if operator in ('<', '(', '['): |
| 2552 | nesting_stack.append(operator) |
| 2553 | elif operator == '>': |
| 2554 | nesting_stack.pop() |
| 2555 | if not nesting_stack: |
| 2556 | # Found matching angle bracket |
| 2557 | return True |
| 2558 | elif operator == ',': |
| 2559 | # Got a comma after a bracket, this is most likely a template |
| 2560 | # argument. We have not seen a closing angle bracket yet, but |
| 2561 | # it's probably a few lines later if we look for it, so just |
| 2562 | # return early here. |
| 2563 | return True |
| 2564 | else: |
| 2565 | # Got some other operator. |
| 2566 | return False |
| 2567 | |
| 2568 | else: |
| 2569 | # Expecting closing parenthesis or closing bracket |
| 2570 | if operator in ('<', '(', '['): |
| 2571 | nesting_stack.append(operator) |
| 2572 | elif operator in (')', ']'): |
| 2573 | # We don't bother checking for matching () or []. If we got |
| 2574 | # something like (] or [), it would have been a syntax error. |
| 2575 | nesting_stack.pop() |
| 2576 | |
| 2577 | else: |
| 2578 | # Scan the next line |
no test coverage detected