Skip to content

Commit

Permalink
Merge pull request #9 from Tapeline/master
Browse files Browse the repository at this point in the history
Quail v2.0-RC-4
  • Loading branch information
Quail-Language authored Feb 26, 2024
2 parents e8fb914 + 591ae91 commit da8aaf4
Show file tree
Hide file tree
Showing 113 changed files with 5,548 additions and 79 deletions.
8 changes: 8 additions & 0 deletions .idea/artifacts/quailTestAddon.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .idea/compiler.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions .idea/encodings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,9 @@ public class GlobalFlags {

public static short debugPort = 4004;

/**
* Specifies list of addons that should be loaded
*/
public static String addons = "";

}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import me.tapeline.quailj.typing.classes.QObject;

// TODO fix error display
// TODO fix in operator and add contains method to list

public class Main {

public static void main(String[] args) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package me.tapeline.quailj.addons;

public class AddonAlreadyRegisteredException extends Exception {

protected QuailAddon addon;

public AddonAlreadyRegisteredException(QuailAddon addon) {
super("Addon " + addon + " already registered");
this.addon = addon;
}

public QuailAddon getAddon() {
return addon;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package me.tapeline.quailj.addons;

import java.io.File;

public class AddonLoadException extends Exception {

protected File file;

public AddonLoadException(String message, File file) {
super(message + "\nFile: " + file);
this.file = file;
}

public AddonLoadException(Throwable cause, File file) {
super("Cannot load addon " + file + " due to " + cause, cause);
this.file = file;
}

public File getFile() {
return file;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package me.tapeline.quailj.addons;

public class AddonNotRegisteredException extends Exception {

protected String addon;

public AddonNotRegisteredException(String addon) {
super("Addon " + addon + " is not registered");
this.addon = addon;
}

public String getAddon() {
return addon;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package me.tapeline.quailj.addons;

import me.tapeline.quailj.parsing.annotation.Annotation;
import me.tapeline.quailj.preprocessing.directives.AbstractDirective;
import me.tapeline.quailj.runtime.Runtime;
import me.tapeline.quailj.runtime.librarymanagement.BuiltinLibrary;

import java.util.List;

public abstract class QuailAddon {

public abstract String getName();
public abstract List<AbstractDirective> providedDirectives();
public abstract List<Annotation> providedAnnotations();
public abstract List<BuiltinLibrary> providedLibraries();
public void customizeRuntime(Runtime runtime) {}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
package me.tapeline.quailj.addons;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Enumeration;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

public class QuailAddonLoader {

public static QuailAddon loadAddonFromJar(File file) throws
UnresolvedAddonMainClassException, AddonLoadException {
JarFile jarFile;
try {
jarFile = new JarFile(file);
} catch (IOException e) {
throw new AddonLoadException(e, file);
}
Enumeration<JarEntry> e = jarFile.entries();
String mainClass = null;
while (e.hasMoreElements()) {
JarEntry entry = e.nextElement();
if (entry.getName().equals("addonMainClass")) {
BufferedReader reader;
try {
reader = new BufferedReader(new InputStreamReader(jarFile.getInputStream(entry)));
} catch (IOException ex) {
throw new AddonLoadException(ex, file);
}
try {
String line = reader.readLine();
if (line == null) throw new UnresolvedAddonMainClassException(file);
mainClass = line.trim();
break;
} catch (IOException exception) {
throw new UnresolvedAddonMainClassException(file);
}
}
}

URL[] urls;
try {
urls = new URL[]{ new URL("jar:file:" + file + "!/") };
} catch (MalformedURLException ex) {
throw new AddonLoadException(ex, file);
}
URLClassLoader cl = URLClassLoader.newInstance(urls);

while (e.hasMoreElements()) {
JarEntry je = e.nextElement();
if(je.isDirectory() || !je.getName().endsWith(".class")) {
continue;
}
// -6 because of .class
String className = je.getName().substring(0, je.getName().length() - 6);
className = className.replace('/', '.');
try {
Class<?> c = cl.loadClass(className);
if (className.equals(mainClass)) {
return (QuailAddon) c.newInstance();
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException exception) {
throw new AddonLoadException(exception, file);
}
}

throw new UnresolvedAddonMainClassException(file);
}

public static QuailAddon loadAndRegisterFromJar(File file) throws UnresolvedAddonMainClassException,
AddonLoadException, AddonAlreadyRegisteredException {
QuailAddon addon = loadAddonFromJar(file);
QuailAddonRegistry.registerAddon(addon);
return addon;
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package me.tapeline.quailj.addons;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

public class QuailAddonRegistry {

protected static HashMap<String, QuailAddon> registeredAddons = new HashMap<>();

public static void registerAddon(QuailAddon addon) throws AddonAlreadyRegisteredException {
if (registeredAddons.containsKey(addon.getName()))
throw new AddonAlreadyRegisteredException(addon);
registeredAddons.put(addon.getName(), addon);
}

public static QuailAddon getAddonByName(String name) {
return registeredAddons.get(name);
}

public static List<QuailAddon> getAddons() {
return new ArrayList<>(registeredAddons.values());
}

public static void unregisterAddon(String name) throws AddonNotRegisteredException {
if (!registeredAddons.containsKey(name))
throw new AddonNotRegisteredException(name);
registeredAddons.remove(name);
}

public static boolean addonRegistered(String name) {
return registeredAddons.containsKey(name);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package me.tapeline.quailj.addons;

import java.io.File;

public class UnresolvedAddonMainClassException extends Exception {

protected File file;

public UnresolvedAddonMainClassException(File file) {
super("Cannot resolve main class in addon " + file);
this.file = file;
}

public File getFile() {
return file;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@

public class DocumentationGenerator {

private HashMap<String, Object> flags = new HashMap<>();

public DocumentationGenerator() {}

public DocumentationGenerator(HashMap<String, Object> flags) {
this.flags = flags;
}

private static final HashMap<String, String> colorAssociations = Dict.make(
new Pair<>("default", "primary"),
new Pair<>("red", "danger"),
Expand Down Expand Up @@ -117,10 +125,20 @@ private List<Node> convertToList(Node node) {
return Collections.singletonList(node);
}

private String convertSeeLink(String link) {
if (link.startsWith(">")) {
link = link.substring(link.indexOf('>') + 1).replaceAll("\\.q", "");
if (flags.containsKey("seeLinkPrefix"))
link = flags.get("seeLinkPrefix") + link;
}
return link;
}

public String compileAllDocNodes(List<Node> nodes) {
List<String> docStrings = new ArrayList<>();
List<DocBadgeNode> docBadges = new ArrayList<>();
List<String> authors = new ArrayList<>();
List<String> seeLinks = new ArrayList<>();
String since = null;
for (Node node : nodes) {
if (node instanceof DocSinceNode)
Expand All @@ -133,6 +151,8 @@ else if (node instanceof DocBadgeNode)
docBadges.add(((DocBadgeNode) node));
else if (node instanceof DocTOCNode)
tocEntries.add(((DocTOCNode) node));
else if (node instanceof DocSeeNode)
seeLinks.add(((DocSeeNode) node).see);
}
StringBuilder sb = new StringBuilder();
if (!docBadges.isEmpty()) {
Expand All @@ -148,6 +168,16 @@ else if (node instanceof DocTOCNode)
sb.append(docString).append("<br>");
sb.append("</p>");
}
if (!seeLinks.isEmpty()) {
sb.append("<p>See:<br>");
for (String see : seeLinks)
sb.append("<a class=\"px-3\" href=\"")
.append(convertSeeLink(see))
.append("\">")
.append(convertSeeLink(see))
.append("</a>");
sb.append("</p>");
}
if (authors.size() == 1) {
sb.append("<p>Author: ").append(authors.get(0)).append("</p>");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
*/
public interface IO {

// TODO: rebase all new File() onto IO::file()

/**
* Sets the current encoding
* @param encoding new encoding
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,9 +70,15 @@ private void parseFlag(String flag) {
else {
String flagName = flag.substring(3, flag.indexOf('='));
if (flagName.equals("encoding"))
globalFlags.put("encoding", flag.substring(flag.indexOf('=' + 1)));
globalFlags.put("encoding", flag.substring(flag.indexOf('=') + 1));
if (flagName.equals("ignoreDocs"))
globalFlags.put("ignoreDocs", toBoolean(flag.substring(flag.indexOf('=' + 1))));
globalFlags.put("ignoreDocs", toBoolean(flag.substring(flag.indexOf('=') + 1)));
if (flagName.equals("debugPort"))
globalFlags.put("debugPort", Short.parseShort(flag.substring(flag.indexOf('=') + 1)));
if (flagName.equals("displayReturnValue"))
globalFlags.put("displayReturnValue", toBoolean(flag.substring(flag.indexOf('=') + 1)));
if (flagName.equals("addons"))
globalFlags.put("addons", flag.substring(flag.indexOf('=') + 1));
}
} else {
int assignPosition = 0;
Expand Down
Loading

0 comments on commit da8aaf4

Please sign in to comment.