Browse Source

Fix generic call arguments being overridden by the generic mapper's selfmapping

kindlich 4 years ago
parent
commit
d02abd30c3
No known key found for this signature in database

+ 91
- 85
CodeModel/src/main/java/org/openzen/zenscript/codemodel/GenericMapper.java View File

@@ -5,94 +5,100 @@
5 5
  */
6 6
 package org.openzen.zenscript.codemodel;
7 7
 
8
-import java.util.Collections;
9
-import java.util.HashMap;
10
-import java.util.Map;
11
-import org.openzen.zencode.shared.CodePosition;
12
-import org.openzen.zenscript.codemodel.generic.TypeParameter;
13
-import org.openzen.zenscript.codemodel.type.GenericTypeID;
14
-import org.openzen.zenscript.codemodel.type.GlobalTypeRegistry;
15
-import org.openzen.zenscript.codemodel.type.StoredType;
8
+import org.openzen.zencode.shared.*;
9
+import org.openzen.zenscript.codemodel.generic.*;
10
+import org.openzen.zenscript.codemodel.type.*;
11
+
12
+import java.util.*;
16 13
 
17 14
 /**
18
- *
19 15
  * @author Hoofdgebruiker
20 16
  */
21 17
 public class GenericMapper {
22
-	public static final GenericMapper EMPTY = new GenericMapper(CodePosition.BUILTIN, null, Collections.emptyMap());
23
-	
24
-	public final CodePosition position;
25
-	public final GlobalTypeRegistry registry;
26
-	private final Map<TypeParameter, StoredType> mapping;
27
-	
28
-	public GenericMapper(CodePosition position, GlobalTypeRegistry registry, Map<TypeParameter, StoredType> mapping) {
29
-		if (mapping == null)
30
-			throw new IllegalArgumentException();
31
-		
32
-		this.position = position;
33
-		this.registry = registry;
34
-		this.mapping = mapping;
35
-	}
36
-	
37
-	public Map<TypeParameter, StoredType> getMapping() {
38
-		return mapping;
39
-	}
40
-	
41
-	public StoredType map(StoredType original) {
42
-		return mapping.isEmpty() ? original : original.instance(this);
43
-	}
44
-	
45
-	public StoredType[] map(StoredType[] original) {
46
-		if (mapping.isEmpty() || original.length == 0)
47
-			return original;
48
-		
49
-		StoredType[] mapped = new StoredType[original.length];
50
-		for (int i = 0; i < original.length; i++)
51
-			mapped[i] = original[i].instance(this);
52
-		return mapped;
53
-	}
54
-	
55
-	public StoredType map(GenericTypeID type) {
56
-		//if (!mapping.containsKey(type.parameter))
57
-		//	throw new IllegalStateException("No mapping found for type " + type);
58
-		
59
-		return mapping.containsKey(type.parameter) ? mapping.get(type.parameter) : type.stored();
60
-	}
61
-	
62
-	public FunctionHeader map(FunctionHeader original) {
63
-		return mapping.isEmpty() ? original : original.withGenericArguments(this);
64
-	}
65
-	
66
-	public GenericMapper getInner(CodePosition position, GlobalTypeRegistry registry, Map<TypeParameter, StoredType> mapping) {
67
-		Map<TypeParameter, StoredType> resultMap = new HashMap<>(this.mapping);
68
-		resultMap.putAll(mapping);
69
-		return new GenericMapper(position, registry, resultMap);
70
-	}
71
-	
72
-	public GenericMapper getInner(CodePosition position, GlobalTypeRegistry registry, TypeParameter[] parameters) {
73
-		Map<TypeParameter, StoredType> resultMap = new HashMap<>(this.mapping);
74
-		for (TypeParameter parameter : parameters)
75
-			resultMap.put(parameter, new StoredType(registry.getGeneric(parameter), null));
76
-		return new GenericMapper(position, registry, resultMap);
77
-	}
78
-	
79
-	@Override
80
-	public String toString() {
81
-		if (mapping.isEmpty())
82
-			return "{}";
83
-		
84
-		StringBuilder result = new StringBuilder();
85
-		result.append('{');
86
-		boolean first = true;
87
-		for (Map.Entry<TypeParameter, StoredType> entry : mapping.entrySet()) {
88
-			if (first) {
89
-				first = false;
90
-			} else {
91
-				result.append(", ");
92
-			}
93
-			result.append(entry.getKey().toString()).append(": ").append(entry.getValue());
94
-		}
95
-		result.append('}');
96
-		return result.toString();
97
-	}
18
+    
19
+    public static final GenericMapper EMPTY = new GenericMapper(CodePosition.BUILTIN, null, Collections
20
+            .emptyMap());
21
+    
22
+    public final CodePosition position;
23
+    public final GlobalTypeRegistry registry;
24
+    private final Map<TypeParameter, StoredType> mapping;
25
+    
26
+    public GenericMapper(CodePosition position, GlobalTypeRegistry registry, Map<TypeParameter, StoredType> mapping) {
27
+        if(mapping == null)
28
+            throw new IllegalArgumentException();
29
+        
30
+        this.position = position;
31
+        this.registry = registry;
32
+        this.mapping = mapping;
33
+    }
34
+    
35
+    public Map<TypeParameter, StoredType> getMapping() {
36
+        return mapping;
37
+    }
38
+    
39
+    public StoredType map(StoredType original) {
40
+        return mapping.isEmpty() ? original : original.instance(this);
41
+    }
42
+    
43
+    public StoredType[] map(StoredType[] original) {
44
+        if(mapping.isEmpty() || original.length == 0)
45
+            return original;
46
+        
47
+        StoredType[] mapped = new StoredType[original.length];
48
+        for(int i = 0; i < original.length; i++)
49
+            mapped[i] = original[i].instance(this);
50
+        return mapped;
51
+    }
52
+    
53
+    public StoredType map(GenericTypeID type) {
54
+        //if (!mapping.containsKey(type.parameter))
55
+        //	throw new IllegalStateException("No mapping found for type " + type);
56
+        
57
+        return mapping.containsKey(type.parameter) ? mapping.get(type.parameter) : type.stored();
58
+    }
59
+    
60
+    public FunctionHeader map(FunctionHeader original) {
61
+        return mapping.isEmpty() ? original : original.withGenericArguments(this);
62
+    }
63
+    
64
+    public GenericMapper getInner(CodePosition position, GlobalTypeRegistry registry, Map<TypeParameter, StoredType> mapping) {
65
+        Map<TypeParameter, StoredType> resultMap = new HashMap<>(this.mapping);
66
+        mapping.forEach((typeParameter, storedType) -> {
67
+            if(resultMap.containsKey(typeParameter)) {
68
+                if(storedType.type instanceof GenericTypeID && ((GenericTypeID) storedType.type).parameter == typeParameter) {
69
+                    return;
70
+                }
71
+            }
72
+            resultMap.put(typeParameter, storedType);
73
+        });
74
+        
75
+        return new GenericMapper(position, registry, resultMap);
76
+    }
77
+    
78
+    public GenericMapper getInner(CodePosition position, GlobalTypeRegistry registry, TypeParameter[] parameters) {
79
+        Map<TypeParameter, StoredType> resultMap = new HashMap<>(this.mapping);
80
+        for(TypeParameter parameter : parameters)
81
+            resultMap.put(parameter, new StoredType(registry.getGeneric(parameter), null));
82
+        return new GenericMapper(position, registry, resultMap);
83
+    }
84
+    
85
+    @Override
86
+    public String toString() {
87
+        if(mapping.isEmpty())
88
+            return "{}";
89
+        
90
+        StringBuilder result = new StringBuilder();
91
+        result.append('{');
92
+        boolean first = true;
93
+        for(Map.Entry<TypeParameter, StoredType> entry : mapping.entrySet()) {
94
+            if(first) {
95
+                first = false;
96
+            } else {
97
+                result.append(", ");
98
+            }
99
+            result.append(entry.getKey().toString()).append(": ").append(entry.getValue());
100
+        }
101
+        result.append('}');
102
+        return result.toString();
103
+    }
98 104
 }

