Parcourir la source

- Added key sorting to switches

- Fixed a couple more bugs with generics
Stan Hebben il y a 6 ans
Parent
révision
1c213dd186

+ 1
- 1
CodeFormatter/src/main/java/org/openzen/zenscript/formatter/FormattingUtils.java Voir le fichier

@@ -93,7 +93,7 @@ public class FormattingUtils {
93 93
 	}
94 94
 	
95 95
 	public static void formatTypeParameters(StringBuilder result, TypeParameter[] parameters, TypeFormatter typeFormatter) {
96
-		if (parameters.length > 0) {
96
+		if (parameters != null) {
97 97
 			result.append("<");
98 98
 			int index = 0;
99 99
 			for (TypeParameter parameter : parameters) {

+ 1
- 1
CodeFormatter/src/main/java/org/openzen/zenscript/formatter/TypeFormatter.java Voir le fichier

@@ -76,7 +76,7 @@ public class TypeFormatter implements ITypeVisitor<String>, GenericParameterBoun
76 76
 	@Override
77 77
 	public String visitDefinition(DefinitionTypeID definition) {
78 78
 		String importedName = importer.importDefinition(definition.definition);
79
-		if (definition.typeParameters.length == 0)
79
+		if (definition.typeParameters == null)
80 80
 			return importedName;
81 81
 		
82 82
 		StringBuilder result = new StringBuilder();

+ 14
- 8
CodeModel/src/main/java/org/openzen/zenscript/codemodel/FunctionHeader.java Voir le fichier

@@ -22,7 +22,6 @@ import org.openzen.zenscript.codemodel.type.member.LocalMemberCache;
22 22
  * @author Hoofdgebruiker
23 23
  */
24 24
 public class FunctionHeader {
25
-	private static final TypeParameter[] NO_GENERIC_PARAMETERS = new TypeParameter[0];
26 25
 	private static final FunctionParameter[] NO_PARAMETERS = new FunctionParameter[0];
27 26
 	
28 27
 	public final TypeParameter[] typeParameters;
@@ -30,13 +29,13 @@ public class FunctionHeader {
30 29
 	public final FunctionParameter[] parameters;
31 30
 	
32 31
 	public FunctionHeader(ITypeID returnType) {
33
-		this.typeParameters = NO_GENERIC_PARAMETERS;
32
+		this.typeParameters = null;
34 33
 		this.returnType = returnType;
35 34
 		this.parameters = NO_PARAMETERS;
36 35
 	}
37 36
 	
38 37
 	public FunctionHeader(ITypeID returnType, FunctionParameter... parameters) {
39
-		this.typeParameters = NO_GENERIC_PARAMETERS;
38
+		this.typeParameters = null;
40 39
 		this.returnType = returnType;
41 40
 		this.parameters = parameters;
42 41
 	}
@@ -47,10 +46,16 @@ public class FunctionHeader {
47 46
 		this.parameters = parameters;
48 47
 	}
49 48
 	
49
+	public int getNumberOfTypeParameters() {
50
+		return typeParameters == null ? 0 : typeParameters.length;
51
+	}
52
+	
50 53
 	public FunctionHeader instance(GlobalTypeRegistry registry, Map<TypeParameter, ITypeID> mapping) {
51
-		TypeParameter[] genericParameters = new TypeParameter[this.typeParameters.length];
52
-		for (int i = 0; i < genericParameters.length; i++)
53
-			genericParameters[i] = this.typeParameters[i].withGenericArguments(registry, mapping);
54
+		TypeParameter[] genericParameters = this.typeParameters == null ? null : new TypeParameter[this.typeParameters.length];
55
+		if (genericParameters != null)
56
+			for (int i = 0; i < genericParameters.length; i++)
57
+				genericParameters[i] = this.typeParameters[i].withGenericArguments(registry, mapping);
58
+		
54 59
 		ITypeID returnType = this.returnType.withGenericArguments(registry, mapping);
55 60
 		FunctionParameter[] parameters = new FunctionParameter[this.parameters.length];
56 61
 		for (int i = 0; i < parameters.length; i++)
@@ -193,8 +198,9 @@ public class FunctionHeader {
193 198
 	
194 199
 	public FunctionHeader withGenericArguments(GlobalTypeRegistry registry, ITypeID[] arguments) {
195 200
 		Map<TypeParameter, ITypeID> typeArguments = new HashMap<>();
196
-		for (int i = 0; i < typeParameters.length; i++)
197
-			typeArguments.put(typeParameters[i], arguments[i]);
201
+		if (typeParameters != null)
202
+			for (int i = 0; i < typeParameters.length; i++)
203
+				typeArguments.put(typeParameters[i], arguments[i]);
198 204
 		
199 205
 		ITypeID returnType = this.returnType.withGenericArguments(registry, typeArguments);
200 206
 		FunctionParameter[] parameters = new FunctionParameter[this.parameters.length];

+ 4
- 0
CodeModel/src/main/java/org/openzen/zenscript/codemodel/expression/CallArguments.java Voir le fichier

@@ -32,4 +32,8 @@ public class CallArguments {
32 32
 		this.typeArguments = typeArguments;
33 33
 		this.arguments = arguments;
34 34
 	}
35
+	
36
+	public int getNumberOfTypeArguments() {
37
+		return typeArguments.length;
38
+	}
35 39
 }

+ 1
- 1
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/DefinitionTypeID.java Voir le fichier

@@ -19,7 +19,7 @@ import org.openzen.zenscript.codemodel.generic.TypeParameter;
19 19
  */
20 20
 public class DefinitionTypeID implements ITypeID {
21 21
 	public static DefinitionTypeID forType(HighLevelDefinition definition) {
22
-		if (definition.genericParameters.length > 0)
22
+		if (definition.genericParameters != null)
23 23
 			throw new IllegalArgumentException("Definition has type arguments!");
24 24
 		
25 25
 		return new DefinitionTypeID(definition, null);

+ 5
- 3
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/ITypeID.java Voir le fichier

@@ -131,9 +131,11 @@ public interface ITypeID {
131 131
 				if (definitionType.definition != definition.definition)
132 132
 					return false;
133 133
 				
134
-				for (int i = 0; i < definitionType.typeParameters.length; i++) {
135
-					if (!match(definitionType.typeParameters[i], definition.typeParameters[i]))
136
-						return false;
134
+				if (definition.typeParameters != null) {
135
+					for (int i = 0; i < definitionType.typeParameters.length; i++) {
136
+						if (!match(definitionType.typeParameters[i], definition.typeParameters[i]))
137
+							return false;
138
+					}
137 139
 				}
138 140
 				
139 141
 				return true;

+ 3
- 3
CodeModel/src/main/java/org/openzen/zenscript/codemodel/type/member/DefinitionMemberGroup.java Voir le fichier

@@ -215,7 +215,7 @@ public class DefinitionMemberGroup {
215 215
 			if (header.parameters.length != arguments)
216 216
 				continue;
217 217
 			
218
-			if (header.typeParameters.length > 0) {
218
+			if (header.typeParameters != null) {
219 219
 				for (ITypeID resultHint : typeHints) {
220 220
 					Map<TypeParameter, ITypeID> mapping = new HashMap<>();
221 221
 					if (header.returnType.inferTypeParameters(scope.getMemberCache(), resultHint, mapping)) {
@@ -293,7 +293,7 @@ public class DefinitionMemberGroup {
293 293
 			FunctionHeader header = method.member.getHeader();
294 294
 			if (header.parameters.length != arguments.arguments.length)
295 295
 				continue;
296
-			if (header.typeParameters.length != arguments.typeArguments.length)
296
+			if (header.getNumberOfTypeParameters() != arguments.getNumberOfTypeArguments())
297 297
 				continue;
298 298
 			
299 299
 			if (arguments.typeArguments.length > 0) {
@@ -317,7 +317,7 @@ public class DefinitionMemberGroup {
317 317
 			FunctionHeader header = method.member.getHeader();
318 318
 			if (header.parameters.length != arguments.arguments.length)
319 319
 				continue;
320
-			if (header.typeParameters.length != arguments.typeArguments.length)
320
+			if (header.getNumberOfTypeParameters() != arguments.getNumberOfTypeArguments())
321 321
 				continue;
322 322
 			
323 323
 			if (arguments.typeArguments.length > 0) {

+ 13
- 12
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaStatementVisitor.java Voir le fichier

@@ -163,24 +163,25 @@ public class JavaStatementVisitor implements StatementVisitor<Boolean> {
163 163
         final boolean hasNoDefault = hasNoDefault(statement);
164 164
 
165 165
         final List<SwitchCase> cases = statement.cases;
166
-
167
-        final int[] keys = new int[hasNoDefault ? cases.size() : cases.size() - 1];
168
-        final Label[] labels = new Label[keys.length];
166
+		final JavaSwitchLabel[] switchLabels = new JavaSwitchLabel[hasNoDefault ? cases.size() : cases.size() - 1];
169 167
         final Label defaultLabel = new Label();
170
-
171
-        Arrays.parallelSetAll(labels, value -> new Label());
172
-
168
+		
173 169
         int i = 0;
174
-        for (final SwitchCase switchCase : cases)
175
-            if (switchCase.value != null)
176
-                keys[i++] = CompilerUtils.getKeyForSwitch(switchCase.value);
170
+        for (final SwitchCase switchCase : cases) {
171
+            if (switchCase.value != null) {
172
+				switchLabels[i++] = new JavaSwitchLabel(CompilerUtils.getKeyForSwitch(switchCase.value), new Label());
173
+			}
174
+		}
175
+		
176
+		JavaSwitchLabel[] sortedSwitchLabels = Arrays.copyOf(switchLabels, switchLabels.length);
177
+		Arrays.sort(sortedSwitchLabels, (a, b) -> a.key - b.key);
177 178
 
178
-        javaWriter.lookupSwitch(defaultLabel, keys, labels);
179
+        javaWriter.lookupSwitch(defaultLabel, sortedSwitchLabels);
179 180
 
180 181
         i = 0;
181 182
         for (final SwitchCase switchCase : cases) {
182 183
             if (hasNoDefault || switchCase.value != null) {
183
-                javaWriter.label(labels[i++]);
184
+                javaWriter.label(switchLabels[i++].label);
184 185
             } else {
185 186
                 javaWriter.label(defaultLabel);
186 187
             }
@@ -203,7 +204,7 @@ public class JavaStatementVisitor implements StatementVisitor<Boolean> {
203 204
         for (SwitchCase switchCase : switchStatement.cases)
204 205
             if (switchCase.value == null) return false;
205 206
         return true;
206
-    }
207
+	}
207 208
 
208 209
     @Override
209 210
     public Boolean visitThrow(ThrowStatement statement) {

+ 22
- 0
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaSwitchLabel.java Voir le fichier

@@ -0,0 +1,22 @@
1
+/*
2
+ * To change this license header, choose License Headers in Project Properties.
3
+ * To change this template file, choose Tools | Templates
4
+ * and open the template in the editor.
5
+ */
6
+package org.openzen.zenscript.javabytecode.compiler;
7
+
8
+import org.objectweb.asm.Label;
9
+
10
+/**
11
+ *
12
+ * @author Hoofdgebruiker
13
+ */
14
+public class JavaSwitchLabel {
15
+	public final int key;
16
+	public final Label label;
17
+	
18
+	public JavaSwitchLabel(int key, Label label) {
19
+		this.key = key;
20
+		this.label = label;
21
+	}
22
+}

+ 8
- 1
JavaBytecodeCompiler/src/main/java/org/openzen/zenscript/javabytecode/compiler/JavaWriter.java Voir le fichier

@@ -1128,7 +1128,14 @@ public class JavaWriter {
1128 1128
             visitor.visitParameter(name, modifier);
1129 1129
     }
1130 1130
 
1131
-    public void lookupSwitch(Label defaultLabel, int[] keys, Label[] labels) {
1131
+    public void lookupSwitch(Label defaultLabel, JavaSwitchLabel[] switchLabels) {
1132
+		int[] keys = new int[switchLabels.length];
1133
+		Label[] labels = new Label[switchLabels.length];
1134
+		for (int i = 0; i < switchLabels.length; i++) {
1135
+			keys[i] = switchLabels[i].key;
1136
+			labels[i] = switchLabels[i].label;
1137
+		}
1138
+		
1132 1139
         visitor.visitLookupSwitchInsn(defaultLabel, keys, labels);
1133 1140
     }
1134 1141
 

+ 1
- 1
Linker/src/main/java/org/openzen/zenscript/linker/ExpressionScope.java Voir le fichier

@@ -80,7 +80,7 @@ public class ExpressionScope extends BaseScope {
80 80
 	}
81 81
 	
82 82
 	public ExpressionScope forCall(FunctionHeader header) {
83
-		if (header.typeParameters.length == 0)
83
+		if (header.typeParameters == null)
84 84
 			return this;
85 85
 		
86 86
 		Map<TypeParameter, ITypeID> genericInferenceMap = new HashMap<>();

+ 10
- 6
Linker/src/main/java/org/openzen/zenscript/linker/FunctionScope.java Voir le fichier

@@ -61,9 +61,11 @@ public class FunctionScope extends StatementScope {
61 61
 				}
62 62
 			}
63 63
 			
64
-			for (TypeParameter parameter : header.typeParameters) {
65
-				if (parameter.name.equals(name.name))
66
-					return new PartialTypeExpression(position, getTypeRegistry().getGeneric(parameter));
64
+			if (header.typeParameters != null) {
65
+				for (TypeParameter parameter : header.typeParameters) {
66
+					if (parameter.name.equals(name.name))
67
+						return new PartialTypeExpression(position, getTypeRegistry().getGeneric(parameter));
68
+				}
67 69
 			}
68 70
 		}
69 71
 		
@@ -73,9 +75,11 @@ public class FunctionScope extends StatementScope {
73 75
 	@Override
74 76
 	public ITypeID getType(CodePosition position, List<GenericName> name) {
75 77
 		if (name.size() == 1 && name.get(0).hasNoArguments()) {
76
-			for (TypeParameter parameter : header.typeParameters) {
77
-				if (parameter.name.equals(name.get(0).name))
78
-					return getTypeRegistry().getGeneric(parameter);
78
+			if (header.typeParameters != null) {
79
+				for (TypeParameter parameter : header.typeParameters) {
80
+					if (parameter.name.equals(name.get(0).name))
81
+						return getTypeRegistry().getGeneric(parameter);
82
+				}
79 83
 			}
80 84
 		}
81 85
 		

+ 2
- 1
Parser/src/main/java/org/openzen/zenscript/parser/definitions/ParsedFunctionHeader.java Voir le fichier

@@ -34,8 +34,9 @@ import org.openzen.zenscript.parser.type.ParsedTypeBasic;
34 34
  */
35 35
 public class ParsedFunctionHeader {
36 36
 	public static ParsedFunctionHeader parse(ZSTokenStream tokens) {
37
-		List<ParsedGenericParameter> genericParameters = new ArrayList<>();
37
+		List<ParsedGenericParameter> genericParameters = null;
38 38
 		if (tokens.optional(ZSTokenType.T_LESS) != null) {
39
+			genericParameters = new ArrayList<>();
39 40
 			do {
40 41
 				genericParameters.add(ParsedGenericParameter.parse(tokens));
41 42
 			} while (tokens.optional(ZSTokenType.T_COMMA) != null);

+ 3
- 3
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedCallArguments.java Voir le fichier

@@ -87,7 +87,7 @@ public class ParsedCallArguments {
87 87
 			innerScope = scope.forCall(candidates.get(0));
88 88
 		} else {
89 89
 			candidates = candidates.stream()
90
-					.filter(candidate -> candidate.typeParameters.length == 0)
90
+					.filter(candidate -> candidate.typeParameters == null)
91 91
 					.collect(Collectors.toList());
92 92
 			
93 93
 			if (candidates.isEmpty()) {
@@ -115,7 +115,7 @@ public class ParsedCallArguments {
115 115
 		ITypeID[] typeParameters = genericParameters;
116 116
 		if (typeParameters == null) {
117 117
 			for (FunctionHeader candidate : candidates) {
118
-				if (candidate.typeParameters.length > 0) {
118
+				if (candidate.typeParameters != null) {
119 119
 					typeParameters = new ITypeID[candidate.typeParameters.length];
120 120
 					for (int i = 0; i < typeParameters.length; i++) {
121 121
 						if (innerScope.genericInferenceMap.get(candidate.typeParameters[i]) == null)
@@ -146,7 +146,7 @@ public class ParsedCallArguments {
146 146
 			return false;
147 147
 		
148 148
 		for (int i = 0; i < arguments.size(); i++) {
149
-			if (typeParameters == null && header.parameters[i].type.hasInferenceBlockingTypeParameters(header.typeParameters))
149
+			if (typeParameters == null && header.typeParameters != null && header.parameters[i].type.hasInferenceBlockingTypeParameters(header.typeParameters))
150 150
 				return false;
151 151
 			
152 152
 			if (!arguments.get(i).isCompatibleWith(scope, header.parameters[i].type))

Loading…
Annuler
Enregistrer