void ParseAttributeParameters(List <string> parameters)
 {
     // Attribute parameters are funny
     // The contents between the brackets vary.
     // They may be comma separated. They may not.
     // Therefore this code is likely to break, but since I'm responsible for
     // generating the text of the attributes parsed here, I can try to ensure
     // that it will always fit the pattern.
     while (true)
     {
         if (tokenizer.Peek().Kind == TypeTokenKind.RightBracket)
         {
             tokenizer.Next();
             return;
         }
         TypeSpecToken value = tokenizer.Next();
         if (value.Kind != TypeTokenKind.TypeName)
         {
             throw ErrorHelper.CreateError(ReflectorError.kTypeParseBase + 6, $"Unexpected token {value.Value} while parsing attribute parameter.");
         }
         parameters.Add(value.Value);
         if (tokenizer.Peek().Kind == TypeTokenKind.Comma)
         {
             tokenizer.Next();
         }
     }
 }
Exemple #2
0
        public TypeSpecToken Next()
        {
            if (curr != null)
            {
                TypeSpecToken retval = curr;
                curr = null;
                return(retval);
            }
            TypeSpecToken token = null;

            do
            {
                switch (state)
                {
                case State.InName:
                    token = DoName();
                    break;

                case State.InArrow:
                    token = DoArrow();
                    break;

                case State.Start:
                    token = DoStart();
                    break;
                }
            } while (token == null);
            return(token);
        }
Exemple #3
0
        TypeSpecToken DoName()
        {
            int curr = reader.Peek();

            if (curr < 0 || InvalidNameCharacter((char)curr))
            {
                if (curr == ':')
                {
                    reader.Read();                      // drop the colon
                    state = State.Start;
                    TypeSpecToken token = TypeSpecToken.LabelFromString(buffer.ToString());
                    buffer.Clear();
                    return(token);
                }
                else
                {
                    state = State.Start;
                    TypeSpecToken token = TypeSpecToken.FromString(buffer.ToString());
                    buffer.Clear();
                    return(token);
                }
            }
            else
            {
                buffer.Append((char)reader.Read());
                return(null);
            }
        }
Exemple #4
0
 public TypeSpecToken Peek()
 {
     if (curr == null)
     {
         curr = Next();
     }
     return(curr);
 }
        TypeSpec Parse()
        {
            TypeSpecToken            token = tokenizer.Peek();
            TypeSpec                 type  = null;
            List <TypeSpecAttribute> attrs = null;
            var    inout     = false;
            string typeLabel = null;

            // Prefix

            // parse any attributes
            if (token.Kind == TypeTokenKind.At)
            {
                attrs = ParseAttributes();
                token = tokenizer.Peek();
            }

            // looks like it's inout
            if (token.Kind == TypeTokenKind.TypeName && token.Value == "inout")
            {
                inout = true;
                tokenizer.Next();
                token = tokenizer.Peek();
            }

            if (token.Kind == TypeTokenKind.TypeLabel)
            {
                typeLabel = token.Value;
                tokenizer.Next();
                token = tokenizer.Peek();
            }


            // meat


            if (token.Kind == TypeTokenKind.LeftParenthesis)               // tuple
            {
                tokenizer.Next();
                TupleTypeSpec tuple = ParseTuple();
                type      = tuple.Elements.Count == 1 ? tuple.Elements [0] : tuple;
                typeLabel = type.TypeLabel;
            }
            else if (token.Kind == TypeTokenKind.TypeName)                 // name
            {
                tokenizer.Next();
                var tokenValue = token.Value.StartsWith("ObjectiveC.", StringComparison.Ordinal) ?
                                 "Foundation" + token.Value.Substring("ObjectiveC".Length) : token.Value;
                type = new NamedTypeSpec(tokenValue);
            }
            else if (token.Kind == TypeTokenKind.LeftBracket)                 // array
            {
                tokenizer.Next();
                type = ParseArray();
            }
            else                 // illegal
            {
                throw ErrorHelper.CreateError(ReflectorError.kTypeParseBase + 0, $"Unexpected token {token.Value}.");
            }

            // look-ahead for closure
            if (tokenizer.Peek().Kind == TypeTokenKind.TypeName && tokenizer.Peek().Value == "throws")
            {
                tokenizer.Next();
                if (tokenizer.Peek().Kind != TypeTokenKind.Arrow)
                {
                    throw ErrorHelper.CreateError(ReflectorError.kTypeParseBase + 1, $"Unexpected token {tokenizer.Peek ().Value} after a 'throws' in a closure.");
                }
                tokenizer.Next();
                type = ParseClosure(type, true);
            }

            if (tokenizer.Peek().Kind == TypeTokenKind.Arrow)
            {
                tokenizer.Next();
                type = ParseClosure(type, false);
            }
            else if (tokenizer.Peek().Kind == TypeTokenKind.LeftAngle)
            {
                tokenizer.Next();
                type = Genericize(type);
            }

            if (tokenizer.Peek().Kind == TypeTokenKind.Period)
            {
                tokenizer.Next();
                var currType = type as NamedTypeSpec;
                if (currType == null)
                {
                    throw ErrorHelper.CreateError(ReflectorError.kTypeParseBase + 2, $"In parsing an inner type (type.type), first element is a {type.Kind} instead of a NamedTypeSpec.");
                }
                var nextType = Parse() as NamedTypeSpec;
                if (nextType == null)
                {
                    throw ErrorHelper.CreateError(ReflectorError.kTypeParseBase + 3, $"In parsing an inner type (type.type), the second element is a {nextType.Kind} instead of a NamedTypeSpec");
                }
                currType.InnerType = nextType;
            }

            // Postfix

            if (tokenizer.Peek().Kind == TypeTokenKind.Ampersand)
            {
                type = ParseProtocolList(type as NamedTypeSpec);
            }

            while (tokenizer.Peek().Kind == TypeTokenKind.QuestionMark)
            {
                tokenizer.Next();
                type = WrapAsBoundGeneric(type, "Swift.Optional");
            }

            if (tokenizer.Peek().Kind == TypeTokenKind.ExclamationPoint)
            {
                tokenizer.Next();
                type = WrapAsBoundGeneric(type, "Swift.ImplicitlyUnwrappedOptional");
            }

            type.IsInOut   = inout;
            type.TypeLabel = typeLabel;

            if (type != null && attrs != null)
            {
                type.Attributes.AddRange(attrs);
            }

            return(type);
        }