-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #5 from mosckital/3-class-diagram
3 class diagram
- Loading branch information
Showing
6 changed files
with
165 additions
and
62 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# Project Structure and Class Diagram | ||
|
||
Normally there are two ways to implement a language feature extension, either to directly implement the `languages.*` API or to build a simple custom Language Server following the *Language Server Protocol*. | ||
In this project, the latter approach is chosen, mainly because of the following points: | ||
|
||
1. We can write the Language Server in Python and leverage the power of the `jedi` library. | ||
2. We can have better control over the resource-intensive operations around static analysis, like finding the parent classes of a class. | ||
3. we can easily extend the features of this extension in the future thanks to the *Language Server Protocol*. | ||
|
||
## Project Structure | ||
|
||
By adopting the Language Server approach, the extension can be divided into two parts, the **client side** and the **server side**. | ||
|
||
### Client Side | ||
|
||
The client's responsibility is relatively simple. It only needs to: | ||
|
||
1. construct client options and server options from settings or inputs; | ||
2. prepare a connection to an instance of the Language Server; | ||
3. start a LanguageClient with the client options, the server options and the prepared connection; | ||
4. delegate all future requests to the server and reply the requests with the returned results from the server. | ||
|
||
### Server Side | ||
|
||
The server must implement the **Language Server Protocol**. | ||
However, as the use cases are only relevant to the CodeLens and Hover features, the server does not need to implement the other features. | ||
|
||
Every time there is a request, the server will use *jedi* for semantic queries like finding the target class and all its direct parent classes. | ||
|
||
Once all relevant classes are found, a custom implementation of the C3 linearisation will be used to calculate the MRO list of the target class. | ||
|
||
Caches can be used to speed up the sematic queries and/or the MRO list calculation. | ||
|
||
The server is also responsible for maintaining its internal state for all VS Code instance state changes. | ||
|
||
## Class Diagram | ||
|
||
The following diagram illustrates the above project structure. | ||
|
||
![Class Diagram PNG](./pics/class_diagram/class_diagram.png) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,64 @@ | ||
@startuml class_diagram | ||
class "Code Instance" <<(V,grey) VS Code>> | ||
package "Extension Client" { | ||
class MROExtClient { | ||
activate() | ||
deactivate() | ||
== | ||
Use a client instance, a client | ||
option and a server option to | ||
start the MRO language server | ||
and delegate all functions to it | ||
} | ||
class LanguageClient | ||
MROExtClient o-u- LanguageClient | ||
class LanguageClientOptions | ||
MROExtClient o-- LanguageClientOptions | ||
class ServerOptions | ||
MROExtClient o-- ServerOptions | ||
} | ||
package "Extension Server" { | ||
class MROLanguageServer{ | ||
onInitialise() | ||
onStateChanges() | ||
onCodeLens() | ||
onCodeLensResolve() | ||
onHover() | ||
== | ||
onStateChanges() represents | ||
the callbacks for various | ||
state changes. | ||
} | ||
interface LanguageServerProtocol | ||
hide LanguageServerProtocol members | ||
MROLanguageServer -u-^ LanguageServerProtocol | ||
class JediWrapper { | ||
fetchDirectParentClasses() | ||
== | ||
A wrapper class to facilitate | ||
the use of the "jedi" library. | ||
} | ||
MROLanguageServer o-- JediWrapper | ||
class C3Linearisation { | ||
calcMRO() | ||
== | ||
Implementing the C3 Linearisation | ||
to calculate the MRO list. Class | ||
information will be cached for | ||
fast calculation. | ||
} | ||
MROLanguageServer o-- C3Linearisation | ||
class AnalysisCache { | ||
updateCache() | ||
invalidateCache() | ||
== | ||
To speed up the calculation | ||
and need to invalidate | ||
outdated caches by listening | ||
to the document changes. | ||
} | ||
MROLanguageServer o-u- AnalysisCache | ||
} | ||
"Code Instance" -r-> MROExtClient : CodeLens/Hover | ||
MROExtClient -r- MROLanguageServer | ||
@enduml |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
@startuml use_case_diagram | ||
actor User | ||
package "Python MRO Extension" { | ||
rectangle "CodeLens" { | ||
usecase CLS as \ | ||
"CodeLens Show | ||
== | ||
Show class MRO list in | ||
the CodeLens section." | ||
usecase CLJ as \ | ||
"CodeLens Jump | ||
== | ||
Jump to class definition | ||
by clicking class name | ||
in the MRO list." | ||
} | ||
rectangle "Hover" { | ||
usecase HC as \ | ||
"Hover Class | ||
== | ||
Append the class MRO list | ||
in the popped window when | ||
hovering over a class." | ||
usecase HO as \ | ||
"Hover Object | ||
== | ||
Append the class MRO list | ||
in the popped window when | ||
hovering over an object and | ||
if its type can be parsed." | ||
} | ||
rectangle "Hover Method" { | ||
usecase HCM as \ | ||
"Hover Class Method | ||
== | ||
Append the actual class | ||
fulfilling the method call | ||
in the popped window when | ||
hovering over a | ||
class method." | ||
usecase HOM as \ | ||
"Hover Object Method | ||
== | ||
Append the actual class | ||
fulfilling the method call | ||
in the popped window | ||
when hovering over an | ||
object method and if its | ||
type can be parsed." | ||
} | ||
} | ||
left to right direction | ||
User --> CLS | ||
User --> CLJ | ||
User --> HC | ||
User --> HO | ||
User --> HCM | ||
User --> HOM | ||
@enduml |