Пример #1
0
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
Пример #2
0
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