Skip to main content
Jump to: navigation, search

JDT Core Programmer Guide/Completion

In this page we collect our understanding of how code completion is implemented, in particular the beast that is CompletionParser

Source code range

Various parties influence the source range that is analysed (scanned & parsed):

  • Parser.parseBlockStatements() starts with scanner.resetTo(md.bodyStart, bodyEnd(md))
    • CompletionParser implements bodyEnd by answering the cursorLocation
  • Since stopping at the cursorLocation is unacceptable in some situations (notably involving lambdas), AssistParser.fallBackToSpringForward() may set eofPosition to one of (a) actual source end or (b) real body end of the method.

It is unclear, how much is gained by stopping to parse in the middle of code:

  • does it help to cope with broken code beyond the cursor location?
  • does it improve performance? (I doubt it has significant impact. --SH)
  • in bug 473654 experiments to avoid setting eof to cursorLocation caused regressions, so some code must meanwhile depend on this strategy.


This is the story of Parser.currentElement.

Recovery starts when a syntax error is encountered, the chain resumeOnSyntaxError() -> buildInitialRecoveryState() sets things in motion:

  • buildInitialRecoveryState() essentially converts existing ASTNodes in Parser.astStack into RecoveredElements.
    • This step maps the nested structure indicated by astStack into a proper tree of recovered elements.
    • Expressions are explicitly omitted.
      • An exception is implemented for block lambdas, so that an empty block is inserted into the tree of recovered elements.
      • If a lambda appears, e.g., in the RHS of a local declaration, the block cannot be made a child of the local, so the hierarchy has to be tweaked:
        • The local declaration is considered as complete
        • The enclosing block is resumed
        • The new block (body of the lambda) is inserted as a sibling to the local declaration.

The last expression may, however, be processed by updateRecoveryState() (right after resumeOnSyntaxError()):

  • relevant things may happen below attachOrphanCompletionNode() -> buildMoreCompletionContext().
    • buildMoreCompletionEnclosingContext() has special treatment for code nested in an if statement and specifically for instanceof.

to be continued.

Back to the top