plantuml / plantuml

Generate diagrams from textual description
https://plantuml.com
Other
9.73k stars 881 forks source link

Syntax error when aliasing in nested declarations #1625

Closed ohunter closed 3 weeks ago

ohunter commented 5 months ago

Describe the bug It seems like the parser might be struggling with aliasing on nested declarations. A simple example such as this works fine.

@startuml
package P as p {
    interface I as i
}
@enduml

However by just adding a class declaration it freaks out.

@startuml
package P as p {
    interface I as i
    class C
}
@enduml

It doesn't even matter if the class is declared inside of the package.

@startuml
package P as p {
    interface I as i
}
class C
@enduml
@startuml
class C
package P as p {
    interface I as i
}
@enduml
@startuml
package P as p {
    class C
    interface I as i
}
@enduml

Those last two are quite interesting as they indicate that the issue isn't necessarily the class declaration. This can also be shown by simply removing the alias

@startuml
package P as p {
    class C
    interface I
}
@enduml

To Reproduce Just try the examples above in the online demo

Expected behavior It should compile without a syntax error

Screenshots image

Desktop (please complete the following information): Shouldn't really matter as this was tested on the online demo

Smartphone (please complete the following information): NA

Additional context Add any other context about the problem here.

ohunter commented 5 months ago

This might be unrelated, but it also fails with this example:

@startuml
allowmixing
abstract       "abstract"       as a1
abstract class "abstract class" as a2
actor          "actor"          as a3
agent          "agent"          as a4
annotation     "annotation"     as a5
artifact       "artifact"       as a6
boundary       "boundary"       as b1
card           "card"           as c1
circle         "circle"         as c2
class          "class"          as c3
cloud          "cloud"          as c4
collections    "collections"    as c5
component      "component"      as c6
control        "control"        as c7
database       "database"       as d1
diamond        "diamond"        as d2
entity         "entity"         as e1
enum           "enum"           as e2
exception      "exception"      as e3
file           "file"           as f1
folder         "folder"         as f2
frame          "frame"          as f3
hexagon        "hexagon"        as h1
interface      "interface"      as i1
label          "label"          as l1
metaclass      "metaclass"      as m1
node           "node"           as n1
package        "package"        as p1
participant    "participant"    as p2
person         "person"         as p3
protocol       "protocol"       as p4
queue          "queue"          as q1
rectangle      "rectangle"      as r1
stack          "stack"          as s1
stereotype     "stereotype"     as s2
storage        "storage"        as s3
struct         "struct"         as s4
usecase        "usecase"        as u1
@enduml

image

The-Lum commented 5 months ago

Hi @ohunter, and all,

See some elements here:

From your example:

@startuml
package P as p {
    interface I as i
    class C
}
@enduml

If you use quote to define label and no quote for alias, we can see the expected output:

@startuml
package P as p {
    interface "I" as i
    class C
}
@enduml

Enjoy.


For the second example:

This might be unrelated, but it also fails with this example

  • It is normal: because participant is only for sequence diagram!

See this example of sequence diagram:

@startuml
'allowmixing
title Sequence Diag.
actor          "actor"          as a3
'agent          "agent"          as a4
'annotation     "annotation"     as a5
'artifact       "artifact"       as a6
boundary       "boundary"       as b1
'card           "card"           as c1
'circle         "circle"         as c2
'class          "class"          as c3
'cloud          "cloud"          as c4
collections    "collections"    as c5
'component      "component"      as c6
control        "control"        as c7
database       "database"       as d1
'diamond        "diamond"        as d2
entity         "entity"         as e1
'enum           "enum"           as e2
'exception      "exception"      as e3
'file           "file"           as f1
'folder         "folder"         as f2
'frame          "frame"          as f3
'hexagon        "hexagon"        as h1
'interface      "interface"      as i1
'label          "label"          as l1
'metaclass      "metaclass"      as m1
'node           "node"           as n1
'package        "package"        as p1
participant    "participant"    as p2
'person         "person"         as p3
'protocol       "protocol"       as p4
queue          "queue"          as q1
'rectangle      "rectangle"      as r1
'stack          "stack"          as s1
'stereotype     "stereotype"     as s2
'storage        "storage"        as s3
'struct         "struct"         as s4
'usecase        "usecase"        as u1
@enduml

If that can help, Regards, Th.

The-Lum commented 5 months ago

Hi all,

Another funny example, compare (tested on 1.2023.13beta3):

Label without quote: that is a Component/Deployment diagram

@startuml
package P as p {
    interface I as i
}
@enduml

Label with quote: that is a Class diagram

@startuml
package P as p {
    interface "I" as i
}
@enduml

Funny... 🤣

ohunter commented 5 months ago

While quoting solves that example it does cause issues with others

@startuml
set separator ::
interface "P::I" as i
@enduml

vs

@startuml
set separator ::
interface P::I
@enduml

I would expect those diagrams to look the same but they dont. So that means that I instead have to write

package P {
interface "I" as i
}

This might be unrelated, but it also fails with this example

  • It is normal: because participant is only for sequence diagram!

Right, but that is why the allowmixing instruction was there. Additionally, it being considered a syntax error is misleading when it is a limitation of the grammar.

The-Lum commented 5 months ago

Hi @ohunter, and all,

Alias, label and namespace

It's not all done...

In fact, the similar diagram of:

@startuml
set separator ::
interface P::I
@enduml

is:

@startuml
set separator ::
interface "I" as P::I
@enduml

Because if there is only alias: the label is deduced from the alias , but if there are alias and label: label is use to label especially to manage space within it (not to manage namespace) as:

@startuml
set separator ::
interface "I is the label" as P::I
@enduml

If that can help.

allowmixing

Right, but that is why the allowmixing instruction was there.

Here is a precision about allowmixing, it is only to mix element from:

Not for other diagram as:

See full example here:

And for:

Additionally, it being considered a syntax error is misleading when it is a limitation of the grammar.

All proposal are welcome, and you can contribute and send a PR...

If that can help. Regards, Th.

The-Lum commented 3 weeks ago

Hi all,

[This is an Issue Review] 👀 This is now answered.

Regards.