Jump to: navigation, search

Recommenders/Attic/ChainCompletion

ChainCompletion Intro

The ChainCompletion plug-in is based on the paper 'XSnippet: Mining For Sample Code' by Naiyana Tansalarak and Kajal Claypool. The purpose is to support the software engineer while coding. There are a lot of scenarios, where a programmer has no clue to instantiate a variable in a specific context ("How do I get an instance of IWorkbenchHelpSystem?"). This plug-in searches through the programming context for all members, which meet the search criteria. The results, namely call chains, are visualized as proposals within the editor. Finally the coder can pick the right one.

ChainCompletion Architecture

The first section #Workflow introduces the main idea of this plug-in and describes briefly how it is implemented. The next Section #Structural Overview goes into the package and class design and explicates it.

Workflow

The section is separated into two subsections. First the idea of the #Algorithm is explained. This algorithm is responisble to compute all possible call chains. After the chains were computed, the #Proposal Generation starts to build the proposals, which were displayed on the proposal box.

Algorithm

To understand the algorithm there are two scenarios which are important:

1. Scenario
IWorkbenchHelpSystem c = PlatformUI.//trigger ChainCompletion here
2. Scenario
class TestClass {
 
   IWorkbenchHelpSystem findMember = PlatformUI.getWorkbench().getHelpSystem();
 
   public void someMethod () {
      IWorkbenchHelpSystem findVariable = PlatformUI.getWorkbench().getHelpSystem();
 
      IWorkbenchHelpSystem c = //trigger ChainCompletion here
    }
 
   private IWorkbenchHelpSystem findMethod() {
      return PlatformUI.getWorkbench().getHelpSystem();
   }
}

The first step is to compute the calling context. The calling context for the first scenario is 'org.eclipse.ui.PlattformUI', because of its static access. The calling context for the second scenario is 'TestClass', because it is an access from the 'this' context.

The second step is to find out the expected type. The expected type for both scenarios is 'IWorkbenchHelpSystem'.

The third step is to determine, which member from the calling context should be taken into account for the computation. If the ChainCompletion is triggered as in scenario 2 all variables, fields and method are considered independently of their visibility. In scenario 1 only the accessible public fields and methods are contemplable.

With this information (expected type, accessible members) the main algorithm can start. The objective of this algorithm is to to find for each type a call chain which matches the expected type. In scenario 1 the call chain is '[PlatformUI.]getWorkbench().getHelpSystem()' ('PlatformUI' does not belong to the call chain, because it is the calling context). For that all variables, fields and methods, which were found in the third step, are stored in lists. Actually only the type (return type) and member name are considered.

For each list a thread worker process starts. First the last element of the list is retrieved (in the beginning there is only one element in the list). The worker checks the objective for this type:

  • If the type matches the expected type this list is stored for the #Proposal Generation.
  • In the other case a new calling context is set to the type which was retrieved. Like in the beginning all accessible members are determined. For each member the list has to be cloned and the members are stored at the end of each list. The computation algorithm starts from the beginning for each list.

At the end of computation scenario 1 has one list (chain depth 3). In this list contains following elements: 'getWorkbench()' and 'getHelpSystem()' with their return types. Scenario 2 will have three list with only one element each:

  1. findMember
  2. findMethod
  3. findVariable

These lists are give to the #Proposal Generation.

Specifics:

  • The objective can also be reached, if the type can be casted to the expected type
  • Redundant chain elements are deleted. E.g. String s = toString().toString().toString()...
  • The determination of all members takes a lot of computation time. So all determined members are temporary stored.
  • The algorithm computes until a specific duration is reached. This maximal duration is defined in the constants class.

TODOs:

  • The ChainCompletion does not work on primitives. The solution is to box this primitives to their corresponding type
  • The ChainCompletion cannot resolve parameters. E.g. method 'contains(CharSequence)' of the string class. If the ChainCompletion is triggered at this point 'someString.contains(*' no proposal would be generated.
  • The ChainCompletion works only on public members. In an inheritance hierarchy, neither protected nor package private members will be found.

Proposal Generation

