コード例 #1
0
 def resolve_type(self, type, must_resolve_all_generics):
     if isinstance(type, astTypes.GenericsType):
         resolved_type = self.resolution_map.get(type.type_var_name)
         if resolved_type == None and must_resolve_all_generics:
             raise Error(
                 f'''Could not resolve generics type: {type.repr()}''')
         return resolved_type if resolved_type != None else type
     elif isinstance(type, astTypes.ClassType):
         return astTypes.ClassType(
             type.decl,
             list(
                 map(
                     lambda x: self.resolve_type(x,
                                                 must_resolve_all_generics),
                     type.type_arguments)))
     elif isinstance(type, astTypes.InterfaceType):
         return astTypes.InterfaceType(
             type.decl,
             list(
                 map(
                     lambda x: self.resolve_type(x,
                                                 must_resolve_all_generics),
                     type.type_arguments)))
     elif isinstance(type, astTypes.LambdaType):
         return astTypes.LambdaType(
             list(
                 map(
                     lambda x: types.MethodParameter(
                         x.name,
                         self.resolve_type(x.type, must_resolve_all_generics
                                           ), x.initializer, None),
                     type.parameters)),
             self.resolve_type(type.return_type, must_resolve_all_generics))
     else:
         return type
コード例 #2
0
    def detect_type(self, expr):
        if expr.expected_type == None:
            # make this work: `<{ [name: string]: SomeObject }> {}`
            if isinstance(expr.parent_node, exprs.CastExpression):
                expr.set_expected_type(expr.parent_node.new_type)
            elif isinstance(
                    expr.parent_node, exprs.BinaryExpression
            ) and expr.parent_node.operator == "=" and expr.parent_node.right == expr:
                expr.set_expected_type(expr.parent_node.left.actual_type)
            elif isinstance(expr.parent_node,
                            exprs.ConditionalExpression) and (
                                expr.parent_node.when_true == expr
                                or expr.parent_node.when_false == expr):
                expr.set_expected_type(
                    expr.parent_node.when_false.actual_type if expr.
                    parent_node.when_true ==
                    expr else expr.parent_node.when_true.actual_type)

        if isinstance(expr, exprs.ArrayLiteral):
            item_type = self.infer_array_or_map_item_type(
                expr.items, expr.expected_type, False)
            expr.set_actual_type(
                astTypes.ClassType(
                    self.main.current_file.literal_types.array.decl,
                    [item_type]))
        elif isinstance(expr, exprs.MapLiteral):
            item_type = self.infer_array_or_map_item_type(
                list(map(lambda x: x.value, expr.items)), expr.expected_type,
                True)
            expr.set_actual_type(
                astTypes.ClassType(
                    self.main.current_file.literal_types.map.decl,
                    [item_type]))

        return True
コード例 #3
0
 def create_expression_parser(self, reader, node_manager=None):
     expression_parser = exprPars.ExpressionParser(reader, self,
                                                   node_manager)
     expression_parser.string_literal_type = astTypes.UnresolvedType(
         "TsString", [])
     expression_parser.numeric_literal_type = astTypes.UnresolvedType(
         "TsNumber", [])
     return expression_parser
コード例 #4
0
 def __init__(self, name, type_arguments, base_interfaces, fields, methods,
              is_exported, leading_trivia):
     self.name = name
     self.type_arguments = type_arguments
     self.base_interfaces = base_interfaces
     self.fields = fields
     self.methods = methods
     self.is_exported = is_exported
     self.leading_trivia = leading_trivia
     self.parent_file = None
     self.attributes = None
     self.type = astTypes.InterfaceType(
         self,
         list(map(lambda x: astTypes.GenericsType(x), self.type_arguments)))
     self._base_interface_cache = None
コード例 #5
0
    def parse(self, precedence=0, required=True):
        self.reader.skip_whitespace()
        left_start = self.reader.offset
        left = self.parse_left(required)
        if left == None:
            return None
        self.add_node(left, left_start)

        while True:
            if self.hooks != None:
                parsed = self.hooks.infix_prehook(left)
                if parsed != None:
                    left = parsed
                    self.add_node(left, left_start)
                    continue

            op = self.parse_operator()
            if op == None or op.precedence <= precedence:
                break
            self.reader.expect_token(op.text)
            op_text = self.config.aliases.get(
                op.text) if op.text in self.config.aliases else op.text

            if op.is_binary:
                right = self.parse(op.precedence -
                                   1 if op.is_right_assoc else op.precedence)
                left = exprs.BinaryExpression(left, op_text, right)
            elif op.is_postfix:
                left = exprs.UnaryExpression(exprs.UNARY_TYPE.POSTFIX, op_text,
                                             left)
            elif op.text == "?":
                when_true = self.parse()
                self.reader.expect_token(":")
                when_false = self.parse(op.precedence - 1)
                left = exprs.ConditionalExpression(left, when_true, when_false)
            elif op.text == "(":
                args = self.parse_call_arguments()
                left = exprs.UnresolvedCallExpression(left, [], args)
            elif op.text == "[":
                element_expr = self.parse()
                self.reader.expect_token("]")
                left = exprs.ElementAccessExpression(left, element_expr)
            elif op.text in self.config.property_access_ops:
                prop = self.reader.expect_identifier(
                    "expected identifier as property name")
                left = exprs.PropertyAccessExpression(left, prop)
            else:
                self.reader.fail(
                    f'''parsing \'{op.text}\' is not yet implemented''')

            self.add_node(left, left_start)

        if isinstance(left, exprs.ParenthesizedExpression) and isinstance(
                left.expression, exprs.Identifier):
            expr = self.parse(0, False)
            if expr != None:
                return exprs.CastExpression(
                    astTypes.UnresolvedType(left.expression.text, []), expr)

        return left
