Procházet zdrojové kódy

Expansion Getters/Setters, expansion static fields and Array contains

kindlich před 6 roky
rodič
revize
28c635f584
No known key found for this signature in database

+ 70
- 12
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaExpressionVisitor.java Zobrazit soubor

@@ -17,6 +17,7 @@ import org.openzen.zenscript.codemodel.type.storage.StorageTag;
17 17
 import org.openzen.zenscript.codemodel.type.storage.UniqueStorageTag;
18 18
 import org.openzen.zenscript.javabytecode.JavaBytecodeContext;
19 19
 import org.openzen.zenscript.javabytecode.JavaLocalVariableInfo;
20
+import org.openzen.zenscript.javabytecode.compiler.JavaModificationExpressionVisitor.PushOption;
20 21
 import org.openzen.zenscript.javashared.*;
21 22
 
22 23
 import java.io.FileOutputStream;
@@ -26,7 +27,6 @@ import java.util.Arrays;
26 27
 import java.util.Comparator;
27 28
 import java.util.Objects;
28 29
 import java.util.StringJoiner;
29
-import org.openzen.zenscript.javabytecode.compiler.JavaModificationExpressionVisitor.PushOption;
30 30
 
31 31
 public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativeTranslator<Void> {
32 32
 	private static final JavaMethod BOOLEAN_PARSE = JavaMethod.getNativeStatic(JavaClass.BOOLEAN, "parseBoolean", "(Ljava/lang/String;)Z");
@@ -392,6 +392,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
392 392
 			case STRING_RANGEGET:
393 393
 			case ARRAY_INDEXGETRANGE:
394 394
 			case ARRAY_INDEXGET:
395
+			case ARRAY_CONTAINS:
395 396
 				break;
396 397
 			case BYTE_INC:
397 398
 				modify(expression.target, () -> {
@@ -457,7 +458,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
457 458
 			case UINT_INC:
458 459
 			case USIZE_INC:
459 460
 				if (expression.target instanceof GetLocalVariableExpression) {
460
-					JavaLocalVariableInfo local = javaWriter.getLocalVariable(((GetLocalVariableExpression)expression.target).variable.variable);
461
+					JavaLocalVariableInfo local = javaWriter.getLocalVariable(((GetLocalVariableExpression) expression.target).variable.variable);
461 462
 					javaWriter.iinc(local.local);
462 463
 					javaWriter.load(local);
463 464
 				} else {
@@ -471,7 +472,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
471 472
 			case UINT_DEC:
472 473
 			case USIZE_DEC:
473 474
 				if (expression.target instanceof GetLocalVariableExpression) {
474
-					JavaLocalVariableInfo local = javaWriter.getLocalVariable(((GetLocalVariableExpression)expression.target).variable.variable);
475
+					JavaLocalVariableInfo local = javaWriter.getLocalVariable(((GetLocalVariableExpression) expression.target).variable.variable);
475 476
 					javaWriter.iinc(local.local, -1);
476 477
 					javaWriter.load(local);
477 478
 				} else {
@@ -525,7 +526,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
525 526
 				final Label isFalse = new Label();
526 527
 				final Label end = new Label();
527 528
 
528
-				if(builtin == BuiltinID.OPTIONAL_IS_NULL)
529
+				if (builtin == BuiltinID.OPTIONAL_IS_NULL)
529 530
 					javaWriter.ifNonNull(isFalse);
530 531
 				else
531 532
 					javaWriter.ifNull(isFalse);
@@ -995,7 +996,64 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
995 996
 				break;
996 997
 			}
997 998
 			case ARRAY_CONTAINS:
998
-				throw new UnsupportedOperationException("Not yet supported!");
999
+				expression.target.accept(this);
1000
+				final Label loopStart = new Label();
1001
+				final Label loopEnd = new Label();
1002
+				final Label isTrue = new Label();
1003
+				final Label expressionEnd = new Label();
1004
+
1005
+				final int counterLocation = javaWriter.local(int.class);
1006
+				javaWriter.iConst0();
1007
+				javaWriter.storeInt(counterLocation);
1008
+
1009
+				javaWriter.label(loopStart);
1010
+				javaWriter.dup();
1011
+				javaWriter.arrayLength();
1012
+
1013
+				javaWriter.loadInt(counterLocation);
1014
+
1015
+				javaWriter.ifICmpLE(loopEnd);
1016
+				javaWriter.dup();
1017
+				javaWriter.loadInt(counterLocation);
1018
+				final StoredType itemType = expression.arguments.arguments[0].type;
1019
+				javaWriter.arrayLoad(context.getType(itemType));
1020
+				javaWriter.iinc(counterLocation);
1021
+				expression.arguments.arguments[0].accept(this);
1022
+
1023
+
1024
+				if (CompilerUtils.isPrimitive(itemType.type)) {
1025
+					//Compare non-int types beforehand
1026
+					if (itemType.type == BasicTypeID.LONG || itemType.type == BasicTypeID.ULONG) {
1027
+						javaWriter.lCmp();
1028
+						javaWriter.ifNE(loopStart);
1029
+					} else if (itemType.type == BasicTypeID.FLOAT) {
1030
+						javaWriter.fCmp();
1031
+						javaWriter.ifNE(loopStart);
1032
+					} else if (itemType.type == BasicTypeID.DOUBLE) {
1033
+						javaWriter.dCmp();
1034
+						javaWriter.ifNE(loopStart);
1035
+					} else
1036
+						javaWriter.ifICmpNE(loopStart);
1037
+				} else {
1038
+					//If equals, use Object.equals in case of null
1039
+					javaWriter.invokeStatic(new JavaMethod(JavaClass.fromInternalName("java/util/Objects", JavaClass.Kind.CLASS), JavaMethod.Kind.STATIC, "equals", false, "(Ljava/lang/Object;Ljava/lang/Object;)Z", 0, false));
1040
+					javaWriter.ifNE(loopStart);
1041
+					// If ==
1042
+					// javaWriter.ifACmpNe(loopStart);
1043
+				}
1044
+
1045
+				javaWriter.label(isTrue);
1046
+
1047
+				javaWriter.pop();
1048
+				javaWriter.iConst1();
1049
+				javaWriter.goTo(expressionEnd);
1050
+
1051
+				javaWriter.label(loopEnd);
1052
+				javaWriter.pop();
1053
+				javaWriter.iConst0();
1054
+				javaWriter.label(expressionEnd);
1055
+
1056
+				break;
999 1057
 			case ARRAY_EQUALS:
1000 1058
 			case ARRAY_NOTEQUALS: {
1001 1059
 				ArrayTypeID type = (ArrayTypeID) expression.target.type.type;
@@ -3459,7 +3517,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
3459 3517
 		javaWriter.aThrow();
3460 3518
 		return null;
3461 3519
 	}
3462
-	
3520
+
3463 3521
 	private void modify(Expression source, Runnable modification, PushOption push) {
3464 3522
 		source.accept(new JavaModificationExpressionVisitor(context, module, javaWriter, this, modification, push));
3465 3523
 	}
@@ -3532,7 +3590,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
3532 3590
 				case UINT_INC:
3533 3591
 				case USIZE_INC:
3534 3592
 					if (expression.target instanceof GetLocalVariableExpression) {
3535
-						JavaLocalVariableInfo local = javaWriter.getLocalVariable(((GetLocalVariableExpression)expression.target).variable.variable);
3593
+						JavaLocalVariableInfo local = javaWriter.getLocalVariable(((GetLocalVariableExpression) expression.target).variable.variable);
3536 3594
 						javaWriter.load(local);
3537 3595
 						javaWriter.iinc(local.local);
3538 3596
 					} else {
@@ -3546,7 +3604,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
3546 3604
 				case UINT_DEC:
3547 3605
 				case USIZE_DEC:
3548 3606
 					if (expression.target instanceof GetLocalVariableExpression) {
3549
-						JavaLocalVariableInfo local = javaWriter.getLocalVariable(((GetLocalVariableExpression)expression.target).variable.variable);
3607
+						JavaLocalVariableInfo local = javaWriter.getLocalVariable(((GetLocalVariableExpression) expression.target).variable.variable);
3550 3608
 						javaWriter.load(local);
3551 3609
 						javaWriter.iinc(local.local, -1);
3552 3610
 					} else {
@@ -3598,12 +3656,12 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
3598 3656
 					throw new IllegalArgumentException("Unknown postcall builtin: " + expression.member.getBuiltin());
3599 3657
 			}
3600 3658
 		}
3601
-		
3659
+
3602 3660
 		modify(expression.target, () -> {
3603 3661
 			if (!checkAndExecuteMethodInfo(expression.member, expression.type, expression))
3604 3662
 				throw new IllegalStateException("Call target has no method info!");
3605 3663
 		}, PushOption.BEFORE);
3606
-		
3664
+
3607 3665
 		return null;
3608 3666
 	}
3609 3667
 
@@ -3694,7 +3752,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
3694 3752
 				javaWriter.getStaticField(context.getJavaField(expression.getter));
3695 3753
 				return null;
3696 3754
 			}
3697
-			
3755
+
3698 3756
 			if (!checkAndExecuteMethodInfo(expression.getter, expression.type, expression))
3699 3757
 				throw new IllegalStateException("Call target has no method info!");
3700 3758
 
@@ -3876,7 +3934,7 @@ public class JavaExpressionVisitor implements ExpressionVisitor<Void>, JavaNativ
3876 3934
 
3877 3935
 	//Will return true if a JavaMethodInfo.class tag exists, and will compile that tag
3878 3936
 	@SuppressWarnings({"Raw", "unchecked"})
3879
-	private boolean checkAndExecuteMethodInfo(DefinitionMemberRef member, StoredType resultType, Expression expression) {
3937
+	boolean checkAndExecuteMethodInfo(DefinitionMemberRef member, StoredType resultType, Expression expression) {
3880 3938
 		JavaMethod methodInfo = context.getJavaMethod(member);
3881 3939
 		if (methodInfo == null)
3882 3940
 			return false;

+ 4
- 1
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaNonPushingExpressionVisitor.java Zobrazit soubor

@@ -623,7 +623,10 @@ public class JavaNonPushingExpressionVisitor implements ExpressionVisitor<Void>
623 623
 
624 624
 	@Override
625 625
 	public Void visitSetter(SetterExpression expression) {
626
-		throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
626
+		expression.target.accept(original);
627
+		expression.value.accept(original);
628
+		original.checkAndExecuteMethodInfo(expression.setter, expression.type, expression);
629
+		return null;
627 630
 	}
628 631
 
629 632
 	@Override

+ 19
- 2
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/definitions/JavaExpansionMemberVisitor.java Zobrazit soubor

@@ -23,15 +23,23 @@ public class JavaExpansionMemberVisitor implements MemberVisitor<Void> {
23 23
 	private final HighLevelDefinition definition;
24 24
 	private final JavaCompiledModule javaModule;
25 25
 
26
+	private final JavaStatementVisitor clinitStatementVisitor;
27
+
26 28
 	public JavaExpansionMemberVisitor(JavaBytecodeContext context, ClassWriter writer, StoredType expandedClass, HighLevelDefinition definition) {
27 29
 		this.writer = writer;
28 30
 		this.expandedClass = expandedClass;
29 31
 		this.definition = definition;
30 32
 		this.context = context;
31 33
 		javaModule = context.getJavaModule(definition.module);
34
+
35
+		final JavaWriter javaWriter = new JavaWriter(definition.position, writer, new JavaMethod(context.getJavaClass(definition), JavaMethod.Kind.STATICINIT, "<clinit>", true, "()V", 0, false), definition, null, null);
36
+		this.clinitStatementVisitor = new JavaStatementVisitor(context, javaModule, javaWriter);
37
+		this.clinitStatementVisitor.start();
38
+		CompilerUtils.writeDefaultFieldInitializers(context, javaWriter, definition, true);
32 39
 	}
33 40
 
34 41
 	public void end() {
42
+		clinitStatementVisitor.end();
35 43
 	}
36 44
 
37 45
 	@Override
@@ -43,7 +51,15 @@ public class JavaExpansionMemberVisitor implements MemberVisitor<Void> {
43 51
 
44 52
 	@Override
45 53
 	public Void visitField(FieldMember member) {
46
-		throw new IllegalStateException("Cannot add fields via expansions");
54
+		if (!member.isStatic())
55
+			throw new IllegalStateException("Cannot add fields via expansions");
56
+
57
+		JavaField field = context.getJavaField(member);
58
+		writer.visitField(CompilerUtils.calcAccess(member.getEffectiveModifiers()), field.name, field.descriptor, field.signature, null).visitEnd();
59
+
60
+		return null;
61
+
62
+
47 63
 	}
48 64
 
49 65
 	@Override
@@ -150,6 +166,7 @@ public class JavaExpansionMemberVisitor implements MemberVisitor<Void> {
150 166
 
151 167
 	@Override
152 168
 	public Void visitStaticInitializer(StaticInitializerMember member) {
153
-		throw new IllegalStateException("Cannot add Static initializers via expansions");
169
+		member.body.accept(clinitStatementVisitor);
170
+		return null;
154 171
 	}
155 172
 }

Loading…
Zrušit
Uložit