diff --git a/demos/classchart.html b/demos/classchart.html index b879618b6..e8e48e482 100644 --- a/demos/classchart.html +++ b/demos/classchart.html @@ -138,7 +138,20 @@ Pineapple : -int leafCount() Pineapple : -int spikeCount() +
+
+    classDiagram
+      class Person {
+        +Id : Guid
+        +FirstName : string
+        +LastName : string
+        -privateProperty : string
+        #ProtectedProperty : string
+        ~InternalProperty : string
+        ~AnotherInternalProperty : List~List~string~~
+      }
+    

diff --git a/docs/syntax/classDiagram.md b/docs/syntax/classDiagram.md index 97032ff56..db612fb4f 100644 --- a/docs/syntax/classDiagram.md +++ b/docs/syntax/classDiagram.md @@ -206,7 +206,7 @@ class BankAccount{ #### Generic Types -Members can be defined using generic types, such as `List`, for fields, parameters, and return types by enclosing the type within `~` (**tilde**). Note: **nested** type declarations such as `List>` are not currently supported. +Members can be defined using generic types, such as `List`, for fields, parameters, and return types by enclosing the type within `~` (**tilde**). **Nested** type declarations such as `List>` are supported. Generics can be represented as part of a class definition and also in the parameters or the return value of a method/function: @@ -222,6 +222,7 @@ class Square~Shape~{ Square : -List~string~ messages Square : +setMessages(List~string~ messages) Square : +getMessages() List~string~ +Square : +getDistanceMatrix() List~List~int~~ ``` ```mermaid @@ -236,6 +237,7 @@ class Square~Shape~{ Square : -List~string~ messages Square : +setMessages(List~string~ messages) Square : +getMessages() List~string~ +Square : +getDistanceMatrix() List~List~int~~ ``` #### Visibility diff --git a/packages/mermaid/src/diagrams/common/common.spec.js b/packages/mermaid/src/diagrams/common/common.spec.js index 68f5138e7..8fd6229da 100644 --- a/packages/mermaid/src/diagrams/common/common.spec.js +++ b/packages/mermaid/src/diagrams/common/common.spec.js @@ -68,5 +68,7 @@ describe('generic parser', function () { expect(parseGenericTypes('test ~Array~Array~string[]~~~')).toEqual( 'test >>' ); + expect(parseGenericTypes('~test')).toEqual('~test'); + expect(parseGenericTypes('~test Array~string~')).toEqual('~test Array'); }); }); diff --git a/packages/mermaid/src/diagrams/common/common.ts b/packages/mermaid/src/diagrams/common/common.ts index 628908aab..d34a2df68 100644 --- a/packages/mermaid/src/diagrams/common/common.ts +++ b/packages/mermaid/src/diagrams/common/common.ts @@ -154,11 +154,17 @@ export const evaluate = (val?: string | boolean): boolean => export const parseGenericTypes = function (text: string): string { let cleanedText = text; - if (text.includes('~')) { - cleanedText = cleanedText.replace(/~([^~].*)/, '<$1'); - cleanedText = cleanedText.replace(/~([^~]*)$/, '>$1'); + if (text.split('~').length - 1 >= 2) { + let newCleanedText = cleanedText; - return parseGenericTypes(cleanedText); + // use a do...while loop instead of replaceAll to detect recursion + // e.g. Array~Array~T~~ + do { + cleanedText = newCleanedText; + newCleanedText = cleanedText.replace(/~([^\s,:;]+)~/, '<$1>'); + } while (newCleanedText != cleanedText); + + return parseGenericTypes(newCleanedText); } else { return cleanedText; } diff --git a/packages/mermaid/src/docs/syntax/classDiagram.md b/packages/mermaid/src/docs/syntax/classDiagram.md index 50593f729..10ccc3522 100644 --- a/packages/mermaid/src/docs/syntax/classDiagram.md +++ b/packages/mermaid/src/docs/syntax/classDiagram.md @@ -123,7 +123,7 @@ class BankAccount{ #### Generic Types -Members can be defined using generic types, such as `List`, for fields, parameters, and return types by enclosing the type within `~` (**tilde**). Note: **nested** type declarations such as `List>` are not currently supported. +Members can be defined using generic types, such as `List`, for fields, parameters, and return types by enclosing the type within `~` (**tilde**). **Nested** type declarations such as `List>` are supported. Generics can be represented as part of a class definition and also in the parameters or the return value of a method/function: @@ -139,6 +139,7 @@ class Square~Shape~{ Square : -List~string~ messages Square : +setMessages(List~string~ messages) Square : +getMessages() List~string~ +Square : +getDistanceMatrix() List~List~int~~ ``` #### Visibility