:plantuml-server-url: https://www.plantuml.com/plantuml
:source-highlighter: rouge
:chapter-label:
:doctype: book

= abaplint
Design Document
:toc:
:toclevels: 3
:numbered:

== Introduction
abaplint implements a custom ABAP parser and other language related topics like scoping and syntax check.

This document describes the overall design of abaplint, and aim to persist design decisions and help new developers into the code-base.

== Packages / Ecosystem


[plantuml, packages, svg]
....
left to right direction
skinparam monochrome true

frame "@abaplint/abaplint" as abaplint

rectangle "3rd Party Tooling" as tooling
tooling --> abaplint

rectangle "vscode-abaplint" as vscode
vscode --> abaplint

rectangle "abaplint-cloud-foundry" as cf
cf --> abaplint

frame "@abaplint/cli" as cli
cli --> abaplint

rectangle "CI Tooling" as ci
ci --> abaplint
ci -left-> cli

frame "@abaplint/transpiler" as transpiler

abaplint -down-> transpiler

frame "@abaplint/runtime" as runtime

transpiler --> runtime

rectangle "Serverless Tooling" as serverless
serverless -left-> transpiler
serverless -left-> runtime
....

== Registry
The Registry is the main entry point to abaplint, files are added to the registry which then are mapped to objects, and the registry also keeps track of the configuration.

[plantuml, registry, svg]
....
skinparam monochrome true

rectangle "Registry" as registry

usecase object1
usecase object2
registry -down-> object1
registry -down-> object2

rectangle "Configuration" as config
registry -down-> config

usecase file1
usecase file2
usecase file3
usecase file4

object1 -down-> file1
object1 -down-> file2

object2 -down-> file3
object2 -down-> file4
....

== Configuration
todo

== Pipeline Overview

[plantuml, pipeline, svg]
....
left to right direction
skinparam monochrome true

package "@abaplint/abaplint" as abaplint {
  rectangle "Lexer" as lexer

  rectangle "Statement Parser" as statement_parser
  rectangle "Structure Parser" as structure_parser
  rectangle "Object Information" as object_information
  rectangle "Syntax & Scoping" as syntax
  rectangle "Rules" as rules

  rectangle "Downport (WIP)" as downport
  rectangle "Quick fixes (WIP)" as quick_fixes
  rectangle "LSP" as lsp

  lexer -left-> statement_parser
  statement_parser -left-> structure_parser
  structure_parser -left-> object_information
  object_information -left-> syntax
  syntax -left-> rules

  lexer -[hidden]-> downport
  statement_parser -[hidden]-> quick_fixes
  structure_parser -[hidden]-> lsp
}
....


* immutable => possible multi-threading and structure

* output of each stage is simple classes or interfaced making it simple typed, limiting cyclic dependencies

* avoid cyclic dependencies, each step can use the previous, use interfaces

=== Lexing & Parsing

.example.abap
[source,abap]
----
DO 5 TIMES.
  WRITE 'hello'.
ENDDO.
----

==== Lexing / Tokenization

Based on rules, the string is split into tokens,

[plantuml, tokens, svg]
....
skinparam monochrome true

usecase "DO" as token1
usecase "5" as token2
usecase "TIMES" as token3
usecase "." as token4
usecase "WRITE" as token5
usecase "'hello'" as token6
usecase "." as token7
usecase "ENDDO" as token8
usecase "." as token9
....

==== Parsing

Categorizes tokens into statements

[plantuml, parsing, svg]
....
skinparam monochrome true

usecase "ENDDO" as token8
usecase "." as token9

rectangle "Statement ENDDO" as enddo
token8 <-up- enddo
token9 <-up- enddo

usecase "WRITE" as token5
usecase "'hello'" as token6
usecase "." as token7

rectangle "Statement WRITE" as write
token5 <-up- write
token6 <-up- write
token7 <-up- write

usecase "DO" as token1
usecase "5" as token2
usecase "TIMES" as token3
usecase "." as token4

rectangle "Statement DO" as do
token1 <-up- do
token2 <-up- do
token3 <-up- do
token4 <-up- do
....

==== Structuring

Not completely correct, but the idea...

[plantuml, structuring, svg]
....
skinparam monochrome true

usecase "ENDDO" as token8
usecase "." as token9

rectangle "Statement ENDDO" as enddo
token8 <-up- enddo
token9 <-up- enddo

usecase "WRITE" as token5
usecase "'hello'" as token6
usecase "." as token7

rectangle "Statement WRITE" as write
token5 <-up- write
token6 <-up- write
token7 <-up- write

usecase "DO" as token1
usecase "5" as token2
usecase "TIMES" as token3
usecase "." as token4

rectangle "Statement DO" as do
token1 <-up- do
token2 <-up- do
token3 <-up- do
token4 <-up- do

collections "Structure DO" as sdo
do <-up- sdo
write <-up- sdo
enddo <-up- sdo
....

=== Object Information
todo

no real types types, only identifiers, in some cases typed

=== Syntax & Scoping
todo

adds real types and real scopes

== Rules
todo

== Parsing vs standard ABAP
* CALL FUNCTION EXCEPTIONS must be well formed
* Macros are only scoped to current file, current workaround is adding the constants to `abaplint.json`, and are not expanded
* Identifieres with dashes as last character "variable-" does not work well

== Development
....
npm install
npm test
....

run following to link the different packages
....
npm run link-local
....
