From 47b5d7a2dfefc8d9b2c006783b93393106f32f08 Mon Sep 17 00:00:00 2001 From: Justin Greywolf Date: Fri, 5 Jun 2020 17:10:33 -0700 Subject: [PATCH 1/6] 1378-accept multiple parameters with methods sec --- package.json | 1 + src/diagrams/class/parser/classDiagram.jison | 10 ++-- src/diagrams/class/svgDraw.js | 60 +++++++++++--------- yarn.lock | 12 ++++ 4 files changed, 52 insertions(+), 31 deletions(-) diff --git a/package.json b/package.json index 90c991b46..5ca9a34b2 100644 --- a/package.json +++ b/package.json @@ -59,6 +59,7 @@ "he": "^1.2.0", "minify": "^4.1.1", "moment-mini": "^2.22.1", + "node": "^14.3.0", "scope-css": "^1.2.1" }, "devDependencies": { diff --git a/src/diagrams/class/parser/classDiagram.jison b/src/diagrams/class/parser/classDiagram.jison index 12e9a2564..bd8cf6f59 100644 --- a/src/diagrams/class/parser/classDiagram.jison +++ b/src/diagrams/class/parser/classDiagram.jison @@ -10,15 +10,15 @@ %% \%\%[^\n]*\n* /* do nothing */ -\n+ return 'NEWLINE'; +\n+ return 'NEWLINE'; \s+ /* skip whitespace */ "classDiagram" return 'CLASS_DIAGRAM'; [\{] { this.begin("struct"); /*console.log('Starting struct');*/return 'STRUCT_START';} <> return "EOF_IN_STRUCT"; [\{] return "OPEN_IN_STRUCT"; -\} { /*console.log('Ending struct');*/this.popState(); return 'STRUCT_STOP';}} +\} { /*console.log('Ending struct');*/this.popState(); return 'STRUCT_STOP';}} [\n] /* nothing */ -[^\{\}\n]* { /*console.log('lex-member: ' + yytext);*/ return "MEMBER";} +[^\{\}\n]* { /*console.log('lex-member: ' + yytext);*/ return "MEMBER";} @@ -40,7 +40,7 @@ \s*\|\> return 'EXTENSION'; \s*\> return 'DEPENDENCY'; \s*\< return 'DEPENDENCY'; -\s*\* return 'COMPOSITION'; +\s*\* return 'COMPOSITION'; \s*o return 'AGGREGATION'; \-\- return 'LINE'; \.\. return 'DOTTED_LINE'; @@ -53,7 +53,7 @@ \= return 'EQUALS'; \w+ return 'ALPHA'; [!"#$%&'*+,-.`?\\/] return 'PUNCTUATION'; -[0-9]+ return 'NUM'; +[0-9]+ return 'NUM'; [\u00AA\u00B5\u00BA\u00C0-\u00D6\u00D8-\u00F6]| [\u00F8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377]| [\u037A-\u037D\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5]| diff --git a/src/diagrams/class/svgDraw.js b/src/diagrams/class/svgDraw.js index a93cd1e87..c97259a55 100644 --- a/src/diagrams/class/svgDraw.js +++ b/src/diagrams/class/svgDraw.js @@ -278,8 +278,8 @@ export const drawClass = function(elem, classDef, conf) { }; export const parseMember = function(text) { - const fieldRegEx = /^(\+|-|~|#)?(\w+)(~\w+~|\[\])?\s+(\w+)$/; - const methodRegEx = /^(\+|-|~|#)?(\w+)\s?\(\s*(\w+(~\w+~|\[\])?\s*(\w+)?)?\s*\)\s?([*|$])?\s?(\w+(~\w+~|\[\])?)?\s*$/; + const fieldRegEx = /^(\+|-|~|#)?(\w+)(~\w+~|\[\])?\s+(\w+)/; + const methodRegEx = /^(\+|-|~|#)?(\w+)\((.*)\)(\*|\$)?\s?(.*)?/; let fieldMatch = text.match(fieldRegEx); let methodMatch = text.match(methodRegEx); @@ -294,43 +294,53 @@ export const parseMember = function(text) { }; const buildFieldDisplay = function(parsedText) { - let visibility = parsedText[1] ? parsedText[1].trim() : ''; - let fieldType = parsedText[2] ? parsedText[2].trim() : ''; - let genericType = parsedText[3] ? parseGenericTypes(parsedText[3]) : ''; - let fieldName = parsedText[4] ? parsedText[4].trim() : ''; + let displayText = ''; + + try { + let visibility = parsedText[1] ? parsedText[1].trim() : ''; + let fieldType = parsedText[2] ? parseGenericTypes(parsedText[2]) : ''; + let fieldName = parsedText[3] ? parsedText[3].trim() : ''; + + displayText = visibility + fieldType + ' ' + fieldName; + } catch (err) { + displayText = parsedText; + } return { - displayText: visibility + fieldType + genericType + ' ' + fieldName, + displayText: displayText, cssStyle: '' }; }; const buildMethodDisplay = function(parsedText) { let cssStyle = ''; - let displayText = parsedText; + let displayText = ''; - let visibility = parsedText[1] ? parsedText[1].trim() : ''; - let methodName = parsedText[2] ? parsedText[2].trim() : ''; - let parameters = parsedText[3] ? parseGenericTypes(parsedText[3]) : ''; - let classifier = parsedText[6] ? parsedText[6].trim() : ''; - let returnType = parsedText[7] ? ' : ' + parseGenericTypes(parsedText[7]).trim() : ''; + try { + let visibility = parsedText[1] ? parsedText[1].trim() : ''; + let methodName = parsedText[2] ? parsedText[2].trim() : ''; + let parameters = parsedText[3] ? parseGenericTypes(parsedText[3]) : ''; + let classifier = parsedText[4] ? parsedText[4].trim() : ''; + let returnType = parsedText[5] ? ' : ' + parseGenericTypes(parsedText[5]).trim() : ''; - displayText = visibility + methodName + '(' + parameters + ')' + returnType; + displayText = visibility + methodName + '(' + parameters + ')' + returnType; - cssStyle = parseClassifier(classifier); + cssStyle = parseClassifier(classifier); + } catch (err) { + displayText = parsedText; + } - let member = { + return { displayText: displayText, cssStyle: cssStyle }; - - return member; }; const buildLegacyDisplay = function(text) { // if for some reason we dont have any match, use old format to parse text - let memberText = ''; + let displayText = ''; let cssStyle = ''; + let memberText = ''; let returnType = ''; let methodStart = text.indexOf('('); let methodEnd = text.indexOf(')'); @@ -338,12 +348,12 @@ const buildLegacyDisplay = function(text) { if (methodStart > 1 && methodEnd > methodStart && methodEnd <= text.length) { let parsedText = text.match(/(\+|-|~|#)?(\w+)/); let visibility = parsedText[1] ? parsedText[1].trim() : ''; - let methodName = parsedText[2]; + let methodName = text.substring(0, methodStart); let parameters = text.substring(methodStart + 1, methodEnd); let classifier = text.substring(methodEnd, methodEnd + 1); cssStyle = parseClassifier(classifier); - memberText = visibility + methodName + '(' + parseGenericTypes(parameters.trim()) + ')'; + displayText = visibility + methodName + '(' + parseGenericTypes(parameters.trim()) + ')'; if (methodEnd < memberText.length) { returnType = text.substring(methodEnd + 2).trim(); @@ -353,15 +363,13 @@ const buildLegacyDisplay = function(text) { } } else { // finally - if all else fails, just send the text back as written (other than parsing for generic types) - memberText = parseGenericTypes(text); + displayText = parseGenericTypes(text); } - let member = { - displayText: memberText + returnType, + return { + displayText: displayText, cssStyle: cssStyle }; - - return member; }; const addTspan = function(textEl, txt, isFirst, conf) { diff --git a/yarn.lock b/yarn.lock index 5b27d9a91..320906b14 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7548,6 +7548,11 @@ no-case@^2.2.0: dependencies: lower-case "^1.1.1" +node-bin-setup@^1.0.0: + version "1.0.6" + resolved "https://registry.yarnpkg.com/node-bin-setup/-/node-bin-setup-1.0.6.tgz#4b5c9bb937ece702d7069b36ca78af4684677528" + integrity sha512-uPIxXNis1CRbv1DwqAxkgBk5NFV3s7cMN/Gf556jSw6jBvV7ca4F9lRL/8cALcZecRibeqU+5dFYqFFmzv5a0Q== + node-forge@0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" @@ -7651,6 +7656,13 @@ node-sass@^4.12.0: stdout-stream "^1.4.0" "true-case-path" "^1.0.2" +node@^14.3.0: + version "14.3.0" + resolved "https://registry.yarnpkg.com/node/-/node-14.3.0.tgz#a0aa79f74add23cf84a2d3ac9d631bbed3ca496a" + integrity sha512-wYdyAhpzQ+iaXnDby6JUok/efke+TW2VJk8lOFc4B6F1omIiBG6gt/xVG074btcliY9Sw49D2veah8bZ20lGEA== + dependencies: + node-bin-setup "^1.0.0" + nomnom@1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.5.2.tgz#f4345448a853cfbd5c0d26320f2477ab0526fe2f" From 9091d686ed09ad81c5bfa1927f12244ac233ffcb Mon Sep 17 00:00:00 2001 From: Justin Greywolf Date: Mon, 8 Jun 2020 18:40:18 -0700 Subject: [PATCH 2/6] 1378-Update regex to match multiple parameters removing node version changes --- package.json | 1 - src/diagrams/class/svgDraw.js | 9 +++++---- yarn.lock | 5 ----- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/package.json b/package.json index 5ca9a34b2..90c991b46 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,6 @@ "he": "^1.2.0", "minify": "^4.1.1", "moment-mini": "^2.22.1", - "node": "^14.3.0", "scope-css": "^1.2.1" }, "devDependencies": { diff --git a/src/diagrams/class/svgDraw.js b/src/diagrams/class/svgDraw.js index c97259a55..61bd51ccc 100644 --- a/src/diagrams/class/svgDraw.js +++ b/src/diagrams/class/svgDraw.js @@ -278,13 +278,14 @@ export const drawClass = function(elem, classDef, conf) { }; export const parseMember = function(text) { - const fieldRegEx = /^(\+|-|~|#)?(\w+)(~\w+~|\[\])?\s+(\w+)/; - const methodRegEx = /^(\+|-|~|#)?(\w+)\((.*)\)(\*|\$)?\s?(.*)?/; + const fieldRegEx = /^(\+|-|~|#)?(\w+)(~\w+~|\[\])?\s+(\w+)$/; + const methodRegEx = /(\+|-|~|#)?(\w+)\((.*)\)(\*|\$)? *(.*)?/; + ///^(\+|-|~|#)?(\w+)\((.*)\)(\*|\$)?[ ]*(.*)?$/; let fieldMatch = text.match(fieldRegEx); let methodMatch = text.match(methodRegEx); - if (fieldMatch) { + if (fieldMatch && !methodMatch) { return buildFieldDisplay(fieldMatch); } else if (methodMatch) { return buildMethodDisplay(methodMatch); @@ -299,7 +300,7 @@ const buildFieldDisplay = function(parsedText) { try { let visibility = parsedText[1] ? parsedText[1].trim() : ''; let fieldType = parsedText[2] ? parseGenericTypes(parsedText[2]) : ''; - let fieldName = parsedText[3] ? parsedText[3].trim() : ''; + let fieldName = parsedText[4] ? parsedText[4].trim() : ''; displayText = visibility + fieldType + ' ' + fieldName; } catch (err) { diff --git a/yarn.lock b/yarn.lock index 320906b14..a55f0753d 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7548,11 +7548,6 @@ no-case@^2.2.0: dependencies: lower-case "^1.1.1" -node-bin-setup@^1.0.0: - version "1.0.6" - resolved "https://registry.yarnpkg.com/node-bin-setup/-/node-bin-setup-1.0.6.tgz#4b5c9bb937ece702d7069b36ca78af4684677528" - integrity sha512-uPIxXNis1CRbv1DwqAxkgBk5NFV3s7cMN/Gf556jSw6jBvV7ca4F9lRL/8cALcZecRibeqU+5dFYqFFmzv5a0Q== - node-forge@0.9.0: version "0.9.0" resolved "https://registry.yarnpkg.com/node-forge/-/node-forge-0.9.0.tgz#d624050edbb44874adca12bb9a52ec63cb782579" From ae6b75b62a9b4d9d8fab7e79a06ecd39bb4f332d Mon Sep 17 00:00:00 2001 From: Justin Greywolf Date: Mon, 8 Jun 2020 18:47:36 -0700 Subject: [PATCH 3/6] Removed additional unintended change --- yarn.lock | 7 ------- 1 file changed, 7 deletions(-) diff --git a/yarn.lock b/yarn.lock index a55f0753d..5b27d9a91 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7651,13 +7651,6 @@ node-sass@^4.12.0: stdout-stream "^1.4.0" "true-case-path" "^1.0.2" -node@^14.3.0: - version "14.3.0" - resolved "https://registry.yarnpkg.com/node/-/node-14.3.0.tgz#a0aa79f74add23cf84a2d3ac9d631bbed3ca496a" - integrity sha512-wYdyAhpzQ+iaXnDby6JUok/efke+TW2VJk8lOFc4B6F1omIiBG6gt/xVG074btcliY9Sw49D2veah8bZ20lGEA== - dependencies: - node-bin-setup "^1.0.0" - nomnom@1.5.2: version "1.5.2" resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.5.2.tgz#f4345448a853cfbd5c0d26320f2477ab0526fe2f" From 0495103635f68ace087c55307000f218a3d0c99b Mon Sep 17 00:00:00 2001 From: Justin Greywolf Date: Mon, 8 Jun 2020 19:21:33 -0700 Subject: [PATCH 4/6] Fix regex and Fix incorrect test --- cypress/integration/rendering/classDiagram.spec.js | 6 +++--- src/diagrams/class/svgDraw.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/cypress/integration/rendering/classDiagram.spec.js b/cypress/integration/rendering/classDiagram.spec.js index 97d7d9041..bf7125717 100644 --- a/cypress/integration/rendering/classDiagram.spec.js +++ b/cypress/integration/rendering/classDiagram.spec.js @@ -71,9 +71,9 @@ describe('Class diagram', () => { classDiagram Class01 <|-- AveryLongClass : Cool <<interface>> Class01 - Class01 : -int privateMethod() - Class01 : +int publicMethod() - Class01 : #int protectedMethod() + Class01 : -privateMethod() + Class01 : +publicMethod() + Class01 : #protectedMethod() Class01 : -int privateChimp Class01 : +int publicGorilla Class01 : #int protectedMarmoset diff --git a/src/diagrams/class/svgDraw.js b/src/diagrams/class/svgDraw.js index 61bd51ccc..828824f05 100644 --- a/src/diagrams/class/svgDraw.js +++ b/src/diagrams/class/svgDraw.js @@ -278,7 +278,7 @@ export const drawClass = function(elem, classDef, conf) { }; export const parseMember = function(text) { - const fieldRegEx = /^(\+|-|~|#)?(\w+)(~\w+~|\[\])?\s+(\w+)$/; + const fieldRegEx = /(\+|-|~|#)?(\w+)(~\w+~|\[\])?\s+(\w+)/; const methodRegEx = /(\+|-|~|#)?(\w+)\((.*)\)(\*|\$)? *(.*)?/; ///^(\+|-|~|#)?(\w+)\((.*)\)(\*|\$)?[ ]*(.*)?$/; From 969a4e7ba5717871d5ba927576bac7a9762bfe52 Mon Sep 17 00:00:00 2001 From: Justin Greywolf Date: Tue, 9 Jun 2020 14:25:03 -0700 Subject: [PATCH 5/6] 1378-refine legacy member parsing to cover additional cases --- src/diagrams/class/svgDraw.js | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/src/diagrams/class/svgDraw.js b/src/diagrams/class/svgDraw.js index 828824f05..aead8ded3 100644 --- a/src/diagrams/class/svgDraw.js +++ b/src/diagrams/class/svgDraw.js @@ -279,8 +279,7 @@ export const drawClass = function(elem, classDef, conf) { export const parseMember = function(text) { const fieldRegEx = /(\+|-|~|#)?(\w+)(~\w+~|\[\])?\s+(\w+)/; - const methodRegEx = /(\+|-|~|#)?(\w+)\((.*)\)(\*|\$)? *(.*)?/; - ///^(\+|-|~|#)?(\w+)\((.*)\)(\*|\$)?[ ]*(.*)?$/; + const methodRegEx = /^([+|\-|~|#])?(\w+) *\( *(.*)\) *(\*|\$)? *(\w*[~|[\]]*\s*\w*~?)$/; let fieldMatch = text.match(fieldRegEx); let methodMatch = text.match(methodRegEx); @@ -299,10 +298,11 @@ const buildFieldDisplay = function(parsedText) { try { let visibility = parsedText[1] ? parsedText[1].trim() : ''; - let fieldType = parsedText[2] ? parseGenericTypes(parsedText[2]) : ''; + let fieldType = parsedText[2] ? parsedText[2].trim() : ''; + let genericType = parsedText[3] ? parseGenericTypes(parsedText[3].trim()) : ''; let fieldName = parsedText[4] ? parsedText[4].trim() : ''; - displayText = visibility + fieldType + ' ' + fieldName; + displayText = visibility + fieldType + genericType + ' ' + fieldName; } catch (err) { displayText = parsedText; } @@ -320,7 +320,7 @@ const buildMethodDisplay = function(parsedText) { try { let visibility = parsedText[1] ? parsedText[1].trim() : ''; let methodName = parsedText[2] ? parsedText[2].trim() : ''; - let parameters = parsedText[3] ? parseGenericTypes(parsedText[3]) : ''; + let parameters = parsedText[3] ? parseGenericTypes(parsedText[3].trim()) : ''; let classifier = parsedText[4] ? parsedText[4].trim() : ''; let returnType = parsedText[5] ? ' : ' + parseGenericTypes(parsedText[5]).trim() : ''; @@ -347,11 +347,22 @@ const buildLegacyDisplay = function(text) { let methodEnd = text.indexOf(')'); if (methodStart > 1 && methodEnd > methodStart && methodEnd <= text.length) { - let parsedText = text.match(/(\+|-|~|#)?(\w+)/); - let visibility = parsedText[1] ? parsedText[1].trim() : ''; - let methodName = text.substring(0, methodStart); + let visibility = ''; + let methodName = ''; + + let firstChar = text.substring(0, 1); + if (firstChar.match(/\w/)) { + methodName = text.substring(0, methodStart).trim(); + } else { + if (firstChar.match(/\+|-|~|#/)) { + visibility = firstChar; + } + + methodName = text.substring(1, methodStart).trim(); + } + let parameters = text.substring(methodStart + 1, methodEnd); - let classifier = text.substring(methodEnd, methodEnd + 1); + let classifier = text.substring(methodEnd + 1, 1); cssStyle = parseClassifier(classifier); displayText = visibility + methodName + '(' + parseGenericTypes(parameters.trim()) + ')'; From 67e167427cbfac981afbcaafbc5595c1b49a7b44 Mon Sep 17 00:00:00 2001 From: Justin Greywolf Date: Tue, 9 Jun 2020 14:54:08 -0700 Subject: [PATCH 6/6] 1378-Added additional test --- src/diagrams/class/svgDraw.spec.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/diagrams/class/svgDraw.spec.js b/src/diagrams/class/svgDraw.spec.js index 2a8273e13..b6e26dbf8 100644 --- a/src/diagrams/class/svgDraw.spec.js +++ b/src/diagrams/class/svgDraw.spec.js @@ -83,6 +83,14 @@ describe('class member Renderer, ', function () { expect(actual.cssStyle).toBe(''); }); + it('should handle simple method declaration with multiple parameters', function () { + const str = 'foo(int id, object thing)'; + let actual = svgDraw.parseMember(str); + + expect(actual.displayText).toBe('foo(int id, object thing)'); + expect(actual.cssStyle).toBe(''); + }); + it('should handle simple method declaration with single item in parameters', function () { const str = 'foo(id)'; let actual = svgDraw.parseMember(str);