Skip to content

Commit 80a26f7

Browse files
committed
Template type members.
1 parent e084895 commit 80a26f7

File tree

11 files changed

+163
-16
lines changed

11 files changed

+163
-16
lines changed

pom.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@
131131
<dependency>
132132
<groupId>mx.kenzie</groupId>
133133
<artifactId>mirror</artifactId>
134-
<version>5.0.1</version>
134+
<version>5.0.2</version>
135135
<scope>compile</scope>
136136
</dependency>
137137
<dependency>

src/main/java/org/byteskript/skript/compiler/AreaFlag.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
public enum AreaFlag implements Flag {
1212
IN_FUNCTION,
1313
IN_TYPE,
14+
IN_ABSTRACT_TYPE,
1415
IN_EVENT
1516

1617
}

src/main/java/org/byteskript/skript/compiler/SkriptLangSpec.java

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,7 @@
2525
import org.byteskript.skript.lang.syntax.control.DeleteEffect;
2626
import org.byteskript.skript.lang.syntax.control.RemoveEffect;
2727
import org.byteskript.skript.lang.syntax.control.SetEffect;
28-
import org.byteskript.skript.lang.syntax.entry.JavaRelay;
29-
import org.byteskript.skript.lang.syntax.entry.ReturnType;
30-
import org.byteskript.skript.lang.syntax.entry.Trigger;
31-
import org.byteskript.skript.lang.syntax.entry.Verify;
28+
import org.byteskript.skript.lang.syntax.entry.*;
3229
import org.byteskript.skript.lang.syntax.event.AnyLoadEvent;
3330
import org.byteskript.skript.lang.syntax.event.CurrentEventExpression;
3431
import org.byteskript.skript.lang.syntax.event.LoadEvent;
@@ -57,6 +54,7 @@
5754
import org.byteskript.skript.lang.syntax.map.MapCreator;
5855
import org.byteskript.skript.lang.syntax.maths.*;
5956
import org.byteskript.skript.lang.syntax.timing.*;
57+
import org.byteskript.skript.lang.syntax.type.TemplateTypeMember;
6058
import org.byteskript.skript.lang.syntax.type.ThisThingExpression;
6159
import org.byteskript.skript.lang.syntax.type.TypeCreator;
6260
import org.byteskript.skript.lang.syntax.type.TypeMember;
@@ -117,10 +115,11 @@ private SkriptLangSpec() {
117115
CommonTypes.FIELD
118116
);
119117
registerSyntax(CompileState.ROOT,
120-
// new InitClassMember(),
121118
new TypeMember(),
119+
new TemplateTypeMember(),
122120
new FunctionMember(),
123-
new NoArgsFunctionMember()
121+
new NoArgsFunctionMember(),
122+
new Template()
124123
);
125124
registerSyntax(CompileState.MEMBER_BODY,
126125
new Verify(),

src/main/java/org/byteskript/skript/lang/syntax/entry/ReturnType.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
public class ReturnType extends SimpleEntry {
1919

2020
public ReturnType() {
21-
super(SkriptLangSpec.LIBRARY, StandardElements.SECTION, "return: %Type%");
21+
super(SkriptLangSpec.LIBRARY, StandardElements.METADATA, "return: %Type%");
2222
}
2323

2424
@Override
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
/*
2+
* Copyright (c) 2021 ByteSkript org (Moderocky)
3+
* View the full licence information and permissions:
4+
* https://github.com/Moderocky/ByteSkript/blob/master/LICENSE
5+
*/
6+
7+
package org.byteskript.skript.lang.syntax.entry;
8+
9+
import mx.kenzie.foundation.Type;
10+
import mx.kenzie.foundation.compiler.State;
11+
import org.byteskript.skript.api.syntax.SimpleEntry;
12+
import org.byteskript.skript.compiler.*;
13+
import org.byteskript.skript.error.ScriptCompileError;
14+
import org.byteskript.skript.lang.element.StandardElements;
15+
16+
import java.util.regex.Matcher;
17+
18+
public class Template extends SimpleEntry {
19+
20+
public Template() {
21+
super(SkriptLangSpec.LIBRARY, StandardElements.METADATA, "template: %Type%");
22+
}
23+
24+
@Override
25+
public boolean allowAsInputFor(Type type) {
26+
return false;
27+
}
28+
29+
@Override
30+
public void compile(Context context, Pattern.Match match) {
31+
final String name = (String) match.meta();
32+
final Type type = context.getType(name);
33+
if (type != null) context.getBuilder().addInterfaces(type);
34+
else context.getBuilder().addInterfaces(new Type(name.replace('.', '/')));
35+
context.setState(CompileState.ROOT);
36+
}
37+
38+
@Override
39+
public Pattern.Match match(String thing, Context context) {
40+
if (!thing.startsWith("template: ")) return null;
41+
final Pattern.Match match = super.match(thing, context);
42+
if (match == null) return null;
43+
final String name = match.groups()[0].trim();
44+
if (name.contains("\""))
45+
throw new ScriptCompileError(context.lineNumber(), "Types should not be written inside quotation marks.");
46+
final String quote = java.util.regex.Pattern.quote(thing);
47+
final Matcher matcher = java.util.regex.Pattern.compile(quote).matcher(thing);
48+
matcher.find();
49+
return new Pattern.Match(matcher, name);
50+
}
51+
52+
@Override
53+
public boolean allowedIn(State state, Context context) {
54+
return context.getState() == CompileState.ROOT && context.hasFlag(AreaFlag.IN_TYPE);
55+
}
56+
57+
58+
}

src/main/java/org/byteskript/skript/lang/syntax/entry/Trigger.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,18 @@ public boolean allowAsInputFor(Type type) {
3030
return false;
3131
}
3232

33+
@Override
34+
public Pattern.Match match(String thing, Context context) {
35+
return super.match(thing, context);
36+
}
37+
3338
@Override
3439
public void compile(Context context, Pattern.Match match) {
3540
final TriggerTree tree = new TriggerTree(context.getSection(1), context.getVariables());
3641
context.createTree(tree);
3742
context.setState(CompileState.CODE_BODY);
3843
final MethodBuilder method = context.getMethod();
44+
method.removeModifiers(0x0400); // not abstract
3945
method.writeCode(prepareVariables(tree));
4046
}
4147

src/main/java/org/byteskript/skript/lang/syntax/function/FunctionMember.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,8 @@ public void compile(Context context, Pattern.Match match) {
5757
variable.internal = true;
5858
((FileContext) context).getVariables().add(0, variable);
5959
}
60+
if (context.hasFlag(AreaFlag.IN_ABSTRACT_TYPE))
61+
context.getMethod().addModifiers(0x0400); // trigger will default this
6062
method
6163
.addAnnotation(org.byteskript.skript.runtime.data.Function.class).setVisible(true)
6264
.addValue("name", method.getErasure().name())
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
/*
2+
* Copyright (c) 2021 ByteSkript org (Moderocky)
3+
* View the full licence information and permissions:
4+
* https://github.com/Moderocky/ByteSkript/blob/master/LICENSE
5+
*/
6+
7+
package org.byteskript.skript.lang.syntax.type;
8+
9+
import mx.kenzie.foundation.ClassBuilder;
10+
import mx.kenzie.foundation.Type;
11+
import org.byteskript.skript.api.syntax.Member;
12+
import org.byteskript.skript.compiler.*;
13+
import org.byteskript.skript.compiler.structure.SectionMeta;
14+
import org.byteskript.skript.lang.element.StandardElements;
15+
import org.byteskript.skript.runtime.data.SourceData;
16+
17+
import java.time.Instant;
18+
import java.util.regex.Matcher;
19+
20+
public class TemplateTypeMember extends Member {
21+
private static final java.util.regex.Pattern PATTERN = java.util.regex.Pattern.compile("template type (?<name>" + SkriptLangSpec.IDENTIFIER.pattern() + ")");
22+
23+
public TemplateTypeMember() {
24+
super(SkriptLangSpec.LIBRARY, StandardElements.MEMBER, "template type");
25+
}
26+
27+
@Override
28+
public Pattern.Match match(String thing, Context context) {
29+
if (thing.length() < 6) return null;
30+
if (!thing.startsWith("template type ")) return null;
31+
final Matcher matcher = PATTERN.matcher(thing);
32+
if (matcher.find() && matcher.group("name") != null)
33+
return new Pattern.Match(matcher);
34+
return null;
35+
}
36+
37+
@Override
38+
public void onSectionExit(Context context, SectionMeta meta) {
39+
context.removeFlag(AreaFlag.IN_TYPE);
40+
context.endSubBuilder();
41+
super.onSectionExit(context, meta);
42+
}
43+
44+
@Override
45+
public void compile(Context context, Pattern.Match match) {
46+
final String name = match.matcher().group("name");
47+
final String path = context.getType().internalName() + "/" + name;
48+
final ClassBuilder builder = context.addSuppressedBuilder(Type.of(path));
49+
final Type type = builder.getType();
50+
context.registerType(name, type);
51+
builder
52+
.addAnnotation(org.byteskript.skript.runtime.data.Type.class).setVisible(true)
53+
.addValue("name", name)
54+
.addValue("template", true);
55+
builder
56+
.addAnnotation(SourceData.class).setVisible(true)
57+
.addValue("line", context.lineNumber())
58+
.addValue("compiled", Instant.now().getEpochSecond());
59+
builder.setModifiers(0x0001 | 0x0400 | 0x0200);
60+
context.useSubBuilder(builder);
61+
context.addFlag(AreaFlag.IN_TYPE);
62+
context.addFlag(AreaFlag.IN_ABSTRACT_TYPE);
63+
context.setState(CompileState.ROOT); // members can go inside this!
64+
}
65+
66+
@Override
67+
public boolean allowAsInputFor(Type type) {
68+
return false;
69+
}
70+
71+
}

src/main/java/org/byteskript/skript/lang/syntax/type/TypeCreator.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
import org.byteskript.skript.lang.element.StandardElements;
1616
import org.byteskript.skript.lang.handler.StandardHandlers;
1717

18+
import java.lang.reflect.Modifier;
19+
1820
public class TypeCreator extends SimpleExpression {
1921

2022
public TypeCreator() {
@@ -25,15 +27,16 @@ public TypeCreator() {
2527

2628
@Override
2729
public Type getReturnType() {
28-
return CommonTypes.LIST;
30+
return CommonTypes.OBJECT;
2931
}
3032

3133
@ForceExtract
32-
public static Object create(Object object)
33-
throws InstantiationException, IllegalAccessException {
34+
public static Object create(Object object) {
3435
if (object == null) return null;
3536
if (!(object instanceof Class<?> type))
3637
throw new ScriptRuntimeError("Tried to create a new non-type thing: " + object);
38+
if (type.isInterface() || Modifier.isAbstract(type.getModifiers()))
39+
throw new ScriptRuntimeError("The type '" + ((Class<?>) object).getSimpleName() + "' is a template and cannot be created.");
3740
try {
3841
return type.newInstance();
3942
} catch (InstantiationException ex) {

src/test/java/org/byteskript/skript/test/ErrorHandlingTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ public static void start() throws Throwable {
3333
public void try_catch() throws Throwable {
3434
final Member function = script.getFunction("try_catch");
3535
assert function != null;
36-
function.run(skript);
36+
function.run(skript).get();
3737
}
3838

3939
public void errorMessage() throws Throwable {
@@ -56,7 +56,7 @@ run another_func()
5656
""".getBytes(StandardCharsets.UTF_8)), "skript.error_test");
5757
final Member function = skript.loadScript(test).getFunction("test_error");
5858
assert function != null;
59-
function.run(skript);
59+
function.run(skript).get();
6060
}
6161

6262
}

0 commit comments

Comments
 (0)