コード例 #6
0
 def handle_lambda(self, lambda_):
     self.start()
     self.main.process_lambda(lambda_)
     lambda_.returns = self.finish(lambda_.returns, "Lambda", None)
     lambda_.set_actual_type(
         astTypes.LambdaType(lambda_.parameters, lambda_.returns), False,
         True)
     return True
コード例 #7
0
 def visit_type(self, type):
     super().visit_type(type)
     
     #console.log(type && type.constructor.name, JSON.stringify(type));
     if isinstance(type, astTypes.UnresolvedType) and ((isinstance(self.current_interface, types.Class) and type.type_name in self.current_interface.type_arguments) or (isinstance(self.current_method, types.Method) and type.type_name in self.current_method.type_arguments)):
         return astTypes.GenericsType(type.type_name)
     
     return type
コード例 #8
0
 def __init__(self, name, values, is_exported, leading_trivia):
     self.name = name
     self.values = values
     self.is_exported = is_exported
     self.leading_trivia = leading_trivia
     self.parent_file = None
     self.attributes = None
     self.references = []
     self.type = astTypes.EnumType(self)
コード例 #9
0
 def __init__(self, name, type_arguments, base_class, base_interfaces,
              fields, properties, constructor_, methods, is_exported,
              leading_trivia):
     self.name = name
     self.type_arguments = type_arguments
     self.base_class = base_class
     self.base_interfaces = base_interfaces
     self.fields = fields
     self.properties = properties
     self.constructor_ = constructor_
     self.methods = methods
     self.is_exported = is_exported
     self.leading_trivia = leading_trivia
     self.parent_file = None
     self.attributes = None
     self.class_references = []
     self.this_references = []
     self.static_this_references = []
     self.super_references = []
     self.type = astTypes.ClassType(
         self,
         list(map(lambda x: astTypes.GenericsType(x), self.type_arguments)))
     self._base_interface_cache = None
コード例 #10
0
    def visit_type(self, type):
        super().visit_type(type)
        if isinstance(type, astTypes.UnresolvedType):
            if self.current_interface != None and type.type_name in self.current_interface.type_arguments:
                return astTypes.GenericsType(type.type_name)

            symbol = self.current_file.available_symbols.get(type.type_name)
            if symbol == None:
                self.error_man.throw(
                    f'''Unresolved type \'{type.type_name}\' was not found in available symbols'''
                )
                return type

            if isinstance(symbol, types.Class):
                return astTypes.ClassType(symbol, type.type_arguments)
            elif isinstance(symbol, types.Interface):
                return astTypes.InterfaceType(symbol, type.type_arguments)
            elif isinstance(symbol, types.Enum):
                return astTypes.EnumType(symbol)
            else:
                self.error_man.throw(f'''Unknown symbol type: {symbol}''')
                return type
        else:
            return type
コード例 #11
0
    def parse_type(self):
        if self.reader.read_token("{"):
            self.reader.expect_token("[")
            self.reader.read_identifier()
            self.reader.expect_token(":")
            self.reader.expect_token("string")
            self.reader.expect_token("]")
            self.reader.expect_token(":")
            map_value_type = self.parse_type()
            self.reader.read_token(";")
            self.reader.expect_token("}")
            return astTypes.UnresolvedType("TsMap", [map_value_type])

        if self.reader.peek_token("("):
            params = self.parse_lambda_params()
            self.reader.expect_token("=>")
            return_type = self.parse_type()
            return astTypes.LambdaType(params, return_type)

        type_name = self.reader.expect_identifier()
        start_pos = self.reader.prev_token_offset

        if type_name == "string":
            type = astTypes.UnresolvedType("TsString", [])
        elif type_name == "boolean":
            type = astTypes.UnresolvedType("TsBoolean", [])
        elif type_name == "number":
            type = astTypes.UnresolvedType("TsNumber", [])
        elif type_name == "any":
            type = astTypes.AnyType.instance
        elif type_name == "void":
            type = astTypes.VoidType.instance
        else:
            type_arguments = self.parse_type_args()
            type = astTypes.UnresolvedType(type_name, type_arguments)

        self.node_manager.add_node(type, start_pos)

        while self.reader.read_token("[]"):
            type = astTypes.UnresolvedType("TsArray", [type])
            self.node_manager.add_node(type, start_pos)

        return type
