diff --git a/.github/README.md b/.github/README.md index 6ba8d2472..f6e3fbcea 100644 --- a/.github/README.md +++ b/.github/README.md @@ -32,7 +32,7 @@ The latest indev build org.panda-lang panda - 0.5.0-alpha + 0.5.1-alpha ``` diff --git a/examples/lang/array.panda b/examples/lang/array.panda new file mode 100644 index 000000000..31e4eb47e --- /dev/null +++ b/examples/lang/array.panda @@ -0,0 +1,10 @@ +require 'java' { collections } + +import java.util.Arrays + +main { + let array = 'Hello World'.split(' ') + array.set(1, 'Panda') + log array.get(0) + log array.toList().get(1) +} \ No newline at end of file diff --git a/examples/lang/loops.panda b/examples/lang/loops.panda index 13617f183..487285296 100644 --- a/examples/lang/loops.panda +++ b/examples/lang/loops.panda @@ -23,7 +23,7 @@ main { /* Iterator based for-each loop */ - List iterable = new ArrayList() // TODO: Replace with generic based collections + List iterable = new ArrayList() iterable.add('#bokkitty') iterable.add('#onlypanda') diff --git a/examples/summary-example/src/app.panda b/examples/summary-example/src/app.panda index 60525bdbe..ee3c4b3ed 100644 --- a/examples/summary-example/src/app.panda +++ b/examples/summary-example/src/app.panda @@ -61,7 +61,7 @@ main { } // assign ArrayList (class) value to List (interface) variable and add some values - List list = new ArrayList() + List list = new ArrayList() list.add("val1") list.add("val2") diff --git a/panda-framework/pom.xml b/panda-framework/pom.xml index 4c733d968..39301928c 100644 --- a/panda-framework/pom.xml +++ b/panda-framework/pom.xml @@ -20,7 +20,7 @@ panda-parent org.panda-lang - 0.5.0-alpha + 0.5.1-alpha panda-framework diff --git a/panda-framework/src/main/java/panda/interpreter/PandaFrameworkConstants.java b/panda-framework/src/main/java/panda/interpreter/PandaFrameworkConstants.java index d0647297b..9bccb2081 100644 --- a/panda-framework/src/main/java/panda/interpreter/PandaFrameworkConstants.java +++ b/panda-framework/src/main/java/panda/interpreter/PandaFrameworkConstants.java @@ -21,7 +21,7 @@ public final class PandaFrameworkConstants { /** * Current version of the Panda Framework */ - public static final String VERSION = "0.5.0-alpha"; + public static final String VERSION = "0.5.1-alpha"; private PandaFrameworkConstants() { } diff --git a/panda-framework/src/main/java/panda/interpreter/architecture/type/generator/MethodGenerator.java b/panda-framework/src/main/java/panda/interpreter/architecture/type/generator/MethodGenerator.java index fd2953be5..e92302806 100644 --- a/panda-framework/src/main/java/panda/interpreter/architecture/type/generator/MethodGenerator.java +++ b/panda-framework/src/main/java/panda/interpreter/architecture/type/generator/MethodGenerator.java @@ -23,7 +23,11 @@ import panda.interpreter.architecture.type.member.method.PandaMethod; import panda.interpreter.architecture.type.member.method.TypeMethod; import panda.interpreter.architecture.type.member.parameter.PropertyParameter; +import panda.interpreter.architecture.type.signature.GenericSignature; +import panda.interpreter.architecture.type.signature.Relation; +import panda.interpreter.architecture.type.signature.Signature; import panda.interpreter.runtime.PandaRuntimeException; +import panda.interpreter.token.PandaSnippet; import java.lang.reflect.Array; import java.lang.reflect.InvocationTargetException; @@ -50,7 +54,7 @@ final class MethodGenerator { this.method = method; } - protected TypeMethod generate(TypeLoader typeLoader) { + TypeMethod generate(TypeLoader typeLoader) { // TODO: Generate bytecode method.setAccessible(true); @@ -110,12 +114,16 @@ protected TypeMethod generate(TypeLoader typeLoader) { List mappedParameters = TypeGeneratorUtils.toParameters(generator, typeLoader, type.getModule(), method.getParameters()); + Signature returnType = method.getGenericReturnType() != method.getReturnType() + ? new GenericSignature(typeLoader, null, method.getGenericReturnType().getTypeName(), null, new Signature[0], Relation.DIRECT, PandaSnippet.empty()) + : generator.findOrGenerate(typeLoader, type.getModule(), method.getReturnType()).getSignature(); + return PandaMethod.builder() .name(method.getName()) .type(type) .isNative(true) .isStatic(Modifier.isStatic(method.getModifiers())) - .returnType(generator.findOrGenerate(typeLoader, type.getModule(), method.getReturnType()).getSignature()) + .returnType(returnType) .location(type.getLocation()) .customBody(methodBody) .parameters(mappedParameters) diff --git a/panda-framework/src/main/java/panda/interpreter/architecture/type/generator/TypeGenerator.java b/panda-framework/src/main/java/panda/interpreter/architecture/type/generator/TypeGenerator.java index 61b4da998..26192f2ae 100644 --- a/panda-framework/src/main/java/panda/interpreter/architecture/type/generator/TypeGenerator.java +++ b/panda-framework/src/main/java/panda/interpreter/architecture/type/generator/TypeGenerator.java @@ -25,10 +25,14 @@ import panda.interpreter.architecture.type.State; import panda.interpreter.architecture.type.Type; import panda.interpreter.architecture.type.Visibility; +import panda.interpreter.architecture.type.member.method.PandaMethod; +import panda.interpreter.architecture.type.member.parameter.PropertyParameterImpl; +import panda.interpreter.architecture.type.signature.GenericSignature; import panda.interpreter.architecture.type.signature.Relation; import panda.interpreter.architecture.type.signature.Signature; import panda.interpreter.architecture.type.signature.TypedSignature; import panda.interpreter.source.ClassSource; +import panda.interpreter.source.Location; import panda.interpreter.token.PandaSnippet; import panda.std.reactive.Completable; import panda.utilities.ClassUtils; @@ -39,13 +43,18 @@ import java.lang.reflect.Field; import java.lang.reflect.Method; import java.lang.reflect.Modifier; +import java.lang.reflect.TypeVariable; +import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; +import java.util.Objects; public final class TypeGenerator { - protected final Map, Type> initializedTypes = new HashMap<>(); - protected final FrameworkController frameworkController; + final Map, Type> initializedTypes = new HashMap<>(); + final FrameworkController frameworkController; public TypeGenerator(FrameworkController frameworkController) { this.frameworkController = frameworkController; @@ -56,20 +65,34 @@ public Type allocate(Class javaType, Type type) { return type; } - public Reference generate(Module module, String name, Class javaType) { + public Reference generate(TypeLoader stdTypeLoader, Module module, String rawName, Class javaType) { + if (rawName.endsWith("[]")) { + rawName = rawName.replace("[]", "Array"); + } + + String name = rawName; + return Option.of(initializedTypes.get(javaType)) .map(Reference::new) .orElse(() -> module.get(name)) .orElseGet(() -> { Completable completableType = new Completable<>(); - Reference reference = new Reference(completableType, module, name, Visibility.OPEN, Kind.of(javaType), new ClassSource(module, javaType).toLocation()); + Location location = new ClassSource(module, javaType).toLocation(); + Reference reference = new Reference(completableType, module, name, Visibility.OPEN, Kind.of(javaType), location); + + TypeVariable[] javaGenerics = javaType.getTypeParameters(); + Signature[] generics = new Signature[javaGenerics.length]; + + for (int index = 0; index < javaGenerics.length; index++) { + generics[index] = new GenericSignature(stdTypeLoader, null, javaGenerics[index].getName(), null, new Signature[0], Relation.DIRECT, PandaSnippet.empty()); + } Type type = PandaType.builder() .name(name) .module(module) .associatedType(Completable.completed(javaType)) .isNative(true) - .signature(new TypedSignature(null, reference, new Signature[0], Relation.DIRECT, PandaSnippet.empty())) + .signature(new TypedSignature(null, reference, generics, Relation.DIRECT, PandaSnippet.empty())) .location(reference.getLocation()) .kind(reference.getKind()) .state(State.of(javaType)) @@ -115,6 +138,51 @@ public Reference generate(Module module, String name, Class javaType) { MethodGenerator generator = new MethodGenerator(frameworkController, this, initializedType, method); initializedType.getMethods().declare(method.getName(), () -> generator.generate(typeLoader)); } + + if (javaType.isArray()) { + Signature componentType = typeLoader.forJavaType(javaType.getComponentType()).get().getSignature(); + Signature indexType = typeLoader.forJavaType(int.class).get().getSignature(); + + type.getMethods().declare("set", () -> PandaMethod.builder() + .type(type) + .name("set") + .parameters(Arrays.asList( + new PropertyParameterImpl(0, indexType, "index", false, false), + new PropertyParameterImpl(1, componentType, "value", false, true) + )) + .returnType(type.getSignature()) + .customBody((property, stack, instance, arguments) -> { + ((Object[]) Objects.requireNonNull(instance))[(int) arguments[0]] = arguments[1]; + return instance; + }) + .location(location) + .build()); + type.getMethods().declare("get", () -> PandaMethod.builder() + .type(type) + .name("get") + .parameters(Collections.singletonList(new PropertyParameterImpl(0, typeLoader.forJavaType(int.class).get().getSignature(), "index", false, false))) + .returnType(componentType) + .customBody((property, stack, instance, arguments) -> ((Object[]) Objects.requireNonNull(instance))[(int) arguments[0]]) + .location(location) + .build()); + + TypedSignature typedListSignature = new TypedSignature( + null, + typeLoader.forJavaType(List.class).get().getReference(), + new Signature[] { typeLoader.forJavaType(String.class).get().getSignature() }, + Relation.DIRECT, + PandaSnippet.empty() + ); + + type.getMethods().declare("toList", () -> PandaMethod.builder() + .type(type) + .name("toList") + .parameters(Collections.emptyList()) + .returnType(typedListSignature) + .customBody((property, stack, instance, arguments) -> Arrays.asList((Object[]) Objects.requireNonNull(instance))) + .location(location) + .build()); + } }); completableType.complete(allocate(javaType, type)); @@ -122,7 +190,7 @@ public Reference generate(Module module, String name, Class javaType) { }); } - protected Type findOrGenerate(TypeLoader typeLoader, Module module, Class javaType) { + Type findOrGenerate(TypeLoader typeLoader, Module module, Class javaType) { if (javaType.isPrimitive()) { javaType = ClassUtils.getNonPrimitiveClass(javaType); } @@ -139,7 +207,7 @@ protected Type findOrGenerate(TypeLoader typeLoader, Module module, Class jav return type; } - return generate(module, javaType.getSimpleName(), javaType).fetchType(); + return generate(typeLoader, module, javaType.getSimpleName(), javaType).fetchType(); } } diff --git a/panda-framework/src/main/java/panda/interpreter/architecture/type/generator/TypeGeneratorUtils.java b/panda-framework/src/main/java/panda/interpreter/architecture/type/generator/TypeGeneratorUtils.java index ffac367a7..f0e8c558e 100644 --- a/panda-framework/src/main/java/panda/interpreter/architecture/type/generator/TypeGeneratorUtils.java +++ b/panda-framework/src/main/java/panda/interpreter/architecture/type/generator/TypeGeneratorUtils.java @@ -35,7 +35,7 @@ static List toParameters(TypeGenerator typeGenerato for (int index = 0; index < parameters.length; index++) { Parameter parameter = parameters[index]; - Type type = typeLoader.load(typeGenerator.generate(module, parameter.getType().getSimpleName(), parameter.getType()).fetchType()); + Type type = typeLoader.load(typeGenerator.generate(typeLoader, module, parameter.getType().getSimpleName(), parameter.getType()).fetchType()); mappedParameters.add(new PropertyParameterImpl(index, type.getSignature(), parameter.getName(), false, false)); } diff --git a/panda-framework/src/main/java/panda/interpreter/architecture/type/member/AbstractMembers.java b/panda-framework/src/main/java/panda/interpreter/architecture/type/member/AbstractMembers.java index fa8dfbe3f..d963d3d74 100644 --- a/panda-framework/src/main/java/panda/interpreter/architecture/type/member/AbstractMembers.java +++ b/panda-framework/src/main/java/panda/interpreter/architecture/type/member/AbstractMembers.java @@ -85,7 +85,8 @@ private List withBases(List properties, Function, Col } protected List getPropertiesLike(String name, Predicate filter) { - List properties = Option.of(propertiesMap.get(name)).orElseGet(Collections::emptyList).stream() + List properties = Option.of(propertiesMap.get(name)) + .orElseGet(Collections::emptyList).stream() .map(Lazy::get) .filter(filter) .collect(Collectors.toList()); diff --git a/panda-framework/src/main/java/panda/interpreter/architecture/type/member/ParametrizedMember.java b/panda-framework/src/main/java/panda/interpreter/architecture/type/member/ParametrizedMember.java index e69451a61..7c12208f7 100644 --- a/panda-framework/src/main/java/panda/interpreter/architecture/type/member/ParametrizedMember.java +++ b/panda-framework/src/main/java/panda/interpreter/architecture/type/member/ParametrizedMember.java @@ -47,7 +47,7 @@ public interface ParametrizedMember extends Member { boolean isInvokableBy(List arguments); /** - * Get references to types of executable's parameters + * Get references to type of executable's parameters * * @return array of used by parameter types */ diff --git a/panda-framework/src/main/java/panda/interpreter/architecture/type/member/method/PandaMethod.java b/panda-framework/src/main/java/panda/interpreter/architecture/type/member/method/PandaMethod.java index 082739181..c01bb49f0 100644 --- a/panda-framework/src/main/java/panda/interpreter/architecture/type/member/method/PandaMethod.java +++ b/panda-framework/src/main/java/panda/interpreter/architecture/type/member/method/PandaMethod.java @@ -30,7 +30,7 @@ public final class PandaMethod extends AbstractParametrizedMember im private final boolean isNative; private final boolean isOverriding; - protected PandaMethod(PandaMethodBuilder builder) { + PandaMethod(PandaMethodBuilder builder) { super(builder); this.methodBody = builder.body; @@ -76,11 +76,11 @@ public static PandaMethodBuilder builder() { public static final class PandaMethodBuilder extends PandaParametrizedExecutableBuilder { - protected MemberInvoker body; - protected boolean isAbstract; - protected boolean isStatic; - protected boolean isNative; - protected boolean isOverriding; + MemberInvoker body; + boolean isAbstract; + boolean isStatic; + boolean isNative; + boolean isOverriding; private PandaMethodBuilder() { } diff --git a/panda-framework/src/main/java/panda/interpreter/architecture/type/signature/SignatureUtils.java b/panda-framework/src/main/java/panda/interpreter/architecture/type/signature/SignatureUtils.java index 7b2442306..3a428b31d 100644 --- a/panda-framework/src/main/java/panda/interpreter/architecture/type/signature/SignatureUtils.java +++ b/panda-framework/src/main/java/panda/interpreter/architecture/type/signature/SignatureUtils.java @@ -28,7 +28,7 @@ public static Result isAssignable(Signature root, S return baseResult; } - for (int index = 0; index < root.getGenerics().length; index++) { + for (int index = 0; index < inheritor.getGenerics().length; index++) { Signature rootParameter = root.getGenerics()[index]; Signature inheritorParameter = inheritor.getGenerics()[index]; Result parameterResult = isAssignable(rootParameter, inheritorParameter); @@ -42,10 +42,6 @@ public static Result isAssignable(Signature root, S } private static Result isBaseAssignable(Signature root, Signature inheritor) { - if (root.getSignature().getGenerics().length != inheritor.getSignature().getGenerics().length) { - return Result.error("Invalid amount of parameters in generic signature"); - } - if (root.isTyped()) { if (inheritor.isTyped()) { return typedToTyped(root.toTyped(), inheritor.toTyped()); @@ -56,6 +52,10 @@ private static Result isBaseAssignable(Signature ro } } + if (root.getSignature().getGenerics().length != inheritor.getSignature().getGenerics().length) { + return Result.error("Invalid amount of parameters in generic signature"); + } + if (root.isGeneric()) { if (inheritor.isTyped()) { return genericToTyped(root.toGeneric(), inheritor.toTyped()); diff --git a/panda-framework/src/main/java/panda/interpreter/resource/mappings/java/JavaModule.java b/panda-framework/src/main/java/panda/interpreter/resource/mappings/java/JavaModule.java index 310191bb7..d64f44bf3 100644 --- a/panda-framework/src/main/java/panda/interpreter/resource/mappings/java/JavaModule.java +++ b/panda-framework/src/main/java/panda/interpreter/resource/mappings/java/JavaModule.java @@ -48,7 +48,7 @@ public final class JavaModule implements CustomInitializer { @Override public void initialize(Module module, TypeGenerator typeGenerator, TypeLoader typeLoader) { Type primitiveVoid = primitive(typeGenerator, module, "Void", void.class); - Type voidType = associated(typeGenerator, primitiveVoid); + Type voidType = associated(typeLoader, typeGenerator, primitiveVoid); typeLoader.load(primitiveVoid, voidType); Type primitiveInt = primitive(typeGenerator, module, "Int", int.class); @@ -60,23 +60,23 @@ public void initialize(Module module, TypeGenerator typeGenerator, TypeLoader ty Type primitiveFloat = primitive(typeGenerator, module, "Float", float.class); Type primitiveDouble = primitive(typeGenerator, module, "Double", double.class); - Type objectType = generate(typeGenerator, module, Object.class); + Type objectType = generate(typeLoader, typeGenerator, module, Object.class); typeLoader.load(objectType); - Type stringType = generate(typeGenerator, module, String.class); + Type stringType = generate(typeLoader, typeGenerator, module, String.class); typeLoader.load(stringType); - Type numberType = generate(typeGenerator, module, Number.class); + Type numberType = generate(typeLoader, typeGenerator, module, Number.class); typeLoader.load(numberType); - Type boolType = associated(typeGenerator, primitiveBool); - Type charType = associated(typeGenerator, primitiveChar); - Type byteType = associated(typeGenerator, primitiveByte); - Type shortType = associated(typeGenerator, primitiveShort); - Type intType = associated(typeGenerator, primitiveInt); - Type longType = associated(typeGenerator, primitiveLong); - Type floatType = associated(typeGenerator, primitiveFloat); - Type doubleType = associated(typeGenerator, primitiveDouble); + Type boolType = associated(typeLoader, typeGenerator, primitiveBool); + Type charType = associated(typeLoader, typeGenerator, primitiveChar); + Type byteType = associated(typeLoader, typeGenerator, primitiveByte); + Type shortType = associated(typeLoader, typeGenerator, primitiveShort); + Type intType = associated(typeLoader, typeGenerator, primitiveInt); + Type longType = associated(typeLoader, typeGenerator, primitiveLong); + Type floatType = associated(typeLoader, typeGenerator, primitiveFloat); + Type doubleType = associated(typeLoader, typeGenerator, primitiveDouble); intType.addAutocast(longType.getReference(), (Autocast) (originalType, object, resultType) -> object.longValue()); intType.addAutocast(doubleType.getReference(), (Autocast) (originalType, object, resultType) -> object.doubleValue()); @@ -98,7 +98,7 @@ public void initialize(Module module, TypeGenerator typeGenerator, TypeLoader ty primitiveDouble, doubleType ); - Type java = generate(typeGenerator, module, Java.class); + Type java = generate(typeLoader, typeGenerator, module, Java.class); java.getMethods().declare(PandaMethod.builder() .name("null") .parameters(Collections.emptyList()) @@ -137,8 +137,8 @@ private Type primitive(TypeGenerator typeGenerator, Module module, String name, return type; } - private Type associated(TypeGenerator typeGenerator, Type primitive) { - Type type = generate(typeGenerator, primitive.getModule(), primitive.getSimpleName().replace("Primitive", ""), ClassUtils.getNonPrimitiveClass(primitive.getAssociated().get())); + private Type associated(TypeLoader typeLoader, TypeGenerator typeGenerator, Type primitive) { + Type type = generate(typeLoader, typeGenerator, primitive.getModule(), primitive.getSimpleName().replace("Primitive", ""), ClassUtils.getNonPrimitiveClass(primitive.getAssociated().get())); type.addAutocast(primitive.getReference(), (originalType, object, resultType) -> object); primitive.addAutocast(type.getReference(), (originalType, object, resultType) -> object); @@ -146,12 +146,12 @@ private Type associated(TypeGenerator typeGenerator, Type primitive) { return type; } - public static Type generate(TypeGenerator typeGenerator, Module module, Class type) { - return generate(typeGenerator, module, type.getSimpleName(), type); + public static Type generate(TypeLoader typeLoader, TypeGenerator typeGenerator, Module module, Class type) { + return generate(typeLoader, typeGenerator, module, type.getSimpleName(), type); } - public static Type generate(TypeGenerator typeGenerator, Module module, String name, Class javaType) { - Reference reference= typeGenerator.generate(module, name, javaType); + public static Type generate(TypeLoader typeLoader, TypeGenerator typeGenerator, Module module, String name, Class javaType) { + Reference reference= typeGenerator.generate(typeLoader, module, name, javaType); module.add(reference); return reference.fetchType(); diff --git a/panda-standalone/pom.xml b/panda-standalone/pom.xml index 4ffee63b9..39a174638 100644 --- a/panda-standalone/pom.xml +++ b/panda-standalone/pom.xml @@ -18,7 +18,7 @@ panda-parent org.panda-lang - 0.5.0-alpha + 0.5.1-alpha 4.0.0 diff --git a/panda-utilities/pom.xml b/panda-utilities/pom.xml index 1feabaa4e..3bc77a120 100644 --- a/panda-utilities/pom.xml +++ b/panda-utilities/pom.xml @@ -20,7 +20,7 @@ panda-parent org.panda-lang - 0.5.0-alpha + 0.5.1-alpha panda-utilities diff --git a/panda/pom.xml b/panda/pom.xml index e97d5f095..89e225da3 100644 --- a/panda/pom.xml +++ b/panda/pom.xml @@ -20,7 +20,7 @@ panda-parent org.panda-lang - 0.5.0-alpha + 0.5.1-alpha panda diff --git a/panda/src/main/java/panda/interpreter/std/StdLoader.java b/panda/src/main/java/panda/interpreter/std/StdLoader.java index 80add6b99..d125f8b95 100644 --- a/panda/src/main/java/panda/interpreter/std/StdLoader.java +++ b/panda/src/main/java/panda/interpreter/std/StdLoader.java @@ -61,7 +61,7 @@ private void loadClass(Packages packages, TypeGenerator typeGenerator, TypeLoade for (String name : mappingsInfo.classes()) { ClassUtils.forName(packageName + name) - .map(type -> typeGenerator.generate(module, name, type)) + .map(type -> typeGenerator.generate(typeLoader, module, name, type)) .peek(module::add) .peek(reference -> typeLoader.load(reference.fetchType())) .orThrow(() -> { diff --git a/panda/src/main/java/panda/interpreter/syntax/expressions/subparsers/MethodCallParser.java b/panda/src/main/java/panda/interpreter/syntax/expressions/subparsers/MethodCallParser.java index a7def5e27..478e6ba5b 100644 --- a/panda/src/main/java/panda/interpreter/syntax/expressions/subparsers/MethodCallParser.java +++ b/panda/src/main/java/panda/interpreter/syntax/expressions/subparsers/MethodCallParser.java @@ -20,6 +20,7 @@ import panda.interpreter.architecture.expression.Expression; import panda.interpreter.architecture.expression.StaticExpression; import panda.interpreter.architecture.expression.ThisExpression; +import panda.interpreter.architecture.module.TypeLoader; import panda.interpreter.architecture.type.Type; import panda.interpreter.architecture.type.TypedUtils; import panda.interpreter.architecture.type.VisibilityComparator; @@ -52,7 +53,7 @@ public final class MethodCallParser implements ExpressionSubparser { @Override public ExpressionSubparserWorker createWorker(Context context) { - return new MethodWorker().withSubparser(this); + return new MethodWorker(context.getTypeLoader()).withSubparser(this); } @Override @@ -73,6 +74,11 @@ public String name() { private static final class MethodWorker extends AbstractExpressionSubparserWorker { private static final ArgumentsParser ARGUMENT_PARSER = new ArgumentsParser(); + private final TypeLoader typeLoader; + + private MethodWorker(TypeLoader typeLoader) { + this.typeLoader = typeLoader; + } @Override public @Nullable ExpressionResult next(ExpressionContext context, TokenInfo nameToken) { @@ -113,6 +119,7 @@ else if (!hasPeriod) /* if (source.getIndex() == 2) ^ not really */ { } Type type = instance.getSignature().toTyped().fetchType(); + typeLoader.load(type); // check if type of instance contains required method if (!type.getMethods().hasPropertyLike(nameToken.getValue())) { @@ -142,9 +149,7 @@ private Expression parseMethod(ExpressionContext context, Type type, Expressi if (!propertiesLike.isEmpty()) { similar = "Similar methods:&r" + Effect.LINE_SEPARATOR; - similar += Joiner.on(Effect.LINE_SEPARATOR.toString()).join(propertiesLike, method -> { - return " • &7" + method.getName() + "&r"; - }); + similar += Joiner.on(Effect.LINE_SEPARATOR.toString()).join(propertiesLike, method -> " • &7" + method.getName() + "&r"); } throw new PandaParserFailure(context.toContext(), argumentsSource, diff --git a/panda/src/main/java/panda/interpreter/syntax/head/ConveyanceUtils.java b/panda/src/main/java/panda/interpreter/syntax/head/ConveyanceUtils.java index 65502a759..555afe65b 100644 --- a/panda/src/main/java/panda/interpreter/syntax/head/ConveyanceUtils.java +++ b/panda/src/main/java/panda/interpreter/syntax/head/ConveyanceUtils.java @@ -25,10 +25,10 @@ final class ConveyanceUtils { private ConveyanceUtils() { } - protected static Type fetchType(Context context, Snippet javaTypeSource) { + static Type fetchType(Context context, Snippet javaTypeSource) { try { Class importedClass = Class.forName(javaTypeSource.asSource(), true, context.getEnvironment().getController().getClassLoader()); - Type type = context.getEnvironment().getTypeGenerator().generate(context.getScript().getModule(), importedClass.getSimpleName(), importedClass).fetchType(); + Type type = context.getEnvironment().getTypeGenerator().generate(context.getTypeLoader(), context.getScript().getModule(), importedClass.getSimpleName(), importedClass).fetchType(); return context.getTypeLoader().load(type); } catch (ClassNotFoundException classNotFoundException) { diff --git a/panda/src/main/java/panda/std/Array.java b/panda/src/main/java/panda/std/Array.java new file mode 100644 index 000000000..2985978af --- /dev/null +++ b/panda/src/main/java/panda/std/Array.java @@ -0,0 +1,25 @@ +package panda.std; + +import panda.utilities.ArrayUtils; + +public final class Array { + + private final T[] array; + + public Array(T[] array) { + this.array = array; + } + + public Option get(int index) { + return ArrayUtils.get(array, index); + } + + public void set(int index, T value) { + array[index] = value; + } + + public T[] getJavaArray() { + return array; + } + +} diff --git a/panda/src/test/groovy/panda/examples/lang/ArrayTest.groovy b/panda/src/test/groovy/panda/examples/lang/ArrayTest.groovy new file mode 100644 index 000000000..ea34475a0 --- /dev/null +++ b/panda/src/test/groovy/panda/examples/lang/ArrayTest.groovy @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2021 dzikoysk + * + * Licensed under the Apache License, Version 2.0 (the "License") + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package panda.examples.lang + +import groovy.transform.CompileStatic +import org.junit.jupiter.api.Test +import panda.examples.PandaTestSpecification + +@CompileStatic +class ArrayTest extends PandaTestSpecification { + + @Test + void 'should compile and execute' () { + launch '/lang/', 'array.panda' + } + +} diff --git a/pom.xml b/pom.xml index 33d88fdfb..0aff6fd76 100644 --- a/pom.xml +++ b/pom.xml @@ -20,7 +20,7 @@ Panda org.panda-lang panda-parent - 0.5.0-alpha + 0.5.1-alpha pom