def resolveGen(shouldBeTyp, normalTyp, generics, parser): if type(shouldBeTyp) is Types.T: if shouldBeTyp.normalName in generics: return generics[shouldBeTyp.normalName] else: generics[shouldBeTyp.normalName] = normalTyp return shouldBeTyp.type elif type(shouldBeTyp) is Types.Array: if type(normalTyp) != Types.Array: return shouldBeTyp t = Types.Array(False, resolveGen(shouldBeTyp.elemT, normalTyp.elemT, generics, parser)) return t elif type(shouldBeTyp) is Types.FuncPointer: args = [] if not type(normalTyp) is Types.FuncPointer: return shouldBeTyp if len(shouldBeTyp.args) != len(normalTyp.args): return shouldBeTyp if normalTyp.isLambda: try: shouldBeTyp = Types.replaceT(shouldBeTyp, generics) shouldBeTyp.duckType(parser, normalTyp, Tree.PlaceHolder(parser), Tree.PlaceHolder(parser), 0) except EOFError as e: normalTyp.check(parser) for (should, nor) in zip(shouldBeTyp.args, normalTyp.args): args.append(resolveGen(should, nor, generics, parser)) resolveGen(shouldBeTyp.returnType, normalTyp.returnType, generics, parser) return Types.replaceT(shouldBeTyp, generics) elif type(shouldBeTyp) in [Types.Struct, Types.Enum]: if not type(normalTyp) is Types.Struct: return shouldBeTyp self = shouldBeTyp other = normalTyp if self.package+"_"+self.normalName != other.package+"_"+other.normalName: return shouldBeTyp types = {} shouldGeneric = shouldBeTyp.remainingGen normalGeneric = normalTyp.gen for i in shouldGeneric: generics[i] = resolveGen(shouldGeneric[i], normalGeneric[i], generics, parser) if type(shouldBeTyp) is Types.Enum: return Types.Enum(self.package, self.normalName, self.const, generics) else: return Types.Struct(False, self.normalName, self.types, self.package, generics) elif type(shouldBeTyp) is Types.Assign: const = shouldBeTyp.const return Types.Assign(Types.replaceT(const, generics)) elif type(shouldBeTyp) is Types.Interface: types = {} for i in shouldBeTyp.types: try: types[i] = resolveGen(shouldBeTyp.types[i], normalTyp.types[i], generics, parser) except KeyError: try: meth = normalTyp.hasMethod(parser, i) if type(meth) is Types.FuncPointer: types[i] = resolveGen(shouldBeTyp.types[i], Types.FuncPointer(meth.args[1:], meth.returnType, generic= meth.generic, do= meth.do), generics, parser) elif meth: types[i] = meth else: types[i] = shouldBeTyp.types[i] except AttributeError: types[i] = shouldBeTyp.types[i] return Types.Interface(False, types, generics) else: return shouldBeTyp
def resolveGen(shouldBeTyp, normalTyp, generics, parser, myNode, other): if type(shouldBeTyp) is Types.Unknown: print("should be typ is unknown") if type(normalTyp) is Types.T and not ( normalTyp.owner in parser.func) and normalTyp.name != shouldBeTyp.name: if normalTyp.normalName in generics: normalTyp = generics[normalTyp.normalName] else: newTyp = Types.replaceT(shouldBeTyp, generics) tmp = normalTyp generics[normalTyp.normalName] = newTyp normalTyp = newTyp normalTyp = resolveGen(tmp.type, newTyp, generics, parser, myNode, other) normalTyp.duckType(parser, newTyp, myNode, other, 0) normalTyp = newTyp if type(shouldBeTyp) is Types.T: if shouldBeTyp.normalName in generics: tmp = generics[shouldBeTyp.normalName] try: tmp.duckType(parser, normalTyp, myNode, other, 0) except EOFError as e: normalTyp.duckType(parser, tmp, myNode, other, 0) generics[shouldBeTyp.normalName] = normalTyp return tmp else: generics[shouldBeTyp.normalName] = normalTyp if normalTyp.name != shouldBeTyp.name: tmp = shouldBeTyp.type tmp = resolveGen(tmp, normalTyp, generics, parser, myNode, other) tmp.duckType(parser, normalTyp, myNode, other, 0) else: tmp = shouldBeTyp #if Types.isGeneric(tmp): # resolveGen(tmp, normalTyp, generics, parser, myNode, other) #else: return normalTyp elif type(shouldBeTyp) is Types.Array: if type(normalTyp) != Types.Array: return shouldBeTyp try: t = Types.Array( False, resolveGen(shouldBeTyp.elemT, normalTyp.elemT, generics, parser, myNode, other)) except EOFError as e: Error.beforeError(e, "Element type in array: ") return t elif type(shouldBeTyp) is Types.FuncPointer: args = [] if not type(normalTyp) is Types.FuncPointer: return Types.replaceT(shouldBeTyp, generics) if len(shouldBeTyp.args) != len(normalTyp.args): return Types.replaceT(shouldBeTyp, generics) for (count, (should, nor)) in enumerate(zip(shouldBeTyp.args, normalTyp.args)): try: res = resolveGen(nor, should, generics, parser, myNode, other) args.append(res) except EOFError as e: Error.beforeError( e, "Function type argument " + str(count) + ": ") try: returnTyp = resolveGen(shouldBeTyp.returnType, normalTyp.returnType, generics, parser, myNode, other) except EOFError as e: Error.beforeError(e, "Function type return type: ") return Types.FuncPointer(args, returnTyp, do=shouldBeTyp.do) #return Types.replaceT(shouldBeTyp, generics) #return Types.FuncPointer(args, returnTyp, Types.remainingT(returnTyp), do = shouldBeTyp.do) elif type(shouldBeTyp) is Types.Tuple: if not type(normalTyp) is Types.Tuple: return shouldBeTyp arr = [] for (key, (should, nor)) in enumerate(zip(shouldBeTyp.list, normalTyp.list)): try: arr.append( resolveGen(should, nor, generics, parser, myNode, other)) except EOFError as e: Error.beforeError(e, "Tuple element #" + str(key) + ": ") return Types.Tuple(arr) elif type(shouldBeTyp) in [Types.Struct, Types.Enum, Types.Alias]: gen = generics if not type(normalTyp) is type(shouldBeTyp): return shouldBeTyp self = shouldBeTyp other = normalTyp if self.package + "_" + self.normalName != other.package + "_" + other.normalName: return shouldBeTyp types = {} shouldGeneric = shouldBeTyp.remainingGen if type(shouldBeTyp) in [Types.Enum, Types.Alias]: normalGeneric = normalTyp.generic else: normalGeneric = normalTyp.gen for i in shouldGeneric: try: generics[i] = resolveGen(shouldGeneric[i], normalGeneric[i], generics, parser, myNode, other) except EOFError as e: Error.beforeError( e, "Field '" + i + "' in " + str(shouldBeTyp) + ": ") if type(shouldBeTyp) is Types.Enum: return Types.Enum(self.package, self.normalName, self.const, generics) elif type(shouldBeTyp) is Types.Alias: return Types.Alias(self.package, self.normalName, Types.replaceT(self.typ, generics), generics) else: return Types.Struct(False, self.normalName, self.types, self.package, generics) elif type(shouldBeTyp) is Types.Assign: const = shouldBeTyp.const return Types.Assign(Types.replaceT(const, generics)) elif type(shouldBeTyp) is Types.Interface: types = {} for i in shouldBeTyp.types: try: types[i] = resolveGen(shouldBeTyp.types[i], normalTyp.types[i], generics, parser, myNode, other) except EOFError as e: Error.beforeError( e, "Field '" + i + "' in " + str(shouldBeTyp) + ": ") except KeyError: try: meth = normalTyp.hasMethod(parser, i) if type(meth) is Types.FuncPointer: types[i] = resolveGen( shouldBeTyp.types[i], Types.FuncPointer(meth.args[1:], meth.returnType, generic=meth.generic, do=meth.do), generics, parser, myNode, other) elif meth: types[i] = meth else: types[i] = shouldBeTyp.types[i] except AttributeError: types[i] = shouldBeTyp.types[i] gen = ODict() for key in shouldBeTyp.generic: gen[key] = Types.replaceT(shouldBeTyp.generic[key], generics) #gen = {i: generics[i] for i in generics if ".".join(i.split(".")[:-1]) == shouldBeTyp.normalName} r = Types.Interface(False, types, gen, shouldBeTyp.normalName) return r else: return shouldBeTyp