diff --git a/.gitignore b/.gitignore index 8e7d63ec40cb8b81aaa7fe19cf4f672d3fca548a..1c0e398ffb5ae6d968d97a3a6870401d9aa26676 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ .idea/ .gradle/ /build/ +/public/ diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f212e144a859a527b8add94d68d5ce474adfe9cd..d07299bade9f50d37d4f4f7631238f18a08caeca 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -4,6 +4,7 @@ variables: stages: - build - test + - ragdoc - publish build: @@ -12,33 +13,86 @@ build: before_script: - ls -lah * script: - - ./gradlew assemble + - "./gradlew assemble" test: image: openjdk:11 stage: test + needs: + - build script: - - ./gradlew test + - "./gradlew test" artifacts: reports: - junit: relast2uml.tests/build/test-results/test/TEST-*.xml + junit: "*/build/test-results/test/TEST-*.xml" -publish: +publish_dev: image: openjdk:11 stage: publish + needs: + - test + script: + - "./gradlew setDevVersionForCI" + - "./gradlew publish" + only: + - dev + +publish_master: + image: openjdk:11 + stage: publish + needs: + - test script: - "./gradlew publish" only: - master +ragdoc_build: + image: + name: "git-st.inf.tu-dresden.de:4567/jastadd/ragdoc-builder" + entrypoint: [""] + stage: ragdoc + needs: + - build + script: + - JAVA_FILES=$(find dumpAstWithPlantuml/src/ -name '*.java') + - /ragdoc-builder/start-builder.sh -excludeGenerated -d data/ $JAVA_FILES + artifacts: + paths: + - "data/" + +ragdoc_view: + image: + name: "git-st.inf.tu-dresden.de:4567/jastadd/ragdoc-view:relations" + entrypoint: [""] + stage: ragdoc + needs: + - ragdoc_build + script: + - DATA_DIR=$(pwd -P)/data + - mkdir -p pages/docs/ragdoc + - OUTPUT_DIR=$(pwd -P)/pages/docs/ragdoc + - cd /ragdoc-view/src/ && rm -rf data && ln -s $DATA_DIR + - /ragdoc-view/build-view.sh --output-path=$OUTPUT_DIR + only: + - dev + - main + artifacts: + paths: + - "pages/docs/ragdoc" + pages: - image: python:3.7-alpine + image: python:3.10.0-bullseye stage: publish + needs: + - ragdoc_view + - test + before_script: + - pip install -r pages/requirements.txt script: - - pip install -U sphinx sphinx-rtd-theme recommonmark sphinxemoji sphinx-markdown-tables - - sphinx-build -b html pages/ public + - cd pages && mkdocs build artifacts: paths: - - public + - public/ only: - - master + - main diff --git a/buildSrc/src/main/groovy/relast2uml.java-publishing-conventions.gradle b/buildSrc/src/main/groovy/relast2uml.java-publishing-conventions.gradle index 0a5d763501b81b682a8a37c30e0282ff5f378b2d..e3130c9008342d8dc2be8d80e2b29ba064cb31fa 100644 --- a/buildSrc/src/main/groovy/relast2uml.java-publishing-conventions.gradle +++ b/buildSrc/src/main/groovy/relast2uml.java-publishing-conventions.gradle @@ -46,6 +46,14 @@ task newVersion() { } } +task setDevVersionForCI() { + doFirst { + def props = new Properties() + props['version'] = version + "-$System.env.CI_PIPELINE_IID" + props.store(file(versionFile).newWriter(), null) + } +} + //679 publishing { publications { diff --git a/dumpAst/src/main/jastadd/DumpAst.relast b/dumpAst/src/main/jastadd/DumpAst.relast index 7a3e31f2cfc389af9e9cd14228697b59c5929dc1..2fad59a121f72fb3629dda4bdbf7733a797ae1fa 100644 --- a/dumpAst/src/main/jastadd/DumpAst.relast +++ b/dumpAst/src/main/jastadd/DumpAst.relast @@ -1,18 +1,25 @@ DumpAst ::= DumpNode* <PackageName> BuildConfig PrintConfig ; rel DumpAst.RootNode -> DumpNode ; -BuildConfig ::= GlobalPatternCollection:PatternCollection ExcludeTypePattern:TypePatternCollectionMapping* IncludeTypePattern:TypePatternCollectionMapping* <TypeIgnorePattern> <IncludeEmptyString:boolean> <Debug:boolean> ; +BuildConfig ::= StyleInformation GlobalPatternCollection:PatternCollection + ExcludeTypePattern:TypePatternCollectionMapping* IncludeTypePattern:TypePatternCollectionMapping* + <TypeIgnorePattern> <IncludeEmptyString:boolean> <ExcludeNullNodes:boolean> <Debug:boolean>; TypePatternCollectionMapping ::= <TypeRegex> PatternCollection ; PatternCollection ::= <TokenPattern> <ChildPattern> <RelationPattern> <AttributePattern> <NonterminalAttributePattern> ; -PrintConfig ::= <Scale:double> <Version> Header* ; +StyleInformation ::= <NameMethod:StyleMethod> <BackgroundColorMethod:StyleMethod> <TextColorMethod:StyleMethod>; + +PrintConfig ::= <Scale:double> <Version> <OrderChildren:boolean> Header* ; Header ::= <Value> ; -DumpNode ::= <Name> <Label> <Object:Object> <Invisible:boolean> DumpChildNode* DumpToken* DumpRelation* /InvisiblePath/ ; + +DumpNode ::= DumpChildNode* DumpToken* DumpRelation* + <Name> <Label> <BackgroundColor> <TextColor> <Object:Object> <Invisible:boolean> + /InvisiblePath/ ; InnerDumpNode ; -rel InnerDumpNode.DumpNode -> DumpNode ; +rel InnerDumpNode.DumpNode <-> DumpNode.ContainerOfInner ; abstract DumpChildNode ::= <Name> <Computed:boolean> ; DumpNormalChildNode : DumpChildNode ; -rel DumpNormalChildNode.DumpNode -> DumpNode ; +rel DumpNormalChildNode.DumpNode <-> DumpNode.ContainerOfNormalChild ; DumpListChildNode : DumpChildNode ::= InnerDumpNode* ; abstract DumpToken ::= <Name> <Computed:boolean> ; diff --git a/dumpAst/src/main/jastadd/GenerationBackend.jadd b/dumpAst/src/main/jastadd/GenerationBackend.jadd index ce550ca7fc0cdc85e7326a649635b7cba8a1698f..beeb183de52a4adccbdb8413309b16c418b55511 100644 --- a/dumpAst/src/main/jastadd/GenerationBackend.jadd +++ b/dumpAst/src/main/jastadd/GenerationBackend.jadd @@ -26,11 +26,23 @@ aspect GenerationBackend { } protected DumpNode DumpAst.transform(TransformationTransferInformation tti, Object obj, Source source) throws java.lang.reflect.InvocationTargetException, IllegalAccessException, NoSuchMethodException { - if (obj == null) { + return transform(tti, obj, source, false); + } + protected DumpNode DumpAst.transform( + TransformationTransferInformation tti, Object obj, Source source, boolean allowNullObj) + throws java.lang.reflect.InvocationTargetException, IllegalAccessException, NoSuchMethodException { + if (obj == null && !allowNullObj) { return null; } - DumpNode node = tti.transformed.get(obj); - String objClassName = obj.getClass().getSimpleName(); + DumpNode node; + String objClassName; + if (obj == null) { + node = null; + objClassName = "null"; + } else { + node = tti.transformed.get(obj); + objClassName = obj.getClass().getSimpleName(); + } if (node != null) { if (source == Source.RELATION) { return node; @@ -40,106 +52,118 @@ aspect GenerationBackend { } else { node = new DumpNode(); node.setObject(obj); - node.setLabel(objClassName + "@" + obj.hashCode()); node.setName("node" + tti.transformed.size()); tti.transformed.put(obj, node); this.addDumpNode(node); } - if (node.isAstNode()) { - // do not process node further if coming from a relation - if (source == Source.RELATION) { - tti.relationTargetsUnprocessed.put(node, true); - return node; - } - if (source == Source.INVISIBLE_PARENT || !isTypeEnabled(objClassName)) { - node.setInvisible(true); + if (!node.isAstNode()) { + return node; + } + applyStyle(node); + // do not process node further if coming from a relation + if (source == Source.RELATION) { + tti.relationTargetsUnprocessed.put(node, true); + return node; + } + if (source == Source.INVISIBLE_PARENT || !isTypeEnabled(objClassName)) { + node.setInvisible(true); + } + if (obj == null) { + // for a null object, we do not need any further analysis + return node; + } + final ClassAnalysisResult car = analyzeClass(obj.getClass()); + // -- singleChild -- + for (SingleChildMethod singleChildMethod : car.singleChildMethods()) { + Object target = singleChildMethod.getMethod().invoke(obj); + String childName = singleChildMethod.getName(); + DumpNode targetNode = transform(tti, target, nextSource(source, !isChildEnabled(objClassName, childName)), !getBuildConfig().getExcludeNullNodes()); + if (targetNode != null) { + DumpNormalChildNode normalChild = new DumpNormalChildNode(); + normalChild.setName(childName); + normalChild.setDumpNode(targetNode); + normalChild.setComputed(singleChildMethod.isNTASingleChildMethod()); + node.addDumpChildNode(normalChild); } - final ClassAnalysisResult car = analyzeClass(obj.getClass()); - // -- singleChild -- - for (SingleChildMethod singleChildMethod : car.singleChildMethods()) { - Object target = singleChildMethod.getMethod().invoke(obj); - String childName = singleChildMethod.getName(); - DumpNode targetNode = transform(tti, target, nextSource(source, !isChildEnabled(objClassName, childName))); + } + // -- listChild -- + for (ListChildMethod listChildMethod : car.listChildMethods()) { + Iterable<?> targetList = (Iterable<?>) listChildMethod.getMethod().invoke(obj); + DumpListChildNode listChild = new DumpListChildNode(); + listChild.setComputed(listChildMethod.isNTAListChildMethod()); + String childName = listChildMethod.getName(); + boolean shouldBeInvisisble = !isChildEnabled(objClassName, childName); + listChild.setName(childName); + for (Object target : targetList) { + DumpNode targetNode = transform(tti, target, nextSource(source, shouldBeInvisisble)); if (target != null && targetNode != null) { - DumpNormalChildNode normalChild = new DumpNormalChildNode(); - normalChild.setName(childName); - normalChild.setDumpNode(targetNode); - normalChild.setComputed(singleChildMethod.isNTASingleChildMethod()); - node.addDumpChildNode(normalChild); + listChild.addInnerDumpNode(new InnerDumpNode(targetNode)); } } - // -- listChild -- - for (ListChildMethod listChildMethod : car.listChildMethods()) { - Iterable<?> targetList = (Iterable<?>) listChildMethod.getMethod().invoke(obj); - DumpListChildNode listChild = new DumpListChildNode(); - listChild.setComputed(listChildMethod.isNTAListChildMethod()); - String childName = listChildMethod.getName(); - boolean shouldBeInvisisble = !isChildEnabled(objClassName, childName); - listChild.setName(childName); - for (Object target : targetList) { - DumpNode targetNode = transform(tti, target, nextSource(source, shouldBeInvisisble)); - if (target != null && targetNode != null) { - listChild.addInnerDumpNode(new InnerDumpNode(targetNode)); - } - } - if (listChild.getNumInnerDumpNode() > 0) { - node.addDumpChildNode(listChild); - } + if (listChild.getNumInnerDumpNode() > 0) { + node.addDumpChildNode(listChild); + } + } + // -- singleRelation -- + for (SingleRelationMethod singleRelationMethod : car.singleRelationMethods()) { + Object target = singleRelationMethod.getMethod().invoke(obj); + DumpNode targetNode = transform(tti, target, Source.RELATION); + if (target != null && targetNode != null) { + DumpNormalRelation normalRelation = new DumpNormalRelation(); + normalRelation.setName(singleRelationMethod.getName()); + normalRelation.setDumpNode(targetNode); + node.addDumpRelation(normalRelation); } - // -- singleRelation -- - for (SingleRelationMethod singleRelationMethod : car.singleRelationMethods()) { - Object target = singleRelationMethod.getMethod().invoke(obj); + } + // -- listRelation -- + for (ListRelationMethod listRelationMethod : car.listRelationMethods()) { + Iterable<?> targetList = (Iterable<?>) listRelationMethod.getMethod().invoke(obj); + DumpListRelation listRelation = new DumpListRelation(); + listRelation.setName(listRelationMethod.getName()); + for (Object target : targetList) { DumpNode targetNode = transform(tti, target, Source.RELATION); if (target != null && targetNode != null) { - DumpNormalRelation normalRelation = new DumpNormalRelation(); - normalRelation.setName(singleRelationMethod.getName()); - normalRelation.setDumpNode(targetNode); - node.addDumpRelation(normalRelation); + listRelation.addInnerDumpNode(new InnerDumpNode(targetNode)); } } - // -- listRelation -- - for (ListRelationMethod listRelationMethod : car.listRelationMethods()) { - Iterable<?> targetList = (Iterable<?>) listRelationMethod.getMethod().invoke(obj); - DumpListRelation listRelation = new DumpListRelation(); - listRelation.setName(listRelationMethod.getName()); - for (Object target : targetList) { - DumpNode targetNode = transform(tti, target, Source.RELATION); - if (target != null && targetNode != null) { - listRelation.addInnerDumpNode(new InnerDumpNode(targetNode)); - } - } - if (listRelation.getNumInnerDumpNode() > 0) { - node.addDumpRelation(listRelation); - } + if (listRelation.getNumInnerDumpNode() > 0) { + node.addDumpRelation(listRelation); } - // -- token -- - for (TokenMethod tokenMethod : car.tokenMethods()) { - Object target = tokenMethod.getMethod().invoke(obj); - if (target != null) { - DumpNode targetNode = transform(tti, target, Source.RELATION); - DumpToken token = null; - // TODO check, if Iterable.isAssignableFrom(target.getClass()). - // if so, check isAstNode for first non-null to add DumpReferenceToken's, otherwise DumpValueToken's - if (targetNode != null && targetNode.isAstNode()) { - token = new DumpReferenceToken().setValue(targetNode); - } else { - if (target != null && (getBuildConfig().getIncludeEmptyString() || !target.toString().isEmpty())) { - DumpValueToken valueToken = new DumpValueToken(); - valueToken.setValue(target); - token = valueToken; - } - } - if (token != null) { - token.setName(tokenMethod.getName()); - token.setComputed(tokenMethod.isAttributeMethod()); - node.addDumpToken(token); + } + // -- token -- + for (TokenMethod tokenMethod : car.tokenMethods()) { + Object target = tokenMethod.getMethod().invoke(obj); + if (target != null) { + DumpNode targetNode = transform(tti, target, Source.RELATION); + DumpToken token = null; + // TODO check, if Iterable.isAssignableFrom(target.getClass()). + // if so, check isAstNode for first non-null to add DumpReferenceToken's, otherwise DumpValueToken's + if (targetNode != null && targetNode.isAstNode()) { + token = new DumpReferenceToken().setValue(targetNode); + } else { + if (target != null && (getBuildConfig().getIncludeEmptyString() || !target.toString().isEmpty())) { + DumpValueToken valueToken = new DumpValueToken(); + valueToken.setValue(target); + token = valueToken; } } + if (token != null) { + token.setName(tokenMethod.getName()); + token.setComputed(tokenMethod.isAttributeMethod()); + node.addDumpToken(token); + } } } return node; } + private void DumpAst.applyStyle(DumpNode node) { + Object obj = node.getObject(); + node.setLabel(getBuildConfig().getStyleInformation().getNameMethod().get(obj)); + node.setBackgroundColor(getBuildConfig().getStyleInformation().getBackgroundColorMethod().get(obj)); + node.setTextColor(getBuildConfig().getStyleInformation().getTextColorMethod().get(obj)); + } + private Source DumpAst.nextSource(Source currentSource, boolean shouldBeInvisible) { return currentSource == Source.INVISIBLE_PARENT ? Source.INVISIBLE_PARENT : (shouldBeInvisible ? Source.INVISIBLE_PARENT : Source.PARENT); @@ -412,6 +436,10 @@ aspect GenerationBackend { // --- isAstNode --- syn boolean DumpNode.isAstNode() { + if (getObject() == null) { + // this is only possible for normal child nodes, and they are ast nodes + return true; + } Class<?> clazz = getObject().getClass(); for (java.lang.reflect.Method method : clazz.getMethods()) { if ("init$Children".equals(method.getName()) && method.getParameterCount() == 0) { @@ -450,33 +478,47 @@ aspect GenerationBackend { return result; } - class TransformationTransferInformation { - java.util.Map<Object, DumpNode> transformed = new java.util.HashMap<>(); - java.util.Map<DumpNode, Boolean> relationTargetsUnprocessed = new java.util.HashMap<>(); + // --- labelAndTextColor --- + syn String DumpNode.labelAndTextColor() { + if (getTextColor().isEmpty()) { + return getLabel(); + } else { + return "<color:" + getTextColor() + ">" + getLabel() + "</color>"; + } } - syn String DumpAst.toPlantUml() { - StringBuilder sb = new StringBuilder(); - com.github.mustachejava.reflect.ReflectionObjectHandler roh = new com.github.mustachejava.reflect.ReflectionObjectHandler() { - @Override - public com.github.mustachejava.Binding createBinding(String name, final com.github.mustachejava.TemplateContext tc, com.github.mustachejava.Code code) { - return new com.github.mustachejava.reflect.GuardedBinding(this, name, tc, code) { - @Override - protected synchronized com.github.mustachejava.util.Wrapper getWrapper(String name, java.util.List<Object> scopes) { - com.github.mustachejava.util.Wrapper wrapper = super.getWrapper(name, scopes); - if (wrapper instanceof com.github.mustachejava.reflect.MissingWrapper) { - throw new com.github.mustachejava.MustacheException(name + " not found in " + tc); - } - return wrapper; - } - }; + // --- myChildren --- + syn java.util.List<DumpNode> DumpNode.myChildren() { + java.util.List<DumpNode> result = new java.util.ArrayList<>(); + for (DumpChildNode childNode : getDumpChildNodeList()) { + for (DumpNode inner : childNode.innerNodes(true)) { + result.add(inner); } - }; - com.github.mustachejava.DefaultMustacheFactory mf = new com.github.mustachejava.DefaultMustacheFactory(); - mf.setObjectHandler(roh); - com.github.mustachejava.Mustache m = mf.compile("dumpAst.mustache"); - m.execute(new java.io.PrintWriter(new AppendableWriter(sb)), this); - return sb.toString(); + } + return result; + } + + // --- successor --- + syn DumpNode DumpNode.successor() { + if (container() == null) { + // not contained + return null; + } + java.util.List<DumpNode> siblingsAndMe = container().myChildren(); + int indexOfMe = siblingsAndMe.indexOf(this); + if (indexOfMe == siblingsAndMe.size() - 1) { + // last child + return null; + } + return siblingsAndMe.get(indexOfMe + 1); + } + + // --- hasSuccessor --- + syn boolean DumpNode.hasSuccessor() = successor() != null; + + class TransformationTransferInformation { + java.util.Map<Object, DumpNode> transformed = new java.util.HashMap<>(); + java.util.Map<DumpNode, Boolean> relationTargetsUnprocessed = new java.util.HashMap<>(); } syn String DumpAst.toYaml(boolean prependCreationComment) { @@ -558,4 +600,17 @@ aspect GenerationBackend { public void close() { } } + + static StyleInformation StyleInformation.createDefault() { + StyleInformation result = new StyleInformation(); + result.setNameMethod(n -> n == null ? "null" : n.getClass().getSimpleName() + "@" + Integer.toHexString(n.hashCode())); + result.setBackgroundColorMethod(n -> ""); + result.setTextColorMethod(n -> ""); + return result; + } + + @FunctionalInterface + public interface StyleMethod<ASTNODE> { + String get(ASTNODE node); + } } diff --git a/dumpAst/src/main/jastadd/GenerationFrontend.jadd b/dumpAst/src/main/jastadd/GenerationFrontend.jadd index 26466b1cd9ae3b1aa6cb9dec45acccd8437a2dfc..97b622a1ba1d333ad23e44dabb0a8571721cf6ab 100644 --- a/dumpAst/src/main/jastadd/GenerationFrontend.jadd +++ b/dumpAst/src/main/jastadd/GenerationFrontend.jadd @@ -62,6 +62,7 @@ public class DumpBuilder { this.target = target; buildConfig = new BuildConfig(); buildConfig.setGlobalPatternCollection(new PatternCollection()); + buildConfig.setStyleInformation(StyleInformation.createDefault()); printConfig = new PrintConfig(); printConfig.setScale(1); printConfig.setVersion(readVersion()); @@ -307,6 +308,16 @@ public class DumpBuilder { } } + public DumpBuilder excludeNullNodes() { + buildConfig.setExcludeNullNodes(true); + return this; + } + + public DumpBuilder includeNullNodes() { + buildConfig.setExcludeNullNodes(false); + return this; + } + public DumpBuilder customPreamble(String option) { printConfig.addHeader(new Header(option)); return this; @@ -321,11 +332,31 @@ public class DumpBuilder { return this; } + public <ASTNODE> DumpBuilder setNameMethod(StyleMethod<ASTNODE> nameMethod) { + buildConfig.getStyleInformation().setNameMethod(nameMethod); + return this; + } + + public <ASTNODE> DumpBuilder setBackgroundColorMethod(StyleMethod<ASTNODE> colorMethod) { + buildConfig.getStyleInformation().setBackgroundColorMethod(colorMethod); + return this; + } + + public <ASTNODE> DumpBuilder setTextColorMethod(StyleMethod<ASTNODE> colorMethod) { + buildConfig.getStyleInformation().setTextColorMethod(colorMethod); + return this; + } + public DumpBuilder setScale(double value) { printConfig.setScale(value); return this; } + public DumpBuilder orderChildren() { + printConfig.setOrderChildren(true); + return this; + } + private String readVersion() { try { java.util.ResourceBundle resources = java.util.ResourceBundle.getBundle("dumpAstVersion"); diff --git a/dumpAst/src/main/jastadd/GenerationMustache.jrag b/dumpAst/src/main/jastadd/GenerationMustache.jrag new file mode 100644 index 0000000000000000000000000000000000000000..d69f4fba573580285101ce63946da0fda5ce52fd --- /dev/null +++ b/dumpAst/src/main/jastadd/GenerationMustache.jrag @@ -0,0 +1,25 @@ +aspect GenerationMustache { + syn String DumpAst.toPlantUml() { + StringBuilder sb = new StringBuilder(); + com.github.mustachejava.reflect.ReflectionObjectHandler roh = new com.github.mustachejava.reflect.ReflectionObjectHandler() { + @Override + public com.github.mustachejava.Binding createBinding(String name, final com.github.mustachejava.TemplateContext tc, com.github.mustachejava.Code code) { + return new com.github.mustachejava.reflect.GuardedBinding(this, name, tc, code) { + @Override + protected synchronized com.github.mustachejava.util.Wrapper getWrapper(String name, java.util.List<Object> scopes) { + com.github.mustachejava.util.Wrapper wrapper = super.getWrapper(name, scopes); + if (wrapper instanceof com.github.mustachejava.reflect.MissingWrapper) { + throw new com.github.mustachejava.MustacheException(name + " not found in " + tc); + } + return wrapper; + } + }; + } + }; + com.github.mustachejava.DefaultMustacheFactory mf = new com.github.mustachejava.DefaultMustacheFactory(); + mf.setObjectHandler(roh); + com.github.mustachejava.Mustache m = mf.compile("dumpAst.mustache"); + m.execute(new java.io.PrintWriter(new AppendableWriter(sb)), this); + return sb.toString(); + } +} diff --git a/dumpAst/src/main/jastadd/Navigation.jrag b/dumpAst/src/main/jastadd/Navigation.jrag index 8783503bbcac55eac737c6777227a7b9bd18b70f..3f04c9c4392d6b02f4fa85b7329e9ae36fe140b9 100644 --- a/dumpAst/src/main/jastadd/Navigation.jrag +++ b/dumpAst/src/main/jastadd/Navigation.jrag @@ -33,6 +33,17 @@ aspect Navigation { eq DumpNode.getDumpRelation().containingDumpNode() = this; eq DumpNode.getInvisiblePath().containingDumpNode() = this; + // --- container --- + syn DumpNode DumpNode.container() { + if (getContainerOfNormalChild() != null) { + return getContainerOfNormalChild().containingDumpNode(); + } + if (getContainerOfInner() != null) { + return getContainerOfInner().containingDumpNode(); + } + return null; + } + // --- innerVisibleNodes --- syn java.util.List<DumpNode> DumpChildNode.innerVisibleNodes() = innerNodes(true); syn java.util.List<DumpNode> DumpRelation.innerVisibleNodes() = innerNodes(true); diff --git a/dumpAst/src/main/resources/dumpAst.mustache b/dumpAst/src/main/resources/dumpAst.mustache index b0c05305e6ff1c6431d593d7628101c90b3230bc..9dd0d02e100d308c175e494648008aebb663e5b0 100644 --- a/dumpAst/src/main/resources/dumpAst.mustache +++ b/dumpAst/src/main/resources/dumpAst.mustache @@ -9,7 +9,7 @@ scale {{Scale}} {{#DumpNodes}} {{#isAstNode}} {{^Invisible}} -object "{{label}}" as {{name}} { +object "{{{labelAndTextColor}}}" as {{name}} {{#backgroundColor}}#{{{backgroundColor}}}{{/backgroundColor}} { {{#DumpTokens}} {{#isDumpValueToken}} {{label}} = {{{Value}}} @@ -63,6 +63,13 @@ object "{{label}}" as {{name}} { {{/InnerDumpNodes}} {{/InvisiblePath}} {{/Invisible}} + {{#PrintConfig}}{{#orderChildren}} + {{#myChildren}} + {{#hasSuccessor}} +{{name}} -[hidden]right-> {{#successor}}{{name}}{{/successor}} + {{/hasSuccessor}} + {{/myChildren}} + {{/orderChildren}}{{/PrintConfig}} {{/DumpNodes}} {{#BuildConfig}} {{#Debug}} diff --git a/dumpAst/src/main/resources/dumpAstVersion.properties b/dumpAst/src/main/resources/dumpAstVersion.properties index 14aef4289892896a1b5965bd9edd25a783a3ebc2..e0a9ca936f23641719ffee3bfed385ca97d946b8 100644 --- a/dumpAst/src/main/resources/dumpAstVersion.properties +++ b/dumpAst/src/main/resources/dumpAstVersion.properties @@ -1,2 +1,2 @@ -#Fri Jan 15 20:29:48 CET 2021 -version=0.3.5 +#Thu Feb 24 09:45:15 CET 2022 +version=0.3.6 diff --git a/grammar2uml/.gitignore b/grammar2uml/.gitignore deleted file mode 100644 index 87b4cdd3d7c6a41502ca98703abeeb69a1d536fb..0000000000000000000000000000000000000000 --- a/grammar2uml/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -build -src/gen-res/ -src/gen/ -out/ -*.class diff --git a/grammar2uml/build.gradle b/grammar2uml/build.gradle deleted file mode 100644 index 78152a3d533446575bcc0a3e5a3e950100034a61..0000000000000000000000000000000000000000 --- a/grammar2uml/build.gradle +++ /dev/null @@ -1,148 +0,0 @@ -buildscript { - repositories.mavenLocal() - repositories.mavenCentral() - dependencies { - classpath group: 'org.jastadd', name: 'jastaddgradle', version: '1.13.3' - } -} - -plugins { - id 'relast2uml.java-jastadd-conventions' - id 'relast2uml.java-application-conventions' - id 'relast2uml.java-publishing-conventions' -} - -apply plugin: 'jastadd' - -application.mainClassName = 'de.tudresden.inf.st.jastadd.grammar2uml.compiler.Compiler' - -jar { - manifest { - attributes "Main-Class": application.mainClassName - } -} - -dependencies { - implementation project(':relast.preprocessor') - - implementation group: 'com.github.spullara.mustache.java', name: 'compiler', version: "${mustache_java_version}" - runtime group: 'org.jastadd', name: 'jastadd', version: '2.3.4' -} - -File preprocessorGrammar = file('../relast.preprocessor/src/main/jastadd/RelAst.relast') -File grammar2umlGrammar = file('./src/main/jastadd/Grammar2Uml.relast') -File intermediateGrammar = file('./src/main/jastadd/MustacheNodes.relast') - -task relast(type: JavaExec) { - group = 'Build' - main = "-jar" - - doFirst { - delete "src/gen/jastadd/*.ast" - delete "src/gen/jastadd/Grammar2Uml.jadd" - delete "src/gen/jastadd/Grammar2UmlRefResolver.jadd" - delete "src/gen/jastadd/Grammar2UmlResolverStubs.jrag" - mkdir "src/gen/jastadd/" - } - - args = [ - "../libs/relast.jar", - preprocessorGrammar, - grammar2umlGrammar, - intermediateGrammar, - "--listClass=java.util.ArrayList", - "--jastAddList=JastAddList", - "--useJastAddNames", - "--file", - "--resolverHelper", - "--grammarName=./src/gen/jastadd/Grammar2Uml" - ] - - inputs.files(file("../libs/relast.jar"), - preprocessorGrammar, - grammar2umlGrammar, - intermediateGrammar) - outputs.files(file("./src/gen/jastadd/Grammar2Uml.ast"), - file("./src/gen/jastadd/Grammar2Uml.jadd"), - file("./src/gen/jastadd/Grammar2UmlRefResolver.jadd"), - file('./src/gen/jastadd/Grammar2UmlResolverStubs.jrag')) -} - -jastadd { - configureModuleBuild() - modules { - //noinspection GroovyAssignabilityCheck - module("Grammar2Uml") { - - java { - basedir ".." - include "relast.preprocessor/main/**/*.java" - include "relast.preprocessor/gen/**/*.java" - include "grammar2uml/src/main/**/*.java" - include "grammar2uml/src/gen/**/*.java" - } - - jastadd { - basedir ".." - include "relast.preprocessor/src/main/jastadd/**/*.ast" - include "relast.preprocessor/src/main/jastadd/**/*.jadd" - include "relast.preprocessor/src/main/jastadd/**/*.jrag" - include "grammar2uml/src/main/jastadd/**/*.ast" - include "grammar2uml/src/main/jastadd/**/*.jadd" - include "grammar2uml/src/main/jastadd/**/*.jrag" - include "grammar2uml/src/gen/jastadd/**/*.ast" - include "grammar2uml/src/gen/jastadd/**/*.jadd" - include "grammar2uml/src/gen/jastadd/**/*.jrag" - } - - scanner { - basedir ".." - include "grammar2uml/src/main/jastadd/scanner/Header.flex", [-5] - include "relast.preprocessor/src/main/jastadd/scanner/Preamble.flex", [-4] - include "relast.preprocessor/src/main/jastadd/scanner/Macros.flex", [-3] - include "grammar2uml/src/main/jastadd/scanner/Macros.flex", [-3] - include "relast.preprocessor/src/main/jastadd/scanner/RulesPreamble.flex", [-2] - include "grammar2uml/src/main/jastadd/scanner/MappingContent.flex", [-1] - include "grammar2uml/src/main/jastadd/scanner/Keywords.flex" - include "relast.preprocessor/src/main/jastadd/scanner/Keywords.flex" - include "relast.preprocessor/src/main/jastadd/scanner/Symbols.flex", [1] - include "relast.preprocessor/src/main/jastadd/scanner/RulesPostamble.flex", [2] - } - - parser { - basedir ".." - include "grammar2uml/src/main/jastadd/parser/Preamble.parser" - include "relast.preprocessor/src/main/jastadd/parser/RelAst.parser" - include "grammar2uml/src/main/jastadd/parser/Grammar2Uml.parser" - } - } - } - - cleanGen.doFirst { - delete "src/gen/java/de" - delete "src/gen-res/BuildInfo.properties" - } - - preprocessParser.doFirst { - - args += ["--no-beaver-symbol"] - - } - - module = "Grammar2Uml" - - astPackage = 'de.tudresden.inf.st.jastadd.grammar2uml.ast' - - parser.name = 'Grammar2UmlParser' - - genDir = 'src/gen/java' - - buildInfoDir = 'src/gen-res' - - scanner.genDir = "src/gen/java/de/tudresden/inf/st/jastadd/grammar2uml/scanner" - parser.genDir = "src/gen/java/de/tudresden/inf/st/jastadd/grammar2uml/parser" - - jastaddOptions = ["--lineColumnNumbers", "--List=JastAddList", "--safeLazy", "--visitCheck=true", "--rewrite=cnta", "--cache=all"] -} - -generateAst.dependsOn relast diff --git a/grammar2uml/src/main/jastadd/Analysis.jrag b/grammar2uml/src/main/jastadd/Analysis.jrag deleted file mode 100644 index 317cf9dab8f3d0beb71e38fa7a2410b3c04090e2..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/jastadd/Analysis.jrag +++ /dev/null @@ -1,12 +0,0 @@ -aspect Analysis { - syn lazy Folder GrammarFile.defaultFolder() { - Folder result = new Folder(); - result.setName(new java.io.File(getFileName()).getName().replace(".relast", "").replace(".ast", "")); - for (Declaration decl : getDeclarationList()) { - if (decl.isTypeDecl() && !decl.asTypeDecl().hasSourceFolder()) { - result.addType(decl.asTypeDecl()); - } - } - return result; - } -} diff --git a/grammar2uml/src/main/jastadd/Errors.jrag b/grammar2uml/src/main/jastadd/Errors.jrag deleted file mode 100644 index 6a67912cee04483dec1f7727b97f8bdc6b19a8c1..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/jastadd/Errors.jrag +++ /dev/null @@ -1,68 +0,0 @@ -import java.util.Set; -import java.util.TreeSet; -import java.util.LinkedList; - -aspect Errors { - coll Set<ErrorMessage> Grammar2Uml.errors() - [new TreeSet<ErrorMessage>()] - root Grammar2Uml; -} - -aspect ErrorMessage { - public class ErrorMessage implements Comparable<ErrorMessage> { - private final ASTNode node; - private final String filename; - private final int line; - private final int col; - private final String message; - - public ErrorMessage(ASTNode node, String message) { - this.node = node; - this.filename = node.containedFileName(); - this.line = node.getStartLine(); - this.col = node.getStartColumn(); - this.message = message; - } - - public ASTNode getNode() { - return node; - } - public int getLine() { - return line; - } - public int getCol() { - return col; - } - public String getMessage() { - return message; - } - - public String toString() { - return filename + " Line " + line + ", column " + col + ": " + message; - } - - @Override - public int compareTo(ErrorMessage err) { - int n = filename.compareTo(err.filename); - if (n != 0) { - return n; - } - - n = line - err.line; - if (n != 0) { - return n; - } - - n = col-err.col; - if (n != 0) { - return n; - } - - return message.compareTo(err.message); - } - } - - protected ErrorMessage ASTNode.error(String message) { - return new ErrorMessage(this, message); - } -} diff --git a/grammar2uml/src/main/jastadd/Grammar2Uml.relast b/grammar2uml/src/main/jastadd/Grammar2Uml.relast deleted file mode 100644 index 9eab1230a1f5abd9fffbb7784043e1a457a14248..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/jastadd/Grammar2Uml.relast +++ /dev/null @@ -1,4 +0,0 @@ -Grammar2Uml ::= Program <FileName> Folder* ; - -Folder ::= <Name:String> ; -rel Folder.Type* <-> TypeDecl.SourceFolder?; diff --git a/grammar2uml/src/main/jastadd/MustacheNodes.relast b/grammar2uml/src/main/jastadd/MustacheNodes.relast deleted file mode 100644 index d4b684c6a23d885c5aca80ebb54aef3f6d4aa402..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/jastadd/MustacheNodes.relast +++ /dev/null @@ -1,21 +0,0 @@ -MGrammar2Uml ::= Folder:MFolder* OtherType:MTypeDecl* Containment:MContainment* Relation:MRelation* Inheritance:MInheritance* ; -MFolder ::= InnerTypeDecl:MTypeDecl*; -MTypeDecl ::= InnerTokenComponent:MTokenComponent*; -MTokenComponent; -abstract MContainment ::= <Label:String> ; -MSingleContainment : MContainment; -MOptContainment : MContainment; -MListContainment : MContainment; -MRelation ::= <Label> <LeftModifier> <RightModifier> <Bidirectional:boolean>; -MInheritance ; - -rel MGrammar2Uml.Grammar2Uml -> Grammar2Uml; -rel MFolder.Folder -> Folder; -rel MTypeDecl.Type -> TypeDecl; -rel MTokenComponent.Token -> TokenComponent; -rel MContainment.Type -> TypeDecl; -rel MContainment.Component -> TypeDecl; -rel MRelation.Left -> TypeDecl; -rel MRelation.Right -> TypeDecl; -rel MInheritance.SuperClass -> TypeDecl; -rel MInheritance.SubClass -> TypeDecl; diff --git a/grammar2uml/src/main/jastadd/NameResolution.jrag b/grammar2uml/src/main/jastadd/NameResolution.jrag deleted file mode 100644 index e6450fbd126ab20cf1d3ccc792af9d3c84ac9636..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/jastadd/NameResolution.jrag +++ /dev/null @@ -1,12 +0,0 @@ -aspect NameResolutionExtended { - refine NameResolution eq Program.resolveTypeDecl(String name) { - try { - return refined(name); - } catch (RuntimeException e) { - System.err.println(e.getMessage()); - TypeDecl dummy = new TypeDecl(); - dummy.setName("(" + name + ")"); - return dummy; - } - } -} diff --git a/grammar2uml/src/main/jastadd/Navigation.jrag b/grammar2uml/src/main/jastadd/Navigation.jrag deleted file mode 100644 index ccd0f3d49ede4fbecfafafff05b5228e42c76ed9..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/jastadd/Navigation.jrag +++ /dev/null @@ -1,21 +0,0 @@ -aspect Navigation { - - // --- program --- - eq Grammar2Uml.getChild().program() = getProgram(); - eq MGrammar2Uml.getChild().program() = getGrammar2Uml().program(); - - // --- grammar2uml --- - inh Grammar2Uml ASTNode.grammar2uml(); - eq Grammar2Uml.getChild().grammar2uml() = this; - eq MGrammar2Uml.getChild().grammar2uml() = getGrammar2Uml(); - - // --- containedFile --- - eq Grammar2Uml.getChild().containedFile() = null; - eq MGrammar2Uml.getChild().containedFile() = null; - - // --- containedFileName --- - eq Grammar2Uml.getChild().containedFileName() = getFileName(); - eq Program.getChild().containedFileName() = null; - eq Grammar.getChild().containedFileName() = null; - eq MGrammar2Uml.getChild().containedFileName() = null; -} diff --git a/grammar2uml/src/main/jastadd/backend/Configuration.jadd b/grammar2uml/src/main/jastadd/backend/Configuration.jadd deleted file mode 100644 index 8dc259407fd5fff7e314af0875e318b0aaa288e2..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/jastadd/backend/Configuration.jadd +++ /dev/null @@ -1,2 +0,0 @@ -aspect Configuration { -} diff --git a/grammar2uml/src/main/jastadd/backend/Generation.jadd b/grammar2uml/src/main/jastadd/backend/Generation.jadd deleted file mode 100644 index 45276bd4aa3744de020a75512bc9ef62e7e130fb..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/jastadd/backend/Generation.jadd +++ /dev/null @@ -1,215 +0,0 @@ -aspect GenerationUtils { - public static final String ASTNode.aspectIndent = " "; - - public String ASTNode.ind(int n) { - StringBuilder s = new StringBuilder(); - for (int i = 0; i < n; i++) { - s.append(aspectIndent); - } - return s.toString(); - } - - // --- prettyPrint --- - syn String JavaTypeUse.prettyPrint() { - StringBuilder sb = new StringBuilder(); - generateAbstractGrammar(sb); - return sb.toString(); - } -} - -aspect AttributesForMustache { - // --- MFolder --- - syn String MFolder.name() = getFolder().getName(); - - // --- MTypeDecl --- - eq MTypeDecl.getInnerTokenComponent(int i).isFirst() = i == 0; - eq MTypeDecl.getInnerTokenComponent(int i).isLast() = i == getNumInnerTokenComponent() - 1; - - syn boolean MTypeDecl.isAbstract() = getType().getAbstract(); - syn String MTypeDecl.name() = getType().getName(); - - // --- MTokenComponent --- - syn String MTokenComponent.name() = getToken().getName(); - inh boolean MTokenComponent.isFirst(); - inh boolean MTokenComponent.isLast(); - - // --- MContainment --- - syn String MContainment.typeName() = getType().getName(); - syn String MContainment.componentName() = getComponent().getName(); - syn String MContainment.modifier(); - eq MSingleContainment.modifier() = "\"1\""; - eq MOptContainment.modifier() = "\"0 .. 1\""; - eq MListContainment.modifier() = "\"*\""; - - // --- MRelation --- - syn String MRelation.leftName() = getLeft().getName(); - syn String MRelation.rightName() = getRight().getName(); - syn boolean MRelation.isBidirectional() = getBidirectional(); -// syn String MRelation.modifier(); -// eq MSingleRelation.modifier() = "\"1\""; -// eq MOptRelation.modifier() = "\"0 .. 1\""; -// eq MListRelation.modifier() = "\"*\""; - - // --- MInheritance --- - syn String MInheritance.superClassName() = getSuperClass().getName(); - syn String MInheritance.subClassName() = getSubClass().getName(); - - // --- toMContainment --- - syn MContainment TypeComponent.toMContainment(); - eq NormalComponent.toMContainment() = new MSingleContainment(); - eq ListComponent.toMContainment() = new MListContainment(); - eq OptComponent.toMContainment() = new MOptContainment(); - - // --- toMRelation --- - syn MRelation Relation.toMRelation(); - eq DirectedRelation.toMRelation() { - MRelation result = new MRelation(); - result.setRightModifier(getSource().toMRelationModifier()); - result.setBidirectional(false); - return result; - } - eq BidirectionalRelation.toMRelation() { - MRelation result = new MRelation(); - result.setLeftModifier(getRight().toMRelationModifier()); - result.setRightModifier(getLeft().toMRelationModifier()); - result.setBidirectional(true); - return result; - } - - // --- toMRelationModifier --- - syn String Role.toMRelationModifier(); - eq NormalRole.toMRelationModifier() = "\"1\""; - eq ListRole.toMRelationModifier() = "\"0 .. 1\""; - eq OptRole.toMRelationModifier() = "\"*\""; - eq UnnamedRole.toMRelationModifier() { - throw new RuntimeException("UnnamedRole cannot be converted to MRelation"); - } - - // --- toMustache --- - syn lazy MGrammar2Uml Grammar2Uml.toMustache() { - MGrammar2Uml result = new MGrammar2Uml(); - result.setGrammar2Uml(this); - for (Folder folder : getFolderList()) { - result.addFolder(folder.toMustache()); - } - for (TypeDecl typeDecl : getProgram().typeDecls()) { - if (!typeDecl.hasSourceFolder()) { - result.addOtherType(typeDecl.toMustache()); - } - for (Component component : typeDecl.getComponentList()) { - if (component.isTypeComponent()) { - TypeComponent typeComponent = component.asTypeComponent(); - MContainment containment = typeComponent.toMContainment(); - containment.setType(typeDecl); - containment.setComponent(component.asTypeComponent().getTypeDecl()); - if (!component.getName().isEmpty() && !component.getName().equals(component.asTypeComponent().getTypeDecl().getName())) { - containment.setLabel(component.getName()); - } - result.addContainment(containment); - } - } - if (typeDecl.hasSuperType()) { - MInheritance inheritance = new MInheritance(); - inheritance.setSuperClass(typeDecl.getSuperType()); - inheritance.setSubClass(typeDecl); - result.addInheritance(inheritance); - } - } - for (Relation relation : getProgram().relations()) { - if (relation.isDirectedRelation()) { - DirectedRelation directedRelation = relation.asDirectedRelation(); - MRelation mRelation = directedRelation.toMRelation(); - mRelation.setLeft(directedRelation.getSource().getType()); - mRelation.setRight(directedRelation.getTarget().getType()); - mRelation.setLabel(directedRelation.getSource().getName()); - result.addRelation(mRelation); - } else { - BidirectionalRelation bidiRelation = relation.asBidirectionalRelation(); - MRelation mRelation = bidiRelation.toMRelation(); - mRelation.setLeft(bidiRelation.getLeft().getType()); - mRelation.setRight(bidiRelation.getRight().getType()); -// mRelation.setLabel(bidiRelation.getSource().getName()); - result.addRelation(mRelation); - } - } - return result; - } - - syn lazy MFolder Folder.toMustache() { - MFolder result = new MFolder(); - result.setFolder(this); - for (TypeDecl typeDecl : getTypeList()) { - result.addInnerTypeDecl(typeDecl.toMustache()); - } - return result; - } - - syn lazy MTypeDecl TypeDecl.toMustache() { - MTypeDecl result = new MTypeDecl(); - result.setType(this); - for (Component component : getComponentList()) { - if (component.isTokenComponent()) { - result.addInnerTokenComponent(component.asTokenComponent().toMustache()); - } - } - return result; - } - - syn lazy MTokenComponent TokenComponent.toMustache() { - MTokenComponent result = new MTokenComponent(); - result.setToken(this); - return result; - } - -} - -aspect AspectGeneration { - syn String Grammar2Uml.generateAspect() = toMustache().generateAspect(); - - syn String MGrammar2Uml.generateAspect() { - StringBuilder sb = new StringBuilder(); - com.github.mustachejava.reflect.ReflectionObjectHandler roh = new com.github.mustachejava.reflect.ReflectionObjectHandler() { - @Override - public com.github.mustachejava.Binding createBinding(String name, final com.github.mustachejava.TemplateContext tc, com.github.mustachejava.Code code) { - return new com.github.mustachejava.reflect.GuardedBinding(this, name, tc, code) { - @Override - protected synchronized com.github.mustachejava.util.Wrapper getWrapper(String name, java.util.List<Object> scopes) { - com.github.mustachejava.util.Wrapper wrapper = super.getWrapper(name, scopes); - if (wrapper instanceof com.github.mustachejava.reflect.MissingWrapper) { - throw new com.github.mustachejava.MustacheException(name + " not found in " + tc); - } - return wrapper; - } - }; - } - }; - com.github.mustachejava.DefaultMustacheFactory mf = new com.github.mustachejava.DefaultMustacheFactory(); -// mf.setObjectHandler(roh); - com.github.mustachejava.Mustache m = mf.compile("grammar2uml.mustache"); - m.execute(new java.io.PrintWriter(new AppendableWriter(sb)), this); - return sb.toString(); - } - public class AppendableWriter extends java.io.Writer { - private final StringBuilder sb; - - public AppendableWriter(StringBuilder sb) { - this.sb = sb; - } - - @Override - public void write(char[] chars, int off, int len) { - sb.append(chars, off, len); - } - - @Override - public void write(String str) { - sb.append(str); - } - - @Override - public void flush() {} - - @Override - public void close() {} - } -} diff --git a/grammar2uml/src/main/jastadd/parser/Grammar2Uml.parser b/grammar2uml/src/main/jastadd/parser/Grammar2Uml.parser deleted file mode 100644 index df2865f7f39906268d759884ec359a046d02f3ae..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/jastadd/parser/Grammar2Uml.parser +++ /dev/null @@ -1,23 +0,0 @@ -Grammar2Uml grammar2uml - = folder.f grammar2uml.r {: r.getFolderList().insertChild(f, 0); return r; :} - | {: return new Grammar2Uml(); :} -; - -Folder folder - = FOLDER ID.name COL type_use_list.t - {: - Folder result = new Folder(); - result.setName(name); - java.util.List<TypeDecl> typeDecls = ((ArrayList<Object>) t).stream().map(x -> TypeDecl.createRef(((Symbol) x).value.toString())).collect(java.util.stream.Collectors.toList()); - java.util.Collections.reverse(typeDecls); - for (TypeDecl typeDecl : typeDecls) { - result.addType(typeDecl); - } - return result; - :} -; - -ArrayList type_use_list - = ID - | type_use_list COMMA ID -; diff --git a/grammar2uml/src/main/jastadd/parser/Preamble.parser b/grammar2uml/src/main/jastadd/parser/Preamble.parser deleted file mode 100644 index b65eedbcac607a2495d8d514d48ba2eb7d415ed2..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/jastadd/parser/Preamble.parser +++ /dev/null @@ -1,7 +0,0 @@ -%header {: -package de.tudresden.inf.st.jastadd.grammar2uml.parser; -import de.tudresden.inf.st.jastadd.grammar2uml.ast.*; -:}; - -%goal goal; -%goal grammar2uml; diff --git a/grammar2uml/src/main/jastadd/scanner/Header.flex b/grammar2uml/src/main/jastadd/scanner/Header.flex deleted file mode 100644 index 1fa63001776ed524713f182197ccb097127394a8..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/jastadd/scanner/Header.flex +++ /dev/null @@ -1,20 +0,0 @@ -package de.tudresden.inf.st.jastadd.grammar2uml.scanner; - -import de.tudresden.inf.st.jastadd.grammar2uml.parser.Grammar2UmlParser.Terminals; -%% - -%public -%final -%class Grammar2UmlScanner -%extends beaver.Scanner - -%type beaver.Symbol -%function nextToken -%yylexthrow beaver.Scanner.Exception -%scanerror Grammar2UmlScanner.ScannerError - -%x COMMENT -%s DECLARATION - -%line -%column diff --git a/grammar2uml/src/main/jastadd/scanner/Keywords.flex b/grammar2uml/src/main/jastadd/scanner/Keywords.flex deleted file mode 100644 index da23f5cac26860abdda8b61003d41a04022d44a5..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/jastadd/scanner/Keywords.flex +++ /dev/null @@ -1 +0,0 @@ -"folder" { yybegin(DECLARATION); return sym(Terminals.FOLDER); } diff --git a/grammar2uml/src/main/jastadd/scanner/Macros.flex b/grammar2uml/src/main/jastadd/scanner/Macros.flex deleted file mode 100644 index eac10a8da1b6ed7c8b01243996e99d25ab119bbd..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/jastadd/scanner/Macros.flex +++ /dev/null @@ -1,2 +0,0 @@ -//MappingContent = [{][:][^:]*[:]+([^:}][^:]*[:]+)*[}] -ID = [:jletter:][:jletterdigit:]* diff --git a/grammar2uml/src/main/jastadd/scanner/MappingContent.flex b/grammar2uml/src/main/jastadd/scanner/MappingContent.flex deleted file mode 100644 index fc2e9c220346d3193ff8c973de951df4a25789c1..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/jastadd/scanner/MappingContent.flex +++ /dev/null @@ -1 +0,0 @@ -//{MappingContent} { return sym(Terminals.MAPPING_CONTENT); } diff --git a/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/Compiler.java b/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/Compiler.java deleted file mode 100644 index f318da191014d5df7410c0f5d0f4c5edf06029f6..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/Compiler.java +++ /dev/null @@ -1,195 +0,0 @@ -package de.tudresden.inf.st.jastadd.grammar2uml.compiler; - -import beaver.Parser; -import org.jastadd.option.BooleanOption; -import org.jastadd.option.ValueOption; -import org.jastadd.relast.compiler.AbstractCompiler; -import org.jastadd.relast.compiler.CompilerException; -import de.tudresden.inf.st.jastadd.grammar2uml.ast.ErrorMessage; -import de.tudresden.inf.st.jastadd.grammar2uml.ast.GrammarFile; -import de.tudresden.inf.st.jastadd.grammar2uml.ast.Program; -import de.tudresden.inf.st.jastadd.grammar2uml.ast.Grammar2Uml; -import de.tudresden.inf.st.jastadd.grammar2uml.parser.Grammar2UmlParser; -import de.tudresden.inf.st.jastadd.grammar2uml.scanner.Grammar2UmlScanner; - -import java.io.BufferedReader; -import java.io.IOException; -import java.io.PrintWriter; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; -import java.util.MissingResourceException; -import java.util.ResourceBundle; - -public class Compiler extends AbstractCompiler { - - private ValueOption optionOutputFile; - private ValueOption optionInputGrammar2Uml; - private BooleanOption optionDefaultFolders; - private BooleanOption optionHelp; - private BooleanOption optionVersion; - private BooleanOption optionVerbose; - - public Compiler() { - super("grammar2uml", false); - } - - /** - * Reads the version string. - * - * The version string is read from the property file - * src/main/resources/Version.properties. This - * file should be generated during the build process. If it is missing - * then there is some problem in the build script. - * - * @author Jesper Öqvist <jesper.oqvist@cs.lth.se> - * @return the read version string, or <code>version ?</code> - */ - private String readVersion() { - try { - return ResourceBundle.getBundle("grammar2umlVersion").getString("version"); - } catch (MissingResourceException e) { - return "version ?"; - } - } - - public static void main(String[] args) { - System.setProperty("mustache.debug", "true"); - try { - new Compiler().run(args); - } catch (CompilerException e) { - System.err.println(e.getMessage()); - System.exit(-1); - } - } - - private void printMessage(String message) { - System.out.println(message); - } - - private void writeToFile(String filename, String str) throws CompilerException { - try { - PrintWriter writer = new PrintWriter(filename); - writer.print(str); - writer.close(); - } catch (Exception e) { - throw new CompilerException("Could not write to file " + filename, e); - } - } - - protected void initOptions() { - optionOutputFile = addOption( - new ValueOption("output", "target file to be generated.") - .defaultValue("uml.md") - .acceptAnyValue() - .needsValue(false)); - optionInputGrammar2Uml = addOption( - new ValueOption("inputGrammar2Uml", "grammar2uml definition file.") - .needsValue(true)); - optionDefaultFolders = addOption( - new BooleanOption("defaultFolders", - "Creates a default folder per grammar file.") - .defaultValue(false)); - optionHelp = addOption( - new BooleanOption("help", "Print usage and exit.") - .defaultValue(false)); - optionVersion = addOption( - new BooleanOption("version", "Print version and exit.") - .defaultValue(false)); - optionVerbose = addOption( - new BooleanOption("verbose", "Print more messages while compiling.") - .defaultValue(false)); - } - - private Grammar2Uml parseProgram() throws CompilerException { - Program program = new Program(); - Grammar2Uml grammar2Uml; - - for (String inputGrammarFileName : getConfiguration().getFiles()) { - printMessage("Parsing " + inputGrammarFileName); - GrammarFile inputGrammar; - try (BufferedReader reader = Files.newBufferedReader(Paths.get(inputGrammarFileName))) { - Grammar2UmlScanner scanner = new Grammar2UmlScanner(reader); - Grammar2UmlParser parser = new Grammar2UmlParser(); - inputGrammar = (GrammarFile) parser.parse(scanner); - if (optionVerbose.value()) { - inputGrammar.dumpTree(System.out); - } - program.addGrammarFile(inputGrammar); - inputGrammar.setFileName(inputGrammarFileName); - } catch (IOException | Parser.Exception e) { - throw new CompilerException("Could not parse grammar file " + inputGrammarFileName, e); - } - } - - if (optionInputGrammar2Uml.isMatched()) { - String inputGrammar2UmlFileName = optionInputGrammar2Uml.value(); - try (BufferedReader reader = Files.newBufferedReader(Paths.get(inputGrammar2UmlFileName))) { - Grammar2UmlScanner scanner = new Grammar2UmlScanner(reader); - Grammar2UmlParser parser = new Grammar2UmlParser(); - grammar2Uml = (Grammar2Uml) parser.parse(scanner, Grammar2UmlParser.AltGoals.grammar2uml); - grammar2Uml.setFileName(inputGrammar2UmlFileName); - } catch (IOException | Parser.Exception e) { - throw new CompilerException("Could not parse grammar2uml file " + inputGrammar2UmlFileName, e); - } - } else { - // no special setting given - grammar2Uml = new Grammar2Uml(); - grammar2Uml.setFileName("<none>"); - } - grammar2Uml.setProgram(program); - grammar2Uml.treeResolveAll(); - if (optionDefaultFolders.value()) { - for (GrammarFile grammarFile : program.getGrammarFileList()) { - grammar2Uml.addFolder(grammarFile.defaultFolder()); - } - } - return grammar2Uml; - } - - @Override - protected int compile() throws CompilerException { - if (optionVersion.value()) { - System.out.println(readVersion()); - return 0; - } - if (optionHelp.value()) { - getConfiguration().printHelp(System.out); - return 0; - } - - printMessage("Running grammar2uml " + readVersion()); - - String output; - if (optionOutputFile.isMatched()) { - output = optionOutputFile.value(); - } else { - output = "uml.md"; - System.out.println("No output output file is set. Assuming '" + output + "'."); - } - Path parent = Paths.get(optionOutputFile.value()).toAbsolutePath().getParent(); - try { - Files.createDirectories(parent); - } catch (IOException e) { - throw new CompilerException("Error creating output dir " + parent, e); - } - - if (getConfiguration().getFiles().isEmpty()) { - throw new CompilerException("No input grammars specified!"); - } - - Grammar2Uml grammar2uml = parseProgram(); - - if (!grammar2uml.errors().isEmpty()) { - System.err.println("Errors:"); - for (ErrorMessage e : grammar2uml.errors()) { - System.err.println(e); - } - System.exit(1); - } - - printMessage("Writing output file " + output); - writeToFile(output, grammar2uml.generateAspect()); - return 0; - } -} diff --git a/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/Grammar2UmlMain.java b/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/Grammar2UmlMain.java deleted file mode 100644 index e552d5548514363c535a2943ac97a1f35788bd8d..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/Grammar2UmlMain.java +++ /dev/null @@ -1,70 +0,0 @@ -package de.tudresden.inf.st.jastadd.grammar2uml.compiler; - -import beaver.Parser; -import de.tudresden.inf.st.jastadd.grammar2uml.ast.*; -import de.tudresden.inf.st.jastadd.grammar2uml.parser.Grammar2UmlParser; -import de.tudresden.inf.st.jastadd.grammar2uml.scanner.Grammar2UmlScanner; - -import java.io.BufferedReader; -import java.io.IOException; -import java.nio.file.Files; -import java.nio.file.Path; -import java.nio.file.Paths; - -/** - * Testing Grammar2Uml without parser. - * - * @author rschoene - Initial contribution - */ -public class Grammar2UmlMain { - - public static void main(String[] args) { -// testing(); - processManualAST(); - } - - public static Grammar2Uml createManualAST() { - System.setProperty("java.util.logging.manager", "org.apache.logging.log4j.jul.LogManager"); - System.setProperty("mustache.debug", "true"); - Grammar2Uml model = new Grammar2Uml(); - Path path = Paths.get("grammar2uml.base", "src", "test", "resources", "Example.relast"); - System.out.println("path.toFile().getAbsolutePath() = " + path.toFile().getAbsolutePath()); - Program program = parseProgram(path); - model.setProgram(program); - - Folder folder1 = new Folder(); - folder1.setName("Folder1"); - folder1.addType(program.resolveTypeDecl("Wert")); - folder1.addType(program.resolveTypeDecl("Quelle")); - model.addFolder(folder1); - - return model; - } - - private static void processManualAST() { - Grammar2Uml model = createManualAST(); - model.treeResolveAll(); - for (Folder f : model.getFolderList()) { - System.out.println(f.getName() + ":"); - for (TypeDecl typeDecl : f.getTypeList()) { - System.out.println(typeDecl.getName()); - } - } - - System.out.println(model.generateAspect()); - } - - public static Program parseProgram(Path path) { - try (BufferedReader reader = Files.newBufferedReader(path)) { - Grammar2UmlScanner scanner = new Grammar2UmlScanner(reader); - Grammar2UmlParser parser = new Grammar2UmlParser(); - GrammarFile grammarFile = (GrammarFile) parser.parse(scanner); - Program program = new Program(); - program.addGrammarFile(grammarFile); - return program; - } catch (IOException | Parser.Exception e) { - e.printStackTrace(); - } - return null; - } -} diff --git a/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/Utils.java b/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/Utils.java deleted file mode 100644 index 496daa3bbe6f1745e2b69c6b0b412e0b1b62d29b..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/java/de/tudresden/inf/st/jastadd/grammar2uml/compiler/Utils.java +++ /dev/null @@ -1,16 +0,0 @@ -package de.tudresden.inf.st.jastadd.grammar2uml.compiler; - -import java.util.*; -import java.util.function.Predicate; - -import static java.util.stream.Collectors.toList; - -public class Utils { - public static <T> List<T> filterToList(Collection<T> collection, Predicate<T> predicate) { - return collection.stream().filter(predicate).collect(toList()); - } - - public static <T> Set<T> asSet(T... t) { - return new HashSet<T>(Arrays.asList(t)); - } -} diff --git a/grammar2uml/src/main/resources/Containment.mustache b/grammar2uml/src/main/resources/Containment.mustache deleted file mode 100644 index 48dbc880dc31026777fbd8e281b75b409bcbac4c..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/resources/Containment.mustache +++ /dev/null @@ -1 +0,0 @@ -{{typeName}} *-- {{{modifier}}} {{componentName}} {{#Label}}: {{Label}}{{/Label}} diff --git a/grammar2uml/src/main/resources/Folder.mustache b/grammar2uml/src/main/resources/Folder.mustache deleted file mode 100644 index e9890e1ba8c128f89db6a45107c2ce99746cbd7a..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/resources/Folder.mustache +++ /dev/null @@ -1,3 +0,0 @@ -package {{name}} <<Folder>> { -{{#InnerTypeDecls}} {{> TypeDecl}}{{/InnerTypeDecls}} -} diff --git a/grammar2uml/src/main/resources/Inheritance.mustache b/grammar2uml/src/main/resources/Inheritance.mustache deleted file mode 100644 index a8f10c07b587f926b60a45646de70e422e68caf0..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/resources/Inheritance.mustache +++ /dev/null @@ -1 +0,0 @@ -{{superClassName}} <|-- {{subClassName}} diff --git a/grammar2uml/src/main/resources/Relation.mustache b/grammar2uml/src/main/resources/Relation.mustache deleted file mode 100644 index 7f23515c96462c8e86a24172d77cea66c81eaac7..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/resources/Relation.mustache +++ /dev/null @@ -1 +0,0 @@ -{{leftName}} {{{leftModifier}}} {{#isBidirectional}}<{{/isBidirectional}}--> {{{rightModifier}}} {{rightName}} {{#Label}}: {{Label}}{{/Label}} diff --git a/grammar2uml/src/main/resources/TypeDecl.mustache b/grammar2uml/src/main/resources/TypeDecl.mustache deleted file mode 100644 index a72b5dcfcdc2b8fe11ca240402d98cc787340d83..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/resources/TypeDecl.mustache +++ /dev/null @@ -1,5 +0,0 @@ -{{=<% %>=}}<%#isAbstract%>abstract <%/isAbstract%>class <%name%><%#InnerTokenComponents%><%#first%> { -<%/first%> - <%name%> -<%#last%> -}<%/last%><%/InnerTokenComponents%><%={{ }}=%> diff --git a/grammar2uml/src/main/resources/grammar2uml.mustache b/grammar2uml/src/main/resources/grammar2uml.mustache deleted file mode 100644 index 6fe27d0d1b3f4e39170b693153c5675f1912c7a1..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/resources/grammar2uml.mustache +++ /dev/null @@ -1,11 +0,0 @@ -```plantuml -@startuml -hide circle -hide methods -{{#Folders}}{{> Folder}}{{/Folders}} -{{#OtherTypes}}{{> TypeDecl}}{{/OtherTypes}} -{{#Containments}}{{> Containment}}{{/Containments}} -{{#Relations}}{{> Relation}}{{/Relations}} -{{#Inheritances}}{{> Inheritance}}{{/Inheritances}} -@enduml -``` diff --git a/grammar2uml/src/main/resources/grammar2umlVersion.properties b/grammar2uml/src/main/resources/grammar2umlVersion.properties deleted file mode 100644 index 3a408660377b15e06ef7d0249b1da178b5ea006d..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/resources/grammar2umlVersion.properties +++ /dev/null @@ -1,2 +0,0 @@ -#Fri Jan 15 20:11:10 CET 2021 -version=0.1.1 diff --git a/grammar2uml/src/main/resources/log4j2.xml b/grammar2uml/src/main/resources/log4j2.xml deleted file mode 100644 index 98cfd73c75df58d8598521bc10b043e214ec4ad8..0000000000000000000000000000000000000000 --- a/grammar2uml/src/main/resources/log4j2.xml +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Configuration status="INFO"> - <Appenders> - <Console name="Console" target="SYSTEM_OUT"> - <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> - </Console> - </Appenders> - <Loggers> - <Root level="info"> - <AppenderRef ref="Console"/> - </Root> - </Loggers> -</Configuration> \ No newline at end of file diff --git a/grammar2uml/src/test/java/de/tudresden/inf/st/jastadd/grammar2uml/test/CompilerTest.java b/grammar2uml/src/test/java/de/tudresden/inf/st/jastadd/grammar2uml/test/CompilerTest.java deleted file mode 100644 index 5d43d2bd2f22a0d72eef263fbd1e467e9a39c942..0000000000000000000000000000000000000000 --- a/grammar2uml/src/test/java/de/tudresden/inf/st/jastadd/grammar2uml/test/CompilerTest.java +++ /dev/null @@ -1,49 +0,0 @@ -package de.tudresden.inf.st.jastadd.grammar2uml.test; - -import org.jastadd.relast.compiler.CompilerException; -import de.tudresden.inf.st.jastadd.grammar2uml.compiler.Compiler; -import org.junit.jupiter.api.Test; - -import java.io.File; -import java.nio.file.Paths; - -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertTrue; - -/** - * TODO: Add description. - * - * @author rschoene - Initial contribution - */ -public class CompilerTest { - - @SuppressWarnings("SameParameterValue") - void transform(String inputGrammar, String inputGrammar2Uml, String output) throws CompilerException { - - System.out.println("Running test in directory '" + Paths.get(".").toAbsolutePath() + "'."); - assertTrue(Paths.get(inputGrammar).toFile().exists(), "input grammar does not exist"); - assertTrue(Paths.get(inputGrammar2Uml).toFile().exists(), "input grammar2uml does not exist"); - assertFalse(Paths.get(inputGrammar).toFile().isDirectory(), "input grammar is a directory"); - assertFalse(Paths.get(inputGrammar2Uml).toFile().isDirectory(), "input grammar2uml is a directory"); - - File outputFile = Paths.get(output).toFile(); - File outputDirFile = outputFile.getParentFile(); - if (!outputDirFile.exists()) { - assertTrue(outputDirFile.mkdir()); - } - - String[] args = { - "--output=" + output, - "--inputGrammar2Uml=" + inputGrammar2Uml, - "--defaultFolders", - inputGrammar - }; - - new Compiler().run(args); - } - - @Test - void transformMinimalExample() throws CompilerException { - transform("src/test/resources/Example.relast", "src/test/resources/Example.grammar2uml", "src/test/resources/uml.md"); - } -} diff --git a/grammar2uml/src/test/resources/.gitignore b/grammar2uml/src/test/resources/.gitignore deleted file mode 100644 index 9749ac39920e0a1fb55067777edd7d9372108858..0000000000000000000000000000000000000000 --- a/grammar2uml/src/test/resources/.gitignore +++ /dev/null @@ -1 +0,0 @@ -uml.md diff --git a/grammar2uml/src/test/resources/Example.grammar2uml b/grammar2uml/src/test/resources/Example.grammar2uml deleted file mode 100644 index 6665ad50fad2535f1596393ca59672827d69d99b..0000000000000000000000000000000000000000 --- a/grammar2uml/src/test/resources/Example.grammar2uml +++ /dev/null @@ -1,3 +0,0 @@ -folder Datenfluss: Prüfmethode, Funktionsprinzip, Datenausgangswert, Verarbeitungsschritt, Dateneingangswert, Wert, Datenquelle, Quelle -folder Darstellung: DarstellungsElement, Dezimalwert, Auffälligkeitsmarkierung, Text - diff --git a/grammar2uml/src/test/resources/Example.relast b/grammar2uml/src/test/resources/Example.relast deleted file mode 100644 index 0eb3846f541bdf720d7adf3687defa446c8c30bd..0000000000000000000000000000000000000000 --- a/grammar2uml/src/test/resources/Example.relast +++ /dev/null @@ -1,37 +0,0 @@ -Root ::= Prüfmethode* Wert*; - -// Beispiel für Prüfmethode: ReLiAbweichung -Prüfmethode ::= Funktionsprinzip Zielobjekt*; -Zielobjekt; - -rel Prüfmethode.Funktionsprinzip* -> Funktionsprinzip; - -// Beispiel Funktionsprinzip: Berechnungen innerhalb von ReLi-Abweichung für ist_diff und ist_diff < max_diff -Funktionsprinzip ::= Dateneingangswert* Verarbeitungsschritt* Datenausgangswert*; - -abstract Datenquelle; -// Beispiel für Wert: FB_links, ist_diff, max_diff -Wert : Datenquelle ::= <Datentyp> <A> <B>; - -// Ein Wert, der bei "Dateneingang" steht, z.B. für ReLi: max_Diff oder FB,links -// Beispiel für Dateneingangswert: Zuordnung, aus welcher Quelle der Wert ausgelesen werden soll -Dateneingangswert ::= [Quelle]; -rel Dateneingangswert.Wert -> Wert; - -// Beispiel für Verarbeitungsschritt: ist_Diff = ..., oder ist_diff < max_diff -Verarbeitungsschritt : Datenquelle ::= <Berechnungsvorschrift>; -rel Verarbeitungsschritt.EingabeWert* -> Wert; - -// Ein Wert, der bei "Datenausgang" steht, z.B. für ReLi $ist_{Diff,Achse n}$ -Datenausgangswert ::= DarstellungsElement; -rel Datenausgangswert.Wert -> Wert; - -// Beispiel für Quelle: Rollenbremsprüfstand -Quelle; - -abstract DarstellungsElement ; -Dezimalwert : DarstellungsElement; -Auffälligkeitsmarkierung : DarstellungsElement; -Text : DarstellungsElement; - -rel Auffälligkeitsmarkierung.Element <-> DarstellungsElement.Auffälligkeitsmarkierung; diff --git a/grammar2uml/src/test/resources/log4j2.xml b/grammar2uml/src/test/resources/log4j2.xml deleted file mode 100644 index 98cfd73c75df58d8598521bc10b043e214ec4ad8..0000000000000000000000000000000000000000 --- a/grammar2uml/src/test/resources/log4j2.xml +++ /dev/null @@ -1,13 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<Configuration status="INFO"> - <Appenders> - <Console name="Console" target="SYSTEM_OUT"> - <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/> - </Console> - </Appenders> - <Loggers> - <Root level="info"> - <AppenderRef ref="Console"/> - </Root> - </Loggers> -</Configuration> \ No newline at end of file diff --git a/pages/.gitignore b/pages/.gitignore index 87174b686c0670d3fb6a66535729af2a8a249d72..14338f39f89e2a45e3473a6597e640aa9458f9a8 100644 --- a/pages/.gitignore +++ b/pages/.gitignore @@ -1 +1,2 @@ -/public/ +/docs/ragdoc/ +__pycache__ diff --git a/pages/Makefile b/pages/Makefile deleted file mode 100644 index 7878ee5305af7d6c04860113aa9ef008991d07af..0000000000000000000000000000000000000000 --- a/pages/Makefile +++ /dev/null @@ -1,20 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line, and also -# from the environment for the first two. -SPHINXOPTS ?= -SPHINXBUILD ?= sphinx-build -SOURCEDIR = . -BUILDDIR = public - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) diff --git a/pages/_static/grammar2uml.png b/pages/_static/grammar2uml.png deleted file mode 100644 index f7002d330f635abc5be675fdd32d8d9421dd97cd..0000000000000000000000000000000000000000 Binary files a/pages/_static/grammar2uml.png and /dev/null differ diff --git a/pages/_static/minimal-example.png b/pages/_static/minimal-example.png deleted file mode 100644 index 6582a4eda68b936051b45991d04a3bba58963c5e..0000000000000000000000000000000000000000 Binary files a/pages/_static/minimal-example.png and /dev/null differ diff --git a/pages/conf.py b/pages/conf.py deleted file mode 100644 index 7483de1d681697c751dc1d215aa6dc35a7177d83..0000000000000000000000000000000000000000 --- a/pages/conf.py +++ /dev/null @@ -1,59 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a full -# list see the documentation: -# https://www.sphinx-doc.org/en/master/usage/configuration.html - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) -import sphinx_rtd_theme - - -# -- Project information ----------------------------------------------------- - -project = 'Relast2Uml' -copyright = '2021, René Schöne' -author = 'René Schöne' - - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'sphinx_rtd_theme', - 'recommonmark', - 'sphinxemoji.sphinxemoji', - 'sphinx_markdown_tables' -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ['public', 'Thumbs.db', '.DS_Store'] - - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = 'sphinx_rtd_theme' - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -sphinxemoji_style = 'twemoji' diff --git a/pages/custom_theme/footer.html b/pages/custom_theme/footer.html new file mode 100644 index 0000000000000000000000000000000000000000..2d6c164695b3a1ed19711d3497caf142a8416ebb --- /dev/null +++ b/pages/custom_theme/footer.html @@ -0,0 +1,11 @@ +{% block footer %} +<p>{% if config.copyright %} +<small>{{ config.copyright }}<br></small> +{% endif %} +<hr> +Built with <a href="https://www.mkdocs.org/">MkDocs</a> using a <a href="https://github.com/snide/sphinx_rtd_theme">theme</a> provided by <a href="https://readthedocs.org">Read the Docs</a>. +{% if page and page.meta and page.meta.git_revision_date_localized %} +<small><br><i>Last updated {{ page.meta.git_revision_date_localized }}</i></small> +{% endif %} +</p> +{% endblock %} diff --git a/pages/adding.md b/pages/docs/adding.md similarity index 73% rename from pages/adding.md rename to pages/docs/adding.md index ef101c862dc944f9ff73184071d53cb99fb0888a..2822997b946d501554f3644f016452e95a1ee0a7 100644 --- a/pages/adding.md +++ b/pages/docs/adding.md @@ -66,36 +66,22 @@ If you want to build the tools of `Relast2Uml` from source, first build the jar git clone https://git-st.inf.tu-dresden.de/jastadd/relast2uml.git cd relast2uml ./gradlew jar -ls grammar2uml/build/libs/ dumpAst/build/libs/ dumpAstWithPlantuml/build/libs/ +ls dumpAst/build/libs/ dumpAstWithPlantuml/build/libs/ ``` -Those JARs can then be copied to your project, e.g. for grammar2uml. +Those JARs can then be copied to your project. ```bash -cp grammar2uml/build/libs/grammar2uml-<version>.jar ../your-project/libs/grammar2uml.jar +cp dumpAst/build/libs/dumpAst-<version>.jar ../your-project/libs/dumpAst.jar cd ../your-project/ ``` -Finally, this JAR has to be integrated into your build process. In case, [Gradle](https://gradle.org/) is used, the JAR file needs to be added as dependency using: +Finally, this JAR has to be integrated into your build process. In case [Gradle](https://gradle.org/) is used, the JAR file needs to be added as dependency using: ```groovy dependencies { - implementation fileTree(include: ['grammar2uml.jar'], dir: 'libs') implementation fileTree(include: ['dumpAst.jar'], dir: 'libs') } ``` The path to the JAR file may need to be changed according to your project structure. -In case of `grammar2uml` a task needs to be created, similar to the one defined [above](#grammar2uml). - -```groovy -task grammar2uml(type: JavaExec) { - main = '-jar' - - args([ - '../libs/grammar2uml.jar', - '--verbose', - 'src/main/jastadd/GoalModel.relast' - ]) -} -``` diff --git a/pages/dumpAst.md b/pages/docs/dumpAst.md similarity index 99% rename from pages/dumpAst.md rename to pages/docs/dumpAst.md index 06eaaced0a2b639466a26eb8b39ce0a308dd6f09..5b23549bcabfa62a26ef097cac6ed95f0f3ef3fd 100644 --- a/pages/dumpAst.md +++ b/pages/docs/dumpAst.md @@ -2,7 +2,7 @@ The tool called `DumpAst` ([see in repo](https://git-st.inf.tu-dresden.de/jastadd/relast2uml/-/tree/master/dumpAst)) is used to create a snapshot of an AST and visualize it. - + It has to be used within your application code, and comes with a fluent interface to add and/or filter parts of the AST. First, import the entry point class `Dumper` diff --git a/pages/_static/dumpAst.png b/pages/docs/img/dumpAst.png similarity index 100% rename from pages/_static/dumpAst.png rename to pages/docs/img/dumpAst.png diff --git a/pages/grammar2uml.md b/pages/grammar2uml.md deleted file mode 100644 index bd261d30575ca4e07ea89943226a7fc3abaa04a7..0000000000000000000000000000000000000000 --- a/pages/grammar2uml.md +++ /dev/null @@ -1,31 +0,0 @@ -# Grammar2Uml - -The tool called `Grammar2Uml` ([see in repo](https://git-st.inf.tu-dresden.de/jastadd/relast2uml/-/tree/master/grammar2uml)) takes a set of grammar specifications and creates a visualization similar to UML class diagrams. - - - - -Every nonterminal will be shown as a rectangular box with its terminal children listed within it. Children are shown as containment relations between parent and child, whereas relations and intrinsic references are shown using arrows. - -Furthermore, some options may be specified. - -| Name | Required (Default) | Description | -|----------------------|--------------------|-------------------------------------------------------------------------| -| `--output` | No (`uml.md`) | target file to be generated. | -| `--inputGrammar2Uml` | No | grammar2uml definition file, see [below](#grammar2uml-definition-file). | -| `--defaultFolders` | No (`false`) | Creates a default folder per grammar file. | -| `--help` | No | Print usage and exit. | -| `--version` | No | Print version and exit. | -| `--verbose` | No | Print more messages while compiling. | - -## Grammar2uml definition file - -To structure the generated visualization, any number of nonterminals can be grouped with folders. -Either specify the option `--defaultFolders` to use one folder per input grammar file, or specify a grammar2uml definition file. -The definition file has a simple syntax, it is a list of folder specifications. One specifications looks like - -``` -folder FOLDER_NAME : NT1, NT2, ..., NT_n -``` - -It produces one folder named `FOLDER_NAME` containing all nonterminals (`NT1`, `NT2`, ..., `NT_n`) following it. diff --git a/pages/index.rst b/pages/index.rst deleted file mode 100644 index 7497cb04536e3ebe867a5c22d9337653fc0bc5e5..0000000000000000000000000000000000000000 --- a/pages/index.rst +++ /dev/null @@ -1,25 +0,0 @@ -.. Relast2Uml documentation master file, created by - sphinx-quickstart on Thu Jan 14 17:56:50 2021. - You can adapt this file completely to your liking, but it should at least - contain the root `toctree` directive. - -Relast2Uml Documentation -======================== - -`Relast2Uml <https://git-st.inf.tu-dresden.de/jastadd/relast2uml>`_ is a collection of tools to visualize specifications and programs using models based on `Reference Attribute Grammars <http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.108.8792&rep=rep1&type=pdf>`_ and `Relation Reference Attribute Grammars <https://doi.org/10.1016/j.cola.2019.100940>`_ built with `JastAdd <http://jastadd.org/>`_. - -.. toctree:: - :maxdepth: 2 - :caption: Contents: - - dumpAst.md - grammar2uml.md - adding.md - - - -Indices and tables -================== - -* :ref:`genindex` -* :ref:`search` diff --git a/pages/main.py b/pages/main.py new file mode 100644 index 0000000000000000000000000000000000000000..d10da843c522e18f0c8d40a9b5672b7ec2094a22 --- /dev/null +++ b/pages/main.py @@ -0,0 +1,29 @@ +import os + +dumpAstVersionFileName = '../dumpAst/src/main/resources/dumpAstVersion.properties' + + +def get_version(): + if os.environ.get('CI_COMMIT_BRANCH', 'unknown') == 'dev': + return 'dev' + with open(dumpAstVersionFileName) as dumpAstVersionFile: + versionFileContent = dumpAstVersionFile.read() + return versionFileContent[versionFileContent.rindex('version=') + 8:].strip() + + +def define_env(env): + """ + This is the hook for defining variables, macros and filters + + - variables: the dictionary that contains the environment variables + - macro: a decorator function, to declare a macro. + """ + env.conf['site_name'] = 'dumpAst ' + get_version() + + @env.macro + def dumpAst_version(): + return get_version() + + +if __name__ == '__main__': + print(get_version()) diff --git a/pages/make.bat b/pages/make.bat deleted file mode 100644 index 922152e96a04a242e6fc40f124261d74890617d8..0000000000000000000000000000000000000000 --- a/pages/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=. -set BUILDDIR=_build - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O% - -:end -popd diff --git a/pages/mkdocs.yml b/pages/mkdocs.yml new file mode 100644 index 0000000000000000000000000000000000000000..86bada7ed5d5f3762b08bab9667c48e4f5b34e24 --- /dev/null +++ b/pages/mkdocs.yml @@ -0,0 +1,26 @@ +site_name: DumpAst +repo_url: https://git-st.inf.tu-dresden.de/jastadd/relast2uml +site_dir: ../public + +nav: + - "DumpAst": dumpAst.md + - "Add to your project": adding.md + - "API documentation": ragdoc/index.html + +theme: + name: readthedocs + custom_dir: custom_theme/ + +markdown_extensions: + - toc: + permalink: + - admonition + +plugins: + - search + - git-revision-date-localized: + type: datetime + timezone: Europe/Berlin + locale: en + fallback_to_build_date: True + - macros diff --git a/pages/requirements.txt b/pages/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..a5b1bbf825def6db5490bd6d87103c08357d879d --- /dev/null +++ b/pages/requirements.txt @@ -0,0 +1,3 @@ +mkdocs==1.2.2 +mkdocs-git-revision-date-localized-plugin==0.10.3 +mkdocs-macros-plugin==0.6.3 diff --git a/settings.gradle b/settings.gradle index ddebe309588e3be93657248ddae60011ca7767a9..631fcc974ebb903bd09ad6b13cd6dd5fbd875f3d 100644 --- a/settings.gradle +++ b/settings.gradle @@ -1,7 +1,6 @@ rootProject.name = 'relast2uml' include 'relast.preprocessor' -include 'grammar2uml' include 'dumpAst' include 'dumpAstWithPlantuml' include 'testDumper' diff --git a/testDumper/src/main/jastadd/testDumper.jrag b/testDumper/src/main/jastadd/testDumper.jrag index a0ef867b1fe9da0ef2b7f5c91cb9cfc9877800ea..4cedce8cfa75749d2fb90adcb0ef5766e36e0ca1 100644 --- a/testDumper/src/main/jastadd/testDumper.jrag +++ b/testDumper/src/main/jastadd/testDumper.jrag @@ -29,6 +29,9 @@ aspect GrammarGlobal { syn int Root.simpleAttr() = 42; syn A Root.referenceAttr() = getA(); + + syn boolean ASTNode.isA() = false; + eq A.isA() = true; } aspect GrammarTypeLevel { diff --git a/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestDumperMain.java b/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestDumperMain.java index fc3d4c80558d64cf5dc882522e8afd11db04258a..d7b14047c0b144339dead510f89f8ea510e60464 100644 --- a/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestDumperMain.java +++ b/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestDumperMain.java @@ -1,10 +1,14 @@ package de.tudresden.inf.st.jastadd.testDumper; +import de.tudresden.inf.st.jastadd.dumpAst.ast.DumpAst; +import de.tudresden.inf.st.jastadd.dumpAst.ast.DumpNode; import org.jastadd.testDumper.ast.A; import org.jastadd.testDumper.ast.B; import org.jastadd.testDumper.ast.C; import org.jastadd.testDumper.ast.Root; +import java.util.stream.Collectors; + public class TestDumperMain { public static void main(String[] args) { Root root = new Root(); @@ -29,13 +33,20 @@ public class TestDumperMain { TestUtils.ExposingDumpBuilder builder = new TestUtils.ExposingDumpBuilder(root); builder.includeAttributes("simpleAttr") - .includeNonterminalAttributes("getCalculated"); + .orderChildren() + .includeNonterminalAttributes("getCalculated") + .setNameMethod(n -> n == null ? "null" : n.getClass().getSimpleName()); System.out.println(">> PlantUml"); - System.out.println(builder.build().toPlantUml()); + DumpAst dumpAst = builder.build(); + System.out.println(dumpAst.toPlantUml()); + + DumpNode node = dumpAst.getDumpNode(0); + System.out.println(node.getName()); + System.out.println(node.myChildren().stream().map(DumpNode::getName).collect(Collectors.joining(", "))); - System.out.println(">> YAML begin"); - System.out.println(builder.build().toYaml(true)); - System.out.println(">> YAML end"); +// System.out.println(">> YAML begin"); +// System.out.println(builder.build().toYaml(true)); +// System.out.println(">> YAML end"); } } diff --git a/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestSimple.java b/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestSimple.java index 507250f1e1dc2b74c794f8b1980a550d105913d5..1ccba6cc518d0ec487b937f0efd81068013ba2af 100644 --- a/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestSimple.java +++ b/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestSimple.java @@ -1,10 +1,9 @@ package de.tudresden.inf.st.jastadd.testDumper; +import de.tudresden.inf.st.jastadd.dumpAst.ast.DumpAst; +import de.tudresden.inf.st.jastadd.dumpAst.ast.DumpBuilder; import de.tudresden.inf.st.jastadd.dumpAst.ast.DumpNode; -import org.jastadd.testDumper.ast.C; -import org.jastadd.testDumper.ast.D; -import org.jastadd.testDumper.ast.Root; -import org.jastadd.testDumper.ast.SubC; +import org.jastadd.testDumper.ast.*; import org.junit.jupiter.api.Test; import java.util.List; @@ -32,9 +31,9 @@ public class TestSimple { @Test void testChildlessNonterminal() { Root root = createRoot(createA(A_NAME, a -> a.setD(new D())), null); List<DumpNode> nodes = TestUtils.dumpModel(root); - Optional<DumpNode> optionalCDumpNode = nodes.stream().filter(n -> n.getObject() instanceof D).findFirst(); - assertTrue(optionalCDumpNode.isPresent()); - assertTrue(optionalCDumpNode.get().isAstNode()); + Optional<DumpNode> actualD = nodes.stream().filter(n -> n.getObject() instanceof D).findFirst(); + assertTrue(actualD.isPresent()); + assertTrue(actualD.get().isAstNode()); } @Test @@ -50,6 +49,22 @@ public class TestSimple { assertThatMapOf(normalChildren(actualRoot)).containsExactlyInAnyOrder(tuple("A", A_NAME)); } + @Test + public void testOneNormalChildIncludeNullNodes() { + Root root = createRoot(createA(A_NAME), null); + + List<DumpNode> nodes = TestUtils.dumpModel(root, DumpBuilder::includeNullNodes); + assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactlyInAnyOrder( + ROOT_NAME, A_NAME, null, null, null, null); + DumpNode actualRoot = TestUtils.findByName(nodes, ROOT_NAME); + assertEquals(1, actualRoot.getNumDumpToken()); + assertEquals(2, actualRoot.getNumDumpChildNode()); + assertEquals(0, actualRoot.getNumDumpRelation()); + + DumpNode actualA = TestUtils.findByName(nodes, A_NAME); + assertEquals(3, actualA.getNumDumpChildNode()); + } + @Test public void testListChildren() { Root root = createRoot(null, null, createB(B1_NAME), createB(B2_NAME), createB(B3_NAME)); @@ -63,6 +78,22 @@ public class TestSimple { assertThatMapOf(listChildren(actualRoot), "B").containsExactlyInAnyOrder(B1_NAME, B2_NAME, B3_NAME); } + @Test + public void testOrderedListChildren() { + Root root = createRoot(null, null, createB(B1_NAME), createB(B2_NAME), createB(B3_NAME)); + + List<DumpNode> nodes = TestUtils.dumpModel(root, DumpBuilder::orderChildren); + assertThat(nodes).flatExtracting(NAME_EXTRACTOR).containsExactlyInAnyOrder(ROOT_NAME, B1_NAME, B2_NAME, B3_NAME); + + DumpNode actualRoot = TestUtils.findByName(nodes, ROOT_NAME); + // in grammar: DumpAst ::= [...] DumpNode* [...]; + // use getParent() twice as first returns JastAddList for DumpNode list + assertTrue(((DumpAst) actualRoot.getParent().getParent()).getPrintConfig().getOrderChildren()); + + List<DumpNode> children = actualRoot.myChildren(); + assertThat(children).extracting(NAME_EXTRACTOR).containsExactlyInAnyOrder(B1_NAME, B2_NAME, B3_NAME); + } + @Test public void testOneOptChild() { Root root = createRoot(null, createC(C_NAME)); @@ -183,4 +214,43 @@ public class TestSimple { entry(TOKEN_LABEL_UNWANTED, 5)); } + @Test + public void testLabel() { + Root root = createRoot(createA(A_NAME), null); + + List<DumpNode> nodes = TestUtils.dumpModel(root, + builder -> builder.<ASTNode<?>>setNameMethod(n -> n.isA() ? "A" : "Not A")); + DumpNode actualRoot = TestUtils.findByName(nodes, ROOT_NAME); + assertEquals("Not A", actualRoot.getLabel()); + + DumpNode actualA = TestUtils.findByName(nodes, A_NAME); + assertEquals("A", actualA.getLabel()); + } + + @Test + public void testTextColor() { + Root root = createRoot(createA(A_NAME), null); + + List<DumpNode> nodes = TestUtils.dumpModel(root, + builder -> builder.<ASTNode<?>>setTextColorMethod(n -> n.isA() ? "red" : "")); + DumpNode actualRoot = TestUtils.findByName(nodes, ROOT_NAME); + assertEquals("", actualRoot.getTextColor()); + + DumpNode actualA = TestUtils.findByName(nodes, A_NAME); + assertEquals("red", actualA.getTextColor()); + } + + @Test + public void testBackgroundColor() { + Root root = createRoot(createA(A_NAME), null); + + List<DumpNode> nodes = TestUtils.dumpModel(root, + builder -> builder.<ASTNode<?>>setBackgroundColorMethod(n -> n.isA() ? "green" : "")); + DumpNode actualRoot = TestUtils.findByName(nodes, ROOT_NAME); + assertEquals("", actualRoot.getBackgroundColor()); + + DumpNode actualA = TestUtils.findByName(nodes, A_NAME); + assertEquals("green", actualA.getBackgroundColor()); + } + } diff --git a/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestUtils.java b/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestUtils.java index dafc29d8b58b71679d806ed3e70db467b10a9de5..10a0859b6dec99ff2b7797c0ea382c774722bdfd 100644 --- a/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestUtils.java +++ b/testDumper/src/test/java/de/tudresden/inf/st/jastadd/testDumper/TestUtils.java @@ -156,6 +156,7 @@ public class TestUtils { public static List<DumpNode> dumpModel(Object target, Consumer<DumpBuilder> options) { ExposingDumpBuilder builder = new ExposingDumpBuilder(target); + builder.excludeNullNodes(); options.accept(builder); DumpAst dumpAst = builder.build(); // let mustache run, but ignore result