+ 17
- 5
Parser/src/main/java/org/openzen/zenscript/parser/expression/ParsedCallArguments.java View File

@@ -5,16 +5,14 @@
5 5
  */
6 6
 package org.openzen.zenscript.parser.expression;
7 7
 
8
-import java.util.ArrayList;
9
-import java.util.Collections;
10
-import java.util.List;
8
+import java.util.*;
11 9
 import java.util.stream.Collectors;
12 10
 import org.openzen.zencode.shared.CodePosition;
13 11
 import org.openzen.zencode.shared.CompileException;
14 12
 import org.openzen.zencode.shared.CompileExceptionCode;
13
+import org.openzen.zenscript.codemodel.*;
14
+import org.openzen.zenscript.codemodel.generic.*;
15 15
 import org.openzen.zenscript.lexer.ZSTokenType;
16
-import org.openzen.zenscript.codemodel.FunctionHeader;
17
-import org.openzen.zenscript.codemodel.FunctionParameter;
18 16
 import org.openzen.zenscript.codemodel.expression.CallArguments;
19 17
 import org.openzen.zenscript.codemodel.expression.Expression;
20 18
 import org.openzen.zenscript.codemodel.partial.IPartialExpression;
@@ -144,7 +142,21 @@ public class ParsedCallArguments {
144 142
 		for (FunctionHeader header : candidates) {
145 143
 			//TODO: this is wrong!
146 144
 			boolean variadic = header.isVariadic();
145
+   
146
+			type_parameter_replacement:
147
+            if(typeArguments != null && typeArguments.length > 0 && header.typeParameters.length == typeArguments.length) {
148
+                final Map<TypeParameter, StoredType> types = new HashMap<>();
149
+                for(int i = 0; i < header.typeParameters.length; i++) {
150
+                    if(!header.typeParameters[i].matches(scope.getMemberCache(), typeArguments[i].type)) {
151
+                        break type_parameter_replacement;
152
+                    }
153
+                    types.put(header.typeParameters[i], typeArguments[i]);
154
+                }
155
+                header = header.withGenericArguments(new GenericMapper(position, scope.getTypeRegistry(), types));
156
+            }
157
+			
147 158
 			for (int i = 0; i < arguments.size(); i++) {
159
+			    
148 160
 				final StoredType parameterType = header.getParameterType(variadic, i);
149 161
 				if (!predictedTypes[i].contains(parameterType))
150 162
 					predictedTypes[i].add(parameterType);

Loading…
Cancel
Save