Skip to content

Commit bfb21ec

Browse files
committed
Move ModulesInfoCreator to docs module
1 parent b016096 commit bfb21ec

File tree

6 files changed

+180
-162
lines changed

6 files changed

+180
-162
lines changed

docs/build.gradle

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,21 @@
1+
plugins {
2+
id 'java'
3+
}
4+
5+
group = 'com.annimon'
6+
version = '2.0-SNAPSHOT'
7+
8+
dependencies {
9+
implementation project(":ownlang-core")
10+
implementation project(":ownlang-parser")
11+
implementation project(":ownlang-utils")
12+
implementation project(":modules:main")
13+
implementation project(":modules:canvasfx")
14+
implementation project(":modules:server")
15+
16+
implementation "org.yaml:snakeyaml:${versions.snakeyaml}"
17+
}
18+
119
tasks.register('generateMarkdownModules') {
220
group = "documentation"
321
def ownlangExec = tasks.getByPath(':ownlang-desktop:ownlangExec')
@@ -8,4 +26,13 @@ tasks.register('generateMarkdownModules') {
826
}
927
}
1028
finalizedBy ownlangExec
29+
}
30+
31+
tasks.register('generateModuleInfo', JavaExec) {
32+
group = "documentation"
33+
description = "Run sample program"
34+
dependsOn classes
35+
mainClass = 'com.annimon.ownlang.docs.ModulesInfoCreator'
36+
classpath = sourceSets.main.runtimeClasspath
37+
args 'server', 'okhttp'
1138
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
package com.annimon.ownlang.docs;
2+
3+
import com.annimon.ownlang.Version;
4+
import com.annimon.ownlang.lib.MapValue;
5+
import com.annimon.ownlang.lib.Types;
6+
import com.annimon.ownlang.lib.Value;
7+
import java.util.*;
8+
import java.util.stream.Collectors;
9+
10+
public class ModuleInfo {
11+
private final String name;
12+
final List<String> functions;
13+
final Map<String, Value> constants;
14+
final List<String> types;
15+
16+
public ModuleInfo(String name) {
17+
this.name = name;
18+
functions = new ArrayList<>();
19+
constants = new HashMap<>();
20+
types = new ArrayList<>();
21+
}
22+
23+
public List<Map<String, Object>> functions() {
24+
return functions.stream().sorted()
25+
.map(f -> {
26+
final Map<String, Object> function = new LinkedHashMap<>();
27+
function.put("name", f);
28+
function.put("args", "");
29+
function.put("desc", "");
30+
function.put("desc_ru", "");
31+
return function;
32+
})
33+
.collect(Collectors.toList());
34+
}
35+
36+
public List<Map<String, Object>> constants() {
37+
final List<Map<String, Object>> result = new ArrayList<>();
38+
constants.entrySet().stream()
39+
.sorted(Map.Entry.comparingByKey())
40+
.forEach(entry -> {
41+
final Value value = entry.getValue();
42+
43+
final Map<String, Object> constant = new LinkedHashMap<>();
44+
constant.put("name", entry.getKey());
45+
constant.put("type", value.type());
46+
constant.put("typeName", Types.typeToString(value.type()));
47+
if (value.type() == Types.MAP) {
48+
String text = ((MapValue) value).getMap().entrySet().stream()
49+
.sorted(Comparator.comparing(
50+
e -> ((MapValue) value).size() > 16 ? e.getKey() : e.getValue()))
51+
.map(Object::toString)
52+
.collect(Collectors.joining(", ", "{", "}"));
53+
constant.put("value", text);
54+
} else {
55+
constant.put("value", value.asString());
56+
}
57+
result.add(constant);
58+
});
59+
return result;
60+
}
61+
62+
public Map<String, Object> info() {
63+
final Map<String, Object> result = new LinkedHashMap<>();
64+
result.put("name", name);
65+
result.put("scope", "both");
66+
result.put("since", "%d.%d.%d".formatted(Version.VERSION_MAJOR, Version.VERSION_MINOR, Version.VERSION_PATCH));
67+
result.put("constants", constants());
68+
result.put("functions", functions());
69+
if (!types.isEmpty()) {
70+
result.put("types", types.stream().sorted()
71+
.map(s -> {
72+
final Map<String, String> type = new HashMap<>();
73+
type.put("name", s);
74+
return type;
75+
})
76+
.toArray());
77+
}
78+
return result;
79+
}
80+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
package com.annimon.ownlang.docs;
2+
3+
import com.annimon.ownlang.lib.ModuleLoader;
4+
import com.annimon.ownlang.lib.Value;
5+
import com.annimon.ownlang.modules.Module;
6+
import org.yaml.snakeyaml.DumperOptions;
7+
import org.yaml.snakeyaml.Yaml;
8+
import java.util.*;
9+
import java.util.stream.Collectors;
10+
import java.util.stream.Stream;
11+
12+
public final class ModulesInfoCreator {
13+
14+
public static void main(String[] args) {
15+
if (args.length == 0) {
16+
System.err.println("No modules provided.\nUsage: ModulesInfoCreator <module1> <module2> ...");
17+
System.exit(1);
18+
}
19+
20+
final Class<Module> clazz = Module.class; // get classloader for package
21+
22+
final List<ModuleInfo> moduleInfos = new ArrayList<>();
23+
24+
for (String moduleName : args) {
25+
final Module module = ModuleLoader.load(moduleName);
26+
27+
final ModuleInfo moduleInfo = new ModuleInfo(moduleName);
28+
moduleInfo.functions.addAll(module.functions().keySet());
29+
moduleInfo.constants.putAll(module.constants());
30+
moduleInfo.types.addAll(listValues(module.getClass()));
31+
moduleInfos.add(moduleInfo);
32+
}
33+
34+
printAsYaml(moduleInfos);
35+
36+
System.out.println("Total functions: " + moduleInfos.stream()
37+
.mapToLong(m -> m.functions.size())
38+
.sum()
39+
);
40+
System.out.println("Total constants: " + moduleInfos.stream()
41+
.mapToLong(m -> m.constants.keySet().size())
42+
.sum()
43+
);
44+
}
45+
46+
private static void printAsYaml(List<ModuleInfo> moduleInfos) {
47+
DumperOptions options = new DumperOptions();
48+
options.setIndent(2);
49+
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
50+
51+
final List<Map<String, Object>> infos = new ArrayList<>();
52+
for (ModuleInfo moduleInfo : moduleInfos) {
53+
infos.add(moduleInfo.info());
54+
}
55+
System.out.println(new Yaml(options).dump(infos));
56+
}
57+
58+
private static List<String> listValues(Class<?> moduleClass) {
59+
return Arrays.stream(moduleClass.getDeclaredClasses())
60+
.filter(clazz -> getAllInterfaces(clazz).stream().anyMatch(i -> i.equals(Value.class)))
61+
.map(Class::getSimpleName)
62+
.collect(Collectors.toList());
63+
}
64+
65+
private static Set<Class<?>> getAllInterfaces(Class<?> clazz) {
66+
if (clazz.getSuperclass() == null) {
67+
return Collections.emptySet();
68+
}
69+
return Stream.concat(Arrays.stream(clazz.getInterfaces()), getAllInterfaces(clazz.getSuperclass()).stream())
70+
.collect(Collectors.toSet());
71+
}
72+
73+
}

ownlang-utils/build.gradle

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ version = '2.0-SNAPSHOT'
77

88
dependencies {
99
api project(":ownlang-parser")
10-
implementation "org.json:json:${versions.json}"
11-
implementation "org.yaml:snakeyaml:${versions.snakeyaml}"
1210
implementation "jline:jline:${versions.jline}"
1311

1412
testImplementation platform("org.junit:junit-bom:${versions.junit}")

ownlang-utils/src/main/java/com/annimon/ownlang/utils/ModulesInfoCreator.java

Lines changed: 0 additions & 159 deletions
This file was deleted.

ownlang-utils/src/main/java/com/annimon/ownlang/utils/Sandbox.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99
import com.annimon.ownlang.parser.SourceLoader;
1010
import com.annimon.ownlang.parser.Token;
1111
import com.annimon.ownlang.parser.ast.Node;
12-
import com.annimon.ownlang.parser.ast.Statement;
1312
import com.annimon.ownlang.parser.visitors.FunctionAdder;
1413
import java.io.File;
1514
import java.io.IOException;

0 commit comments

Comments
 (0)