├── .gitignore ├── LICENSE ├── README.md ├── code-analyzer.js ├── code-generator.js ├── codegen-utils.js ├── grammar ├── build.sh ├── java7.jison ├── java7.jisonlex └── java7.js ├── main.js ├── menus └── menu.json ├── package.json ├── preferences └── preference.json └── unittest-files ├── generate └── CodeGenTestModel.mdj ├── parse ├── AnnotationTypeTest.java ├── AnnotationTypeTest_ast.json ├── AssociationTest.java ├── ClassTest.java ├── ClassTest_ast.json ├── EnumTest.java ├── EnumTest_ast.json ├── GenericClassTest.java ├── GenericClassTest_ast.json ├── InterfaceTest.java ├── InterfaceTest_ast.json └── test.sh └── reverse ├── AnnotationTypeTest.java ├── ClassAbstractTest.java ├── ClassAccessModifiersTest.java ├── ClassConstructorTest.java ├── ClassExtendsTest.java ├── ClassFinalTest.java ├── ClassGenericTest.java ├── ClassImplementsTest.java ├── ClassTest.java ├── EnumTest.java ├── FieldAccessModifiersTest.java ├── FieldInitializersTest.java ├── FieldModifiersTest.java ├── FieldMultipleVariablesTest.java ├── FieldTypesTest.java ├── InterfaceExtendsTest.java ├── InterfaceTest.java ├── JavaDocAnnotationTypeTest.java ├── JavaDocClassTest.java ├── JavaDocEnumTest.java ├── JavaDocInterfaceTest.java ├── MethodGenericTest.java ├── MethodModifiersTest.java ├── MethodParametersTest.java ├── MethodReturnTypeTest.java ├── MethodTest.java ├── MethodThrowsTest.java └── PackageTest.java /.gitignore: -------------------------------------------------------------------------------- 1 | Thumbs.db 2 | 3 | # ignore node_modules created by grunt, but not more deeply-nested node_modules 4 | /node_modules 5 | /npm-debug.log 6 | 7 | #OSX .DS_Store files 8 | .DS_Store 9 | 10 | #Java Test Sources 11 | /unittest-files/src-jdk 12 | jisonOutput.txt 13 | ### Node template 14 | # Logs 15 | logs 16 | *.log 17 | npm-debug.log* 18 | yarn-debug.log* 19 | yarn-error.log* 20 | 21 | # Runtime data 22 | pids 23 | *.pid 24 | *.seed 25 | *.pid.lock 26 | 27 | # Directory for instrumented libs generated by jscoverage/JSCover 28 | lib-cov 29 | 30 | # Coverage directory used by tools like istanbul 31 | coverage 32 | 33 | # nyc test coverage 34 | .nyc_output 35 | 36 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files) 37 | .grunt 38 | 39 | # Bower dependency directory (https://bower.io/) 40 | bower_components 41 | 42 | # node-waf configuration 43 | .lock-wscript 44 | 45 | # Compiled binary addons (https://nodejs.org/api/addons.html) 46 | build/Release 47 | 48 | # Dependency directories 49 | node_modules/ 50 | jspm_packages/ 51 | 52 | # TypeScript v1 declaration files 53 | typings/ 54 | 55 | # Optional npm cache directory 56 | .npm 57 | 58 | # Optional eslint cache 59 | .eslintcache 60 | 61 | # Optional REPL history 62 | .node_repl_history 63 | 64 | # Output of 'npm pack' 65 | *.tgz 66 | 67 | # Yarn Integrity file 68 | .yarn-integrity 69 | 70 | # dotenv environment variables file 71 | .env 72 | 73 | # parcel-bundler cache (https://parceljs.org/) 74 | .cache 75 | 76 | # next.js build output 77 | .next 78 | 79 | # nuxt.js build output 80 | .nuxt 81 | 82 | # vuepress build output 83 | .vuepress/dist 84 | 85 | # Serverless directories 86 | .serverless 87 | ### Eclipse template 88 | 89 | .metadata 90 | bin/ 91 | tmp/ 92 | *.tmp 93 | *.bak 94 | *.swp 95 | *~.nib 96 | local.properties 97 | .settings/ 98 | .loadpath 99 | .recommenders 100 | 101 | # External tool builders 102 | .externalToolBuilders/ 103 | 104 | # Locally stored "Eclipse launch configurations" 105 | *.launch 106 | 107 | # PyDev specific (Python IDE for Eclipse) 108 | *.pydevproject 109 | 110 | # CDT-specific (C/C++ Development Tooling) 111 | .cproject 112 | 113 | # CDT- autotools 114 | .autotools 115 | 116 | # Java annotation processor (APT) 117 | .factorypath 118 | 119 | # PDT-specific (PHP Development Tools) 120 | .buildpath 121 | 122 | # sbteclipse plugin 123 | .target 124 | 125 | # Tern plugin 126 | .tern-project 127 | 128 | # TeXlipse plugin 129 | .texlipse 130 | 131 | # STS (Spring Tool Suite) 132 | .springBeans 133 | 134 | # Code Recommenders 135 | .recommenders/ 136 | 137 | # Annotation Processing 138 | .apt_generated/ 139 | 140 | # Scala IDE specific (Scala & Java development for Eclipse) 141 | .cache-main 142 | .scala_dependencies 143 | .worksheet 144 | ### Linux template 145 | *~ 146 | 147 | # temporary files which can be created if a process still has a handle open of a deleted file 148 | .fuse_hidden* 149 | 150 | # KDE directory preferences 151 | .directory 152 | 153 | # Linux trash folder which might appear on any partition or disk 154 | .Trash-* 155 | 156 | # .nfs files are created when an open file is removed but is still being accessed 157 | .nfs* 158 | ### JetBrains template 159 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm 160 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 161 | 162 | # ignore .idea directory 163 | .idea/ 164 | 165 | # CMake 166 | cmake-build-*/ 167 | 168 | # File-based project format 169 | *.iws 170 | 171 | # IntelliJ 172 | out/ 173 | 174 | # mpeltonen/sbt-idea plugin 175 | .idea_modules/ 176 | 177 | # JIRA plugin 178 | atlassian-ide-plugin.xml 179 | 180 | # Crashlytics plugin (for Android Studio and IntelliJ) 181 | com_crashlytics_export_strings.xml 182 | crashlytics.properties 183 | crashlytics-build.properties 184 | fabric.properties 185 | 186 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014-2018 MKLab. All rights reserved. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a 4 | copy of this software and associated documentation files (the "Software"), 5 | to deal in the Software without restriction, including without limitation 6 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | and/or sell copies of the Software, and to permit persons to whom the 8 | Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in 11 | all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 18 | FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 19 | DEALINGS IN THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Java Extension for StarUML 2 | 3 | This extension for StarUML(http://staruml.io) support to generate Java code from UML model and to reverse Java code to UML model. Install this extension from Extension Manager of StarUML. 4 | 5 | > :warning: This extensions do not provide perfect reverse engineering which is a test and temporal feature. If you need a complete reverse engineering feature, please check other professional reverse engineering tools. 6 | 7 | > :white_check_mark: This extension is based on Java 1.7 Specification. 8 | 9 | ## Java Code Generation 10 | 11 | 1. Click the menu (`Tools > Java > Generate Code...`) 12 | 2. Select a base model (or package) that will be generated to Java. 13 | 3. Select a folder where generated Java source files will be placed. 14 | 15 | Belows are the rules to convert from UML model elements to Java source codes. 16 | 17 | ### UMLPackage 18 | 19 | - converted to _Java Package_ (as a folder). 20 | 21 | ### UMLClass 22 | 23 | - converted to _Java Class_. (as a separate `.java` file) 24 | - `visibility` to one of modifiers `public`, `protected`, `private` and none. 25 | - `isAbstract` property to `abstract` modifier. 26 | - `isFinalSpecialization` and `isLeaf` property to `final` modifier. 27 | - Default constructor is generated. 28 | - All contained types (_UMLClass_, _UMLInterface_, _UMLEnumeration_) are generated as inner type definition. 29 | - Documentation property to JavaDoc comment. 30 | 31 | ### UMLAttribute 32 | 33 | - converted to _Java Field_. 34 | - `visibility` property to one of modifiers `public`, `protected`, `private` and none. 35 | - `name` property to field identifier. 36 | - `type` property to field type. 37 | - `multiplicity` property to array type. 38 | - `isStatic` property to `static` modifier. 39 | - `isLeaf` property to `final` modifier. 40 | - `defaultValue` property to initial value. 41 | - Documentation property to JavaDoc comment. 42 | 43 | ### UMLOperation 44 | 45 | - converted to _Java Methods_. 46 | - `visibility` property to one of modifiers `public`, `protected`, `private` and none. 47 | - `name` property to method identifier. 48 | - `isAbstract` property to `abstract` modifier. 49 | - `isStatic` property to `static` modifier. 50 | - _UMLParameter_ to _Java Method Parameters_. 51 | - _UMLParameter_'s name property to parameter identifier. 52 | - _UMLParameter_'s type property to type of parameter. 53 | - _UMLParameter_ with `direction` = `return` to return type of method. When no return parameter, `void` is used. 54 | - _UMLParameter_ with `isReadOnly` = `true` to `final` modifier of parameter. 55 | - Documentation property to JavaDoc comment. 56 | 57 | ### UMLInterface 58 | 59 | - converted to _Java Interface_. (as a separate `.java` file) 60 | - `visibility` property to one of modifiers `public`, `protected`, `private` and none. 61 | - Documentation property to JavaDoc comment. 62 | 63 | ### UMLEnumeration 64 | 65 | - converted to _Java Enum_. (as a separate `.java` file) 66 | - `visibility` property to one of modifiers `public`, `protected`, `private` and none. 67 | - _UMLEnumerationLiteral_ to literals of enum. 68 | 69 | ### UMLAssociationEnd 70 | 71 | - converted to _Java Field_. 72 | - `visibility` property to one of modifiers `public`, `protected`, `private` and none. 73 | - `name` property to field identifier. 74 | - `type` property to field type. 75 | - If `multiplicity` is one of `0..*`, `1..*`, `*`, then collection type (`java.util.List<>` when `isOrdered` = `true` or `java.util.Set<>`) is used. 76 | - `defaultValue` property to initial value. 77 | - Documentation property to JavaDoc comment. 78 | 79 | ### UMLGeneralization 80 | 81 | - converted to _Java Extends_ (`extends`). 82 | - Allowed only for _UMLClass_ to _UMLClass_, and _UMLInterface_ to _UMLInterface_. 83 | 84 | ### UMLInterfaceRealization 85 | 86 | - converted to _Java Implements_ (`implements`). 87 | - Allowed only for _UMLClass_ to _UMLInterface_. 88 | 89 | ## Java Reverse Engineering 90 | 91 | 1. Click the menu (`Tools > Java > Reverse Code...`) 92 | 2. Select a folder containing Java source files to be converted to UML model elements. 93 | 3. `JavaReverse` model will be created in the Project. 94 | 95 | Belows are the rules to convert from Java source code to UML model elements. 96 | 97 | ### Java Package 98 | 99 | - converted to _UMLPackage_. 100 | 101 | ### Java Class 102 | 103 | - converted to _UMLClass_. 104 | - Class name to `name` property. 105 | - Type parameters to _UMLTemplateParameter_. 106 | - Access modifier `public`, `protected` and `private` to `visibility` property. 107 | - `abstract` modifier to `isAbstract` property. 108 | - `final` modifier to `isLeaf` property. 109 | - Constructors to _UMLOperation_ with stereotype `<>`. 110 | - All contained types (_UMLClass_, _UMLInterface_, _UMLEnumeration_) are generated as inner type definition. 111 | - JavaDoc comment to Documentation. 112 | 113 | ### Java Field (to UMLAttribute) 114 | 115 | - converted to _UMLAttribute_ if **"Use Association"** is **off** in Preferences. 116 | - Field type to `type` property. 117 | 118 | - Primitive Types : `type` property has the primitive type name as string. 119 | - `T[]`(array), `java.util.List`, `java.util.Set` or its decendants: `type` property refers to `T` with multiplicity `*`. 120 | - `T` (User-Defined Types) : `type` property refers to the `T` type. 121 | - Otherwise : `type` property has the type name as string. 122 | 123 | - Access modifier `public`, `protected` and `private` to `visibility` property. 124 | - `static` modifier to `isStatic` property. 125 | - `final` modifier to `isLeaf` and `isReadOnly` property. 126 | - `transient` modifier to a Tag with `name="transient"` and `checked=true` . 127 | - `volatile` modifier to a Tag with `name="volatile"` and `checked=true`. 128 | - Initial value to `defaultValue` property. 129 | - JavaDoc comment to Documentation. 130 | 131 | ### Java Field (to UMLAssociation) 132 | 133 | - converted to (Directed) _UMLAssociation_ if **"Use Association"** is **on** in Preferences and there is a UML type element (_UMLClass_, _UMLInterface_, or _UMLEnumeration_) correspond to the field type. 134 | - Field type to `end2.reference` property. 135 | 136 | - `T[]`(array), `java.util.List`, `java.util.Set` or its decendants: `reference` property refers to `T` with multiplicity `*`. 137 | - `T` (User-Defined Types) : `reference` property refers to the `T` type. 138 | - Otherwise : converted to _UMLAttribute_, not _UMLAssociation_. 139 | 140 | - Access modifier `public`, `protected` and `private` to `visibility` property. 141 | - JavaDoc comment to Documentation. 142 | 143 | ### Java Method 144 | 145 | - converted to _UMLOperation_. 146 | - Type parameters to _UMLTemplateParameter_. 147 | - Access modifier `public`, `protected` and `private` to `visibility` property. 148 | - `static` modifier to `isStatic` property. 149 | - `abstract` modifier to `isAbstract` property. 150 | - `final` modifier to `isLeaf` property. 151 | - `synchronized` modifier to `concurrency="concurrent"` property. 152 | - `native` modifier to a Tag with `name="native"` and `checked=true`. 153 | - `strictfp` modifier to a Tag with `name="strictfp"` and `checked=true`. 154 | - `throws` clauses to `raisedExceptions` property. 155 | - JavaDoc comment to Documentation. 156 | 157 | ### Java Interface 158 | 159 | - converted to _UMLInterface_. 160 | - Class name to `name` property. 161 | - Type parameters to _UMLTemplateParameter_. 162 | - Access modifier `public`, `protected` and `private` to `visibility` property. 163 | - JavaDoc comment to Documentation. 164 | 165 | ### Java Enum 166 | 167 | - converted to _UMLEnumeration_. 168 | - Enum name to `name` property. 169 | - Type parameters to _UMLTemplateParameter_. 170 | - Access modifier `public`, `protected` and `private` to `visibility` property. 171 | - Enum constants are converted to _UMLEnumerationLiteral_. 172 | - JavaDoc comment to Documentation. 173 | 174 | ### Java AnnotationType 175 | 176 | - converted to _UMLClass_ with stereotype `<>`. 177 | - Annotation type elements to _UMLOperation_. (Default value to a Tag with `name="default"`). 178 | - JavaDoc comment to Documentation. 179 | 180 | --- 181 | 182 | Licensed under the MIT license (see LICENSE file). 183 | -------------------------------------------------------------------------------- /code-analyzer.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2018 MKLab. All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | * 22 | */ 23 | 24 | const fs = require("fs"); 25 | const path = require("path"); 26 | const java7 = require("./grammar/java7"); 27 | 28 | // Java Primitive Types 29 | var javaPrimitiveTypes = [ 30 | "void", 31 | "byte", 32 | "short", 33 | "int", 34 | "long", 35 | "float", 36 | "double", 37 | "boolean", 38 | "char", 39 | "Byte", 40 | "Double", 41 | "Float", 42 | "Integer", 43 | "Long", 44 | "Short", 45 | "String", 46 | "Character", 47 | "java.lang.Byte", 48 | "java.lang.Double", 49 | "java.lang.Float", 50 | "java.lang.Integer", 51 | "java.lang.Long", 52 | "java.lang.Short", 53 | "java.lang.String", 54 | "java.lang.Character", 55 | ]; 56 | 57 | // Java Collection Types 58 | var javaCollectionTypes = [ 59 | "Collection", 60 | "Set", 61 | "SortedSet", 62 | "NavigableSet", 63 | "HashSet", 64 | "TreeSet", 65 | "LinkedHashSet", 66 | "List", 67 | "ArrayList", 68 | "LinkedList", 69 | "Deque", 70 | "ArrayDeque", 71 | "Queue", 72 | ]; 73 | 74 | // Java Collection Types (full names) 75 | var javaUtilCollectionTypes = javaCollectionTypes.map((c) => { 76 | return "java.util." + c; 77 | }); 78 | 79 | /** 80 | * Java Code Analyzer 81 | */ 82 | class JavaCodeAnalyzer { 83 | /** 84 | * @constructor 85 | */ 86 | constructor() { 87 | /** @member {type.UMLModel} */ 88 | this._root = new type.UMLModel(); 89 | this._root.name = "JavaReverse"; 90 | 91 | /** @member {Array.} */ 92 | this._files = []; 93 | 94 | /** @member {Object} */ 95 | this._currentCompilationUnit = null; 96 | 97 | /** 98 | * @member {{classifier:type.UMLClassifier, node: Object, kind:string}} 99 | */ 100 | this._extendPendings = []; 101 | 102 | /** 103 | * @member {{classifier:type.UMLClassifier, node: Object}} 104 | */ 105 | this._implementPendings = []; 106 | 107 | /** 108 | * @member {{classifier:type.UMLClassifier, association: type.UMLAssociation, node: Object}} 109 | */ 110 | this._associationPendings = []; 111 | 112 | /** 113 | * @member {{operation:type.UMLOperation, node: Object}} 114 | */ 115 | this._throwPendings = []; 116 | 117 | /** 118 | * @member {{namespace:type.UMLModelElement, feature:type.UMLStructuralFeature, node: Object}} 119 | */ 120 | this._typedFeaturePendings = []; 121 | } 122 | 123 | /** 124 | * Add File to Reverse Engineer 125 | * @param {File} file 126 | */ 127 | addFile(file) { 128 | this._files.push(file); 129 | } 130 | 131 | /** 132 | * Analyze all files. 133 | * @param {Object} options 134 | */ 135 | analyze(options) { 136 | // Perform 1st Phase 137 | this.performFirstPhase(options); 138 | 139 | // Perform 2nd Phase 140 | this.performSecondPhase(options); 141 | 142 | // Load To Project 143 | var writer = new app.repository.Writer(); 144 | writer.writeObj("data", this._root); 145 | var json = writer.current.data; 146 | app.project.importFromJson(app.project.getProject(), json); 147 | 148 | // Generate Diagrams 149 | this.generateDiagrams(options); 150 | console.log("[Java] done."); 151 | } 152 | 153 | /** 154 | * Perform First Phase 155 | * - Create Packages, Classes, Interfaces, Enums, AnnotationTypes. 156 | * 157 | * @param {Object} options 158 | */ 159 | performFirstPhase(options) { 160 | this._files.forEach((file) => { 161 | var data = fs.readFileSync(file, "utf8"); 162 | try { 163 | /* Not processing empty file @author Rtfsc8(rtfsc8@rtfsc8.top) */ 164 | if (!!!data) { 165 | return; 166 | } 167 | var ast = java7.parse(data); 168 | this._currentCompilationUnit = ast; 169 | this._currentCompilationUnit.file = file; 170 | this.translateCompilationUnit(options, this._root, ast); 171 | } catch (ex) { 172 | console.error("[Java] Failed to parse - " + file); 173 | console.error(ex); 174 | } 175 | }); 176 | } 177 | 178 | /** 179 | * Perform Second Phase 180 | * - Create Generalizations 181 | * - Create InterfaceRealizations 182 | * - Create Fields or Associations 183 | * - Resolve Type References 184 | * 185 | * @param {Object} options 186 | */ 187 | performSecondPhase(options) { 188 | var i, len, j, len2, _typeName, _type, _itemTypeName, _itemType, _pathName; 189 | 190 | // Create Generalizations 191 | // if super type not found, create a Class correspond to the super type. 192 | for (i = 0, len = this._extendPendings.length; i < len; i++) { 193 | var _extend = this._extendPendings[i]; 194 | _typeName = _extend.node.qualifiedName.name; 195 | 196 | _type = this._findType( 197 | _extend.classifier, 198 | _typeName, 199 | _extend.compilationUnitNode, 200 | ); 201 | if (!_type) { 202 | _pathName = this._toPathName(_typeName); 203 | if (_extend.kind === "interface") { 204 | _type = this._ensureInterface(this._root, _pathName); 205 | } else { 206 | _type = this._ensureClass(this._root, _pathName); 207 | } 208 | } 209 | 210 | var generalization = new type.UMLGeneralization(); 211 | generalization._parent = _extend.classifier; 212 | generalization.source = _extend.classifier; 213 | generalization.target = _type; 214 | _extend.classifier.ownedElements.push(generalization); 215 | } 216 | 217 | // Create InterfaceRealizations 218 | // if super interface not found, create a Interface correspond to the super interface 219 | for (i = 0, len = this._implementPendings.length; i < len; i++) { 220 | var _implement = this._implementPendings[i]; 221 | _typeName = _implement.node.qualifiedName.name; 222 | _type = this._findType( 223 | _implement.classifier, 224 | _typeName, 225 | _implement.compilationUnitNode, 226 | ); 227 | if (!_type) { 228 | _pathName = this._toPathName(_typeName); 229 | _type = this._ensureInterface(this._root, _pathName); 230 | } 231 | var realization = new type.UMLInterfaceRealization(); 232 | realization._parent = _implement.classifier; 233 | realization.source = _implement.classifier; 234 | realization.target = _type; 235 | _implement.classifier.ownedElements.push(realization); 236 | } 237 | 238 | // Create Associations 239 | for (i = 0, len = this._associationPendings.length; i < len; i++) { 240 | var _asso = this._associationPendings[i]; 241 | _typeName = _asso.node.type.qualifiedName.name; 242 | _type = this._findType( 243 | _asso.classifier, 244 | _typeName, 245 | _asso.node.compilationUnitNode, 246 | ); 247 | _itemTypeName = this._isGenericCollection( 248 | _asso.node.type, 249 | _asso.node.compilationUnitNode, 250 | ); 251 | if (_itemTypeName) { 252 | _itemType = this._findType( 253 | _asso.classifier, 254 | _itemTypeName, 255 | _asso.node.compilationUnitNode, 256 | ); 257 | } else { 258 | _itemType = null; 259 | } 260 | 261 | // if type found, add as Association 262 | if (_type || _itemType) { 263 | for (j = 0, len2 = _asso.node.variables.length; j < len2; j++) { 264 | var variableNode = _asso.node.variables[j]; 265 | 266 | // Create Association 267 | var association = new type.UMLAssociation(); 268 | association._parent = _asso.classifier; 269 | _asso.classifier.ownedElements.push(association); 270 | 271 | // Set End1 272 | association.end1.reference = _asso.classifier; 273 | association.end1.name = ""; 274 | association.end1.visibility = type.UMLModelElement.VK_PACKAGE; 275 | association.end1.navigable = false; 276 | 277 | // Set End2 278 | if (_itemType) { 279 | association.end2.reference = _itemType; 280 | association.end2.multiplicity = "*"; 281 | this._addTag( 282 | association.end2, 283 | type.Tag.TK_STRING, 284 | "collection", 285 | _asso.node.type.qualifiedName.name, 286 | ); 287 | } else { 288 | association.end2.reference = _type; 289 | } 290 | association.end2.name = variableNode.name; 291 | association.end2.visibility = this._getVisibility( 292 | _asso.node.modifiers, 293 | ); 294 | association.end2.navigable = true; 295 | 296 | // Final Modifier 297 | if (_asso.node.modifiers && _asso.node.modifiers.includes("final")) { 298 | association.end2.isReadOnly = true; 299 | } 300 | 301 | // Static Modifier 302 | if (_asso.node.modifiers && _asso.node.modifiers.includes("static")) { 303 | this._addTag(association.end2, type.Tag.TK_BOOLEAN, "static", true); 304 | } 305 | 306 | // Volatile Modifier 307 | if ( 308 | _asso.node.modifiers && 309 | _asso.node.modifiers.includes("volatile") 310 | ) { 311 | this._addTag( 312 | association.end2, 313 | type.Tag.TK_BOOLEAN, 314 | "volatile", 315 | true, 316 | ); 317 | } 318 | 319 | // Transient Modifier 320 | if ( 321 | _asso.node.modifiers && 322 | _asso.node.modifiers.includes("transient") 323 | ) { 324 | this._addTag( 325 | association.end2, 326 | type.Tag.TK_BOOLEAN, 327 | "transient", 328 | true, 329 | ); 330 | } 331 | } 332 | // if type not found, add as Attribute 333 | } else { 334 | this.translateFieldAsAttribute(options, _asso.classifier, _asso.node); 335 | } 336 | } 337 | 338 | // Assign Throws to Operations 339 | for (i = 0, len = this._throwPendings.length; i < len; i++) { 340 | var _throw = this._throwPendings[i]; 341 | _typeName = _throw.node.name; 342 | _type = this._findType( 343 | _throw.operation, 344 | _typeName, 345 | _throw.compilationUnitNode, 346 | ); 347 | if (!_type) { 348 | _pathName = this._toPathName(_typeName); 349 | _type = this._ensureClass(this._root, _pathName); 350 | } 351 | _throw.operation.raisedExceptions.push(_type); 352 | } 353 | 354 | // Resolve Type References 355 | for (i = 0, len = this._typedFeaturePendings.length; i < len; i++) { 356 | var _typedFeature = this._typedFeaturePendings[i]; 357 | //Fix bug: some reverse code error like qualifiedName attribute undefined 358 | if (!!!_typedFeature.node.type.qualifiedName) { 359 | continue; 360 | } 361 | _typeName = _typedFeature.node.type.qualifiedName.name; 362 | 363 | // Find type and assign 364 | _type = this._findType( 365 | _typedFeature.namespace, 366 | _typeName, 367 | _typedFeature.node.compilationUnitNode, 368 | ); 369 | 370 | // if type is exists 371 | if (_type) { 372 | _typedFeature.feature.type = _type; 373 | // if type is not exists 374 | } else { 375 | // if type is generic collection type (e.g. java.util.List) 376 | _itemTypeName = this._isGenericCollection( 377 | _typedFeature.node.type, 378 | _typedFeature.node.compilationUnitNode, 379 | ); 380 | if (_itemTypeName) { 381 | _typeName = _itemTypeName; 382 | _typedFeature.feature.multiplicity = "*"; 383 | this._addTag( 384 | _typedFeature.feature, 385 | type.Tag.TK_STRING, 386 | "collection", 387 | _typedFeature.node.type.qualifiedName.name, 388 | ); 389 | } 390 | 391 | // if type is primitive type 392 | if (javaPrimitiveTypes.includes(_typeName)) { 393 | _typedFeature.feature.type = _typeName; 394 | // otherwise 395 | } else { 396 | _pathName = this._toPathName(_typeName); 397 | var _newClass = this._ensureClass(this._root, _pathName); 398 | _typedFeature.feature.type = _newClass; 399 | } 400 | } 401 | 402 | // Translate type's arrayDimension to multiplicity 403 | if ( 404 | _typedFeature.node.type.arrayDimension && 405 | _typedFeature.node.type.arrayDimension.length > 0 406 | ) { 407 | var _dim = []; 408 | for ( 409 | j = 0, len2 = _typedFeature.node.type.arrayDimension.length; 410 | j < len2; 411 | j++ 412 | ) { 413 | _dim.push("*"); 414 | } 415 | _typedFeature.feature.multiplicity = _dim.join(","); 416 | } 417 | } 418 | } 419 | 420 | /** 421 | * Generate Diagrams (Type Hierarchy, Package Structure, Package Overview) 422 | * @param {Object} options 423 | */ 424 | generateDiagrams(options) { 425 | var baseModel = app.repository.get(this._root._id); 426 | if (options.packageStructure) { 427 | app.commands.execute( 428 | "diagram-generator:package-structure", 429 | baseModel, 430 | true, 431 | ); 432 | } 433 | if (options.typeHierarchy) { 434 | app.commands.execute("diagram-generator:type-hierarchy", baseModel, true); 435 | } 436 | if (options.packageOverview) { 437 | baseModel.traverse((elem) => { 438 | if (elem instanceof type.UMLPackage) { 439 | app.commands.execute("diagram-generator:overview", elem, true); 440 | } 441 | }); 442 | } 443 | } 444 | 445 | /** 446 | * Convert string type name to path name (Array of string) 447 | * @param {string} typeName 448 | * @return {Array.} pathName 449 | */ 450 | _toPathName(typeName) { 451 | var pathName = 452 | typeName.indexOf(".") > 0 ? typeName.trim().split(".") : null; 453 | if (!pathName) { 454 | pathName = [typeName]; 455 | } 456 | return pathName; 457 | } 458 | 459 | /** 460 | * Find Type. 461 | * 462 | * @param {type.Model} namespace 463 | * @param {string|Object} type Type name string or type node. 464 | * @param {Object} compilationUnitNode To search type with import statements. 465 | * @return {type.Model} element correspond to the type. 466 | */ 467 | _findType(namespace, type, compilationUnitNode) { 468 | var typeName, pathName; 469 | var _type = null; 470 | 471 | if (type.node === "Type") { 472 | typeName = type.qualifiedName.name; 473 | } else if (typeof type === "string") { 474 | typeName = type; 475 | } 476 | 477 | pathName = this._toPathName(typeName); 478 | 479 | // 1. Lookdown from context 480 | if (pathName.length > 1) { 481 | _type = namespace.lookdown(pathName); 482 | } else { 483 | _type = namespace.findByName(typeName); 484 | } 485 | 486 | // 2. Lookup from context 487 | if (!_type) { 488 | _type = namespace.lookup(typeName, null, this._root); 489 | } 490 | 491 | // 3. Find from imported namespaces 492 | if (!_type) { 493 | if (compilationUnitNode.imports) { 494 | var i, len; 495 | for (i = 0, len = compilationUnitNode.imports.length; i < len; i++) { 496 | var _import = compilationUnitNode.imports[i]; 497 | // Find in wildcard imports (e.g. import java.lang.*) 498 | if (_import.wildcard) { 499 | var _namespace = this._root.lookdown(_import.qualifiedName.name); 500 | if (_namespace) { 501 | _type = _namespace.findByName(typeName); 502 | } 503 | // Find in import exact matches (e.g. import java.lang.String) 504 | } else { 505 | _type = this._root.lookdown(_import.qualifiedName.name); 506 | } 507 | } 508 | } 509 | } 510 | 511 | // 4. Lookdown from Root 512 | if (!_type) { 513 | if (pathName.length > 1) { 514 | _type = this._root.lookdown(pathName); 515 | } else { 516 | _type = this._root.findByName(typeName); 517 | } 518 | } 519 | 520 | return _type; 521 | } 522 | 523 | /** 524 | * Return visiblity from modifiers 525 | * 526 | * @param {Array.} modifiers 527 | * @return {string} Visibility constants for UML Elements 528 | */ 529 | _getVisibility(modifiers) { 530 | if (modifiers) { 531 | if (modifiers.includes("public")) { 532 | return type.UMLModelElement.VK_PUBLIC; 533 | } else if (modifiers.includes("protected")) { 534 | return type.UMLModelElement.VK_PROTECTED; 535 | } else if (modifiers.includes("private")) { 536 | return type.UMLModelElement.VK_PRIVATE; 537 | } 538 | } 539 | return type.UMLModelElement.VK_PACKAGE; 540 | } 541 | 542 | /** 543 | * Add a Tag 544 | * @param {type.Model} elem 545 | * @param {string} kind Kind of Tag 546 | * @param {string} name 547 | * @param {?} value Value of Tag 548 | */ 549 | _addTag(elem, kind, name, value) { 550 | var tag = new type.Tag(); 551 | tag._parent = elem; 552 | tag.name = name; 553 | tag.kind = kind; 554 | switch (kind) { 555 | case type.Tag.TK_STRING: 556 | tag.value = value; 557 | break; 558 | case type.Tag.TK_BOOLEAN: 559 | tag.checked = value; 560 | break; 561 | case type.Tag.TK_NUMBER: 562 | tag.number = value; 563 | break; 564 | case type.Tag.TK_REFERENCE: 565 | tag.reference = value; 566 | break; 567 | case type.Tag.TK_HIDDEN: 568 | tag.value = value; 569 | break; 570 | } 571 | elem.tags.push(tag); 572 | } 573 | 574 | /** 575 | * Return the package of a given pathNames. If not exists, create the package. 576 | * @param {type.Model} namespace 577 | * @param {Array.} pathNames 578 | * @return {type.Model} Package element corresponding to the pathNames 579 | */ 580 | _ensurePackage(namespace, pathNames) { 581 | if (pathNames.length > 0) { 582 | var name = pathNames.shift(); 583 | if (name && name.length > 0) { 584 | var elem = namespace.findByName(name); 585 | if (elem !== null) { 586 | // Package exists 587 | if (pathNames.length > 0) { 588 | return this._ensurePackage(elem, pathNames); 589 | } else { 590 | return elem; 591 | } 592 | } else { 593 | // Package not exists, then create one. 594 | var _package = new type.UMLPackage(); 595 | namespace.ownedElements.push(_package); 596 | _package._parent = namespace; 597 | _package.name = name; 598 | if (pathNames.length > 0) { 599 | return this._ensurePackage(_package, pathNames); 600 | } else { 601 | return _package; 602 | } 603 | } 604 | } 605 | } else { 606 | return namespace; 607 | } 608 | } 609 | 610 | /** 611 | * Return the class of a given pathNames. If not exists, create the class. 612 | * @param {type.Model} namespace 613 | * @param {Array.} pathNames 614 | * @return {type.Model} Class element corresponding to the pathNames 615 | */ 616 | _ensureClass(namespace, pathNames) { 617 | if (pathNames.length > 0) { 618 | var _className = pathNames.pop(); 619 | var _package = this._ensurePackage(namespace, pathNames); 620 | var _class = _package.findByName(_className); 621 | if (!_class) { 622 | _class = new type.UMLClass(); 623 | _class._parent = _package; 624 | _class.name = _className; 625 | _class.visibility = type.UMLModelElement.VK_PUBLIC; 626 | _package.ownedElements.push(_class); 627 | } 628 | return _class; 629 | } 630 | return null; 631 | } 632 | 633 | /** 634 | * Return the interface of a given pathNames. If not exists, create the interface. 635 | * @param {type.Model} namespace 636 | * @param {Array.} pathNames 637 | * @return {type.Model} Interface element corresponding to the pathNames 638 | */ 639 | _ensureInterface(namespace, pathNames) { 640 | if (pathNames.length > 0) { 641 | var _interfaceName = pathNames.pop(); 642 | var _package = this._ensurePackage(namespace, pathNames); 643 | var _interface = _package.findByName(_interfaceName); 644 | if (!_interface) { 645 | _interface = new type.UMLInterface(); 646 | _interface._parent = _package; 647 | _interface.name = _interfaceName; 648 | _interface.visibility = type.UMLModelElement.VK_PUBLIC; 649 | _package.ownedElements.push(_interface); 650 | } 651 | return _interface; 652 | } 653 | return null; 654 | } 655 | 656 | /** 657 | * Test a given type is a generic collection or not 658 | * @param {Object} typeNode 659 | * @return {string} Collection item type name 660 | */ 661 | _isGenericCollection(typeNode, compilationUnitNode) { 662 | if ( 663 | typeNode.qualifiedName.typeParameters && 664 | typeNode.qualifiedName.typeParameters.length > 0 665 | ) { 666 | var _collectionType = typeNode.qualifiedName.name; 667 | var _itemType = typeNode.qualifiedName.typeParameters[0].name; 668 | 669 | // Used Full name (e.g. java.util.List) 670 | if (javaUtilCollectionTypes.includes(_collectionType)) { 671 | return _itemType; 672 | } 673 | 674 | // Used name with imports (e.g. List and import java.util.List or java.util.*) 675 | if (javaCollectionTypes.includes(_collectionType)) { 676 | if (compilationUnitNode.imports) { 677 | var i, len; 678 | for (i = 0, len = compilationUnitNode.imports.length; i < len; i++) { 679 | var _import = compilationUnitNode.imports[i]; 680 | 681 | // Full name import (e.g. import java.util.List) 682 | if (_import.qualifiedName.name === "java.util." + _collectionType) { 683 | return _itemType; 684 | } 685 | 686 | // Wildcard import (e.g. import java.util.*) 687 | if ( 688 | _import.qualifiedName.name === "java.util" && 689 | _import.wildcard 690 | ) { 691 | return _itemType; 692 | } 693 | } 694 | } 695 | } 696 | } 697 | return null; 698 | } 699 | 700 | /** 701 | * Translate Java CompilationUnit Node. 702 | * @param {Object} options 703 | * @param {type.Model} namespace 704 | * @param {Object} compilationUnitNode 705 | */ 706 | translateCompilationUnit(options, namespace, compilationUnitNode) { 707 | var _namespace = namespace; 708 | 709 | if (compilationUnitNode["package"]) { 710 | var _package = this.translatePackage( 711 | options, 712 | namespace, 713 | compilationUnitNode["package"], 714 | ); 715 | if (_package !== null) { 716 | _namespace = _package; 717 | } 718 | } 719 | 720 | // Translate Types 721 | this.translateTypes(options, _namespace, compilationUnitNode.types); 722 | } 723 | 724 | /** 725 | * Translate Type Nodes 726 | * @param {Object} options 727 | * @param {type.Model} namespace 728 | * @param {Array.} typeNodeArray 729 | */ 730 | translateTypes(options, namespace, typeNodeArray) { 731 | var i, len; 732 | if (Array.isArray(typeNodeArray) && typeNodeArray.length > 0) { 733 | for (i = 0, len = typeNodeArray.length; i < len; i++) { 734 | var typeNode = typeNodeArray[i]; 735 | switch (typeNode.node) { 736 | case "Class": 737 | this.translateClass(options, namespace, typeNode); 738 | break; 739 | case "Interface": 740 | this.translateInterface(options, namespace, typeNode); 741 | break; 742 | case "Enum": 743 | this.translateEnum(options, namespace, typeNode); 744 | break; 745 | case "AnnotationType": 746 | this.translateAnnotationType(options, namespace, typeNode); 747 | break; 748 | } 749 | } 750 | } 751 | } 752 | 753 | /** 754 | * Translate Java Package Node. 755 | * @param {Object} options 756 | * @param {type.Model} namespace 757 | * @param {Object} compilationUnitNode 758 | */ 759 | translatePackage(options, namespace, packageNode) { 760 | if ( 761 | packageNode && 762 | packageNode.qualifiedName && 763 | packageNode.qualifiedName.name 764 | ) { 765 | var pathNames = packageNode.qualifiedName.name.split("."); 766 | return this._ensurePackage(namespace, pathNames); 767 | } 768 | return null; 769 | } 770 | 771 | /** 772 | * Translate Members Nodes 773 | * @param {Object} options 774 | * @param {type.Model} namespace 775 | * @param {Array.} memberNodeArray 776 | */ 777 | translateMembers(options, namespace, memberNodeArray) { 778 | var i, len; 779 | if (Array.isArray(memberNodeArray) && memberNodeArray.length > 0) { 780 | for (i = 0, len = memberNodeArray.length; i < len; i++) { 781 | var memberNode = memberNodeArray[i]; 782 | if (memberNode && typeof memberNode.node === "string") { 783 | var visibility = this._getVisibility(memberNode.modifiers); 784 | 785 | // Generate public members only if publicOnly == true 786 | if ( 787 | options.publicOnly && 788 | visibility !== type.UMLModelElement.VK_PUBLIC 789 | ) { 790 | continue; 791 | } 792 | 793 | memberNode.compilationUnitNode = this._currentCompilationUnit; 794 | 795 | switch (memberNode.node) { 796 | case "Field": 797 | if (options.association) { 798 | this.translateFieldAsAssociation( 799 | options, 800 | namespace, 801 | memberNode, 802 | ); 803 | } else { 804 | this.translateFieldAsAttribute(options, namespace, memberNode); 805 | } 806 | break; 807 | case "Constructor": 808 | this.translateMethod(options, namespace, memberNode, true); 809 | break; 810 | case "Method": 811 | this.translateMethod(options, namespace, memberNode); 812 | break; 813 | case "EnumConstant": 814 | this.translateEnumConstant(options, namespace, memberNode); 815 | break; 816 | } 817 | } 818 | } 819 | } 820 | } 821 | 822 | /** 823 | * Translate Java Type Parameter Nodes. 824 | * @param {Object} options 825 | * @param {type.Model} namespace 826 | * @param {Object} typeParameterNodeArray 827 | */ 828 | translateTypeParameters(options, namespace, typeParameterNodeArray) { 829 | if (Array.isArray(typeParameterNodeArray)) { 830 | var i, len, _typeParam; 831 | for (i = 0, len = typeParameterNodeArray.length; i < len; i++) { 832 | _typeParam = typeParameterNodeArray[i]; 833 | if (_typeParam.node === "TypeParameter") { 834 | var _templateParameter = new type.UMLTemplateParameter(); 835 | _templateParameter._parent = namespace; 836 | _templateParameter.name = _typeParam.name; 837 | if (_typeParam.type) { 838 | _templateParameter.parameterType = _typeParam.type; 839 | } 840 | namespace.templateParameters.push(_templateParameter); 841 | } 842 | } 843 | } 844 | } 845 | 846 | /** 847 | * Translate Java Class Node. 848 | * @param {Object} options 849 | * @param {type.Model} namespace 850 | * @param {Object} compilationUnitNode 851 | */ 852 | translateClass(options, namespace, classNode) { 853 | var i, len, _class; 854 | 855 | // Create Class 856 | _class = new type.UMLClass(); 857 | _class._parent = namespace; 858 | _class.name = classNode.name; 859 | 860 | // Access Modifiers 861 | _class.visibility = this._getVisibility(classNode.modifiers); 862 | 863 | // Abstract Class 864 | if (classNode.modifiers && classNode.modifiers.includes("abstract")) { 865 | _class.isAbstract = true; 866 | } 867 | 868 | // Final Class 869 | if (classNode.modifiers && classNode.modifiers.includes("final")) { 870 | _class.isFinalSpecialization = true; 871 | _class.isLeaf = true; 872 | } 873 | 874 | // JavaDoc 875 | if (classNode.comment) { 876 | _class.documentation = classNode.comment; 877 | } 878 | 879 | namespace.ownedElements.push(_class); 880 | 881 | // Register Extends for 2nd Phase Translation 882 | if (classNode["extends"]) { 883 | var _extendPending = { 884 | classifier: _class, 885 | node: classNode["extends"], 886 | kind: "class", 887 | compilationUnitNode: this._currentCompilationUnit, 888 | }; 889 | this._extendPendings.push(_extendPending); 890 | } 891 | 892 | // - 1) 타입이 소스에 있는 경우 --> 해당 타입으로 Generalization 생성 893 | // - 2) 타입이 소스에 없는 경우 (e.g. java.util.ArrayList) --> 타입을 생성(어디에?)한 뒤 Generalization 생성 894 | // 모든 타입이 생성된 다음에 Generalization (혹은 기타 Relationships)이 연결되어야 하므로, 어딘가에 등록한 다음이 2nd Phase에서 처리. 895 | 896 | // Register Implements for 2nd Phase Translation 897 | if (classNode["implements"]) { 898 | for (i = 0, len = classNode["implements"].length; i < len; i++) { 899 | var _impl = classNode["implements"][i]; 900 | var _implementPending = { 901 | classifier: _class, 902 | node: _impl, 903 | compilationUnitNode: this._currentCompilationUnit, 904 | }; 905 | this._implementPendings.push(_implementPending); 906 | } 907 | } 908 | // Translate Type Parameters 909 | this.translateTypeParameters(options, _class, classNode.typeParameters); 910 | // Translate Types 911 | this.translateTypes(options, _class, classNode.body); 912 | // Translate Members 913 | this.translateMembers(options, _class, classNode.body); 914 | } 915 | 916 | /** 917 | * Translate Java Interface Node. 918 | * @param {Object} options 919 | * @param {type.Model} namespace 920 | * @param {Object} interfaceNode 921 | */ 922 | translateInterface(options, namespace, interfaceNode) { 923 | var i, len, _interface; 924 | 925 | // Create Interface 926 | _interface = new type.UMLInterface(); 927 | _interface._parent = namespace; 928 | _interface.name = interfaceNode.name; 929 | _interface.visibility = this._getVisibility(interfaceNode.modifiers); 930 | 931 | // JavaDoc 932 | if (interfaceNode.comment) { 933 | _interface.documentation = interfaceNode.comment; 934 | } 935 | 936 | namespace.ownedElements.push(_interface); 937 | 938 | // Register Extends for 2nd Phase Translation 939 | if (interfaceNode["extends"]) { 940 | for (i = 0, len = interfaceNode["extends"].length; i < len; i++) { 941 | var _extend = interfaceNode["extends"][i]; 942 | this._extendPendings.push({ 943 | classifier: _interface, 944 | node: _extend, 945 | kind: "interface", 946 | compilationUnitNode: this._currentCompilationUnit, 947 | }); 948 | } 949 | } 950 | 951 | // Translate Type Parameters 952 | this.translateTypeParameters( 953 | options, 954 | _interface, 955 | interfaceNode.typeParameters, 956 | ); 957 | // Translate Types 958 | this.translateTypes(options, _interface, interfaceNode.body); 959 | // Translate Members 960 | this.translateMembers(options, _interface, interfaceNode.body); 961 | } 962 | 963 | /** 964 | * Translate Java Enum Node. 965 | * @param {Object} options 966 | * @param {type.Model} namespace 967 | * @param {Object} enumNode 968 | */ 969 | translateEnum(options, namespace, enumNode) { 970 | var _enum; 971 | 972 | // Create Enumeration 973 | _enum = new type.UMLEnumeration(); 974 | _enum._parent = namespace; 975 | _enum.name = enumNode.name; 976 | _enum.visibility = this._getVisibility(enumNode.modifiers); 977 | 978 | // JavaDoc 979 | if (enumNode.comment) { 980 | _enum.documentation = enumNode.comment; 981 | } 982 | 983 | namespace.ownedElements.push(_enum); 984 | 985 | // Translate Type Parameters 986 | this.translateTypeParameters(options, _enum, enumNode.typeParameters); 987 | // Translate Types 988 | this.translateTypes(options, _enum, enumNode.body); 989 | // Translate Members 990 | this.translateMembers(options, _enum, enumNode.body); 991 | } 992 | 993 | /** 994 | * Translate Java AnnotationType Node. 995 | * @param {Object} options 996 | * @param {type.Model} namespace 997 | * @param {Object} annotationTypeNode 998 | */ 999 | translateAnnotationType(options, namespace, annotationTypeNode) { 1000 | var _annotationType; 1001 | 1002 | // Create Class <> 1003 | _annotationType = new type.UMLClass(); 1004 | _annotationType._parent = namespace; 1005 | _annotationType.name = annotationTypeNode.name; 1006 | _annotationType.stereotype = "annotationType"; 1007 | _annotationType.visibility = this._getVisibility( 1008 | annotationTypeNode.modifiers, 1009 | ); 1010 | 1011 | // JavaDoc 1012 | if (annotationTypeNode.comment) { 1013 | _annotationType.documentation = annotationTypeNode.comment; 1014 | } 1015 | 1016 | namespace.ownedElements.push(_annotationType); 1017 | 1018 | // Translate Type Parameters 1019 | this.translateTypeParameters( 1020 | options, 1021 | _annotationType, 1022 | annotationTypeNode.typeParameters, 1023 | ); 1024 | // Translate Types 1025 | this.translateTypes(options, _annotationType, annotationTypeNode.body); 1026 | // Translate Members 1027 | this.translateMembers(options, _annotationType, annotationTypeNode.body); 1028 | } 1029 | 1030 | /** 1031 | * Translate Java Field Node as UMLAssociation. 1032 | * @param {Object} options 1033 | * @param {type.Model} namespace 1034 | * @param {Object} fieldNode 1035 | */ 1036 | translateFieldAsAssociation(options, namespace, fieldNode) { 1037 | if (fieldNode.variables && fieldNode.variables.length > 0) { 1038 | // Add to _associationPendings 1039 | var _associationPending = { 1040 | classifier: namespace, 1041 | node: fieldNode, 1042 | }; 1043 | this._associationPendings.push(_associationPending); 1044 | } 1045 | } 1046 | 1047 | /** 1048 | * Translate Java Field Node as UMLAttribute. 1049 | * @param {Object} options 1050 | * @param {type.Model} namespace 1051 | * @param {Object} fieldNode 1052 | */ 1053 | translateFieldAsAttribute(options, namespace, fieldNode) { 1054 | var i, len; 1055 | if (fieldNode.variables && fieldNode.variables.length > 0) { 1056 | for (i = 0, len = fieldNode.variables.length; i < len; i++) { 1057 | var variableNode = fieldNode.variables[i]; 1058 | 1059 | // Create Attribute 1060 | var _attribute = new type.UMLAttribute(); 1061 | _attribute._parent = namespace; 1062 | _attribute.name = variableNode.name; 1063 | 1064 | // Access Modifiers 1065 | _attribute.visibility = this._getVisibility(fieldNode.modifiers); 1066 | if (variableNode.initializer) { 1067 | _attribute.defaultValue = variableNode.initializer; 1068 | } 1069 | 1070 | // Static Modifier 1071 | if (fieldNode.modifiers && fieldNode.modifiers.includes("static")) { 1072 | _attribute.isStatic = true; 1073 | } 1074 | 1075 | // Final Modifier 1076 | if (fieldNode.modifiers && fieldNode.modifiers.includes("final")) { 1077 | _attribute.isLeaf = true; 1078 | _attribute.isReadOnly = true; 1079 | } 1080 | 1081 | // Volatile Modifier 1082 | if (fieldNode.modifiers && fieldNode.modifiers.includes("volatile")) { 1083 | this._addTag(_attribute, type.Tag.TK_BOOLEAN, "volatile", true); 1084 | } 1085 | 1086 | // Transient Modifier 1087 | if (fieldNode.modifiers && fieldNode.modifiers.includes("transient")) { 1088 | this._addTag(_attribute, type.Tag.TK_BOOLEAN, "transient", true); 1089 | } 1090 | 1091 | // JavaDoc 1092 | if (fieldNode.comment) { 1093 | _attribute.documentation = fieldNode.comment; 1094 | } 1095 | 1096 | namespace.attributes.push(_attribute); 1097 | 1098 | // Add to _typedFeaturePendings 1099 | var _typedFeature = { 1100 | namespace: namespace, 1101 | feature: _attribute, 1102 | node: fieldNode, 1103 | }; 1104 | this._typedFeaturePendings.push(_typedFeature); 1105 | } 1106 | } 1107 | } 1108 | 1109 | /** 1110 | * Translate Method 1111 | * @param {Object} options 1112 | * @param {type.Model} namespace 1113 | * @param {Object} methodNode 1114 | * @param {boolean} isConstructor 1115 | */ 1116 | translateMethod(options, namespace, methodNode, isConstructor) { 1117 | var i, len; 1118 | var _operation = new type.UMLOperation(); 1119 | _operation._parent = namespace; 1120 | _operation.name = methodNode.name; 1121 | namespace.operations.push(_operation); 1122 | 1123 | // Modifiers 1124 | _operation.visibility = this._getVisibility(methodNode.modifiers); 1125 | if (methodNode.modifiers && methodNode.modifiers.includes("static")) { 1126 | _operation.isStatic = true; 1127 | } 1128 | if (methodNode.modifiers && methodNode.modifiers.includes("abstract")) { 1129 | _operation.isAbstract = true; 1130 | } 1131 | if (methodNode.modifiers && methodNode.modifiers.includes("final")) { 1132 | _operation.isLeaf = true; 1133 | } 1134 | if (methodNode.modifiers && methodNode.modifiers.includes("synchronized")) { 1135 | _operation.concurrency = type.UMLBehavioralFeature.CCK_CONCURRENT; 1136 | } 1137 | if (methodNode.modifiers && methodNode.modifiers.includes("native")) { 1138 | this._addTag(_operation, type.Tag.TK_BOOLEAN, "native", true); 1139 | } 1140 | if (methodNode.modifiers && methodNode.modifiers.includes("strictfp")) { 1141 | this._addTag(_operation, type.Tag.TK_BOOLEAN, "strictfp", true); 1142 | } 1143 | 1144 | // Constructor 1145 | if (isConstructor) { 1146 | _operation.stereotype = "constructor"; 1147 | } 1148 | 1149 | // Stuff to do here to grab the correct Javadoc and put it into parameters and return 1150 | 1151 | // Formal Parameters 1152 | if (methodNode.parameters && methodNode.parameters.length > 0) { 1153 | for (i = 0, len = methodNode.parameters.length; i < len; i++) { 1154 | var parameterNode = methodNode.parameters[i]; 1155 | parameterNode.compilationUnitNode = methodNode.compilationUnitNode; 1156 | this.translateParameter(options, _operation, parameterNode); 1157 | } 1158 | } 1159 | 1160 | // Return Type 1161 | if (methodNode.type) { 1162 | var _returnParam = new type.UMLParameter(); 1163 | _returnParam._parent = _operation; 1164 | _returnParam.name = ""; 1165 | _returnParam.direction = type.UMLParameter.DK_RETURN; 1166 | // Add to _typedFeaturePendings 1167 | this._typedFeaturePendings.push({ 1168 | namespace: namespace, 1169 | feature: _returnParam, 1170 | node: methodNode, 1171 | }); 1172 | _operation.parameters.push(_returnParam); 1173 | } 1174 | 1175 | // Throws 1176 | if (methodNode.throws) { 1177 | for (i = 0, len = methodNode.throws.length; i < len; i++) { 1178 | var _throwNode = methodNode.throws[i]; 1179 | var _throwPending = { 1180 | operation: _operation, 1181 | node: _throwNode, 1182 | compilationUnitNode: methodNode.compilationUnitNode, 1183 | }; 1184 | this._throwPendings.push(_throwPending); 1185 | } 1186 | } 1187 | 1188 | // JavaDoc 1189 | if (methodNode.comment) { 1190 | _operation.documentation = methodNode.comment; 1191 | } 1192 | 1193 | // "default" for Annotation Type Element 1194 | if (methodNode.defaultValue) { 1195 | this._addTag( 1196 | _operation, 1197 | type.Tag.TK_STRING, 1198 | "default", 1199 | methodNode.defaultValue, 1200 | ); 1201 | } 1202 | 1203 | // Translate Type Parameters 1204 | this.translateTypeParameters( 1205 | options, 1206 | _operation, 1207 | methodNode.typeParameters, 1208 | ); 1209 | } 1210 | 1211 | /** 1212 | * Translate Enumeration Constant 1213 | * @param {Object} options 1214 | * @param {type.Model} namespace 1215 | * @param {Object} enumConstantNode 1216 | */ 1217 | translateEnumConstant(options, namespace, enumConstantNode) { 1218 | var _literal = new type.UMLEnumerationLiteral(); 1219 | _literal._parent = namespace; 1220 | _literal.name = enumConstantNode.name; 1221 | 1222 | // JavaDoc 1223 | if (enumConstantNode.comment) { 1224 | _literal.documentation = enumConstantNode.comment; 1225 | } 1226 | 1227 | namespace.literals.push(_literal); 1228 | } 1229 | 1230 | /** 1231 | * Translate Method Parameters 1232 | * @param {Object} options 1233 | * @param {type.Model} namespace 1234 | * @param {Object} parameterNode 1235 | */ 1236 | translateParameter(options, namespace, parameterNode) { 1237 | var _parameter = new type.UMLParameter(); 1238 | _parameter._parent = namespace; 1239 | _parameter.name = parameterNode.variable.name; 1240 | namespace.parameters.push(_parameter); 1241 | 1242 | // Add to _typedFeaturePendings 1243 | this._typedFeaturePendings.push({ 1244 | namespace: namespace._parent, 1245 | feature: _parameter, 1246 | node: parameterNode, 1247 | }); 1248 | } 1249 | } 1250 | 1251 | /** 1252 | * Analyze all java files in basePath 1253 | * @param {string} basePath 1254 | * @param {Object} options 1255 | */ 1256 | function analyze(basePath, options) { 1257 | var javaAnalyzer = new JavaCodeAnalyzer(); 1258 | 1259 | function visit(base) { 1260 | var stat = fs.lstatSync(base); 1261 | if (stat.isFile()) { 1262 | var ext = path.extname(base).toLowerCase(); 1263 | if (ext === ".java") { 1264 | javaAnalyzer.addFile(base); 1265 | } 1266 | } else if (stat.isDirectory()) { 1267 | var files = fs.readdirSync(base); 1268 | if (files && files.length > 0) { 1269 | files.forEach((entry) => { 1270 | var fullPath = path.join(base, entry); 1271 | visit(fullPath); 1272 | }); 1273 | } 1274 | } 1275 | } 1276 | 1277 | // Traverse all file entries 1278 | visit(basePath); 1279 | 1280 | // Perform reverse engineering 1281 | javaAnalyzer.analyze(options); 1282 | } 1283 | 1284 | exports.analyze = analyze; 1285 | -------------------------------------------------------------------------------- /code-generator.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2018 MKLab. All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | * 22 | */ 23 | 24 | const fs = require("fs"); 25 | const path = require("path"); 26 | const codegen = require("./codegen-utils"); 27 | 28 | /** 29 | * Return element's full path including parent's classes or interfaces 30 | * @param {type.Model} elem 31 | * @param {Array.} imports Used to collect import declarations 32 | * @return {string} 33 | */ 34 | function getElemPath(elem, imports, curPackage) { 35 | // find package of elem and whole _type string with parents' decarations 36 | var owner = elem._parent; 37 | var _name = elem.name; 38 | while (owner instanceof type.UMLClass || owner instanceof type.UMLInterface) { 39 | if (owner.name.length > 0) { 40 | _name = owner.name + "." + _name; 41 | } else { 42 | _name = "." + _name; 43 | } 44 | elem = owner; 45 | owner = owner._parent; 46 | } 47 | 48 | // generate _import as fullpath of owner package 49 | var _fullImport = elem.name; 50 | var _import = ""; 51 | if (owner !== null && owner !== curPackage) { 52 | while (owner instanceof type.UMLPackage) { 53 | _import = _fullImport; // ignore final root package that would be view point 54 | _fullImport = owner.name + "." + _fullImport; 55 | owner = owner._parent; 56 | } 57 | imports.add(_import); 58 | } 59 | 60 | return _name; 61 | } 62 | 63 | /** 64 | * Java Code Generator 65 | */ 66 | class JavaCodeGenerator { 67 | /** 68 | * @constructor 69 | * 70 | * @param {type.UMLPackage} baseModel 71 | * @param {string} basePath generated files and directories to be placed 72 | */ 73 | constructor(baseModel, basePath) { 74 | /** @member {type.Model} */ 75 | this.baseModel = baseModel; 76 | 77 | /** @member {string} */ 78 | this.basePath = basePath; 79 | } 80 | 81 | /** 82 | * Return Indent String based on options 83 | * @param {Object} options 84 | * @return {string} 85 | */ 86 | getIndentString(options) { 87 | if (options.useTab) { 88 | return "\t"; 89 | } else { 90 | var i; 91 | var len; 92 | var indent = []; 93 | for (i = 0, len = options.indentSpaces; i < len; i++) { 94 | indent.push(" "); 95 | } 96 | return indent.join(""); 97 | } 98 | } 99 | 100 | /** 101 | * Generate codes from a given element 102 | * @param {type.Model} elem 103 | * @param {string} basePath 104 | * @param {Object} options 105 | * @param {Object} curPackage 106 | */ 107 | generate(elem, basePath, options, curPackage) { 108 | var fullPath; 109 | var codeWriter; 110 | var codeWriter2; 111 | 112 | var imports = new Set(); 113 | 114 | // Package 115 | if (elem instanceof type.UMLPackage) { 116 | fullPath = path.join(basePath, elem.name); 117 | fs.mkdirSync(fullPath); 118 | if (Array.isArray(elem.ownedElements)) { 119 | elem.ownedElements.forEach((child) => { 120 | return this.generate(child, fullPath, options, elem); 121 | }); 122 | } 123 | } else if (elem instanceof type.UMLClass) { 124 | // AnnotationType 125 | if (elem.stereotype === "annotationType") { 126 | fullPath = path.join(basePath, elem.name + ".java"); 127 | codeWriter = new codegen.CodeWriter(this.getIndentString(options)); 128 | this.writePackageDeclaration( 129 | codeWriter, 130 | elem, 131 | options, 132 | imports, 133 | curPackage, 134 | ); 135 | 136 | codeWriter2 = new codegen.CodeWriter(this.getIndentString(options)); 137 | this.writeAnnotationType( 138 | codeWriter2, 139 | elem, 140 | options, 141 | imports, 142 | curPackage, 143 | ); 144 | 145 | if (imports.size > 0) { 146 | codeWriter.writeLine(); 147 | imports.forEach(function (v, i, s) { 148 | codeWriter.writeLine("import " + v + ";"); 149 | }); 150 | } 151 | codeWriter.writeLine(); 152 | codeWriter.writeLine("import java.io.*;"); 153 | codeWriter.writeLine("import java.util.*;"); 154 | codeWriter.writeLine("\n"); 155 | 156 | fs.writeFileSync( 157 | fullPath, 158 | codeWriter.getData() + codeWriter2.getData(), 159 | ); 160 | // Class 161 | } else { 162 | fullPath = basePath + "/" + elem.name + ".java"; 163 | codeWriter = new codegen.CodeWriter(this.getIndentString(options)); 164 | this.writePackageDeclaration( 165 | codeWriter, 166 | elem, 167 | options, 168 | imports, 169 | curPackage, 170 | ); 171 | 172 | codeWriter2 = new codegen.CodeWriter(this.getIndentString(options)); 173 | this.writeClass(codeWriter2, elem, options, imports, curPackage); 174 | 175 | if (imports.size > 0) { 176 | codeWriter.writeLine(); 177 | imports.forEach(function (v, i, s) { 178 | codeWriter.writeLine("import " + v + ";"); 179 | }); 180 | } 181 | codeWriter.writeLine(); 182 | codeWriter.writeLine("import java.io.*;"); 183 | codeWriter.writeLine("import java.util.*;"); 184 | codeWriter.writeLine("\n"); 185 | 186 | fs.writeFileSync( 187 | fullPath, 188 | codeWriter.getData() + codeWriter2.getData(), 189 | ); 190 | } 191 | 192 | // Interface 193 | } else if (elem instanceof type.UMLInterface) { 194 | fullPath = basePath + "/" + elem.name + ".java"; 195 | codeWriter = new codegen.CodeWriter(this.getIndentString(options)); 196 | this.writePackageDeclaration( 197 | codeWriter, 198 | elem, 199 | options, 200 | imports, 201 | curPackage, 202 | ); 203 | 204 | codeWriter2 = new codegen.CodeWriter(this.getIndentString(options)); 205 | this.writeInterface(codeWriter2, elem, options, imports, curPackage); 206 | 207 | if (imports.size > 0) { 208 | codeWriter.writeLine(); 209 | imports.forEach(function (v, i, s) { 210 | codeWriter.writeLine("import " + v + ";"); 211 | }); 212 | } 213 | codeWriter.writeLine(); 214 | codeWriter.writeLine("import java.io.*;"); 215 | codeWriter.writeLine("import java.util.*;"); 216 | codeWriter.writeLine("\n"); 217 | 218 | fs.writeFileSync(fullPath, codeWriter.getData() + codeWriter2.getData()); 219 | 220 | // Enum 221 | } else if (elem instanceof type.UMLEnumeration) { 222 | fullPath = basePath + "/" + elem.name + ".java"; 223 | codeWriter = new codegen.CodeWriter(this.getIndentString(options)); 224 | this.writePackageDeclaration( 225 | codeWriter, 226 | elem, 227 | options, 228 | imports, 229 | curPackage, 230 | ); 231 | 232 | codeWriter2 = new codegen.CodeWriter(this.getIndentString(options)); 233 | this.writeEnum(codeWriter2, elem, options, imports, curPackage); 234 | 235 | if (imports.size > 0) { 236 | codeWriter.writeLine(); 237 | imports.forEach(function (v, i, s) { 238 | codeWriter.writeLine("import " + v + ";"); 239 | }); 240 | } 241 | codeWriter.writeLine("\n"); 242 | 243 | fs.writeFileSync(fullPath, codeWriter.getData() + codeWriter2.getData()); 244 | } 245 | } 246 | 247 | /** 248 | * Return visibility 249 | * @param {type.Model} elem 250 | * @return {string} 251 | */ 252 | getVisibility(elem) { 253 | switch (elem.visibility) { 254 | case type.UMLModelElement.VK_PUBLIC: 255 | return "public"; 256 | case type.UMLModelElement.VK_PROTECTED: 257 | return "protected"; 258 | case type.UMLModelElement.VK_PRIVATE: 259 | return "private"; 260 | } 261 | return null; 262 | } 263 | 264 | /** 265 | * Collect modifiers of a given element. 266 | * @param {type.Model} elem 267 | * @return {Array.} 268 | */ 269 | getModifiers(elem) { 270 | var modifiers = []; 271 | var visibility = this.getVisibility(elem); 272 | if (visibility) { 273 | modifiers.push(visibility); 274 | } 275 | if (elem.isStatic === true) { 276 | modifiers.push("static"); 277 | } 278 | if (elem.isAbstract === true) { 279 | modifiers.push("abstract"); 280 | } 281 | if (elem.isFinalSpecialization === true || elem.isLeaf === true) { 282 | modifiers.push("final"); 283 | } 284 | if (elem.concurrency === type.UMLBehavioralFeature.CCK_CONCURRENT) { 285 | modifiers.push("synchronized"); 286 | } 287 | // transient 288 | // strictfp 289 | // const 290 | // native 291 | return modifiers; 292 | } 293 | 294 | /** 295 | * Collect super classes of a given element 296 | * @param {type.Model} elem 297 | * @return {Array.} 298 | */ 299 | getSuperClasses(elem) { 300 | var generalizations = app.repository.getRelationshipsOf( 301 | elem, 302 | function (rel) { 303 | return rel instanceof type.UMLGeneralization && rel.source === elem; 304 | }, 305 | ); 306 | return generalizations.map(function (gen) { 307 | return gen.target; 308 | }); 309 | } 310 | 311 | /** 312 | * Collect super interfaces of a given element 313 | * @param {type.Model} elem 314 | * @return {Array.} 315 | */ 316 | getSuperInterfaces(elem) { 317 | if (elem instanceof type.UMLClass) { 318 | var realizations = app.repository.getRelationshipsOf( 319 | elem, 320 | function (rel) { 321 | return ( 322 | rel instanceof type.UMLInterfaceRealization && rel.source === elem 323 | ); 324 | }, 325 | ); 326 | return realizations.map(function (gen) { 327 | return gen.target; 328 | }); 329 | } else { 330 | return this.getSuperClasses(elem); 331 | } 332 | } 333 | 334 | /** 335 | * Collect all super classes to allExtends Array 336 | * @param {type.Model} elem 337 | * @param {Set.} allExtendsSet Used to avoid repeated elements in allExtends array 338 | * @param {Array.} allExtends Used to collect super classes in order 339 | */ 340 | collectExtends(elem, allExtendsSet, allExtends) { 341 | var _exts = this.getSuperClasses(elem); 342 | for (var i = 0; i < _exts.length; i++) { 343 | var _ext = _exts[i]; 344 | this.collectExtends(_ext, allExtendsSet, allExtends); 345 | if (!allExtendsSet.has(_ext)) { 346 | allExtendsSet.add(_ext); 347 | allExtends.push(_ext); 348 | } 349 | } 350 | } 351 | 352 | /** 353 | * Collect all super interfaces to allImplements Array 354 | * @param {type.Model} elem 355 | * @param {Set.} allImplementsSet Used to avoid repeated elements in allImplements array 356 | * @param {Array.} allImplements Used to collect super interfaces in order 357 | */ 358 | collectImplements(elem, allImplementsSet, allImplements) { 359 | var _impls = this.getSuperInterfaces(elem); 360 | for (var i = 0; i < _impls.length; i++) { 361 | var _impl = _impls[i]; 362 | this.collectImplements(_impl, allImplementsSet, allImplements); 363 | if (!allImplementsSet.has(_impl)) { 364 | allImplementsSet.add(_impl); 365 | allImplements.push(_impl); 366 | } 367 | } 368 | } 369 | 370 | /** 371 | * Return type expression 372 | * @param {type.Model} elem 373 | * @param {Array.} imports Used to collect import declarations 374 | * @return {string} 375 | */ 376 | getType(elem, imports, curPackage) { 377 | var _type = "void"; 378 | var typeElem = null; 379 | 380 | // type name 381 | if (elem instanceof type.UMLAssociationEnd) { 382 | if ( 383 | elem.reference instanceof type.UMLModelElement && 384 | elem.reference.name.length > 0 385 | ) { 386 | typeElem = elem.reference; 387 | // inner types need add owner's name as prefix 388 | _type = getElemPath(typeElem, imports, curPackage); 389 | } 390 | } else { 391 | if ( 392 | elem.type instanceof type.UMLModelElement && 393 | elem.type.name.length > 0 394 | ) { 395 | typeElem = elem.type; 396 | // inner types need add owner's name as prefix 397 | _type = getElemPath(typeElem, imports, curPackage); 398 | } else if (typeof elem.type === "string" && elem.type.length > 0) { 399 | _type = elem.type; 400 | } 401 | } 402 | 403 | // multiplicity 404 | if (elem.multiplicity) { 405 | if (["0..*", "1..*", "*"].includes(elem.multiplicity.trim())) { 406 | if (elem.isOrdered === true) { 407 | _type = "List<" + _type + ">"; 408 | } else { 409 | _type = "Set<" + _type + ">"; 410 | } 411 | } else if ( 412 | elem.multiplicity !== "1" && 413 | elem.multiplicity.match(/^\d+$/) 414 | ) { 415 | // number 416 | _type += "[]"; 417 | } 418 | } 419 | return _type; 420 | } 421 | 422 | /** 423 | * Write Doc 424 | * @param {StringWriter} codeWriter 425 | * @param {string} text 426 | * @param {Object} options 427 | * @param {Set.} imports 428 | * @param {Object} curPackage 429 | */ 430 | writeDoc(codeWriter, text, options, imports, curPackage) { 431 | var i, len, lines; 432 | if (options.javaDoc && typeof text === "string") { 433 | lines = text.trim().split("\n"); 434 | codeWriter.writeLine("/**"); 435 | for (i = 0, len = lines.length; i < len; i++) { 436 | codeWriter.writeLine(" * " + lines[i]); 437 | } 438 | codeWriter.writeLine(" */"); 439 | } 440 | } 441 | 442 | /** 443 | * Write Package Declaration 444 | * @param {StringWriter} codeWriter 445 | * @param {type.Model} elem 446 | * @param {Object} options 447 | * @param {Set.} imports 448 | * @param {Object} curPackage 449 | */ 450 | writePackageDeclaration(codeWriter, elem, options, imports, curPackage) { 451 | var packagePath = null; 452 | if (elem._parent) { 453 | packagePath = elem._parent 454 | .getPath(this.baseModel) 455 | .map(function (e) { 456 | return e.name; 457 | }) 458 | .join("."); 459 | } 460 | if (packagePath) { 461 | codeWriter.writeLine("package " + packagePath + ";"); 462 | } 463 | } 464 | 465 | /** 466 | * Write Constructor 467 | * @param {StringWriter} codeWriter 468 | * @param {type.Model} elem 469 | * @param {Object} options 470 | */ 471 | writeConstructor(codeWriter, elem, options, imports, curPackage) { 472 | if (elem.name.length > 0) { 473 | var terms = []; 474 | // Doc 475 | this.writeDoc( 476 | codeWriter, 477 | "Default constructor", 478 | options, 479 | imports, 480 | curPackage, 481 | ); 482 | // Visibility 483 | var visibility = this.getVisibility(elem); 484 | if (visibility) { 485 | terms.push(visibility); 486 | } 487 | terms.push(elem.name + "()"); 488 | codeWriter.writeLine(terms.join(" ") + " {"); 489 | codeWriter.writeLine("}"); 490 | } 491 | } 492 | 493 | /** 494 | * Write Member Variable 495 | * @param {StringWriter} codeWriter 496 | * @param {type.Model} elem 497 | * @param {Object} options 498 | * @param {Set.} imports 499 | * @param {Object} curPackage 500 | */ 501 | writeMemberVariable(codeWriter, elem, options, imports, curPackage) { 502 | if (elem.name.length > 0) { 503 | var terms = []; 504 | // doc 505 | this.writeDoc( 506 | codeWriter, 507 | elem.documentation, 508 | options, 509 | imports, 510 | curPackage, 511 | ); 512 | // modifiers 513 | var _modifiers = this.getModifiers(elem); 514 | if (_modifiers.length > 0) { 515 | terms.push(_modifiers.join(" ")); 516 | } 517 | // type 518 | terms.push(this.getType(elem, imports, curPackage)); 519 | // name 520 | terms.push(elem.name); 521 | // initial value 522 | if (elem.defaultValue && elem.defaultValue.length > 0) { 523 | terms.push("= " + elem.defaultValue); 524 | } 525 | codeWriter.writeLine(terms.join(" ") + ";"); 526 | } 527 | } 528 | 529 | /** 530 | * Write Method 531 | * @param {StringWriter} codeWriter 532 | * @param {type.Model} elem 533 | * @param {type.Model} owner Who wants to write this method 534 | * @param {Object} options 535 | * @param {boolean} skipBody 536 | * @param {boolean} skipParams 537 | * @param {boolean} declaredBy Who declared this method 538 | * @param {Set.} imports 539 | * @param {Object} curPackage 540 | */ 541 | writeMethod( 542 | codeWriter, 543 | elem, 544 | owner, 545 | options, 546 | skipBody, 547 | skipParams, 548 | declaredBy, 549 | imports, 550 | curPackage, 551 | ) { 552 | if (elem.name.length > 0) { 553 | var terms = []; 554 | var params = elem.getNonReturnParameters(); 555 | var returnParam = elem.getReturnParameter(); 556 | 557 | // doc 558 | var doc = elem.documentation.trim(); 559 | 560 | // Erase Javadoc @param and @return 561 | var i; 562 | var lines = doc.split("\n"); 563 | doc = ""; 564 | for (let i = 0, len = lines.length; i < len; i++) { 565 | if ( 566 | lines[i].lastIndexOf("@param", 0) !== 0 && 567 | lines[i].lastIndexOf("@return", 0) !== 0 568 | ) { 569 | doc += "\n" + lines[i]; 570 | } 571 | } 572 | 573 | params.forEach(function (param) { 574 | doc += "\n@param " + param.name + " " + param.documentation; 575 | }); 576 | if (returnParam) { 577 | doc += "\n@return " + returnParam.documentation; 578 | } 579 | this.writeDoc(codeWriter, doc, options, imports, curPackage); 580 | 581 | // modifiers 582 | var _modifiers = this.getModifiers(elem); 583 | if (_modifiers.length > 0) { 584 | terms.push(_modifiers.join(" ")); 585 | } 586 | 587 | // type 588 | if (returnParam) { 589 | terms.push(this.getType(returnParam, imports, curPackage)); 590 | } else { 591 | if (elem.name === owner.name) { 592 | // constructor has no return 593 | } else { 594 | terms.push("void"); 595 | } 596 | } 597 | 598 | // name + parameters 599 | var paramTerms = []; 600 | if (!skipParams) { 601 | var len; 602 | for (i = 0, len = params.length; i < len; i++) { 603 | var p = params[i]; 604 | var s = this.getType(p, imports, curPackage) + " " + p.name; 605 | if (p.isReadOnly === true) { 606 | s = "final " + s; 607 | } 608 | paramTerms.push(s); 609 | } 610 | } 611 | terms.push(elem.name + "(" + paramTerms.join(", ") + ")"); 612 | 613 | // body 614 | if (skipBody === true || _modifiers.includes("abstract")) { 615 | codeWriter.writeLine(terms.join(" ") + ";"); 616 | } else { 617 | codeWriter.writeLine(terms.join(" ") + " {"); 618 | codeWriter.indent(); 619 | if (declaredBy === owner) { 620 | codeWriter.writeLine("// TODO implement here"); 621 | } else { 622 | codeWriter.writeLine( 623 | "// TODO implement " + 624 | declaredBy.name + 625 | "." + 626 | elem.name + 627 | "() here", 628 | ); 629 | } 630 | 631 | // return statement 632 | if (returnParam) { 633 | var returnType = this.getType(returnParam, imports, curPackage); 634 | if (returnType === "boolean") { 635 | codeWriter.writeLine("return false;"); 636 | } else if ( 637 | returnType === "int" || 638 | returnType === "long" || 639 | returnType === "short" || 640 | returnType === "byte" 641 | ) { 642 | codeWriter.writeLine("return 0;"); 643 | } else if (returnType === "float") { 644 | codeWriter.writeLine("return 0.0f;"); 645 | } else if (returnType === "double") { 646 | codeWriter.writeLine("return 0.0d;"); 647 | } else if (returnType === "char") { 648 | codeWriter.writeLine('return "0";'); 649 | } else if (returnType === "String") { 650 | codeWriter.writeLine('return "";'); 651 | } else { 652 | codeWriter.writeLine("return null;"); 653 | } 654 | } 655 | 656 | codeWriter.outdent(); 657 | codeWriter.writeLine("}"); 658 | } 659 | } 660 | } 661 | 662 | /** 663 | * Write Class 664 | * @param {StringWriter} codeWriter 665 | * @param {type.Model} elem 666 | * @param {Object} options 667 | * @param {Set.} imports 668 | * @param {Object} curPackage 669 | */ 670 | writeClass(codeWriter, elem, options, imports, curPackage) { 671 | var i, len; 672 | var terms = []; 673 | 674 | // Doc 675 | var doc = elem.documentation.trim(); 676 | if ( 677 | app.project.getProject().author && 678 | app.project.getProject().author.length > 0 679 | ) { 680 | doc += "\n@author " + app.project.getProject().author; 681 | } 682 | this.writeDoc(codeWriter, doc, options, imports, curPackage); 683 | 684 | // Modifiers 685 | var _modifiers = this.getModifiers(elem); 686 | if ( 687 | _modifiers.includes("abstract") !== true && 688 | elem.operations.some(function (op) { 689 | return op.isAbstract === true; 690 | }) 691 | ) { 692 | _modifiers.push("abstract"); 693 | } 694 | if (_modifiers.length > 0) { 695 | terms.push(_modifiers.join(" ")); 696 | } 697 | 698 | // Class 699 | terms.push("class"); 700 | terms.push(elem.name); 701 | 702 | // Extends 703 | var _extends = this.getSuperClasses(elem); 704 | if (_extends.length > 0) { 705 | terms.push("extends " + getElemPath(_extends[0], imports, curPackage)); 706 | } 707 | 708 | // Implements 709 | var _implements = this.getSuperInterfaces(elem); 710 | if (_implements.length > 0) { 711 | terms.push( 712 | "implements " + 713 | _implements 714 | .map(function (e) { 715 | return getElemPath(e, imports, curPackage); 716 | }) 717 | .join(", "), 718 | ); 719 | } 720 | codeWriter.writeLine(terms.join(" ") + " {"); 721 | codeWriter.writeLine(); 722 | codeWriter.indent(); 723 | 724 | // Constructor 725 | this.writeConstructor(codeWriter, elem, options, imports, curPackage); 726 | codeWriter.writeLine(); 727 | 728 | // Member Variables 729 | // (from attributes) 730 | for (i = 0, len = elem.attributes.length; i < len; i++) { 731 | this.writeMemberVariable( 732 | codeWriter, 733 | elem.attributes[i], 734 | options, 735 | imports, 736 | curPackage, 737 | ); 738 | codeWriter.writeLine(); 739 | } 740 | 741 | // (from associations) 742 | var associations = app.repository.getRelationshipsOf(elem, function (rel) { 743 | return rel instanceof type.UMLAssociation; 744 | }); 745 | for (let i = 0, len = associations.length; i < len; i++) { 746 | var asso = associations[i]; 747 | if ( 748 | asso.end1.reference === elem && 749 | asso.end2.navigable !== "notNavigable" 750 | ) { 751 | this.writeMemberVariable( 752 | codeWriter, 753 | asso.end2, 754 | options, 755 | imports, 756 | curPackage, 757 | ); 758 | codeWriter.writeLine(); 759 | } 760 | if ( 761 | asso.end2.reference === elem && 762 | asso.end1.navigable !== "notNavigable" 763 | ) { 764 | this.writeMemberVariable( 765 | codeWriter, 766 | asso.end1, 767 | options, 768 | imports, 769 | curPackage, 770 | ); 771 | codeWriter.writeLine(); 772 | } 773 | } 774 | 775 | // Methods 776 | for (i = 0, len = elem.operations.length; i < len; i++) { 777 | this.writeMethod( 778 | codeWriter, 779 | elem.operations[i], 780 | elem, 781 | options, 782 | false, 783 | false, 784 | elem, 785 | imports, 786 | curPackage, 787 | ); 788 | codeWriter.writeLine(); 789 | } 790 | 791 | // Extends methods 792 | if (_extends.length > 0) { 793 | for (i = 0, len = _extends[0].operations.length; i < len; i++) { 794 | var _modifiers2 = this.getModifiers(_extends[0].operations[i]); 795 | if (_modifiers2.includes("abstract") === true) { 796 | this.writeMethod( 797 | codeWriter, 798 | _extends[0].operations[i], 799 | elem, 800 | options, 801 | false, 802 | false, 803 | _extends[0], 804 | imports, 805 | curPackage, 806 | ); 807 | codeWriter.writeLine(); 808 | } 809 | } 810 | } 811 | 812 | // Interface methods including all super interfaces 813 | var _allExtendsSet = new Set(); 814 | var _allExtends = []; 815 | this.collectExtends(elem, _allExtendsSet, _allExtends); 816 | 817 | // collect methods implemented by all extends to _allImplementsSet to be ignored when writeLine 818 | var _allImplementsSet = new Set(); 819 | var _allImplements = []; 820 | if (_allExtends.length > 0) { 821 | for (i = 0, len = _allExtends.length; i < len; i++) { 822 | this.collectImplements( 823 | _allExtends[i], 824 | _allImplementsSet, 825 | _allImplements, 826 | ); 827 | } 828 | } 829 | 830 | // collect valid super interfaces 831 | _allImplements.splice(0, _allImplements.length); 832 | this.collectImplements(elem, _allImplementsSet, _allImplements); 833 | 834 | // write methods in valid super interfaces 835 | for (var j = 0; j < _allImplements.length; j++) { 836 | for (i = 0, len = _allImplements[j].operations.length; i < len; i++) { 837 | this.writeMethod( 838 | codeWriter, 839 | _allImplements[j].operations[i], 840 | elem, 841 | options, 842 | false, 843 | false, 844 | _allImplements[j], 845 | imports, 846 | curPackage, 847 | ); 848 | codeWriter.writeLine(); 849 | } 850 | } 851 | 852 | // Inner Definitions 853 | for (i = 0, len = elem.ownedElements.length; i < len; i++) { 854 | var def = elem.ownedElements[i]; 855 | if (def instanceof type.UMLClass) { 856 | if (def.stereotype === "annotationType") { 857 | this.writeAnnotationType( 858 | codeWriter, 859 | def, 860 | options, 861 | imports, 862 | curPackage, 863 | ); 864 | } else { 865 | this.writeClass(codeWriter, def, options, imports, curPackage); 866 | } 867 | codeWriter.writeLine(); 868 | } else if (def instanceof type.UMLInterface) { 869 | this.writeInterface(codeWriter, def, options, imports, curPackage); 870 | codeWriter.writeLine(); 871 | } else if (def instanceof type.UMLEnumeration) { 872 | this.writeEnum(codeWriter, def, options, imports, curPackage); 873 | codeWriter.writeLine(); 874 | } 875 | } 876 | 877 | codeWriter.outdent(); 878 | codeWriter.writeLine("}"); 879 | } 880 | 881 | /** 882 | * Write Interface 883 | * @param {StringWriter} codeWriter 884 | * @param {type.Model} elem 885 | * @param {Object} options 886 | * @param {Set.} imports 887 | * @param {Object} curPackage 888 | */ 889 | writeInterface(codeWriter, elem, options, imports, curPackage) { 890 | var i, len; 891 | var terms = []; 892 | 893 | // Doc 894 | this.writeDoc(codeWriter, elem.documentation, options, imports, curPackage); 895 | 896 | // Modifiers 897 | var visibility = this.getVisibility(elem); 898 | if (visibility) { 899 | terms.push(visibility); 900 | } 901 | 902 | // Interface 903 | terms.push("interface"); 904 | terms.push(elem.name); 905 | 906 | // Extends 907 | var _extends = this.getSuperClasses(elem); 908 | if (_extends.length > 0) { 909 | terms.push( 910 | "extends " + 911 | _extends 912 | .map(function (e) { 913 | return getElemPath(e, imports, curPackage); 914 | }) 915 | .join(", "), 916 | ); 917 | } 918 | codeWriter.writeLine(terms.join(" ") + " {"); 919 | codeWriter.writeLine(); 920 | codeWriter.indent(); 921 | 922 | // Member Variables 923 | // (from attributes) 924 | for (i = 0, len = elem.attributes.length; i < len; i++) { 925 | this.writeMemberVariable( 926 | codeWriter, 927 | elem.attributes[i], 928 | options, 929 | imports, 930 | curPackage, 931 | ); 932 | codeWriter.writeLine(); 933 | } 934 | // (from associations) 935 | var associations = app.repository.getRelationshipsOf(elem, function (rel) { 936 | return rel instanceof type.UMLAssociation; 937 | }); 938 | for (i = 0, len = associations.length; i < len; i++) { 939 | var asso = associations[i]; 940 | if ( 941 | asso.end1.reference === elem && 942 | asso.end2.navigable !== "notNavigable" 943 | ) { 944 | this.writeMemberVariable( 945 | codeWriter, 946 | asso.end2, 947 | options, 948 | imports, 949 | curPackage, 950 | ); 951 | codeWriter.writeLine(); 952 | } 953 | if ( 954 | asso.end2.reference === elem && 955 | asso.end1.navigable !== "notNavigable" 956 | ) { 957 | this.writeMemberVariable( 958 | codeWriter, 959 | asso.end1, 960 | options, 961 | imports, 962 | curPackage, 963 | ); 964 | codeWriter.writeLine(); 965 | } 966 | } 967 | 968 | // Methods 969 | for (i = 0, len = elem.operations.length; i < len; i++) { 970 | this.writeMethod( 971 | codeWriter, 972 | elem.operations[i], 973 | elem, 974 | options, 975 | true, 976 | false, 977 | elem, 978 | imports, 979 | curPackage, 980 | ); 981 | codeWriter.writeLine(); 982 | } 983 | 984 | // Inner Definitions 985 | for (i = 0, len = elem.ownedElements.length; i < len; i++) { 986 | var def = elem.ownedElements[i]; 987 | if (def instanceof type.UMLClass) { 988 | if (def.stereotype === "annotationType") { 989 | this.writeAnnotationType( 990 | codeWriter, 991 | def, 992 | options, 993 | imports, 994 | curPackage, 995 | ); 996 | } else { 997 | this.writeClass(codeWriter, def, options, imports, curPackage); 998 | } 999 | codeWriter.writeLine(); 1000 | } else if (def instanceof type.UMLInterface) { 1001 | this.writeInterface(codeWriter, def, options, imports, curPackage); 1002 | codeWriter.writeLine(); 1003 | } else if (def instanceof type.UMLEnumeration) { 1004 | this.writeEnum(codeWriter, def, options, imports, curPackage); 1005 | codeWriter.writeLine(); 1006 | } 1007 | } 1008 | 1009 | codeWriter.outdent(); 1010 | codeWriter.writeLine("}"); 1011 | } 1012 | 1013 | /** 1014 | * Write Enum 1015 | * @param {StringWriter} codeWriter 1016 | * @param {type.Model} elem 1017 | * @param {Object} options 1018 | * @param {Set.} imports 1019 | * @param {Object} curPackage 1020 | */ 1021 | writeEnum(codeWriter, elem, options, imports, curPackage) { 1022 | var i, len; 1023 | var terms = []; 1024 | // Doc 1025 | this.writeDoc(codeWriter, elem.documentation, options, imports, curPackage); 1026 | 1027 | // Modifiers 1028 | var visibility = this.getVisibility(elem); 1029 | if (visibility) { 1030 | terms.push(visibility); 1031 | } 1032 | // Enum 1033 | terms.push("enum"); 1034 | terms.push(elem.name); 1035 | 1036 | codeWriter.writeLine(terms.join(" ") + " {"); 1037 | codeWriter.indent(); 1038 | 1039 | // Literals 1040 | for (i = 0, len = elem.literals.length; i < len; i++) { 1041 | codeWriter.writeLine( 1042 | elem.literals[i].name + (i < elem.literals.length - 1 ? "," : ""), 1043 | ); 1044 | } 1045 | 1046 | codeWriter.outdent(); 1047 | codeWriter.writeLine("}"); 1048 | } 1049 | 1050 | /** 1051 | * Write AnnotationType 1052 | * @param {StringWriter} codeWriter 1053 | * @param {type.Model} elem 1054 | * @param {Object} options 1055 | * @param {Set.} imports 1056 | * @param {Object} curPackage 1057 | */ 1058 | writeAnnotationType(codeWriter, elem, options, imports, curPackage) { 1059 | var i, len; 1060 | var terms = []; 1061 | 1062 | // Doc 1063 | var doc = elem.documentation.trim(); 1064 | if ( 1065 | app.project.getProject().author && 1066 | app.project.getProject().author.length > 0 1067 | ) { 1068 | doc += "\n@author " + app.project.getProject().author; 1069 | } 1070 | this.writeDoc(codeWriter, doc, options, imports, curPackage); 1071 | 1072 | // Modifiers 1073 | var _modifiers = this.getModifiers(elem); 1074 | if ( 1075 | _modifiers.includes("abstract") !== true && 1076 | elem.operations.some(function (op) { 1077 | return op.isAbstract === true; 1078 | }) 1079 | ) { 1080 | _modifiers.push("abstract"); 1081 | } 1082 | if (_modifiers.length > 0) { 1083 | terms.push(_modifiers.join(" ")); 1084 | } 1085 | 1086 | // AnnotationType 1087 | terms.push("@interface"); 1088 | terms.push(elem.name); 1089 | 1090 | codeWriter.writeLine(terms.join(" ") + " {"); 1091 | codeWriter.writeLine(); 1092 | codeWriter.indent(); 1093 | 1094 | // Member Variables 1095 | for (i = 0, len = elem.attributes.length; i < len; i++) { 1096 | this.writeMemberVariable( 1097 | codeWriter, 1098 | elem.attributes[i], 1099 | options, 1100 | imports, 1101 | curPackage, 1102 | ); 1103 | codeWriter.writeLine(); 1104 | } 1105 | 1106 | // Methods 1107 | for (i = 0, len = elem.operations.length; i < len; i++) { 1108 | this.writeMethod( 1109 | codeWriter, 1110 | elem.operations[i], 1111 | elem, 1112 | options, 1113 | true, 1114 | true, 1115 | elem, 1116 | imports, 1117 | curPackage, 1118 | ); 1119 | codeWriter.writeLine(); 1120 | } 1121 | 1122 | // Extends methods 1123 | var _extends = this.getSuperClasses(elem); 1124 | if (_extends.length > 0) { 1125 | for (i = 0, len = _extends[0].operations.length; i < len; i++) { 1126 | _modifiers = this.getModifiers(_extends[0].operations[i]); 1127 | if (_modifiers.includes("abstract") === true) { 1128 | this.writeMethod( 1129 | codeWriter, 1130 | _extends[0].operations[i], 1131 | elem, 1132 | options, 1133 | false, 1134 | false, 1135 | _extends[0], 1136 | imports, 1137 | curPackage, 1138 | ); 1139 | codeWriter.writeLine(); 1140 | } 1141 | } 1142 | } 1143 | 1144 | // Inner Definitions 1145 | for (i = 0, len = elem.ownedElements.length; i < len; i++) { 1146 | var def = elem.ownedElements[i]; 1147 | if (def instanceof type.UMLClass) { 1148 | if (def.stereotype === "annotationType") { 1149 | this.writeAnnotationType( 1150 | codeWriter, 1151 | def, 1152 | options, 1153 | imports, 1154 | curPackage, 1155 | ); 1156 | } else { 1157 | this.writeClass(codeWriter, def, options, imports, curPackage); 1158 | } 1159 | codeWriter.writeLine(); 1160 | } else if (def instanceof type.UMLInterface) { 1161 | this.writeInterface(codeWriter, def, options, imports, curPackage); 1162 | codeWriter.writeLine(); 1163 | } else if (def instanceof type.UMLEnumeration) { 1164 | this.writeEnum(codeWriter, def, options, imports, curPackage); 1165 | codeWriter.writeLine(); 1166 | } 1167 | } 1168 | 1169 | codeWriter.outdent(); 1170 | codeWriter.writeLine("}"); 1171 | } 1172 | } 1173 | 1174 | /** 1175 | * Generate 1176 | * @param {type.Model} baseModel 1177 | * @param {string} basePath 1178 | * @param {Object} options 1179 | */ 1180 | function generate(baseModel, basePath, options) { 1181 | var javaCodeGenerator = new JavaCodeGenerator(baseModel, basePath); 1182 | javaCodeGenerator.generate(baseModel, basePath, options, null); 1183 | } 1184 | 1185 | exports.generate = generate; 1186 | -------------------------------------------------------------------------------- /codegen-utils.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2018 MKLab. All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | * 22 | */ 23 | 24 | /** 25 | * CodeWriter 26 | */ 27 | class CodeWriter { 28 | /** 29 | * @constructor 30 | */ 31 | constructor(indentString) { 32 | /** @member {Array.} lines */ 33 | this.lines = []; 34 | 35 | /** @member {string} indentString */ 36 | this.indentString = indentString || " "; // default 4 spaces 37 | 38 | /** @member {Array.} indentations */ 39 | this.indentations = []; 40 | } 41 | 42 | /** 43 | * Indent 44 | */ 45 | indent() { 46 | this.indentations.push(this.indentString); 47 | } 48 | 49 | /** 50 | * Outdent 51 | */ 52 | outdent() { 53 | this.indentations.splice(this.indentations.length - 1, 1); 54 | } 55 | 56 | /** 57 | * Write a line 58 | * @param {string} line 59 | */ 60 | writeLine(line) { 61 | if (line) { 62 | this.lines.push(this.indentations.join("") + line); 63 | } else { 64 | this.lines.push(""); 65 | } 66 | } 67 | 68 | /** 69 | * Return as all string data 70 | * @return {string} 71 | */ 72 | getData() { 73 | return this.lines.join("\n"); 74 | } 75 | } 76 | 77 | exports.CodeWriter = CodeWriter; 78 | -------------------------------------------------------------------------------- /grammar/build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | jison "$PWD/java7.jison" "$PWD/java7.jisonlex" -t -p lalr > jisonOutput.txt 4 | -------------------------------------------------------------------------------- /grammar/java7.jisonlex: -------------------------------------------------------------------------------- 1 | /* Integer literals */ 2 | 3 | %lex 4 | %options flex 5 | DecimalIntegerLiteral {DecimalNumeral}{IntegerTypeSuffix}? 6 | HexIntegerLiteral {HexNumeral}{IntegerTypeSuffix}? 7 | OctalIntegerLiteral {OctalNumeral}{IntegerTypeSuffix}? 8 | BinaryIntegerLiteral {BinaryNumeral}{IntegerTypeSuffix}? 9 | IntegerTypeSuffix [lL] 10 | DecimalNumeral '0'| ({NonZeroDigit} ({Digits} | {Underscores} {Digits})?) 11 | Digits {Digit} {DigitOrUnderscore}* {Digit}? 12 | Digit [0] | {NonZeroDigit} 13 | NonZeroDigit [1-9] 14 | DigitOrUnderscore {Digit} | [_] 15 | Underscores [_]+ 16 | HexNumeral [0] [xX] {HexDigits}{1,16} 17 | HexDigits {HexDigit} ({HexDigitOrUnderscore}* {HexDigit})? 18 | HexDigit [0-9a-fA-F] 19 | HexDigitOrUnderscore {HexDigit} |[_] 20 | OctalNumeral [0] {Underscores}? {OctalDigits} 21 | OctalDigits {OctalDigit} ({OctalDigitOrUnderscore}* {OctalDigit})? 22 | OctalDigit [0-7] 23 | OctalDigitOrUnderscore {OctalDigit} | [_] 24 | BinaryNumeral [0] [bB] {BinaryDigits}? 25 | BinaryDigits {BinaryDigit} ({BinaryDigitOrUnderscore}* {BinaryDigit})? 26 | BinaryDigit [01] 27 | BinaryDigitOrUnderscore {BinaryDigit} | [_] 28 | 29 | /* Floating point literals */ 30 | 31 | DecimalFloatingPointLiteral ({Digits} '.' {Digits}? {ExponentPart}? {FloatTypeSuffix}? ) | ( '.' {Digits} {ExponentPart}? {FloatTypeSuffix}? ) | ( {Digits} {ExponentPart} {FloatTypeSuffix}? ) | ({Digits} {FloatTypeSuffix}) 32 | ExponentPart {ExponentIndicator}{SignedInteger} 33 | ExponentIndicator [eE] 34 | SignedInteger {Sign}? {Digits} 35 | Sign [+-] 36 | FloatTypeSuffix [fFdD] 37 | HexadecimalFloatingPointLiteral {HexSignificand} {BinaryExponent} {FloatTypeSuffix}? 38 | HexSignificand {HexNumeral} '.'? | ( '0' [xX] {HexDigits}? '.' {HexDigits}) 39 | BinaryExponent {BinaryExponentIndicator} {SignedInteger} 40 | BinaryExponentIndicator [pP] 41 | 42 | /* Character Literal */ 43 | 44 | SingleCharacter [^'\\] 45 | StringCharacters {StringCharacter}+ 46 | StringCharacter [^"\\] | {EscapeSequence} 47 | EscapeSequence ('\\' [btnfr"'\\]) | {OctalEscape} | {UnicodeEscape} 48 | OctalEscape ('\\' {OctalDigit}) | ('\\' {OctalDigit} {OctalDigit}) | ('\\' {ZeroToThree} {OctalDigit} {OctalDigit}) 49 | UnicodeEscape '\\' 'u' {HexDigit} {HexDigit} {HexDigit} {HexDigit} 50 | ZeroToThree [0-3] 51 | 52 | /* Identifiers */ 53 | 54 | JavaLetter [a-zA-Z$_]|{JavaUnicodeLetter} 55 | JavaLetterOrDigit [a-zA-Z0-9$_]|{JavaUnicodeLetterorDigit} 56 | JavaIdentifier {JavaLetter}{JavaLetterOrDigit}* 57 | JavaIntegerLiteral {DecimalIntegerLiteral}|{HexIntegerLiteral}|{OctalIntegerLiteral}|{BinaryIntegerLiteral} 58 | JavaFloatingPointLiteral {DecimalFloatingPointLiteral}|{HexadecimalFloatingPointLiteral} 59 | JavaCharacterLiteral ('\''{SingleCharacter}'\'')|('\''{EscapeSequence}'\'') 60 | JavaStringLiteral '"' {StringCharacters}? '"' 61 | 62 | JavaUnicodeLetter [\u0100-\u02c1]|[\u02c6-\u02d1]|[\u02e0-\u02e4]|\u02ec|\u02ee|[\u0370-\u0374]|[\u0376-\u0377]|[\u037a-\u037d]|\u0386|[\u0388-\u038a]|\u038c|[\u038e-\u03a1]|[\u03a3-\u03f5]|[\u03f7-\u0481]|[\u048a-\u0527]|[\u0531-\u0556]|\u0559|[\u0561-\u0587]|[\u05d0-\u05ea]|[\u05f0-\u05f2]|\u060b|[\u0620-\u064a]|[\u066e-\u066f]|[\u0671-\u06d3]|\u06d5|[\u06e5-\u06e6]|[\u06ee-\u06ef]|[\u06fa-\u06fc]|\u06ff|\u0710|[\u0712-\u072f]|[\u074d-\u07a5]|\u07b1|[\u07ca-\u07ea]|[\u07f4-\u07f5]|\u07fa|[\u0800-\u0815]|\u081a|\u0824|\u0828|[\u0840-\u0858]|[\u0904-\u0939]|\u093d|\u0950|[\u0958-\u0961]|[\u0971-\u0977]|[\u0979-\u097f]|[\u0985-\u098c]|[\u098f-\u0990]|[\u0993-\u09a8]|[\u09aa-\u09b0]|\u09b2|[\u09b6-\u09b9]|\u09bd|\u09ce|[\u09dc-\u09dd]|[\u09df-\u09e1]|[\u09f0-\u09f3]|\u09fb|[\u0a05-\u0a0a]|[\u0a0f-\u0a10]|[\u0a13-\u0a28]|[\u0a2a-\u0a30]|[\u0a32-\u0a33]|[\u0a35-\u0a36]|[\u0a38-\u0a39]|[\u0a59-\u0a5c]|\u0a5e|[\u0a72-\u0a74]|[\u0a85-\u0a8d]|[\u0a8f-\u0a91]|[\u0a93-\u0aa8]|[\u0aaa-\u0ab0]|[\u0ab2-\u0ab3]|[\u0ab5-\u0ab9]|\u0abd|\u0ad0|[\u0ae0-\u0ae1]|\u0af1|[\u0b05-\u0b0c]|[\u0b0f-\u0b10]|[\u0b13-\u0b28]|[\u0b2a-\u0b30]|[\u0b32-\u0b33]|[\u0b35-\u0b39]|\u0b3d|[\u0b5c-\u0b5d]|[\u0b5f-\u0b61]|\u0b71|\u0b83|[\u0b85-\u0b8a]|[\u0b8e-\u0b90]|[\u0b92-\u0b95]|[\u0b99-\u0b9a]|\u0b9c|[\u0b9e-\u0b9f]|[\u0ba3-\u0ba4]|[\u0ba8-\u0baa]|[\u0bae-\u0bb9]|\u0bd0|\u0bf9|[\u0c05-\u0c0c]|[\u0c0e-\u0c10]|[\u0c12-\u0c28]|[\u0c2a-\u0c33]|[\u0c35-\u0c39]|\u0c3d|[\u0c58-\u0c59]|[\u0c60-\u0c61]|[\u0c85-\u0c8c]|[\u0c8e-\u0c90]|[\u0c92-\u0ca8]|[\u0caa-\u0cb3]|[\u0cb5-\u0cb9]|\u0cbd|\u0cde|[\u0ce0-\u0ce1]|[\u0cf1-\u0cf2]|[\u0d05-\u0d0c]|[\u0d0e-\u0d10]|[\u0d12-\u0d3a]|\u0d3d|\u0d4e|[\u0d60-\u0d61]|[\u0d7a-\u0d7f]|[\u0d85-\u0d96]|[\u0d9a-\u0db1]|[\u0db3-\u0dbb]|\u0dbd|[\u0dc0-\u0dc6]|[\u0e01-\u0e30]|[\u0e32-\u0e33]|[\u0e3f-\u0e46]|[\u0e81-\u0e82]|\u0e84|[\u0e87-\u0e88]|\u0e8a|\u0e8d|[\u0e94-\u0e97]|[\u0e99-\u0e9f]|[\u0ea1-\u0ea3]|\u0ea5|\u0ea7|[\u0eaa-\u0eab]|[\u0ead-\u0eb0]|[\u0eb2-\u0eb3]|\u0ebd|[\u0ec0-\u0ec4]|\u0ec6|[\u0edc-\u0edd]|\u0f00|[\u0f40-\u0f47]|[\u0f49-\u0f6c]|[\u0f88-\u0f8c]|[\u1000-\u102a]|\u103f|[\u1050-\u1055]|[\u105a-\u105d]|\u1061|[\u1065-\u1066]|[\u106e-\u1070]|[\u1075-\u1081]|\u108e|[\u10a0-\u10c5]|[\u10d0-\u10fa]|\u10fc|[\u1100-\u1248]|[\u124a-\u124d]|[\u1250-\u1256]|\u1258|[\u125a-\u125d]|[\u1260-\u1288]|[\u128a-\u128d]|[\u1290-\u12b0]|[\u12b2-\u12b5]|[\u12b8-\u12be]|\u12c0|[\u12c2-\u12c5]|[\u12c8-\u12d6]|[\u12d8-\u1310]|[\u1312-\u1315]|[\u1318-\u135a]|[\u1380-\u138f]|[\u13a0-\u13f4]|[\u1401-\u166c]|[\u166f-\u167f]|[\u1681-\u169a]|[\u16a0-\u16ea]|[\u16ee-\u16f0]|[\u1700-\u170c]|[\u170e-\u1711]|[\u1720-\u1731]|[\u1740-\u1751]|[\u1760-\u176c]|[\u176e-\u1770]|[\u1780-\u17b3]|\u17d7|[\u17db-\u17dc]|[\u1820-\u1877]|[\u1880-\u18a8]|\u18aa|[\u18b0-\u18f5]|[\u1900-\u191c]|[\u1950-\u196d]|[\u1970-\u1974]|[\u1980-\u19ab]|[\u19c1-\u19c7]|[\u1a00-\u1a16]|[\u1a20-\u1a54]|\u1aa7|[\u1b05-\u1b33]|[\u1b45-\u1b4b]|[\u1b83-\u1ba0]|[\u1bae-\u1baf]|[\u1bc0-\u1be5]|[\u1c00-\u1c23]|[\u1c4d-\u1c4f]|[\u1c5a-\u1c7d]|[\u1ce9-\u1cec]|[\u1cee-\u1cf1]|[\u1d00-\u1dbf]|[\u1e00-\u1f15]|[\u1f18-\u1f1d]|[\u1f20-\u1f45]|[\u1f48-\u1f4d]|[\u1f50-\u1f57]|\u1f59|\u1f5b|\u1f5d|[\u1f5f-\u1f7d]|[\u1f80-\u1fb4]|[\u1fb6-\u1fbc]|\u1fbe|[\u1fc2-\u1fc4]|[\u1fc6-\u1fcc]|[\u1fd0-\u1fd3]|[\u1fd6-\u1fdb]|[\u1fe0-\u1fec]|[\u1ff2-\u1ff4]|[\u1ff6-\u1ffc]|[\u203f-\u2040]|\u2054|\u2071|\u207f|[\u2090-\u209c]|[\u20a0-\u20b9]|\u2102|\u2107|[\u210a-\u2113]|\u2115|[\u2119-\u211d]|\u2124|\u2126|\u2128|[\u212a-\u212d]|[\u212f-\u2139]|[\u213c-\u213f]|[\u2145-\u2149]|\u214e|[\u2160-\u2188]|[\u2c00-\u2c2e]|[\u2c30-\u2c5e]|[\u2c60-\u2ce4]|[\u2ceb-\u2cee]|[\u2d00-\u2d25]|[\u2d30-\u2d65]|\u2d6f|[\u2d80-\u2d96]|[\u2da0-\u2da6]|[\u2da8-\u2dae]|[\u2db0-\u2db6]|[\u2db8-\u2dbe]|[\u2dc0-\u2dc6]|[\u2dc8-\u2dce]|[\u2dd0-\u2dd6]|[\u2dd8-\u2dde]|\u2e2f|[\u3005-\u3007]|[\u3021-\u3029]|[\u3031-\u3035]|[\u3038-\u303c]|[\u3041-\u3096]|[\u309d-\u309f]|[\u30a1-\u30fa]|[\u30fc-\u30ff]|[\u3105-\u312d]|[\u3131-\u318e]|[\u31a0-\u31ba]|[\u31f0-\u31ff]|[\u3400-\u4db5]|[\u4e00-\u9fcb]|[\ua000-\ua48c]|[\ua4d0-\ua4fd]|[\ua500-\ua60c]|[\ua610-\ua61f]|[\ua62a-\ua62b]|[\ua640-\ua66e]|[\ua67f-\ua697]|[\ua6a0-\ua6ef]|[\ua717-\ua71f]|[\ua722-\ua788]|[\ua78b-\ua78e]|[\ua790-\ua791]|[\ua7a0-\ua7a9]|[\ua7fa-\ua801]|[\ua803-\ua805]|[\ua807-\ua80a]|[\ua80c-\ua822]|\ua838|[\ua840-\ua873]|[\ua882-\ua8b3]|[\ua8f2-\ua8f7]|\ua8fb|[\ua90a-\ua925]|[\ua930-\ua946]|[\ua960-\ua97c]|[\ua984-\ua9b2]|\ua9cf|[\uaa00-\uaa28]|[\uaa40-\uaa42]|[\uaa44-\uaa4b]|[\uaa60-\uaa76]|\uaa7a|[\uaa80-\uaaaf]|\uaab1|[\uaab5-\uaab6]|[\uaab9-\uaabd]|\uaac0|\uaac2|[\uaadb-\uaadd]|[\uab01-\uab06]|[\uab09-\uab0e]|[\uab11-\uab16]|[\uab20-\uab26]|[\uab28-\uab2e]|[\uabc0-\uabe2]|[\uac00-\ud7a3]|[\ud7b0-\ud7c6]|[\ud7cb-\ud7fb]|[\uf900-\ufa2d]|[\ufa30-\ufa6d]|[\ufa70-\ufad9]|[\ufb00-\ufb06]|[\ufb13-\ufb17]|\ufb1d|[\ufb1f-\ufb28]|[\ufb2a-\ufb36]|[\ufb38-\ufb3c]|\ufb3e|[\ufb40-\ufb41]|[\ufb43-\ufb44]|[\ufb46-\ufbb1]|[\ufbd3-\ufd3d]|[\ufd50-\ufd8f]|[\ufd92-\ufdc7]|[\ufdf0-\ufdfc]|[\ufe33-\ufe34]|[\ufe4d-\ufe4f]|\ufe69|[\ufe70-\ufe74]|[\ufe76-\ufefc]|\uff04|[\uff21-\uff3a]|\uff3f|[\uff41-\uff5a]|[\uff66-\uffbe]|[\uffc2-\uffc7]|[\uffca-\uffcf]|[\uffd2-\uffd7]|[\uffda-\uffdc]|[\uffe0-\uffe1]|[\uffe5-\uffe6]|\ud800[\udc00-\udc0b]|\ud800[\udc0d-\udc26]|\ud800[\udc28-\udc3a]|\ud800[\udc3c-\udc3d]|\ud800[\udc3f-\udc4d]|\ud800[\udc50-\udc5d]|\ud800[\udc80-\udcfa]|\ud800[\udd40-\udd74]|\ud800[\ude80-\ude9c]|\ud800[\udea0-\uded0]|\ud800[\udf00-\udf1e]|\ud800[\udf30-\udf4a]|\ud800[\udf80-\udf9d]|\ud800[\udfa0-\udfc3]|\ud800[\udfc8-\udfcf]|\ud800[\udfd1-\udfd5]|\ud801[\udc00-\udc9d]|\ud802[\udc00-\udc05]|\ud802\udc08|\ud802[\udc0a-\udc35]|\ud802[\udc37-\udc38]|\ud802\udc3c|\ud802[\udc3f-\udc55]|\ud802[\udd00-\udd15]|\ud802[\udd20-\udd39]|\ud802\ude00|\ud802[\ude10-\ude13]|\ud802[\ude15-\ude17]|\ud802[\ude19-\ude33]|\ud802[\ude60-\ude7c]|\ud802[\udf00-\udf35]|\ud802[\udf40-\udf55]|\ud802[\udf60-\udf72]|\ud803[\udc00-\udc48]|\ud804[\udc03-\udc37]|\ud804[\udc83-\udcaf]|\ud808[\udc00-\udf6e]|\ud809[\udc00-\udc62]|\ud80c[\udc00-\udfff]|\ud80d[\udc00-\udc2e]|\ud81a[\udc00-\ude38]|\ud82c[\udc00-\udc01]|\ud835[\udc00-\udc54]|\ud835[\udc56-\udc9c]|\ud835[\udc9e-\udc9f]|\ud835\udca2|\ud835[\udca5-\udca6]|\ud835[\udca9-\udcac]|\ud835[\udcae-\udcb9]|\ud835\udcbb|\ud835[\udcbd-\udcc3]|\ud835[\udcc5-\udd05]|\ud835[\udd07-\udd0a]|\ud835[\udd0d-\udd14]|\ud835[\udd16-\udd1c]|\ud835[\udd1e-\udd39]|\ud835[\udd3b-\udd3e]|\ud835[\udd40-\udd44]|\ud835\udd46|\ud835[\udd4a-\udd50]|\ud835[\udd52-\udea5]|\ud835[\udea8-\udec0]|\ud835[\udec2-\udeda]|\ud835[\udedc-\udefa]|\ud835[\udefc-\udf14]|\ud835[\udf16-\udf34]|\ud835[\udf36-\udf4e]|\ud835[\udf50-\udf6e]|\ud835[\udf70-\udf88]|\ud835[\udf8a-\udfa8]|\ud835[\udfaa-\udfc2]|\ud835[\udfc4-\udfcb]|\ud840[\udc00-\udfff]|\ud841[\udc00-\udfff]|\ud842[\udc00-\udfff]|\ud843[\udc00-\udfff]|\ud844[\udc00-\udfff]|\ud845[\udc00-\udfff]|\ud846[\udc00-\udfff]|\ud847[\udc00-\udfff]|\ud848[\udc00-\udfff]|\ud849[\udc00-\udfff]|\ud84a[\udc00-\udfff]|\ud84b[\udc00-\udfff]|\ud84c[\udc00-\udfff]|\ud84d[\udc00-\udfff]|\ud84e[\udc00-\udfff]|\ud84f[\udc00-\udfff]|\ud850[\udc00-\udfff]|\ud851[\udc00-\udfff]|\ud852[\udc00-\udfff]|\ud853[\udc00-\udfff]|\ud854[\udc00-\udfff]|\ud855[\udc00-\udfff]|\ud856[\udc00-\udfff]|\ud857[\udc00-\udfff]|\ud858[\udc00-\udfff]|\ud859[\udc00-\udfff]|\ud85a[\udc00-\udfff]|\ud85b[\udc00-\udfff]|\ud85c[\udc00-\udfff]|\ud85d[\udc00-\udfff]|\ud85e[\udc00-\udfff]|\ud85f[\udc00-\udfff]|\ud860[\udc00-\udfff]|\ud861[\udc00-\udfff]|\ud862[\udc00-\udfff]|\ud863[\udc00-\udfff]|\ud864[\udc00-\udfff]|\ud865[\udc00-\udfff]|\ud866[\udc00-\udfff]|\ud867[\udc00-\udfff]|\ud868[\udc00-\udfff]|\ud869[\udc00-\uded6]|\ud869[\udf00-\udfff]|\ud86a[\udc00-\udfff]|\ud86b[\udc00-\udfff]|\ud86c[\udc00-\udfff]|\ud86d[\udc00-\udf34]|\ud86d[\udf40-\udfff]|\ud86e[\udc00-\udc1d]|\ud87e[\udc00-\ude1d] 63 | JavaUnicodeLetterorDigit [\u0100-\u02c1]|[\u02c6-\u02d1]|[\u02e0-\u02e4]|\u02ec|\u02ee|[\u0300-\u0374]|[\u0376-\u0377]|[\u037a-\u037d]|\u0386|[\u0388-\u038a]|\u038c|[\u038e-\u03a1]|[\u03a3-\u03f5]|[\u03f7-\u0481]|[\u0483-\u0487]|[\u048a-\u0527]|[\u0531-\u0556]|\u0559|[\u0561-\u0587]|[\u0591-\u05bd]|\u05bf|[\u05c1-\u05c2]|[\u05c4-\u05c5]|\u05c7|[\u05d0-\u05ea]|[\u05f0-\u05f2]|[\u0600-\u0603]|\u060b|[\u0610-\u061a]|[\u0620-\u0669]|[\u066e-\u06d3]|[\u06d5-\u06dd]|[\u06df-\u06e8]|[\u06ea-\u06fc]|\u06ff|[\u070f-\u074a]|[\u074d-\u07b1]|[\u07c0-\u07f5]|\u07fa|[\u0800-\u082d]|[\u0840-\u085b]|[\u0900-\u0963]|[\u0966-\u096f]|[\u0971-\u0977]|[\u0979-\u097f]|[\u0981-\u0983]|[\u0985-\u098c]|[\u098f-\u0990]|[\u0993-\u09a8]|[\u09aa-\u09b0]|\u09b2|[\u09b6-\u09b9]|[\u09bc-\u09c4]|[\u09c7-\u09c8]|[\u09cb-\u09ce]|\u09d7|[\u09dc-\u09dd]|[\u09df-\u09e3]|[\u09e6-\u09f3]|\u09fb|[\u0a01-\u0a03]|[\u0a05-\u0a0a]|[\u0a0f-\u0a10]|[\u0a13-\u0a28]|[\u0a2a-\u0a30]|[\u0a32-\u0a33]|[\u0a35-\u0a36]|[\u0a38-\u0a39]|\u0a3c|[\u0a3e-\u0a42]|[\u0a47-\u0a48]|[\u0a4b-\u0a4d]|\u0a51|[\u0a59-\u0a5c]|\u0a5e|[\u0a66-\u0a75]|[\u0a81-\u0a83]|[\u0a85-\u0a8d]|[\u0a8f-\u0a91]|[\u0a93-\u0aa8]|[\u0aaa-\u0ab0]|[\u0ab2-\u0ab3]|[\u0ab5-\u0ab9]|[\u0abc-\u0ac5]|[\u0ac7-\u0ac9]|[\u0acb-\u0acd]|\u0ad0|[\u0ae0-\u0ae3]|[\u0ae6-\u0aef]|\u0af1|[\u0b01-\u0b03]|[\u0b05-\u0b0c]|[\u0b0f-\u0b10]|[\u0b13-\u0b28]|[\u0b2a-\u0b30]|[\u0b32-\u0b33]|[\u0b35-\u0b39]|[\u0b3c-\u0b44]|[\u0b47-\u0b48]|[\u0b4b-\u0b4d]|[\u0b56-\u0b57]|[\u0b5c-\u0b5d]|[\u0b5f-\u0b63]|[\u0b66-\u0b6f]|\u0b71|[\u0b82-\u0b83]|[\u0b85-\u0b8a]|[\u0b8e-\u0b90]|[\u0b92-\u0b95]|[\u0b99-\u0b9a]|\u0b9c|[\u0b9e-\u0b9f]|[\u0ba3-\u0ba4]|[\u0ba8-\u0baa]|[\u0bae-\u0bb9]|[\u0bbe-\u0bc2]|[\u0bc6-\u0bc8]|[\u0bca-\u0bcd]|\u0bd0|\u0bd7|[\u0be6-\u0bef]|\u0bf9|[\u0c01-\u0c03]|[\u0c05-\u0c0c]|[\u0c0e-\u0c10]|[\u0c12-\u0c28]|[\u0c2a-\u0c33]|[\u0c35-\u0c39]|[\u0c3d-\u0c44]|[\u0c46-\u0c48]|[\u0c4a-\u0c4d]|[\u0c55-\u0c56]|[\u0c58-\u0c59]|[\u0c60-\u0c63]|[\u0c66-\u0c6f]|[\u0c82-\u0c83]|[\u0c85-\u0c8c]|[\u0c8e-\u0c90]|[\u0c92-\u0ca8]|[\u0caa-\u0cb3]|[\u0cb5-\u0cb9]|[\u0cbc-\u0cc4]|[\u0cc6-\u0cc8]|[\u0cca-\u0ccd]|[\u0cd5-\u0cd6]|\u0cde|[\u0ce0-\u0ce3]|[\u0ce6-\u0cef]|[\u0cf1-\u0cf2]|[\u0d02-\u0d03]|[\u0d05-\u0d0c]|[\u0d0e-\u0d10]|[\u0d12-\u0d3a]|[\u0d3d-\u0d44]|[\u0d46-\u0d48]|[\u0d4a-\u0d4e]|\u0d57|[\u0d60-\u0d63]|[\u0d66-\u0d6f]|[\u0d7a-\u0d7f]|[\u0d82-\u0d83]|[\u0d85-\u0d96]|[\u0d9a-\u0db1]|[\u0db3-\u0dbb]|\u0dbd|[\u0dc0-\u0dc6]|\u0dca|[\u0dcf-\u0dd4]|\u0dd6|[\u0dd8-\u0ddf]|[\u0df2-\u0df3]|[\u0e01-\u0e3a]|[\u0e3f-\u0e4e]|[\u0e50-\u0e59]|[\u0e81-\u0e82]|\u0e84|[\u0e87-\u0e88]|\u0e8a|\u0e8d|[\u0e94-\u0e97]|[\u0e99-\u0e9f]|[\u0ea1-\u0ea3]|\u0ea5|\u0ea7|[\u0eaa-\u0eab]|[\u0ead-\u0eb9]|[\u0ebb-\u0ebd]|[\u0ec0-\u0ec4]|\u0ec6|[\u0ec8-\u0ecd]|[\u0ed0-\u0ed9]|[\u0edc-\u0edd]|\u0f00|[\u0f18-\u0f19]|[\u0f20-\u0f29]|\u0f35|\u0f37|\u0f39|[\u0f3e-\u0f47]|[\u0f49-\u0f6c]|[\u0f71-\u0f84]|[\u0f86-\u0f97]|[\u0f99-\u0fbc]|\u0fc6|[\u1000-\u1049]|[\u1050-\u109d]|[\u10a0-\u10c5]|[\u10d0-\u10fa]|\u10fc|[\u1100-\u1248]|[\u124a-\u124d]|[\u1250-\u1256]|\u1258|[\u125a-\u125d]|[\u1260-\u1288]|[\u128a-\u128d]|[\u1290-\u12b0]|[\u12b2-\u12b5]|[\u12b8-\u12be]|\u12c0|[\u12c2-\u12c5]|[\u12c8-\u12d6]|[\u12d8-\u1310]|[\u1312-\u1315]|[\u1318-\u135a]|[\u135d-\u135f]|[\u1380-\u138f]|[\u13a0-\u13f4]|[\u1401-\u166c]|[\u166f-\u167f]|[\u1681-\u169a]|[\u16a0-\u16ea]|[\u16ee-\u16f0]|[\u1700-\u170c]|[\u170e-\u1714]|[\u1720-\u1734]|[\u1740-\u1753]|[\u1760-\u176c]|[\u176e-\u1770]|[\u1772-\u1773]|[\u1780-\u17d3]|\u17d7|[\u17db-\u17dd]|[\u17e0-\u17e9]|[\u180b-\u180d]|[\u1810-\u1819]|[\u1820-\u1877]|[\u1880-\u18aa]|[\u18b0-\u18f5]|[\u1900-\u191c]|[\u1920-\u192b]|[\u1930-\u193b]|[\u1946-\u196d]|[\u1970-\u1974]|[\u1980-\u19ab]|[\u19b0-\u19c9]|[\u19d0-\u19d9]|[\u1a00-\u1a1b]|[\u1a20-\u1a5e]|[\u1a60-\u1a7c]|[\u1a7f-\u1a89]|[\u1a90-\u1a99]|\u1aa7|[\u1b00-\u1b4b]|[\u1b50-\u1b59]|[\u1b6b-\u1b73]|[\u1b80-\u1baa]|[\u1bae-\u1bb9]|[\u1bc0-\u1bf3]|[\u1c00-\u1c37]|[\u1c40-\u1c49]|[\u1c4d-\u1c7d]|[\u1cd0-\u1cd2]|[\u1cd4-\u1cf2]|[\u1d00-\u1de6]|[\u1dfc-\u1f15]|[\u1f18-\u1f1d]|[\u1f20-\u1f45]|[\u1f48-\u1f4d]|[\u1f50-\u1f57]|\u1f59|\u1f5b|\u1f5d|[\u1f5f-\u1f7d]|[\u1f80-\u1fb4]|[\u1fb6-\u1fbc]|\u1fbe|[\u1fc2-\u1fc4]|[\u1fc6-\u1fcc]|[\u1fd0-\u1fd3]|[\u1fd6-\u1fdb]|[\u1fe0-\u1fec]|[\u1ff2-\u1ff4]|[\u1ff6-\u1ffc]|[\u200b-\u200f]|[\u202a-\u202e]|[\u203f-\u2040]|\u2054|[\u2060-\u2064]|[\u206a-\u206f]|\u2071|\u207f|[\u2090-\u209c]|[\u20a0-\u20b9]|[\u20d0-\u20dc]|\u20e1|[\u20e5-\u20f0]|\u2102|\u2107|[\u210a-\u2113]|\u2115|[\u2119-\u211d]|\u2124|\u2126|\u2128|[\u212a-\u212d]|[\u212f-\u2139]|[\u213c-\u213f]|[\u2145-\u2149]|\u214e|[\u2160-\u2188]|[\u2c00-\u2c2e]|[\u2c30-\u2c5e]|[\u2c60-\u2ce4]|[\u2ceb-\u2cf1]|[\u2d00-\u2d25]|[\u2d30-\u2d65]|\u2d6f|[\u2d7f-\u2d96]|[\u2da0-\u2da6]|[\u2da8-\u2dae]|[\u2db0-\u2db6]|[\u2db8-\u2dbe]|[\u2dc0-\u2dc6]|[\u2dc8-\u2dce]|[\u2dd0-\u2dd6]|[\u2dd8-\u2dde]|[\u2de0-\u2dff]|\u2e2f|[\u3005-\u3007]|[\u3021-\u302f]|[\u3031-\u3035]|[\u3038-\u303c]|[\u3041-\u3096]|[\u3099-\u309a]|[\u309d-\u309f]|[\u30a1-\u30fa]|[\u30fc-\u30ff]|[\u3105-\u312d]|[\u3131-\u318e]|[\u31a0-\u31ba]|[\u31f0-\u31ff]|[\u3400-\u4db5]|[\u4e00-\u9fcb]|[\ua000-\ua48c]|[\ua4d0-\ua4fd]|[\ua500-\ua60c]|[\ua610-\ua62b]|[\ua640-\ua66f]|[\ua67c-\ua67d]|[\ua67f-\ua697]|[\ua6a0-\ua6f1]|[\ua717-\ua71f]|[\ua722-\ua788]|[\ua78b-\ua78e]|[\ua790-\ua791]|[\ua7a0-\ua7a9]|[\ua7fa-\ua827]|\ua838|[\ua840-\ua873]|[\ua880-\ua8c4]|[\ua8d0-\ua8d9]|[\ua8e0-\ua8f7]|\ua8fb|[\ua900-\ua92d]|[\ua930-\ua953]|[\ua960-\ua97c]|[\ua980-\ua9c0]|[\ua9cf-\ua9d9]|[\uaa00-\uaa36]|[\uaa40-\uaa4d]|[\uaa50-\uaa59]|[\uaa60-\uaa76]|[\uaa7a-\uaa7b]|[\uaa80-\uaac2]|[\uaadb-\uaadd]|[\uab01-\uab06]|[\uab09-\uab0e]|[\uab11-\uab16]|[\uab20-\uab26]|[\uab28-\uab2e]|[\uabc0-\uabea]|[\uabec-\uabed]|[\uabf0-\uabf9]|[\uac00-\ud7a3]|[\ud7b0-\ud7c6]|[\ud7cb-\ud7fb]|[\uf900-\ufa2d]|[\ufa30-\ufa6d]|[\ufa70-\ufad9]|[\ufb00-\ufb06]|[\ufb13-\ufb17]|[\ufb1d-\ufb28]|[\ufb2a-\ufb36]|[\ufb38-\ufb3c]|\ufb3e|[\ufb40-\ufb41]|[\ufb43-\ufb44]|[\ufb46-\ufbb1]|[\ufbd3-\ufd3d]|[\ufd50-\ufd8f]|[\ufd92-\ufdc7]|[\ufdf0-\ufdfc]|[\ufe00-\ufe0f]|[\ufe20-\ufe26]|[\ufe33-\ufe34]|[\ufe4d-\ufe4f]|\ufe69|[\ufe70-\ufe74]|[\ufe76-\ufefc]|\ufeff|\uff04|[\uff10-\uff19]|[\uff21-\uff3a]|\uff3f|[\uff41-\uff5a]|[\uff66-\uffbe]|[\uffc2-\uffc7]|[\uffca-\uffcf]|[\uffd2-\uffd7]|[\uffda-\uffdc]|[\uffe0-\uffe1]|[\uffe5-\uffe6]|[\ufff9-\ufffb]|\ud800[\udc00-\udc0b]|\ud800[\udc0d-\udc26]|\ud800[\udc28-\udc3a]|\ud800[\udc3c-\udc3d]|\ud800[\udc3f-\udc4d]|\ud800[\udc50-\udc5d]|\ud800[\udc80-\udcfa]|\ud800[\udd40-\udd74]|\ud800\uddfd|\ud800[\ude80-\ude9c]|\ud800[\udea0-\uded0]|\ud800[\udf00-\udf1e]|\ud800[\udf30-\udf4a]|\ud800[\udf80-\udf9d]|\ud800[\udfa0-\udfc3]|\ud800[\udfc8-\udfcf]|\ud800[\udfd1-\udfd5]|\ud801[\udc00-\udc9d]|\ud801[\udca0-\udca9]|\ud802[\udc00-\udc05]|\ud802\udc08|\ud802[\udc0a-\udc35]|\ud802[\udc37-\udc38]|\ud802\udc3c|\ud802[\udc3f-\udc55]|\ud802[\udd00-\udd15]|\ud802[\udd20-\udd39]|\ud802[\ude00-\ude03]|\ud802[\ude05-\ude06]|\ud802[\ude0c-\ude13]|\ud802[\ude15-\ude17]|\ud802[\ude19-\ude33]|\ud802[\ude38-\ude3a]|\ud802\ude3f|\ud802[\ude60-\ude7c]|\ud802[\udf00-\udf35]|\ud802[\udf40-\udf55]|\ud802[\udf60-\udf72]|\ud803[\udc00-\udc48]|\ud804[\udc00-\udc46]|\ud804[\udc66-\udc6f]|\ud804[\udc80-\udcba]|\ud804\udcbd|\ud808[\udc00-\udf6e]|\ud809[\udc00-\udc62]|\ud80c[\udc00-\udfff]|\ud80d[\udc00-\udc2e]|\ud81a[\udc00-\ude38]|\ud82c[\udc00-\udc01]|\ud834[\udd65-\udd69]|\ud834[\udd6d-\udd82]|\ud834[\udd85-\udd8b]|\ud834[\uddaa-\uddad]|\ud834[\ude42-\ude44]|\ud835[\udc00-\udc54]|\ud835[\udc56-\udc9c]|\ud835[\udc9e-\udc9f]|\ud835\udca2|\ud835[\udca5-\udca6]|\ud835[\udca9-\udcac]|\ud835[\udcae-\udcb9]|\ud835\udcbb|\ud835[\udcbd-\udcc3]|\ud835[\udcc5-\udd05]|\ud835[\udd07-\udd0a]|\ud835[\udd0d-\udd14]|\ud835[\udd16-\udd1c]|\ud835[\udd1e-\udd39]|\ud835[\udd3b-\udd3e]|\ud835[\udd40-\udd44]|\ud835\udd46|\ud835[\udd4a-\udd50]|\ud835[\udd52-\udea5]|\ud835[\udea8-\udec0]|\ud835[\udec2-\udeda]|\ud835[\udedc-\udefa]|\ud835[\udefc-\udf14]|\ud835[\udf16-\udf34]|\ud835[\udf36-\udf4e]|\ud835[\udf50-\udf6e]|\ud835[\udf70-\udf88]|\ud835[\udf8a-\udfa8]|\ud835[\udfaa-\udfc2]|\ud835[\udfc4-\udfcb]|\ud835[\udfce-\udfff]|\ud840[\udc00-\udfff]|\ud841[\udc00-\udfff]|\ud842[\udc00-\udfff]|\ud843[\udc00-\udfff]|\ud844[\udc00-\udfff]|\ud845[\udc00-\udfff]|\ud846[\udc00-\udfff]|\ud847[\udc00-\udfff]|\ud848[\udc00-\udfff]|\ud849[\udc00-\udfff]|\ud84a[\udc00-\udfff]|\ud84b[\udc00-\udfff]|\ud84c[\udc00-\udfff]|\ud84d[\udc00-\udfff]|\ud84e[\udc00-\udfff]|\ud84f[\udc00-\udfff]|\ud850[\udc00-\udfff]|\ud851[\udc00-\udfff]|\ud852[\udc00-\udfff]|\ud853[\udc00-\udfff]|\ud854[\udc00-\udfff]|\ud855[\udc00-\udfff]|\ud856[\udc00-\udfff]|\ud857[\udc00-\udfff]|\ud858[\udc00-\udfff]|\ud859[\udc00-\udfff]|\ud85a[\udc00-\udfff]|\ud85b[\udc00-\udfff]|\ud85c[\udc00-\udfff]|\ud85d[\udc00-\udfff]|\ud85e[\udc00-\udfff]|\ud85f[\udc00-\udfff]|\ud860[\udc00-\udfff]|\ud861[\udc00-\udfff]|\ud862[\udc00-\udfff]|\ud863[\udc00-\udfff]|\ud864[\udc00-\udfff]|\ud865[\udc00-\udfff]|\ud866[\udc00-\udfff]|\ud867[\udc00-\udfff]|\ud868[\udc00-\udfff]|\ud869[\udc00-\uded6]|\ud869[\udf00-\udfff]|\ud86a[\udc00-\udfff]|\ud86b[\udc00-\udfff]|\ud86c[\udc00-\udfff]|\ud86d[\udc00-\udf34]|\ud86d[\udf40-\udfff]|\ud86e[\udc00-\udc1d]|\ud87e[\udc00-\ude1d]|\udb40\udc01|\udb40[\udc20-\udc7f]|\udb40[\udd00-\uddef] 64 | 65 | CommentEnd "*/" 66 | CommentEnd1 [\*][^/]+ 67 | CommentEnd2 [/][^*]* 68 | CommentBody {CommentEnd1}|{CommentEnd2}|{NotSlashAsterix} 69 | NotAsterix [^*] 70 | Comment [/][\*]({NotCommentEnd}\n|\t])*[\*][/] 71 | 72 | Template [<][^=\(\);\|\+\-\"\'\{\*\\}:]+[>]+ 73 | 74 | %s comment 75 | %% 76 | 77 | \s+ /* skip whitespace */ 78 | [/]{2}.* /* skip comments */ 79 | 80 | 81 | ((("/*"))) %{ this.begin('comment'); %} 82 | 83 | [^\*]+ %{ 84 | if (yy.__currentComment) { 85 | yy.__currentComment += "\n" + yytext.trim(); 86 | } else { 87 | yy.__currentComment = yytext.trim(); 88 | } 89 | %} 90 | [\"] /* skip */ 91 | [=] /* skip */ 92 | [\*][=\"']* %{ 93 | var currentChar = yytext; 94 | // console.log("currentChar" + currentChar); 95 | if(currentChar === '*') { 96 | var nxtChar = this._input[0]; // peek into next char without altering lexer's position 97 | //console.log("* match :"+yytext) 98 | //console.log("* match, nxt char:"+nxtChar) 99 | if(nxtChar === '/') 100 | { 101 | //console.log("inside popBlock"+nxtChar); 102 | nxtChar = this.input(); 103 | if(nxtChar.length > 1) 104 | this.unput(2,nxtChar.length); 105 | //console.log("popped state"); 106 | //console.log(this.showPosition()); 107 | this.popState(); 108 | } 109 | } 110 | %} 111 | 112 | /* Character Literals */ 113 | 114 | {JavaCharacterLiteral} return 'CharacterLiteral'; 115 | 116 | {JavaStringLiteral} return 'StringLiteral'; 117 | 118 | (("<<")) return 'LSHIFT'; 119 | 120 | {Template} %{ 121 | var r = yytext; 122 | var forTest3 = ""; 123 | /* 124 | * test 1: check if it is template declaration or LT operator 125 | * test 3: check for && operator. if found, its not a template 126 | * test 2: balanced < and > symbols 127 | */ 128 | var test1=false,test2=false,test3=false, skipTest3= false; 129 | for(var i=1; i') 154 | balance = balance-1; 155 | if(balance === 0) { 156 | splitPos = i; 157 | break; 158 | } 159 | } 160 | if(balance === 0) { 161 | if(splitPos === (r.length-1)) { 162 | test2 = true; 163 | forTest3 = r; 164 | } 165 | else { 166 | if(r[splitPos+1]=='>') { /* >> left shift operator */ 167 | /* test case /openjdk/hotspot/test/compiler/6711117/Test.java:76 */ 168 | test2 = false; 169 | this.unput(r.substring(1,r.length)); 170 | return 'LT'; 171 | } else { 172 | forTest3 = r.substring(0,splitPos+1); 173 | //console.log("inside test2: "+yytext); 174 | //console.log("test2 unput: "+r.substring(splitPos+1,r.length)); 175 | this.unput(r.substring(splitPos+1,r.length)) 176 | test2 = true; 177 | } 178 | } 179 | } 180 | else { 181 | test2 = false; 182 | this.unput(r.substring(1,r.length)); 183 | return 'LT'; 184 | } 185 | /* Start Test 3 */ 186 | //console.log("test3 start"+forTest3); 187 | if(forTest3.search("&&") === -1) { 188 | test3 = true; 189 | } 190 | else 191 | { 192 | test3 = false; 193 | //console.log("inside test3: "+forTest3); 194 | this.unput(forTest3.substring(1,forTest3.length)); 195 | return 'LT'; 196 | } 197 | if(test1 && test2 && test3) { 198 | yytext = forTest3; 199 | return 'TEMPLATE'; 200 | } 201 | %}/* */ 202 | 203 | /* Keywords */ 204 | "abstract" return 'ABSTRACT'; 205 | "assert" return 'ASSERT'; 206 | "boolean" return 'BOOLEAN'; 207 | "break" return 'BREAK'; 208 | "byte" return 'BYTE'; 209 | "case" return 'CASE'; 210 | "catch" return 'CATCH'; 211 | "char" return 'CHAR'; 212 | "class" return 'CLASS'; 213 | "const" return 'CONST'; 214 | "continue" return 'CONTINUE'; 215 | "default" return 'DEFAULT'; 216 | "do" return 'DO'; 217 | "double" return 'DOUBLE'; 218 | "else" return 'ELSE'; 219 | "enum" return 'ENUM'; 220 | "extends" return 'EXTENDS'; 221 | "final" return 'FINAL'; 222 | "finally" return 'FINALLY'; 223 | "float" return 'FLOAT'; 224 | "for" return 'FOR'; 225 | "if" return 'IF'; 226 | "goto" return 'GOTO'; 227 | "implements" return 'IMPLEMENTS'; 228 | "import" return 'IMPORT'; 229 | "instanceof" return 'INSTANCEOF'; 230 | "int" return 'INT'; 231 | "interface" return 'INTERFACE'; 232 | "long" return 'LONG'; 233 | "native" return 'NATIVE'; 234 | "new" return 'NEW'; 235 | "package" return 'PACKAGE'; 236 | "private" return 'PRIVATE'; 237 | "protected" return 'PROTECTED'; 238 | "public" return 'PUBLIC'; 239 | "return" return 'RETURN'; 240 | "short" return 'SHORT'; 241 | "static" return 'STATIC'; 242 | "strictfp" return 'STRICTFP'; 243 | "super" return 'SUPER'; 244 | "switch" return 'SWITCH'; 245 | "synchronized" return 'SYNCHRONIZED'; 246 | "this" return 'THIS'; 247 | "throw" return 'THROW'; 248 | "throws" return 'THROWS'; 249 | "transient" return 'TRANSIENT'; 250 | "try" return 'TRY'; 251 | "void" return 'VOID'; 252 | "volatile" return 'VOLATILE'; 253 | "while" return 'WHILE'; 254 | 255 | /* Integer Literals */ 256 | {DecimalIntegerLiteral} return 'IntegerLiteral'; 257 | {OctalIntegerLiteral} return 'IntegerLiteral'; 258 | {HexIntegerLiteral} return 'IntegerLiteral'; 259 | 260 | /* Floating-point Literals */ 261 | {JavaFloatingPointLiteral} return 'FloatingPointLiteral'; 262 | 263 | /* Boolean Literals */ 264 | "true"|"false" return 'BooleanLiteral'; 265 | 266 | /* Null literal */ 267 | 268 | "null" return 'NullLiteral'; 269 | 270 | /* Separators */ 271 | 272 | "(" return 'LPAREN'; 273 | ")" return 'RPAREN'; 274 | "{" return 'LBRACE'; 275 | "}" return 'RBRACE'; 276 | "[" return 'LBRACK'; 277 | "]" return 'RBRACK'; 278 | ";" return 'SEMI'; 279 | "," return 'COMMA'; 280 | "." return 'DOT'; 281 | 282 | /* Operators */ 283 | 284 | "=" return 'ASSIGN'; 285 | ">" return 'GT'; 286 | "<" return 'LT'; 287 | "!" return 'BANG'; 288 | "~" return 'TILDE'; 289 | "?" return 'QUESTION'; 290 | ":" return 'COLON'; 291 | "==" return 'EQUAL'; 292 | "<=" return 'LE'; 293 | ">=" return 'GE'; 294 | "!=" return 'NOTEQUAL'; 295 | "&&" return 'AND'; 296 | "||" return 'OR'; 297 | "++" return 'INC'; 298 | "--" return 'DEC'; 299 | "+" return 'ADD'; 300 | "-" return 'SUB'; 301 | "*" return 'MUL'; 302 | "/" return 'DIV'; 303 | "&" return 'BITAND'; 304 | "|" return 'BITOR'; 305 | "^" return 'CARET'; 306 | "%" return 'MOD'; 307 | 308 | "+=" return 'ADD_ASSIGN'; 309 | "-=" return 'SUB_ASSIGN'; 310 | "*=" return 'MUL_ASSIGN'; 311 | "/=" return 'DIV_ASSIGN'; 312 | "&=" return 'AND_ASSIGN'; 313 | "|=" return 'OR_ASSIGN'; 314 | "^=" return 'XOR_ASSIGN'; 315 | "%=" return 'MOD_ASSIGN'; 316 | "<<=" return 'LSHIFT_ASSIGN'; 317 | ">>=" return 'RSHIFT_ASSIGN'; 318 | ">>>=" return 'URSHIFT_ASSIGN'; 319 | 320 | /* Additional Symbols */ 321 | 322 | "@" return 'AT'; 323 | "..." return 'ELLIPSIS'; 324 | 325 | /* Identifier */ 326 | {JavaIdentifier} %{ 327 | // console.log(yytext); 328 | // console.log(this); 329 | // console.log(yylineno); 330 | // console.log(yylloc); 331 | return 'Identifier'; 332 | %} 333 | 334 | 335 | <> return 'EOF'; 336 | -------------------------------------------------------------------------------- /main.js: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2014-2018 MKLab. All rights reserved. 3 | * 4 | * Permission is hereby granted, free of charge, to any person obtaining a 5 | * copy of this software and associated documentation files (the "Software"), 6 | * to deal in the Software without restriction, including without limitation 7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | * and/or sell copies of the Software, and to permit persons to whom the 9 | * Software is furnished to do so, subject to the following conditions: 10 | * 11 | * The above copyright notice and this permission notice shall be included in 12 | * all copies or substantial portions of the Software. 13 | * 14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 17 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 18 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 19 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 20 | * DEALINGS IN THE SOFTWARE. 21 | * 22 | */ 23 | 24 | const codeGenerator = require("./code-generator"); 25 | const codeAnalyzer = require("./code-analyzer"); 26 | 27 | function getGenOptions() { 28 | return { 29 | javaDoc: app.preferences.get("java.gen.javaDoc"), 30 | useTab: app.preferences.get("java.gen.useTab"), 31 | indentSpaces: app.preferences.get("java.gen.indentSpaces"), 32 | }; 33 | } 34 | 35 | function getRevOptions() { 36 | return { 37 | association: app.preferences.get("java.rev.association"), 38 | publicOnly: app.preferences.get("java.rev.publicOnly"), 39 | typeHierarchy: app.preferences.get("java.rev.typeHierarchy"), 40 | packageOverview: app.preferences.get("java.rev.packageOverview"), 41 | packageStructure: app.preferences.get("java.rev.packageStructure"), 42 | }; 43 | } 44 | 45 | /** 46 | * Command Handler for Java Generate 47 | * 48 | * @param {Element} base 49 | * @param {string} path 50 | * @param {Object} options 51 | */ 52 | async function _handleGenerate(base, path, options) { 53 | // If options is not passed, get from preference 54 | options = options || getGenOptions(); 55 | // If base is not assigned, popup ElementPicker 56 | if (!base) { 57 | app.elementPickerDialog 58 | .showDialog( 59 | "Select a base model to generate codes", 60 | null, 61 | type.UMLPackage, 62 | ) 63 | .then(async function ({ buttonId, returnValue }) { 64 | if (buttonId === "ok") { 65 | base = returnValue; 66 | // If path is not assigned, popup Open Dialog to select a folder 67 | if (!path) { 68 | var files = await app.dialogs.showOpenDialogAsync( 69 | "Select a folder where generated codes to be located", 70 | null, 71 | null, 72 | { properties: ["openDirectory"] }, 73 | ); 74 | if (files && files.length > 0) { 75 | path = files[0]; 76 | codeGenerator.generate(base, path, options); 77 | } 78 | } else { 79 | codeGenerator.generate(base, path, options); 80 | } 81 | } 82 | }); 83 | } else { 84 | // If path is not assigned, popup Open Dialog to select a folder 85 | if (!path) { 86 | var files = await app.dialogs.showOpenDialogAsync( 87 | "Select a folder where generated codes to be located", 88 | null, 89 | null, 90 | { properties: ["openDirectory"] }, 91 | ); 92 | if (files && files.length > 0) { 93 | path = files[0]; 94 | codeGenerator.generate(base, path, options); 95 | } 96 | } else { 97 | codeGenerator.generate(base, path, options); 98 | } 99 | } 100 | } 101 | 102 | /** 103 | * Command Handler for Java Reverse 104 | * 105 | * @param {string} basePath 106 | * @param {Object} options 107 | */ 108 | async function _handleReverse(basePath, options) { 109 | // If options is not passed, get from preference 110 | options = getRevOptions(); 111 | // If basePath is not assigned, popup Open Dialog to select a folder 112 | if (!basePath) { 113 | var files = await app.dialogs.showOpenDialogAsync( 114 | "Select Folder", 115 | null, 116 | null, 117 | { 118 | properties: ["openDirectory"], 119 | }, 120 | ); 121 | if (files && files.length > 0) { 122 | basePath = files[0]; 123 | codeAnalyzer.analyze(basePath, options); 124 | } 125 | } 126 | } 127 | 128 | /** 129 | * Popup PreferenceDialog with Java Preference Schema 130 | */ 131 | function _handleConfigure() { 132 | app.commands.execute("application:preferences", "java"); 133 | } 134 | 135 | function init() { 136 | app.commands.register("java:generate", _handleGenerate); 137 | app.commands.register("java:reverse", _handleReverse); 138 | app.commands.register("java:configure", _handleConfigure); 139 | } 140 | 141 | exports.init = init; 142 | -------------------------------------------------------------------------------- /menus/menu.json: -------------------------------------------------------------------------------- 1 | { 2 | "menu": [ 3 | { 4 | "id": "tools", 5 | "submenu": [ 6 | { 7 | "label": "Java", 8 | "id": "tools.java", 9 | "submenu": [ 10 | { "label": "Generate Code...", "id": "tools.java.generate", "command": "java:generate" }, 11 | { "label": "Reverse Code...", "id": "tools.java.reverse", "command": "java:reverse" }, 12 | { "type": "separator" }, 13 | { "label": "Configure...", "id": "tools.java.configure", "command": "java:configure" } 14 | ] 15 | } 16 | ] 17 | } 18 | ] 19 | } 20 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "staruml.java", 3 | "title": "Java", 4 | "description": "Java code generation and reverse engineering.", 5 | "homepage": "https://github.com/staruml/staruml-java", 6 | "issues": "https://github.com/staruml/staruml-java/issues", 7 | "keywords": [ 8 | "java" 9 | ], 10 | "version": "0.9.7", 11 | "author": { 12 | "name": "Minkyu Lee", 13 | "email": "niklaus.lee@gmail.com", 14 | "url": "https://github.com/niklauslee" 15 | }, 16 | "license": "MIT", 17 | "engines": { 18 | "staruml": ">=6.0.0" 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /preferences/preference.json: -------------------------------------------------------------------------------- 1 | { 2 | "id": "java", 3 | "name": "Java", 4 | "schema": { 5 | "java.gen": { 6 | "text": "Java Code Generation", 7 | "type": "section" 8 | }, 9 | "java.gen.javaDoc": { 10 | "text": "JavaDoc", 11 | "description": "Generate JavaDoc comments.", 12 | "type": "check", 13 | "default": true 14 | }, 15 | "java.gen.useTab": { 16 | "text": "Use Tab", 17 | "description": "Use Tab for indentation instead of spaces.", 18 | "type": "check", 19 | "default": false 20 | }, 21 | "java.gen.indentSpaces": { 22 | "text": "Indent Spaces", 23 | "description": "Number of spaces for indentation.", 24 | "type": "number", 25 | "default": 4 26 | }, 27 | "java.rev": { 28 | "text": "Java Reverse Engineering", 29 | "type": "section" 30 | }, 31 | "java.rev.association": { 32 | "text": "Use Association", 33 | "description": "Reverse Java Fields as UML Associations.", 34 | "type": "check", 35 | "default": true 36 | }, 37 | "java.rev.publicOnly": { 38 | "text": "Public Only", 39 | "description": "Reverse public members only.", 40 | "type": "check", 41 | "default": false 42 | }, 43 | "java.rev.typeHierarchy": { 44 | "text": "Type Hierarchy Diagram", 45 | "description": "Create a type hierarchy diagram for all classes and interfaces", 46 | "type": "check", 47 | "default": true 48 | }, 49 | "java.rev.packageOverview": { 50 | "text": "Package Overview Diagram", 51 | "description": "Create overview diagram for each package", 52 | "type": "check", 53 | "default": true 54 | }, 55 | "java.rev.packageStructure": { 56 | "text": "Package Structure Diagram", 57 | "description": "Create a package structure diagram for all packages", 58 | "type": "check", 59 | "default": true 60 | } 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /unittest-files/parse/AnnotationTypeTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.test; 2 | 3 | @interface ClassPreamble { 4 | int _annotationConstant; 5 | String author(); 6 | String lastModified() default "N/A"; 7 | } 8 | -------------------------------------------------------------------------------- /unittest-files/parse/AnnotationTypeTest_ast.json: -------------------------------------------------------------------------------- 1 | { 2 | "node": "CompilationUnit", 3 | "package": { 4 | "node": "Package", 5 | "qualifiedName": { 6 | "node": "QualifiedName", 7 | "name": "com.mycompany.test" 8 | } 9 | }, 10 | "types": [ 11 | { 12 | "node": "AnnotationType", 13 | "name": "ClassPreamble", 14 | "body": [ 15 | { 16 | "node": "AnnotationConstant", 17 | "type": { 18 | "node": "Type", 19 | "qualifiedName": { 20 | "node": "QualifiedName", 21 | "name": "int" 22 | } 23 | }, 24 | "variables": [ 25 | { 26 | "node": "Variable", 27 | "name": "_annotationConstant" 28 | } 29 | ] 30 | }, 31 | { 32 | "node": "AnnotationMethod", 33 | "name": "author", 34 | "type": { 35 | "node": "Type", 36 | "qualifiedName": { 37 | "node": "QualifiedName", 38 | "name": "String" 39 | } 40 | } 41 | }, 42 | { 43 | "node": "AnnotationMethod", 44 | "name": "lastModified", 45 | "defaultValue": "\"N/A\"", 46 | "type": { 47 | "node": "Type", 48 | "qualifiedName": { 49 | "node": "QualifiedName", 50 | "name": "String" 51 | } 52 | } 53 | } 54 | ] 55 | } 56 | ] 57 | } -------------------------------------------------------------------------------- /unittest-files/parse/AssociationTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.test; 2 | 3 | import java.util.*; 4 | 5 | public class AssociationTest { 6 | 7 | // Associations with multiplicity (*) and isOrdered = true 8 | public List classList; 9 | public ArrayList classArrayList; 10 | public LinkedList classLinkedList; 11 | public Vector classVector; 12 | 13 | // Associations with multiplicity (*) and isOrdered = false 14 | public Set classSet; 15 | public HashSet classHashSet; 16 | public SortedSet classSortedSet; 17 | public NavigableSet classNavigableSet; 18 | public TreeSet classTreeSet; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /unittest-files/parse/ClassTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.test; 2 | 3 | import java.util.ArrayList; 4 | import java.lang.*; 5 | import static java.awt.Color; 6 | import static java.lang.Math.*; 7 | 8 | public class ClassTest extends GenericClassTest implements com.mycompany.test.InterfaceTest, java.lang.Runnable { 9 | 10 | // Visibility 11 | private int _privateField; 12 | protected int _protectedField; 13 | public int _publicField; 14 | int _packageField; 15 | 16 | // Array Types 17 | String[] StringArray; 18 | int[][] int2DimentionalArray; 19 | 20 | // Multiple Variables 21 | int a, b, c, d; 22 | 23 | // Field Modifiers 24 | static final transient volatile int _field; 25 | 26 | // Field Initializer 27 | int _fieldInt = 10; 28 | String _fieldString = "String Literal"; 29 | char _fieldChar = 'c'; 30 | boolean _fieldBoolean = true; 31 | InterfaceTest _fieldNull = null; // Refer to inner interface 32 | 33 | // Method 34 | public void test(int arg1, final String arg2) throws IllegalAccess, java.lang.Exception {} 35 | static final synchronized native strictfp void test2() {} 36 | abstract int test3() {} 37 | 38 | // Annotated Method 39 | @Deprecated 40 | @SuppressWarnings({ "unchecked", "deprecation" }) 41 | @MethodInfo(author = "Pankaj", comments = "Main method", date = "Nov 17 2012", revision = 10) 42 | void annotatedMethod() {} 43 | 44 | // Inner Class 45 | static class InnerClass { 46 | } 47 | 48 | // Inner Interface (same name with outer-scope InterfaceTest interface) 49 | static interface InterfaceTest { 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /unittest-files/parse/ClassTest_ast.json: -------------------------------------------------------------------------------- 1 | { 2 | "node": "CompilationUnit", 3 | "package": { 4 | "node": "Package", 5 | "qualifiedName": { 6 | "node": "QualifiedName", 7 | "name": "com.mycompany.test" 8 | } 9 | }, 10 | "imports": [ 11 | { 12 | "node": "Import", 13 | "qualifiedName": { 14 | "node": "QualifiedName", 15 | "name": "java.util.ArrayList" 16 | } 17 | }, 18 | { 19 | "node": "Import", 20 | "qualifiedName": { 21 | "node": "QualifiedName", 22 | "name": "java.lang" 23 | }, 24 | "wildcard": true 25 | }, 26 | { 27 | "node": "Import", 28 | "qualifiedName": { 29 | "node": "QualifiedName", 30 | "name": "java.awt.Color" 31 | }, 32 | "isStatic": true 33 | }, 34 | { 35 | "node": "Import", 36 | "qualifiedName": { 37 | "node": "QualifiedName", 38 | "name": "java.lang.Math" 39 | }, 40 | "wildcard": true, 41 | "isStatic": true 42 | } 43 | ], 44 | "types": [ 45 | { 46 | "node": "Class", 47 | "name": "ClassTest", 48 | "extends": { 49 | "node": "Type", 50 | "qualifiedName": { 51 | "node": "QualifiedName", 52 | "name": "java.util.Vector" 53 | } 54 | }, 55 | "implements": [ 56 | { 57 | "node": "Type", 58 | "qualifiedName": { 59 | "node": "QualifiedName", 60 | "name": "java.lang.Runnable" 61 | } 62 | }, 63 | { 64 | "node": "Type", 65 | "qualifiedName": { 66 | "node": "QualifiedName", 67 | "name": "java.lang.Serializable" 68 | } 69 | } 70 | ], 71 | "body": [ 72 | { 73 | "node": "Field", 74 | "type": { 75 | "node": "Type", 76 | "qualifiedName": { 77 | "node": "QualifiedName", 78 | "name": "int" 79 | } 80 | }, 81 | "variables": [ 82 | { 83 | "node": "Variable", 84 | "name": "_privateField" 85 | } 86 | ], 87 | "modifiers": [ 88 | "private" 89 | ] 90 | }, 91 | { 92 | "node": "Field", 93 | "type": { 94 | "node": "Type", 95 | "qualifiedName": { 96 | "node": "QualifiedName", 97 | "name": "int" 98 | } 99 | }, 100 | "variables": [ 101 | { 102 | "node": "Variable", 103 | "name": "_protectedField" 104 | } 105 | ], 106 | "modifiers": [ 107 | "protected" 108 | ] 109 | }, 110 | { 111 | "node": "Field", 112 | "type": { 113 | "node": "Type", 114 | "qualifiedName": { 115 | "node": "QualifiedName", 116 | "name": "int" 117 | } 118 | }, 119 | "variables": [ 120 | { 121 | "node": "Variable", 122 | "name": "_publicField" 123 | } 124 | ], 125 | "modifiers": [ 126 | "public" 127 | ] 128 | }, 129 | { 130 | "node": "Field", 131 | "type": { 132 | "node": "Type", 133 | "qualifiedName": { 134 | "node": "QualifiedName", 135 | "name": "int" 136 | } 137 | }, 138 | "variables": [ 139 | { 140 | "node": "Variable", 141 | "name": "_packageField" 142 | } 143 | ] 144 | }, 145 | { 146 | "node": "Field", 147 | "type": { 148 | "node": "Type", 149 | "qualifiedName": { 150 | "node": "QualifiedName", 151 | "name": "String" 152 | }, 153 | "arrayDimension": [ 154 | "[]" 155 | ] 156 | }, 157 | "variables": [ 158 | { 159 | "node": "Variable", 160 | "name": "StringArray" 161 | } 162 | ] 163 | }, 164 | { 165 | "node": "Field", 166 | "type": { 167 | "node": "Type", 168 | "qualifiedName": { 169 | "node": "QualifiedName", 170 | "name": "int" 171 | }, 172 | "arrayDimension": [ 173 | "[]", 174 | "[]" 175 | ] 176 | }, 177 | "variables": [ 178 | { 179 | "node": "Variable", 180 | "name": "int2DimentionalArray" 181 | } 182 | ] 183 | }, 184 | { 185 | "node": "Field", 186 | "type": { 187 | "node": "Type", 188 | "qualifiedName": { 189 | "node": "QualifiedName", 190 | "name": "int" 191 | } 192 | }, 193 | "variables": [ 194 | { 195 | "node": "Variable", 196 | "name": "a" 197 | }, 198 | { 199 | "node": "Variable", 200 | "name": "b" 201 | }, 202 | { 203 | "node": "Variable", 204 | "name": "c" 205 | }, 206 | { 207 | "node": "Variable", 208 | "name": "d" 209 | } 210 | ] 211 | }, 212 | { 213 | "node": "Field", 214 | "type": { 215 | "node": "Type", 216 | "qualifiedName": { 217 | "node": "QualifiedName", 218 | "name": "int" 219 | } 220 | }, 221 | "variables": [ 222 | { 223 | "node": "Variable", 224 | "name": "_field" 225 | } 226 | ], 227 | "modifiers": [ 228 | "static", 229 | "final", 230 | "transient", 231 | "volatile" 232 | ] 233 | }, 234 | { 235 | "node": "Field", 236 | "type": { 237 | "node": "Type", 238 | "qualifiedName": { 239 | "node": "QualifiedName", 240 | "name": "int" 241 | } 242 | }, 243 | "variables": [ 244 | { 245 | "node": "Variable", 246 | "name": "_fieldInt", 247 | "initializer": "10" 248 | } 249 | ] 250 | }, 251 | { 252 | "node": "Field", 253 | "type": { 254 | "node": "Type", 255 | "qualifiedName": { 256 | "node": "QualifiedName", 257 | "name": "String" 258 | } 259 | }, 260 | "variables": [ 261 | { 262 | "node": "Variable", 263 | "name": "_fieldString", 264 | "initializer": "\"String Literal\"" 265 | } 266 | ] 267 | }, 268 | { 269 | "node": "Field", 270 | "type": { 271 | "node": "Type", 272 | "qualifiedName": { 273 | "node": "QualifiedName", 274 | "name": "char" 275 | } 276 | }, 277 | "variables": [ 278 | { 279 | "node": "Variable", 280 | "name": "_fieldChar", 281 | "initializer": "'c'" 282 | } 283 | ] 284 | }, 285 | { 286 | "node": "Field", 287 | "type": { 288 | "node": "Type", 289 | "qualifiedName": { 290 | "node": "QualifiedName", 291 | "name": "boolean" 292 | } 293 | }, 294 | "variables": [ 295 | { 296 | "node": "Variable", 297 | "name": "_fieldBoolean", 298 | "initializer": "true" 299 | } 300 | ] 301 | }, 302 | { 303 | "node": "Field", 304 | "type": { 305 | "node": "Type", 306 | "qualifiedName": { 307 | "node": "QualifiedName", 308 | "name": "Object" 309 | } 310 | }, 311 | "variables": [ 312 | { 313 | "node": "Variable", 314 | "name": "_fieldNull", 315 | "initializer": "null" 316 | } 317 | ] 318 | }, 319 | { 320 | "node": "Method", 321 | "name": "test", 322 | "type": { 323 | "node": "Type", 324 | "qualifiedName": { 325 | "node": "QualifiedName", 326 | "name": "void" 327 | } 328 | }, 329 | "parameters": [ 330 | { 331 | "node": "Parameter", 332 | "type": { 333 | "node": "Type", 334 | "qualifiedName": { 335 | "node": "QualifiedName", 336 | "name": "int" 337 | } 338 | }, 339 | "variable": { 340 | "node": "Variable", 341 | "name": "arg1" 342 | } 343 | }, 344 | { 345 | "node": "Parameter", 346 | "type": { 347 | "node": "Type", 348 | "qualifiedName": { 349 | "node": "QualifiedName", 350 | "name": "String" 351 | } 352 | }, 353 | "variable": { 354 | "node": "Variable", 355 | "name": "arg2" 356 | }, 357 | "modifiers": [ 358 | "final" 359 | ] 360 | } 361 | ], 362 | "throws": [ 363 | { 364 | "node": "QualifiedName", 365 | "name": "IllegalAccess" 366 | }, 367 | { 368 | "node": "QualifiedName", 369 | "name": "java.lang.Exception" 370 | } 371 | ], 372 | "modifiers": [ 373 | "public" 374 | ] 375 | }, 376 | { 377 | "node": "Method", 378 | "name": "test2", 379 | "type": { 380 | "node": "Type", 381 | "qualifiedName": { 382 | "node": "QualifiedName", 383 | "name": "void" 384 | } 385 | }, 386 | "parameters": [], 387 | "modifiers": [ 388 | "static", 389 | "final", 390 | "synchronized", 391 | "native", 392 | "strictfp" 393 | ] 394 | }, 395 | { 396 | "node": "Method", 397 | "name": "test3", 398 | "type": { 399 | "node": "Type", 400 | "qualifiedName": { 401 | "node": "QualifiedName", 402 | "name": "int" 403 | } 404 | }, 405 | "parameters": [], 406 | "modifiers": [ 407 | "abstract" 408 | ] 409 | }, 410 | { 411 | "node": "Method", 412 | "name": "annotatedMethod", 413 | "type": { 414 | "node": "Type", 415 | "qualifiedName": { 416 | "node": "QualifiedName", 417 | "name": "void" 418 | } 419 | }, 420 | "parameters": [], 421 | "annotations": [ 422 | { 423 | "node": "Annotation", 424 | "qualifiedName": { 425 | "node": "QualifiedName", 426 | "name": "Deprecated" 427 | } 428 | }, 429 | { 430 | "node": "Annotation", 431 | "qualifiedName": { 432 | "node": "QualifiedName", 433 | "name": "SuppressWarnings" 434 | }, 435 | "valueList": [ 436 | [ 437 | "\"unchecked\"", 438 | "\"deprecation\"" 439 | ] 440 | ] 441 | }, 442 | { 443 | "node": "Annotation", 444 | "qualifiedName": { 445 | "node": "QualifiedName", 446 | "name": "MethodInfo" 447 | }, 448 | "valuePairs": [ 449 | { 450 | "node": "ValuePair", 451 | "name": "author", 452 | "value": "\"Pankaj\"" 453 | }, 454 | { 455 | "node": "ValuePair", 456 | "name": "comments", 457 | "value": "\"Main method\"" 458 | }, 459 | { 460 | "node": "ValuePair", 461 | "name": "date", 462 | "value": "\"Nov 17 2012\"" 463 | }, 464 | { 465 | "node": "ValuePair", 466 | "name": "revision", 467 | "value": "10" 468 | } 469 | ] 470 | } 471 | ] 472 | }, 473 | { 474 | "node": "Class", 475 | "name": "InnerClass", 476 | "extends": null, 477 | "implements": [], 478 | "body": [], 479 | "modifiers": [ 480 | "static" 481 | ] 482 | } 483 | ], 484 | "modifiers": [ 485 | "public" 486 | ] 487 | } 488 | ] 489 | } -------------------------------------------------------------------------------- /unittest-files/parse/EnumTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.test; 2 | 3 | public enum RetryType { 4 | NONE( false ), 5 | BEFORE_RESPONSE( true ), 6 | AFTER_RESPONSE( true ) ; 7 | 8 | private final boolean isRetry ; 9 | 10 | RetryType( boolean isRetry ) { 11 | this.isRetry = isRetry ; 12 | } 13 | 14 | public boolean isRetry() { 15 | return this.isRetry ; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /unittest-files/parse/EnumTest_ast.json: -------------------------------------------------------------------------------- 1 | { 2 | "node": "CompilationUnit", 3 | "package": { 4 | "node": "Package", 5 | "qualifiedName": { 6 | "node": "QualifiedName", 7 | "name": "com.mycompany.test" 8 | } 9 | }, 10 | "types": [ 11 | { 12 | "node": "Enum", 13 | "name": "RetryType", 14 | "implements": [], 15 | "body": [ 16 | { 17 | "node": "EnumConstant", 18 | "name": "NONE", 19 | "arguments": [ 20 | "false" 21 | ] 22 | }, 23 | { 24 | "node": "EnumConstant", 25 | "name": "BEFORE_RESPONSE", 26 | "arguments": [ 27 | "true" 28 | ] 29 | }, 30 | { 31 | "node": "EnumConstant", 32 | "name": "AFTER_RESPONSE", 33 | "arguments": [ 34 | "true" 35 | ] 36 | }, 37 | { 38 | "node": "Field", 39 | "type": { 40 | "node": "Type", 41 | "qualifiedName": { 42 | "node": "QualifiedName", 43 | "name": "boolean" 44 | } 45 | }, 46 | "variables": [ 47 | { 48 | "node": "Variable", 49 | "name": "isRetry" 50 | } 51 | ], 52 | "modifiers": [ 53 | "private", 54 | "final" 55 | ] 56 | }, 57 | { 58 | "node": "Constructor", 59 | "name": "RetryType", 60 | "parameters": [ 61 | { 62 | "node": "Parameter", 63 | "type": { 64 | "node": "Type", 65 | "qualifiedName": { 66 | "node": "QualifiedName", 67 | "name": "boolean" 68 | } 69 | }, 70 | "variable": { 71 | "node": "Variable", 72 | "name": "isRetry" 73 | } 74 | } 75 | ] 76 | }, 77 | { 78 | "node": "Method", 79 | "name": "isRetry", 80 | "type": { 81 | "node": "Type", 82 | "qualifiedName": { 83 | "node": "QualifiedName", 84 | "name": "boolean" 85 | } 86 | }, 87 | "parameters": [], 88 | "modifiers": [ 89 | "public" 90 | ] 91 | } 92 | ], 93 | "modifiers": [ 94 | "public" 95 | ] 96 | } 97 | ] 98 | } -------------------------------------------------------------------------------- /unittest-files/parse/GenericClassTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.test; 2 | 3 | // Generic Class 4 | public class GenericClassTest extends AbstractList implements List, RandomAccess, Cloneable, java.io.Serializable { 5 | 6 | // Field 7 | private OrderedPair> p = new OrderedPair<>("primes", new Box()); 8 | private ClassTest classTestRef; 9 | 10 | // Constructor and Method 11 | public GenericClassTest(Collection c) {} 12 | public Enumeration elements() {} 13 | public void printAll(ArrayList list) {} 14 | } 15 | -------------------------------------------------------------------------------- /unittest-files/parse/GenericClassTest_ast.json: -------------------------------------------------------------------------------- 1 | { 2 | "node": "CompilationUnit", 3 | "package": { 4 | "node": "Package", 5 | "qualifiedName": { 6 | "node": "QualifiedName", 7 | "name": "com.mycompany.test" 8 | } 9 | }, 10 | "types": [ 11 | { 12 | "node": "Class", 13 | "name": "Vector", 14 | "typeParameters": [ 15 | "E", 16 | "T" 17 | ], 18 | "extends": { 19 | "node": "Type", 20 | "qualifiedName": { 21 | "node": "QualifiedName", 22 | "name": "AbstractList", 23 | "typeParameters": [ 24 | "E" 25 | ] 26 | } 27 | }, 28 | "implements": [ 29 | { 30 | "node": "Type", 31 | "qualifiedName": { 32 | "node": "QualifiedName", 33 | "name": "List", 34 | "typeParameters": [ 35 | "E" 36 | ] 37 | } 38 | }, 39 | { 40 | "node": "Type", 41 | "qualifiedName": { 42 | "node": "QualifiedName", 43 | "name": "RandomAccess" 44 | } 45 | }, 46 | { 47 | "node": "Type", 48 | "qualifiedName": { 49 | "node": "QualifiedName", 50 | "name": "Cloneable" 51 | } 52 | }, 53 | { 54 | "node": "Type", 55 | "qualifiedName": { 56 | "node": "QualifiedName", 57 | "name": "java.io.Serializable" 58 | } 59 | } 60 | ], 61 | "body": [ 62 | { 63 | "node": "Field", 64 | "type": { 65 | "node": "Type", 66 | "qualifiedName": { 67 | "node": "QualifiedName", 68 | "name": "OrderedPair", 69 | "typeParameters": [ 70 | "String", 71 | "Box" 72 | ] 73 | } 74 | }, 75 | "variables": [ 76 | { 77 | "node": "Variable", 78 | "name": "p", 79 | "initializer": null 80 | } 81 | ], 82 | "modifiers": [ 83 | "private" 84 | ] 85 | }, 86 | { 87 | "node": "Constructor", 88 | "name": "Vector", 89 | "parameters": [ 90 | { 91 | "node": "Parameter", 92 | "type": { 93 | "node": "Type", 94 | "qualifiedName": { 95 | "node": "QualifiedName", 96 | "name": "Collection", 97 | "typeParameters": [ 98 | "? extends E" 99 | ] 100 | } 101 | }, 102 | "variable": { 103 | "node": "Variable", 104 | "name": "c" 105 | } 106 | } 107 | ], 108 | "modifiers": [ 109 | "public" 110 | ] 111 | }, 112 | { 113 | "node": "Method", 114 | "name": "elements", 115 | "type": { 116 | "node": "Type", 117 | "qualifiedName": { 118 | "node": "QualifiedName", 119 | "name": "Enumeration", 120 | "typeParameters": [ 121 | "E" 122 | ] 123 | } 124 | }, 125 | "parameters": [], 126 | "modifiers": [ 127 | "public" 128 | ] 129 | } 130 | ], 131 | "modifiers": [ 132 | "public" 133 | ] 134 | } 135 | ] 136 | } -------------------------------------------------------------------------------- /unittest-files/parse/InterfaceTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.test; 2 | 3 | public interface InterfaceTest extends java.lang.Runnable, java.lang.Serializable { 4 | 5 | public static final int interfaceStaticField = 100; 6 | 7 | public CompositeContext createContext(ColorModel srcColorModel, ColorModel dstColorModel); 8 | 9 | } 10 | -------------------------------------------------------------------------------- /unittest-files/parse/InterfaceTest_ast.json: -------------------------------------------------------------------------------- 1 | { 2 | "node": "CompilationUnit", 3 | "package": { 4 | "node": "Package", 5 | "qualifiedName": { 6 | "node": "QualifiedName", 7 | "name": "com.mycompany.test" 8 | } 9 | }, 10 | "types": [ 11 | { 12 | "node": "Interface", 13 | "name": "InterfaceTest", 14 | "extends": [ 15 | { 16 | "node": "Type", 17 | "qualifiedName": { 18 | "node": "QualifiedName", 19 | "name": "java.lang.Runnable" 20 | } 21 | }, 22 | { 23 | "node": "Type", 24 | "qualifiedName": { 25 | "node": "QualifiedName", 26 | "name": "java.lang.Serializable" 27 | } 28 | } 29 | ], 30 | "body": [ 31 | { 32 | "node": "Field", 33 | "type": { 34 | "node": "Type", 35 | "qualifiedName": { 36 | "node": "QualifiedName", 37 | "name": "int" 38 | } 39 | }, 40 | "variables": [ 41 | { 42 | "node": "Variable", 43 | "name": "interfaceStaticField", 44 | "initializer": "100" 45 | } 46 | ], 47 | "modifiers": [ 48 | "public", 49 | "static", 50 | "final" 51 | ] 52 | }, 53 | { 54 | "node": "Method", 55 | "type": { 56 | "node": "Type", 57 | "qualifiedName": { 58 | "node": "QualifiedName", 59 | "name": "CompositeContext" 60 | } 61 | }, 62 | "name": "createContext", 63 | "parameters": [ 64 | { 65 | "node": "Parameter", 66 | "type": { 67 | "node": "Type", 68 | "qualifiedName": { 69 | "node": "QualifiedName", 70 | "name": "ColorModel" 71 | } 72 | }, 73 | "variable": { 74 | "node": "Variable", 75 | "name": "srcColorModel" 76 | } 77 | }, 78 | { 79 | "node": "Parameter", 80 | "type": { 81 | "node": "Type", 82 | "qualifiedName": { 83 | "node": "QualifiedName", 84 | "name": "ColorModel" 85 | } 86 | }, 87 | "variable": { 88 | "node": "Variable", 89 | "name": "dstColorModel" 90 | } 91 | } 92 | ], 93 | "modifiers": [ 94 | "public" 95 | ] 96 | } 97 | ], 98 | "modifiers": [ 99 | "public" 100 | ] 101 | } 102 | ] 103 | } -------------------------------------------------------------------------------- /unittest-files/parse/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | Files=""; 4 | for f in $(find "$PWD/java-testset" -name '*.java') 5 | do 6 | echo $f 7 | node "$PWD/java7.js" "$f" ; 8 | if [ $? -ne 0 ]; 9 | then 10 | echo "Error in execution at $f" 11 | printf "$f\n" >> failing_classes.txt 12 | Files="$Files:$f"; 13 | fi; 14 | 15 | done 16 | 17 | echo $Files -------------------------------------------------------------------------------- /unittest-files/reverse/AnnotationTypeTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | @interface AnnotationTypeTest { 4 | 5 | // Annotation Type Elements 6 | String annotationTypeElement(); 7 | 8 | // Annotation Type Element with Default 9 | String annotationTypeElementWithDefault() default "N/A"; 10 | 11 | } 12 | -------------------------------------------------------------------------------- /unittest-files/reverse/ClassAbstractTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | public abstract class ClassAbstractTest { 4 | } 5 | -------------------------------------------------------------------------------- /unittest-files/reverse/ClassAccessModifiersTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | public class PublicClassTest { 4 | } 5 | 6 | protected class ProtectedClassTest { 7 | } 8 | 9 | private class PrivateClassTest { 10 | } 11 | 12 | class PackageClassTest { 13 | } 14 | -------------------------------------------------------------------------------- /unittest-files/reverse/ClassConstructorTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | public class ClassConstructorTest { 4 | 5 | public ClassConstructorTest() {} 6 | 7 | } 8 | -------------------------------------------------------------------------------- /unittest-files/reverse/ClassExtendsTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | public final class ClassExtendsTest extends ClassTest { 4 | } 5 | -------------------------------------------------------------------------------- /unittest-files/reverse/ClassFinalTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | public final class ClassFinalTest { 4 | } 5 | -------------------------------------------------------------------------------- /unittest-files/reverse/ClassGenericTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | // Generic Class 4 | public class ClassGenericTest { 5 | } 6 | -------------------------------------------------------------------------------- /unittest-files/reverse/ClassImplementsTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | public final class ClassImplementsTest implements InterfaceTest { 4 | } 5 | -------------------------------------------------------------------------------- /unittest-files/reverse/ClassTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | public class ClassTest { 4 | } 5 | -------------------------------------------------------------------------------- /unittest-files/reverse/EnumTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | public enum EnumTest { 4 | // Enum Constants 5 | ENUM_CONSTANT1(false), 6 | ENUM_CONSTANT2(true), 7 | ENUM_CONSTANT3(true); 8 | 9 | // Enum Field 10 | private final boolean enumField ; 11 | 12 | // Enum Constructor 13 | EnumTest(boolean enumField) { 14 | this.enumField = enumField ; 15 | } 16 | 17 | // Enum Method 18 | public boolean enumMethod() { 19 | return this.enumField ; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /unittest-files/reverse/FieldAccessModifiersTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | public class FieldAccessModifiersTest { 4 | 5 | public int publicField; 6 | 7 | protected int protectedField; 8 | 9 | private int privateField; 10 | 11 | int packageField; 12 | 13 | } 14 | -------------------------------------------------------------------------------- /unittest-files/reverse/FieldInitializersTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | public class FieldInitializersTest { 4 | 5 | int intFieldInitializer = 10; 6 | 7 | String stringFieldInitializer = "String Literal"; 8 | 9 | char charFieldInitializer = 'c'; 10 | 11 | boolean booleanFieldInitializer = true; 12 | 13 | Object objectFieldInitializer = null; 14 | 15 | } 16 | -------------------------------------------------------------------------------- /unittest-files/reverse/FieldModifiersTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | public class FieldModifiersTest { 4 | 5 | // Static Field 6 | static int staticField; 7 | 8 | // Final Field 9 | final int finalField; 10 | 11 | // Transient Field 12 | transient int transientField; 13 | 14 | // Volatiel Field 15 | volatile int volatileField; 16 | } 17 | -------------------------------------------------------------------------------- /unittest-files/reverse/FieldMultipleVariablesTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | public class FieldMultipleVariablesTest { 4 | 5 | int field1, field2, field3, field4; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /unittest-files/reverse/FieldTypesTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | import java.util.*; 4 | 5 | public class FieldTypesTest { 6 | 7 | // Primitive Types 8 | int intField; 9 | float floatField; 10 | long longField; 11 | double doubleField; 12 | String stringField; 13 | 14 | // Array Type 15 | String[] stringArrayField; 16 | 17 | // 2-Dimensional Array Type 18 | int[][] int2DArrayField; 19 | 20 | // Collection Type 21 | java.util.List stringListField; 22 | ArrayList classTestListField; 23 | 24 | } 25 | -------------------------------------------------------------------------------- /unittest-files/reverse/InterfaceExtendsTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | public final class InterfaceExtendsTest extends InterfaceTest { 4 | } 5 | -------------------------------------------------------------------------------- /unittest-files/reverse/InterfaceTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | public interface InterfaceTest { 4 | } 5 | -------------------------------------------------------------------------------- /unittest-files/reverse/JavaDocAnnotationTypeTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | /** 4 | * JavaDoc for AnnotationType 5 | */ 6 | @interface JavaDocAnnotationTypeTest { 7 | 8 | /** 9 | * JavaDoc for AnnotationTypeElement1 10 | */ 11 | String javaDocAnnotationTypeElement1(); 12 | 13 | /** 14 | * JavaDoc for AnnotationTypeElement2 15 | */ 16 | String javaDocAnnotationTypeElement2(); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /unittest-files/reverse/JavaDocClassTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | /** 4 | * This is first line of JavaDoc documentation. 5 | * This is second line of JavaDoc documentation. 6 | * 7 | * @author Minkyu Lee 8 | */ 9 | public class JavaDocClassTest { 10 | 11 | /** 12 | * JavaDoc for Field1 13 | */ 14 | int javaDocField1; 15 | 16 | /** 17 | * JavaDoc for Field2 18 | */ 19 | int javaDocField2; 20 | 21 | /** 22 | * JavaDoc for Constructor 23 | */ 24 | JavaDocFieldTest() { 25 | } 26 | 27 | /** 28 | * JavaDoc for Method1 29 | * 30 | * @param javaDocParam1 JavaDoc for Param1 31 | * @param javaDocParam2 JavaDoc for Param2 32 | */ 33 | void javaDocMethod1(int javaDocParam1, int javaDocParam2) { 34 | } 35 | 36 | 37 | /** 38 | * JavaDoc for Inner Class 39 | */ 40 | class JavaDocInnerClassTest { 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /unittest-files/reverse/JavaDocEnumTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | /** 4 | * JavaDoc for Enum 5 | */ 6 | public enum JavaDocEnumTest { 7 | 8 | /** 9 | * JavaDoc for EnumConstant1 10 | */ 11 | JAVADOC_ENUM_CONSTANT1(false), 12 | 13 | /** 14 | * JavaDoc for EnumConstant2 15 | */ 16 | JAVADOC_ENUM_CONSTANT2(true); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /unittest-files/reverse/JavaDocInterfaceTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | /** 4 | * JavaDoc for Interface 5 | */ 6 | public interface JavaDocInterfaceTest { 7 | 8 | /** 9 | * JavaDoc for Interface Field 10 | */ 11 | static final int javaDocInterfaceField = 100; 12 | 13 | /** 14 | * JavaDoc for Interface Operation 15 | */ 16 | void javaDocInterfaceOperation(); 17 | 18 | } 19 | -------------------------------------------------------------------------------- /unittest-files/reverse/MethodGenericTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | public class MethodGenericTest { 4 | 5 | public void genericMethod(ArrayList genericMethodListParam) {} 6 | 7 | } 8 | -------------------------------------------------------------------------------- /unittest-files/reverse/MethodModifiersTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | public class MethodModifiersTest { 4 | 5 | // Static Method 6 | static void staticMethod() {} 7 | 8 | // Abstract Method 9 | abstract void abstractMethod() {} 10 | 11 | // Final Method 12 | final void finalMethod() {} 13 | 14 | // Synchronized Method 15 | synchronized void synchronizedMethod() {} 16 | 17 | // Native Method 18 | native void nativeMethod() {} 19 | 20 | // Strictfp Method 21 | strictfp void strictfpMethod() {} 22 | 23 | } 24 | -------------------------------------------------------------------------------- /unittest-files/reverse/MethodParametersTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | public class MethodParametersTest { 4 | 5 | void paramTestMethod(String stringParam, int intParam, ClassTest classTestParam) {} 6 | 7 | } 8 | -------------------------------------------------------------------------------- /unittest-files/reverse/MethodReturnTypeTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | public class MethodReturnTypeTest { 4 | 5 | // int Return 6 | int intReturnMethod() { 7 | return 0; 8 | }; 9 | 10 | // Object Return 11 | ClassTest classTestReturnMethod() { 12 | return null; 13 | } 14 | 15 | // Collection Return 16 | public Enumeration enumerationReturnMethod() { 17 | return null; 18 | } 19 | 20 | } 21 | -------------------------------------------------------------------------------- /unittest-files/reverse/MethodTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | public class MethodTest { 4 | 5 | void methodTest() {} 6 | 7 | } 8 | -------------------------------------------------------------------------------- /unittest-files/reverse/MethodThrowsTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | public class MethodThrowsTest { 4 | 5 | void throwsTestMethod() throws java.lang.Exception {} 6 | 7 | } 8 | -------------------------------------------------------------------------------- /unittest-files/reverse/PackageTest.java: -------------------------------------------------------------------------------- 1 | package com.mycompany.packagetest; 2 | 3 | public class __Temp { 4 | } 5 | --------------------------------------------------------------------------------