Поддержка инстанцирования java-класса с помощью ключевого слова new

This commit is contained in:
Victor 2019-10-03 21:04:17 +03:00
parent 483c7c1242
commit 826891ac52
4 changed files with 31 additions and 13 deletions

View File

@ -1,15 +1,14 @@
package com.annimon.ownlang.lib;
import com.annimon.ownlang.exceptions.UnknownFunctionException;
import com.annimon.ownlang.parser.ast.ClassDeclarationStatement;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public final class ClassDeclarations {
private static final Map<String, ClassDeclarationStatement> declarations;
static {
declarations = new HashMap<>();
declarations = new ConcurrentHashMap<>();
}
private ClassDeclarations() { }
@ -22,12 +21,7 @@ public final class ClassDeclarations {
return declarations;
}
public static boolean isExists(String key) {
return declarations.containsKey(key);
}
public static ClassDeclarationStatement get(String key) {
if (!isExists(key)) throw new UnknownFunctionException(key);
return declarations.get(key);
}

View File

@ -0,0 +1,9 @@
package com.annimon.ownlang.lib;
/**
* Interface for values that supports creating instances with `new` keyword.
*/
public interface Instantiable {
Value newInstance(Value[] args);
}

View File

@ -103,7 +103,7 @@ public final class java implements Module {
}
}
private static class ClassValue extends MapValue {
private static class ClassValue extends MapValue implements Instantiable {
public static Value classOrNull(Class<?> clazz) {
if (clazz == null) return NULL;
@ -162,7 +162,8 @@ public final class java implements Module {
return NumberValue.fromBoolean(clazz.isAssignableFrom( ((ClassValue)args[0]).clazz ));
}
private Value newInstance(Value[] args) {
@Override
public Value newInstance(Value[] args) {
return findConstructorAndInstantiate(args, clazz.getConstructors());
}

View File

@ -1,5 +1,6 @@
package com.annimon.ownlang.parser.ast;
import com.annimon.ownlang.exceptions.UnknownClassException;
import com.annimon.ownlang.lib.*;
import java.util.Iterator;
import java.util.List;
@ -17,6 +18,16 @@ public final class ObjectCreationExpression implements Expression {
@Override
public Value eval() {
final ClassDeclarationStatement cd = ClassDeclarations.get(className);
if (cd == null) {
// Is Instantiable?
if (Variables.isExists(className)) {
final Value variable = Variables.get(className);
if (variable instanceof Instantiable) {
return ((Instantiable) variable).newInstance(ctorArgs());
}
}
throw new UnknownClassException(className);
}
// Create an instance and put evaluated fields with method declarations
final ClassInstanceValue instance = new ClassInstanceValue(className);
@ -30,14 +41,17 @@ public final class ObjectCreationExpression implements Expression {
}
// Call a constructor
instance.callConstructor(ctorArgs());
return instance;
}
private Value[] ctorArgs() {
final int argsSize = constructorArguments.size();
final Value[] ctorArgs = new Value[argsSize];
for (int i = 0; i < argsSize; i++) {
ctorArgs[i] = constructorArguments.get(i).eval();
}
instance.callConstructor(ctorArgs);
return instance;
return ctorArgs;
}
@Override