Skip to content
Snippets Groups Projects
Commit d739aa19 authored by René Schöne's avatar René Schöne
Browse files

0.2.5

- add option to generate separate grammar diagrams
- reverted to separate inheritance type to exclude them if necessary
- added some attributes to silence JastAdd warnings
parent ae54ec88
No related branches found
No related tags found
No related merge requests found
Pipeline #14509 passed
Showing
with 221 additions and 33 deletions
...@@ -161,7 +161,7 @@ jastadd { ...@@ -161,7 +161,7 @@ jastadd {
parser.genDir = "src/gen/java/de/tudresden/inf/st/jastadd/grammar2uml/parser" parser.genDir = "src/gen/java/de/tudresden/inf/st/jastadd/grammar2uml/parser"
// default options are: '--rewrite=cnta', '--safeLazy', '--visitCheck=false', '--cacheCycle=false' // default options are: '--rewrite=cnta', '--safeLazy', '--visitCheck=false', '--cacheCycle=false'
extraJastAddOptions = ["--lineColumnNumbers", "--List=JastAddList", "--visitCheck=true"] extraJastAddOptions = ["--lineColumnNumbers", "--List=JastAddList"]
} }
// --- Tests --- // --- Tests ---
......
aspect Analysis { aspect Analysis {
syn lazy Folder GrammarFile.defaultFolder() { syn lazy Folder GrammarFile.defaultFolder() {
Folder result = new Folder(); Folder result = new Folder();
result.setActive(true);
result.setName(new java.io.File(getFileName()).getName().replace(".relast", "").replace(".ast", "")); result.setName(new java.io.File(getFileName()).getName().replace(".relast", "").replace(".ast", ""));
for (Declaration decl : getDeclarationList()) { for (Declaration decl : getDeclarationList()) {
if (decl.isTypeDecl() && !decl.asTypeDecl().hasSourceFolder()) { if (decl.isTypeDecl() && !decl.asTypeDecl().hasSourceFolder()) {
...@@ -9,4 +10,65 @@ aspect Analysis { ...@@ -9,4 +10,65 @@ aspect Analysis {
} }
return result; return result;
} }
syn java.util.Set<TypeDecl> Grammar2Uml.activeTypeDecls() {
java.util.Set<TypeDecl> result = new java.util.HashSet<>();
for (Folder folder : getFolderList()) {
if (folder.getActive()) {
folder.getTypeList().forEach(typeDecl -> result.add(typeDecl));
}
}
return result;
}
syn boolean TypeDecl.relatesToActiveTypeDecl() {
java.util.Set<TypeDecl> activeTypeDecls = grammar2uml().activeTypeDecls();
// self
if (activeTypeDecls.contains(this)) {
return true;
}
// inheritance
if (hasSuperType() && activeTypeDecls.contains(getSuperType())) {
return true;
}
for (TypeDecl subType : getSubTypeList()) {
if (activeTypeDecls.contains(subType)) {
return true;
}
}
// relations
for (Role role : getRoleList()) {
Relation relation = role.containingRelation();
boolean activeRelation = relation.isDirectedRelation() ?
(activeTypeDecls.contains(relation.asDirectedRelation().getSource().getType()) ||
activeTypeDecls.contains(relation.asDirectedRelation().getTarget().getType())) :
(activeTypeDecls.contains(relation.asBidirectionalRelation().getLeft().getType()) ||
activeTypeDecls.contains(relation.asBidirectionalRelation().getRight().getType()));
if (activeRelation) {
return true;
}
}
// containment
for (TypeComponent potentialParent : getPotentialParentList()) {
if (activeTypeDecls.contains(potentialParent.containingTypeDecl())) {
return true;
}
}
for (Component component : getComponentList()) {
if (component.isTypeComponent() && activeTypeDecls.contains(component.asTypeComponent().getTypeDecl())) {
return true;
}
}
return false;
}
inh Relation Role.containingRelation();
eq DirectedRelation.getSource().containingRelation() = this;
eq DirectedRelation.getTarget().containingRelation() = this;
eq BidirectionalRelation.getLeft().containingRelation() = this;
eq BidirectionalRelation.getRight().containingRelation() = this;
} }
Grammar2Uml ::= Program <FileName> Folder* <StyleDefinition:StyleDefinition> ; Grammar2Uml ::= Program <FileName> Folder* <StyleDefinition:StyleDefinition> ;
Folder ::= <Name:String> ; Folder ::= <Name:String> <Active:boolean> ;
rel Folder.Type* <-> TypeDecl.SourceFolder?; rel Folder.Type* <-> TypeDecl.SourceFolder?;
Style ::= <BackgroundColor> <InlineAsSuperType:boolean> ; Style ::= <BackgroundColor> <InlineAsSuperType:boolean> ;
MGrammar2Uml ::= Folder:MFolder* OtherType:MTypeDecl* Containment:MContainment* Relation:MRelation* ; MGrammar2Uml ::= Folder:MFolder* OtherType:MTypeDecl* Containment:MContainment* Relation:MRelation* Inheritance:MInheritance* ;
MFolder ::= InnerTypeDecl:MTypeDecl*; MFolder ::= InnerTypeDecl:MTypeDecl* <Active:boolean> ;
MTypeDecl ::= InnerTokenComponent:MTokenComponent* <Name> Style; MTypeDecl ::= InnerTokenComponent:MTokenComponent* <Name> Style;
MTokenComponent; MTokenComponent;
abstract MContainment ::= <Label:String> ; abstract MContainment ::= <Label:String> ;
...@@ -7,6 +7,7 @@ MSingleContainment : MContainment; ...@@ -7,6 +7,7 @@ MSingleContainment : MContainment;
MOptContainment : MContainment; MOptContainment : MContainment;
MListContainment : MContainment; MListContainment : MContainment;
MRelation ::= <Label> <LeftModifier> <RightModifier> <Bidirectional:boolean>; MRelation ::= <Label> <LeftModifier> <RightModifier> <Bidirectional:boolean>;
MInheritance;
rel MGrammar2Uml.Grammar2Uml -> Grammar2Uml; rel MGrammar2Uml.Grammar2Uml -> Grammar2Uml;
rel MFolder.Folder -> Folder; rel MFolder.Folder -> Folder;
...@@ -16,4 +17,6 @@ rel MContainment.Type -> MTypeDecl; ...@@ -16,4 +17,6 @@ rel MContainment.Type -> MTypeDecl;
rel MContainment.Component -> MTypeDecl; rel MContainment.Component -> MTypeDecl;
rel MRelation.Left -> MTypeDecl; rel MRelation.Left -> MTypeDecl;
rel MRelation.Right -> MTypeDecl; rel MRelation.Right -> MTypeDecl;
rel MTypeDecl.SuperClass? -> MTypeDecl; //rel MTypeDecl.SuperClass? -> MTypeDecl;
rel MInheritance.SuperClass -> MTypeDecl;
rel MInheritance.SubClass -> MTypeDecl;
...@@ -3,16 +3,23 @@ aspect Navigation { ...@@ -3,16 +3,23 @@ aspect Navigation {
// --- program --- // --- program ---
eq Grammar2Uml.getChild().program() = getProgram(); eq Grammar2Uml.getChild().program() = getProgram();
eq MGrammar2Uml.getChild().program() = getGrammar2Uml().program(); eq MGrammar2Uml.getChild().program() = getGrammar2Uml().program();
eq Document.getChild().program() = null;
// --- grammar2uml --- // --- grammar2uml ---
inh Grammar2Uml ASTNode.grammar2uml(); inh Grammar2Uml ASTNode.grammar2uml();
eq Grammar2Uml.getChild().grammar2uml() = this; eq Grammar2Uml.getChild().grammar2uml() = this;
eq MGrammar2Uml.getChild().grammar2uml() = getGrammar2Uml(); eq MGrammar2Uml.getChild().grammar2uml() = getGrammar2Uml();
eq Document.getChild().grammar2uml() = null;
// --- containedFile --- // --- containedFile ---
eq Grammar2Uml.getChild().containedFile() = null; eq Grammar2Uml.getChild().containedFile() = null;
eq MGrammar2Uml.getChild().containedFile() = null; eq MGrammar2Uml.getChild().containedFile() = null;
eq Document.getChild().containedFile() = null;
// --- containedFileName --- // --- containedFileName ---
eq Grammar2Uml.containedFileName() = getFileName(); eq Grammar2Uml.containedFileName() = getFileName();
// --- containingFolder ---
inh MFolder MTypeDecl.containingFolder();
eq MFolder.getInnerTypeDecl().containingFolder() = this;
} }
...@@ -27,6 +27,14 @@ aspect AttributesForMustache { ...@@ -27,6 +27,14 @@ aspect AttributesForMustache {
syn boolean MTypeDecl.isAbstract() = getType().getAbstract(); syn boolean MTypeDecl.isAbstract() = getType().getAbstract();
syn boolean MTypeDecl.relatesToActiveTypeDecl() = getType().relatesToActiveTypeDecl();
syn boolean MTypeDecl.folderInactiveAndUnrelated() = !containingFolderActive() && !relatesToActiveTypeDecl();
syn boolean MTypeDecl.folderInactiveAndRelated() = !containingFolderActive() && relatesToActiveTypeDecl();
syn boolean MTypeDecl.containingFolderActive() {
return !getType().hasSourceFolder() || getType().getSourceFolder().getActive();
}
syn String MTypeDecl.backgroundColor() = getStyle().getBackgroundColor(); syn String MTypeDecl.backgroundColor() = getStyle().getBackgroundColor();
// --- MTokenComponent --- // --- MTokenComponent ---
...@@ -51,12 +59,24 @@ aspect AttributesForMustache { ...@@ -51,12 +59,24 @@ aspect AttributesForMustache {
// eq MSingleRelation.modifier() = "\"1\""; // eq MSingleRelation.modifier() = "\"1\"";
// eq MOptRelation.modifier() = "\"0 .. 1\""; // eq MOptRelation.modifier() = "\"0 .. 1\"";
// eq MListRelation.modifier() = "\"*\""; // eq MListRelation.modifier() = "\"*\"";
syn boolean MRelation.bothRelated() = getLeft().relatesToActiveTypeDecl() && getRight().relatesToActiveTypeDecl();
syn boolean MRelation.atLeastOneInActiveFolder() = getLeft().containingFolderActive() ||
getRight().containingFolderActive();
// --- MInheritance ---
syn boolean MInheritance.bothRelated() = getSuperClass().relatesToActiveTypeDecl() &&
getSubClass().relatesToActiveTypeDecl();
syn boolean MInheritance.atLeastOneInActiveFolder() = getSuperClass().containingFolderActive() ||
getSubClass().containingFolderActive();
// --- toMContainment --- // --- toMContainment ---
syn MContainment TypeComponent.toMContainment(); syn MContainment TypeComponent.toMContainment();
eq NormalComponent.toMContainment() = new MSingleContainment(); eq NormalComponent.toMContainment() = new MSingleContainment();
eq ListComponent.toMContainment() = new MListContainment(); eq ListComponent.toMContainment() = new MListContainment();
eq OptComponent.toMContainment() = new MOptContainment(); eq OptComponent.toMContainment() = new MOptContainment();
syn boolean MContainment.bothRelated() = getType().relatesToActiveTypeDecl() && getComponent().relatesToActiveTypeDecl();
syn boolean MContainment.atLeastOneInActiveFolder() = getType().containingFolderActive() ||
getComponent().containingFolderActive();
// --- toMRelation --- // --- toMRelation ---
syn MRelation Relation.toMRelation(); syn MRelation Relation.toMRelation();
...@@ -98,6 +118,15 @@ aspect AttributesForMustache { ...@@ -98,6 +118,15 @@ aspect AttributesForMustache {
if (!typeDecl.hasSourceFolder()) { if (!typeDecl.hasSourceFolder()) {
result.addOtherType(typeDecl.toMustache()); result.addOtherType(typeDecl.toMustache());
} }
if (typeDecl.hasSuperType()) {
Style parentStyle = typeDecl.getSuperType().toMustache().getStyle();
if (!parentStyle.getInlineAsSuperType()) {
MInheritance inheritance = new MInheritance();
inheritance.setSuperClass(typeDecl.getSuperType().toMustache());
inheritance.setSubClass(typeDecl.toMustache());
result.addInheritance(inheritance);
}
}
for (Component component : typeDecl.getComponentList()) { for (Component component : typeDecl.getComponentList()) {
if (component.isTypeComponent()) { if (component.isTypeComponent()) {
TypeComponent typeComponent = component.asTypeComponent(); TypeComponent typeComponent = component.asTypeComponent();
...@@ -137,6 +166,7 @@ aspect AttributesForMustache { ...@@ -137,6 +166,7 @@ aspect AttributesForMustache {
for (TypeDecl typeDecl : getTypeList()) { for (TypeDecl typeDecl : getTypeList()) {
result.addInnerTypeDecl(typeDecl.toMustache()); result.addInnerTypeDecl(typeDecl.toMustache());
} }
result.setActive(this.getActive());
return result; return result;
} }
...@@ -157,8 +187,6 @@ aspect AttributesForMustache { ...@@ -157,8 +187,6 @@ aspect AttributesForMustache {
Style parentStyle = this.getSuperType().toMustache().getStyle(); Style parentStyle = this.getSuperType().toMustache().getStyle();
if (parentStyle.getInlineAsSuperType()) { if (parentStyle.getInlineAsSuperType()) {
result.setName(getName() + ":" + this.getSuperType().getName()); result.setName(getName() + ":" + this.getSuperType().getName());
} else {
result.setSuperClass(this.getSuperType().toMustache());
} }
} }
return result; return result;
......
...@@ -12,6 +12,7 @@ import org.jastadd.relast.compiler.CompilerException; ...@@ -12,6 +12,7 @@ import org.jastadd.relast.compiler.CompilerException;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.MissingResourceException; import java.util.MissingResourceException;
import java.util.ResourceBundle; import java.util.ResourceBundle;
...@@ -21,6 +22,7 @@ public class Compiler extends AbstractCompiler { ...@@ -21,6 +22,7 @@ public class Compiler extends AbstractCompiler {
private final Grammar2UmlProcessor processor; private final Grammar2UmlProcessor processor;
private ValueOption optionOutputFile; private ValueOption optionOutputFile;
private ValueOption optionInputGrammar2Uml; private ValueOption optionInputGrammar2Uml;
private ValueOption optionGenerateSeparateGrammarDiagrams;
private BooleanOption optionDefaultFolders; private BooleanOption optionDefaultFolders;
private BooleanOption optionHelp; private BooleanOption optionHelp;
private BooleanOption optionVersion; private BooleanOption optionVersion;
...@@ -69,6 +71,9 @@ public class Compiler extends AbstractCompiler { ...@@ -69,6 +71,9 @@ public class Compiler extends AbstractCompiler {
optionInputGrammar2Uml = addOption( optionInputGrammar2Uml = addOption(
new ValueOption("inputGrammar2Uml" , "grammar2uml definition file.") new ValueOption("inputGrammar2Uml" , "grammar2uml definition file.")
.needsValue(true)); .needsValue(true));
optionGenerateSeparateGrammarDiagrams = addOption(
new ValueOption("separateGrammarDiagrams" , "Generate separate grammar diagrams according to the given pattern (e.g., 'gen/*.png'). Must contain a '*' for separation.")
.needsValue(true));
optionDefaultFolders = addOption( optionDefaultFolders = addOption(
new BooleanOption("defaultFolders" , new BooleanOption("defaultFolders" ,
"Creates a default folder per grammar file.") "Creates a default folder per grammar file.")
...@@ -113,8 +118,16 @@ public class Compiler extends AbstractCompiler { ...@@ -113,8 +118,16 @@ public class Compiler extends AbstractCompiler {
} }
processor.setUseDefaultFolders(optionDefaultFolders.value()) processor.setUseDefaultFolders(optionDefaultFolders.value())
.setVerbose(optionVerbose.value()) .setVerbose(optionVerbose.value());
.writeFile(Paths.get(optionOutputFile.value()).toAbsolutePath());
processor.writeFile(Paths.get(optionOutputFile.value()).toAbsolutePath());
if (optionGenerateSeparateGrammarDiagrams.isMatched()) {
Path destinationPattern = Path.of(optionGenerateSeparateGrammarDiagrams.value());
Path parent = destinationPattern.getParent();
String extension = Grammar2UmlProcessor.fileExtensionOf(destinationPattern.getFileName());
processor.generateSeparateGrammarDiagrams(parent, extension);
}
return 0; return 0;
} }
......
...@@ -14,9 +14,7 @@ import java.io.IOException; ...@@ -14,9 +14,7 @@ import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.nio.file.Paths; import java.nio.file.Paths;
import java.util.ArrayList; import java.util.*;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
/** /**
...@@ -29,7 +27,7 @@ public class Grammar2UmlProcessor { ...@@ -29,7 +27,7 @@ public class Grammar2UmlProcessor {
private boolean verbose; private boolean verbose;
private boolean useDefaultFolders; private boolean useDefaultFolders;
private final List<Folder> folders = new ArrayList<>(); private final List<Folder> folders = new ArrayList<>();
private String generatedAspect = null; private Grammar2Uml grammar2uml = null;
private final List<Consumer<Grammar2Uml>> callbacks = new ArrayList<>(); private final List<Consumer<Grammar2Uml>> callbacks = new ArrayList<>();
private StyleDefinition styleDefinition = (typeDecl, style) -> {}; private StyleDefinition styleDefinition = (typeDecl, style) -> {};
...@@ -66,17 +64,22 @@ public class Grammar2UmlProcessor { ...@@ -66,17 +64,22 @@ public class Grammar2UmlProcessor {
public void writeFile(Path destination) throws CompilerException { public void writeFile(Path destination) throws CompilerException {
build(); build();
Path parent = destination.toAbsolutePath().getParent(); String generatedAspect = grammar2uml.generateAspect();
ensureDirectory(destination.toAbsolutePath().getParent());
writeFileContent(destination, generatedAspect);
}
private void ensureDirectory(Path directory) throws CompilerException {
try { try {
Files.createDirectories(parent); Files.createDirectories(directory);
} catch (IOException e) { } catch (IOException e) {
throw new CompilerException("Error creating output dir " + parent, e); throw new CompilerException("Error creating output dir " + directory, e);
} }
if (inputGrammarFiles.isEmpty()) {
throw new CompilerException("No input grammars specified!");
} }
private void writeFileContent(Path destination, String generatedAspect) throws CompilerException {
printMessage("Writing output file " + destination); printMessage("Writing output file " + destination);
String extension = fileExtensionOf(destination).toUpperCase(); String extension = fileExtensionOf(destination).toUpperCase();
FileFormatOption plantUmlOption = null; FileFormatOption plantUmlOption = null;
...@@ -105,13 +108,69 @@ public class Grammar2UmlProcessor { ...@@ -105,13 +108,69 @@ public class Grammar2UmlProcessor {
} }
} }
public void generateSeparateGrammarDiagrams(Path destinationDirectory, String extension) throws CompilerException {
build();
ensureDirectory(destinationDirectory);
// remember active states, and set them all to false
Set<Folder> previouslyActive = new HashSet<>();
for (Folder folder : grammar2uml.getFolderList()) {
if (folder.getActive()) {
previouslyActive.add(folder);
}
folder.setActive(false);
}
for (Folder folder : grammar2uml.getFolderList()) {
folder.setActive(true);
// generate aspect and write file
grammar2uml.flushTreeCache();
System.out.println("--- " + folder.getName() + " ---");
String generatedAspect = grammar2uml.generateAspect();
writeFileContent(destinationDirectory.resolve(folder.getName() + "." + extension), generatedAspect);
folder.setActive(false);
}
// restore previous active states
for (Folder folder : grammar2uml.getFolderList()) {
if (previouslyActive.contains(folder)) {
folder.setActive(true);
}
}
}
// private void debugAttributes() {
// for (Folder folder : grammar2uml.getFolderList()) {
// System.out.println(folder.getName() + ": active=" + folder.getActive() + ", mFolder.active=" + folder.toMustache().getActive());
// }
// for (TypeDecl typeDecl : grammar2uml.getProgram().typeDecls().stream()
// .sorted(Comparator.comparing(TypeDecl::getName))
// .collect(Collectors.toList())) {
// MTypeDecl mTypeDecl = typeDecl.toMustache();
// System.out.println(typeDecl.getName() + ": " + String.join(", ",
// "relates=" + typeDecl.relatesToActiveTypeDecl(),
// "folderInactive+Unrelated=" + mTypeDecl.folderInactiveAndUnrelated(),
// "folderInactive+Related=" + mTypeDecl.folderInactiveAndRelated(),
// "folderActive=" + mTypeDecl.containingFolderActive()));
// }
// }
private void build() throws CompilerException { private void build() throws CompilerException {
if (generatedAspect != null) { if (grammar2uml != null) {
return; // already built return; // already built
} }
if (inputGrammarFiles.isEmpty()) {
throw new CompilerException("No input grammars specified!");
}
Program program = new Program(); Program program = new Program();
Grammar2Uml grammar2uml = new Grammar2Uml(); grammar2uml = new Grammar2Uml();
for (String inputGrammarFileName : inputGrammarFiles) { for (String inputGrammarFileName : inputGrammarFiles) {
printMessage("Parsing " + inputGrammarFileName); printMessage("Parsing " + inputGrammarFileName);
GrammarFile inputGrammar; GrammarFile inputGrammar;
...@@ -152,8 +211,6 @@ public class Grammar2UmlProcessor { ...@@ -152,8 +211,6 @@ public class Grammar2UmlProcessor {
} }
throw new CompilerException("Exiting because of previous errors."); throw new CompilerException("Exiting because of previous errors.");
} }
generatedAspect = grammar2uml.generateAspect();
} }
private void printMessage(String message) { private void printMessage(String message) {
...@@ -162,7 +219,7 @@ public class Grammar2UmlProcessor { ...@@ -162,7 +219,7 @@ public class Grammar2UmlProcessor {
} }
} }
private String fileExtensionOf(Path path) { static String fileExtensionOf(Path path) {
String fileName = path.toFile().getName(); String fileName = path.toFile().getName();
int lastIndexOfDot = fileName.lastIndexOf("."); int lastIndexOfDot = fileName.lastIndexOf(".");
return fileName.substring(lastIndexOfDot + 1); return fileName.substring(lastIndexOfDot + 1);
......
...@@ -28,7 +28,11 @@ public class SimpleMain { ...@@ -28,7 +28,11 @@ public class SimpleMain {
private static void useAPI() throws CompilerException { private static void useAPI() throws CompilerException {
Grammar2UmlProcessor processor = new Grammar2UmlProcessor(); Grammar2UmlProcessor processor = new Grammar2UmlProcessor();
// run --args 'src/main/jastadd/Grammar2Uml.relast src/gen/jastadd-sources/relast.preprocessor/RelAst.relast --defaultFolders --output=uml.md' // run --args 'src/main/jastadd/Grammar2Uml.relast src/gen/jastadd-sources/relast.preprocessor/RelAst.relast --defaultFolders --output=uml.md'
processor.addGrammar("src/main/jastadd/Grammar2Uml.relast", processor
.setVerbose(false)
.addFolder()
.addPostProcessing(grammar2Uml -> {})
.addGrammar("src/main/jastadd/Grammar2Uml.relast",
"src/gen/jastadd-sources/relast.preprocessor/RelAst.relast") "src/gen/jastadd-sources/relast.preprocessor/RelAst.relast")
.setStyleDefinition((typeDecl, style) -> { .setStyleDefinition((typeDecl, style) -> {
switch (typeDecl.getName()) { switch (typeDecl.getName()) {
...@@ -41,8 +45,11 @@ public class SimpleMain { ...@@ -41,8 +45,11 @@ public class SimpleMain {
} }
}) })
.setUseDefaultFolders(true); .setUseDefaultFolders(true);
processor.writeFile(Paths.get("api.md")); System.out.println("== API == ");
processor.writeFile(Paths.get("api.png")); // processor.writeFile(Paths.get("api.md"));
// processor.writeFile(Paths.get("api.png"));
System.out.println("== SEPARATE == ");
processor.generateSeparateGrammarDiagrams(Paths.get("."), "png");
} }
public static Grammar2Uml createManualAST() { public static Grammar2Uml createManualAST() {
......
{{#atLeastOneInActiveFolder}}
{{{typeName}}} *-- {{{modifier}}} {{{componentName}}} {{#Label}}: {{Label}}{{/Label}} {{{typeName}}} *-- {{{modifier}}} {{{componentName}}} {{#Label}}: {{Label}}{{/Label}}
{{/atLeastOneInActiveFolder}}
{{#atLeastOneInActiveFolder}}
{{#SuperClass}}"{{{Name}}}"{{/SuperClass}} <|-- {{#SubClass}}"{{{Name}}}"{{/SubClass}}
{{/atLeastOneInActiveFolder}}
{{#atLeastOneInActiveFolder}}
{{{leftName}}} {{{leftModifier}}} {{#isBidirectional}}<{{/isBidirectional}}-[norank]-> {{{rightModifier}}} {{{rightName}}} {{#Label}}: {{Label}}{{/Label}} {{{leftName}}} {{{leftModifier}}} {{#isBidirectional}}<{{/isBidirectional}}-[norank]-> {{{rightModifier}}} {{{rightName}}} {{#Label}}: {{Label}}{{/Label}}
{{/atLeastOneInActiveFolder}}
{{#isAbstract}}abstract {{/isAbstract}}class "{{{Name}}}"{{#backgroundColor}} #{{{backgroundColor}}}{{/backgroundColor}}{{#InnerTokenComponents}}{{#first}} { {{^folderInactiveAndUnrelated}}
{{#isAbstract}}abstract {{/isAbstract}}class "{{{Name}}}"{{#backgroundColor}} #{{{backgroundColor}}}{{/backgroundColor}}{{#folderInactiveAndRelated}} ##[dashed]{{/folderInactiveAndRelated}}{{^folderInactiveAndRelated}}{{#InnerTokenComponents}}{{#first}} {
{{/first}} {{/first}}
{{{type}}} {{{name}}} {{{type}}} {{{name}}}
{{#last}} {{#last}}
}{{/last}}{{/InnerTokenComponents}} }{{/last}}{{/InnerTokenComponents}}
{{#hasSuperClass}}{{#SuperClass}}"{{{Name}}}"{{/SuperClass}} <|-- "{{{Name}}}"{{/hasSuperClass}}
{{/folderInactiveAndRelated}}
{{/folderInactiveAndUnrelated}}
```plantuml ```plantuml
@startuml @startuml
hide circle hide circle
hide methods hide empty members
{{#Folders}}{{> Folder}}{{/Folders}} {{#Folders}}{{> Folder}}{{/Folders}}
{{#OtherTypes}}{{> TypeDecl}}{{/OtherTypes}} {{#OtherTypes}}{{> TypeDecl}}{{/OtherTypes}}
{{#Containments}}{{> Containment}}{{/Containments}} {{#Containments}}{{> Containment}}{{/Containments}}
{{#Relations}}{{> Relation}}{{/Relations}} {{#Relations}}{{> Relation}}{{/Relations}}
{{#Inheritances}}{{> Inheritance}}{{/Inheritances}}
@enduml @enduml
``` ```
#Sat May 21 15:41:29 CEST 2022 #Fri Aug 26 14:06:56 CEST 2022
version=0.2.4 version=0.2.5
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment