Пример #1
0
        private static ResolvableType CreateUnapplyReturnType(IEnumerable<string> typeNames)
        {
            IEnumerable<string> names = typeNames as IList<string> ?? typeNames.ToList();
            if (!names.Any())
            {
                return ResolvableType.BooleanTy;
            }

            if (names.Count() == 1)
            {
                RTypeName optionType = new RTypeName("Option");
                optionType.AddGenericArgument(new RTypeName(names.First()));
                return new ResolvableType(optionType);
            }
            else
            {
                RTypeName optionType = new RTypeName("Option");
                RTypeName tuppleType = CreateTupleType(names);
                optionType.AddGenericArgument(tuppleType);
                return new ResolvableType(optionType);
            }
        }
Пример #2
0
        // Consume follow is needed to handle pattern matching case:
        // case x: Foo => x.length
        // without consumeFollow false it will parse and closure type (Foo => x) which is incorrect
        public bool ParseType(out RTypeName type, bool consumeFollow = true)
        {
            if (Require(RppLexer.Id))
            {
                IToken typeNameToken = _lastToken;
                if (Require(RppLexer.OP_LBracket))
                {
                    RTypeName genericType = new RTypeName(typeNameToken);
                    type = genericType;

                    RTypeName subType;
                    if (!ParseType(out subType))
                    {
                        RaiseSyntaxError("Type is expected");
                    }

                    genericType.AddGenericArgument(subType);

                    while (true)
                    {
                        if (Require(RppLexer.OP_RBracket))
                        {
                            break;
                        }

                        if (Require(RppLexer.OP_Comma))
                        {
                            if (!ParseType(out subType))
                            {
                                RaiseSyntaxError("Type is expected");
                            }

                            genericType.AddGenericArgument(subType);
                        }
                        else
                        {
                            RaiseSyntaxError("Expected comma");
                        }
                    }

                    return true;
                }

                // A => B
                if (consumeFollow && Require(RppLexer.OP_Follow))
                {
                    RTypeName returnType;
                    if (!ParseType(out returnType))
                    {
                        RaiseSyntaxError("Type is expected");
                    }

                    type = CreateClosureTypeName(new List<RTypeName> {new RTypeName(typeNameToken)}, returnType);
                    return true;
                }

                type = new RTypeName(typeNameToken);
                return true;
            }

            // (A, B) => C
            // (A => B)
            if (Require(RppLexer.OP_LParen))
            {
                bool closingParenRequired = true;
                RTypeName returnType;
                IList<RTypeName> paramTypes = new List<RTypeName>();
                while (true)
                {
                    if (Require(RppLexer.OP_RParen))
                    {
                        closingParenRequired = false;
                        break;
                    }

                    if (Peek(RppLexer.OP_Follow))
                    {
                        break;
                    }

                    if (paramTypes.Count > 0)
                    {
                        Expect(RppLexer.OP_Comma);
                    }

                    RTypeName paramType;
                    if (ParseType(out paramType))
                    {
                        paramTypes.Add(paramType);
                    }
                    else
                    {
                        RaiseSyntaxError("Type is expected");
                    }
                }

                if (!Require(RppLexer.OP_Follow))
                {
                    // (A => A)
                    if (paramTypes.Count == 1)
                    {
                        type = paramTypes[0];
                        return true;
                    }

                    // (A, B, C)
                    type = CreateTupleTypeName(paramTypes);
                    return true;
                }

                if (!ParseType(out returnType))
                {
                    RaiseSyntaxError("Type is expected");
                }

                if (closingParenRequired)
                {
                    Expect(RppLexer.OP_RParen);
                }

                type = CreateClosureTypeName(paramTypes, returnType);
                return true;
            }

            type = null;
            return false;
        }
Пример #3
0
 /// <summary>
 /// Creates Function[paramCount] type name if return type is not Unit.
 /// If it's Unit then it creates Action[paramCount].
 /// </summary>
 private static RTypeName CreateClosureTypeName(ICollection<RTypeName> paramTypes, RTypeName returnType)
 {
     bool isAction = IsAction(returnType);
     string baseTypeName = isAction ? "Action" : "Function";
     RTypeName closureType = new RTypeName(baseTypeName + paramTypes.Count);
     paramTypes.ForEach(closureType.AddGenericArgument);
     if (!isAction)
     {
         closureType.AddGenericArgument(returnType);
     }
     return closureType;
 }
Пример #4
0
 private static RTypeName Reconstruct(RType type)
 {
     RTypeName typeName = new RTypeName(type.Name);
     type.GenericArguments.ForEach(ga => typeName.AddGenericArgument(Reconstruct(ga)));
     return typeName;
 }