The result of the algorithm has to be translated to char sequences Eclipse understand. With this char sequences eclipse generates the proposals which are displayed in the proposal box within the editor. Each proposal contains a name, description and the code.

The name describes in a short way which code snippet can be chosen. If one code snippet contains a method part with parameters, than this parameters are replaced by dots.

The descriptions contains the length of the call chain (result of scenario 1 has the length two and scenario 2 the length one). Additionally there is a note, if a proposal has to be casted.

The code is a well-defined char sequence, which Eclipse can use to generate the output, if a specific call chain is chosen.

Specifics:

  • The proposal generation computes until a specific proposal count is reached. This maximal proposal count is defined in the constants class.
  • It is possible to start the ChainCompletion on a specific prefix. The proposal generation finds the call chain, which corresponds to this prefix. (E.g. Scenario 2: IWorkbenchHelpSystem c = findV* --> findVariable)

TODOs:

  • If a coder picks a specific proposal it has to be stored into a distributed database. This database should be used to evaluate the proposal, to display others the best pick.

Structural Overview

The first subsection #Package Structure describes the packages and their responsibilities. Next the subsection #Class Overview contains all classes, which are briefly illustrated.

Package Structure

The subsection gives an overview of the package structure and maps the packages to the classes, which are described in the subsection #Class Overview .

Package Content Description
[*].chain
  • ChainedJavaCompletionProposalComputer
  • Constants
This is the main package of this plug-in. Beside the constants class it contains the entry point of this plug-in, the class called ChainedJavaCompletionProposalComputer.
[*].chain.algorithm
  • ChainedJavaProposal
  • ChainingAlgorithm
This package is responsible for the computation and storing of all possible call chains.
[*].chain.algorithm.internal
  • ChainedProposalAnchor
  • ChainingAlgorithmWorker
  • FieldChainWalaElement
  • FieldsAndMethodsCompletionContext
  • MethodChainWalaElement
This package contains some classes which are needed for the computation of the algorithm.
[*].chain.proposals
  • TemplateProposalEngine
This package is responsible to create the proposals from the result of the algorithm.
[*].chain.util
  • LookupUtilJdt
  • LookupUtilWala
Describes the bridge between this plug-in and the frameworks Wala and JDT, which are deposite at this package.

[*] is a abbreviation for org.eclipse.recommenders.internal.rcp.codecompletion

Class Overview

This subsection gives an overview of the classes and their responsibilities.

Class Description
ChainedJavaCompletionProposalComputer This class implements the IJavaCompletionProposalComputer interface and functions as entry point. Within this class the algorithm and proposal generation is started.
Constants This class contains some constants for the computation within the algorithm and proposal generation.
ChainedJavaProposal This class descibes one proposal, which is generated by the algorithm. A list of all proposals are returned to the TemplateProposalEngine.
ChainingAlgorithm This class is responsible to compute the proposals. For each member of the calling context it creates one ChainingAlgorithmWorker.
ChainedProposalAnchor This class is created by FieldsAndMethodsCompletionContext and contains one specific member from the calling context. All members are returned to the algorithm and can be the first element of the calling chain.
ChainingAlgorithmWorker This class is responsible to process one call chain. This processing includes the checks if the objective has been reached, to store new types for faster computation, and to create new workers to extend the call chain. This class implements the Runnable interface.
FieldChainWalaElement This class describes a field, which can be one part of the calling chain.
FieldsAndMethodsCompletionContext This class has two responsibilities. The first one ist to figure out the calling context. The second responsibility is to gather each member of this calling context and to store into instances of the ChainedProposalAnchor class.
MethodChainWalaElement This class describes a method, which can be one part of the calling chain.
TemplateProposalEngine This class is responsible to take the results of the algorithm and to generate proper proposals, which Eclipse can process. The proposals are instances of IJavaCompletionProposal.
LookupUtilJdt This class contains static methods to lookup the signatures from members. This class uses the JDT framework.
LookupUtilWala This class contains static methods to generate inheritance hierarchies to lookup if a class can be casted to a specific type. It also contains a method to test if to types are equal. To do so, it uses the Wala framework.