コード例 #12
0
 def parse_specified_type(self):
     type_name = self.reader.read_identifier()
     type_args = self.parse_type_args()
     return astTypes.UnresolvedType(type_name, type_args)
コード例 #13
0
    def unary_prehook(self):
        if self.reader.read_token("null"):
            return exprs.NullLiteral()
        elif self.reader.read_token("true"):
            return exprs.BooleanLiteral(True)
        elif self.reader.read_token("false"):
            return exprs.BooleanLiteral(False)
        elif self.reader.read_token("`"):
            parts = []
            lit_part = ""
            while True:
                if self.reader.read_exactly("`"):
                    if lit_part != "":
                        parts.append(
                            exprs.TemplateStringPart.literal(lit_part))
                        lit_part = ""

                    break
                elif self.reader.read_exactly("${"):
                    if lit_part != "":
                        parts.append(
                            exprs.TemplateStringPart.literal(lit_part))
                        lit_part = ""

                    expr = self.parse_expression()
                    parts.append(exprs.TemplateStringPart.expression(expr))
                    self.reader.expect_token("}")
                elif self.allow_dollar_ids and self.reader.read_exactly("$"):
                    if lit_part != "":
                        parts.append(
                            exprs.TemplateStringPart.literal(lit_part))
                        lit_part = ""

                    id = self.reader.read_identifier()
                    parts.append(
                        exprs.TemplateStringPart.expression(
                            exprs.Identifier(id)))
                elif self.reader.read_exactly("\\"):
                    chr = self.reader.read_char()
                    if chr == "n":
                        lit_part += "\n"
                    elif chr == "r":
                        lit_part += "\r"
                    elif chr == "t":
                        lit_part += "\t"
                    elif chr == "`":
                        lit_part += "`"
                    elif chr == "$":
                        lit_part += "$"
                    elif chr == "\\":
                        lit_part += "\\"
                    else:
                        self.reader.fail("invalid escape",
                                         self.reader.offset - 1)
                else:
                    chr = self.reader.read_char()
                    chr_code = ord(chr[0])
                    if not (32 <= chr_code
                            and chr_code <= 126) or chr == "`" or chr == "\\":
                        self.reader.fail(
                            f'''not allowed character (code={chr_code})''',
                            self.reader.offset - 1)
                    lit_part += chr
            return exprs.TemplateString(parts)
        elif self.reader.read_token("new"):
            type = self.parse_type()
            if isinstance(type, astTypes.UnresolvedType):
                self.reader.expect_token("(")
                args = self.expression_parser.parse_call_arguments()
                return exprs.UnresolvedNewExpression(type, args)
            else:
                raise Error(
                    f'''[TypeScriptParser2] Expected UnresolvedType here!''')
        elif self.reader.read_token("<"):
            new_type = self.parse_type()
            self.reader.expect_token(">")
            expression = self.parse_expression()
            return exprs.CastExpression(new_type, expression)
        elif self.reader.read_token("/"):
            pattern = ""
            while True:
                chr = self.reader.read_char()
                if chr == "\\":
                    chr2 = self.reader.read_char()
                    pattern += "/" if chr2 == "/" else "\\" + chr2
                elif chr == "/":
                    break
                else:
                    pattern += chr
            modifiers = self.reader.read_modifiers(["g", "i"])
            return exprs.RegexLiteral(pattern, "i" in modifiers, "g"
                                      in modifiers)
        elif self.reader.read_token("typeof"):
            expr = self.expression_parser.parse(
                self.expression_parser.prefix_precedence)
            self.reader.expect_token("===")
            check = self.reader.expect_string()

            ts_type = None
            if check == "string":
                ts_type = "TsString"
            elif check == "boolean":
                ts_type = "TsBoolean"
            elif check == "object":
                ts_type = "Object"
            elif check == "function":
                # TODO: ???
                ts_type = "Function"
            elif check == "undefined":
                # TODO: ???
                ts_type = "Object"
            else:
                self.reader.fail("unexpected typeof comparison")

            return exprs.InstanceOfExpression(
                expr, astTypes.UnresolvedType(ts_type, []))
        elif self.reader.peek_regex("\\([A-Za-z0-9_]+\\s*[:,]|\\(\\)") != None:
            params = self.parse_lambda_params()
            self.reader.expect_token("=>")
            block = self.parse_lambda_block()
            return types.Lambda(params, block)
        elif self.reader.read_token("await"):
            expression = self.parse_expression()
            return exprs.AwaitExpression(expression)

        map_literal = self.expression_parser.parse_map_literal()
        if map_literal != None:
            return map_literal

        array_literal = self.expression_parser.parse_array_literal()
        if array_literal != None:
            return array_literal

        return None