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
Checking pipeline status
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