示例#1
0
        /// <summary>
        /// Decodes an LNode as a type definition.
        /// </summary>
        /// <param name="node">The node to decode.</param>
        /// <param name="state">The decoder's state.</param>
        /// <returns>A decoded type.</returns>
        public static IrType Decode(LNode node, DecoderState state)
        {
            QualifiedName name;

            if (!FeedbackHelpers.AssertArgCount(node, 4, state.Log) ||
                !state.AssertDecodeQualifiedName(node.Args[0], out name))
            {
                return(null);
            }
            else if (node.Calls(TypeParameterDefinitionSymbol))
            {
                return(new IrGenericParameter(node, state));
            }
            else if (node.Calls(TypeDefinitionSymbol))
            {
                return(new IrType(node, state));
            }
            else
            {
                state.Log.LogSyntaxError(
                    node,
                    FeedbackHelpers.QuoteEven(
                        "expected ",
                        TypeDefinitionSymbol.Name,
                        " or ",
                        TypeParameterDefinitionSymbol.Name,
                        "."));
                return(null);
            }
        }
示例#2
0
        /// <summary>
        /// Decodes an assembly from an LNode.
        /// </summary>
        /// <param name="data">The LNode to decode.</param>
        /// <param name="state">The decoder to use.</param>
        /// <returns>
        /// A decoded assembly if the node can be decoded;
        /// otherwise, <c>null</c>.
        /// </returns>
        public static IrAssembly Decode(LNode data, DecoderState state)
        {
            QualifiedName name;

            if (!FeedbackHelpers.AssertArgCount(data, 2, state.Log) ||
                !state.AssertDecodeQualifiedName(data.Args[0], out name))
            {
                return(null);
            }
            else
            {
                return(new IrAssembly(data, state));
            }
        }
示例#3
0
        /// <inheritdoc/>
        public override IType Decode(LNode data, DecoderState state)
        {
            if (data.Calls(pointerSymbol))
            {
                if (!FeedbackHelpers.AssertArgCount(data, 2, state.Log))
                {
                    return(ErrorType.Instance);
                }

                var         elemType = state.DecodeType(data.Args[0]);
                PointerKind kind;
                if (AssertDecodePointerKind(data.Args[1], state, out kind))
                {
                    return(elemType.MakePointerType(kind));
                }
                else
                {
                    return(ErrorType.Instance);
                }
            }
            else if (data.Calls(genericParameterSymbol))
            {
                if (!FeedbackHelpers.AssertArgCount(data, 2, state.Log))
                {
                    return(ErrorType.Instance);
                }

                IGenericMember parent;
                SimpleName     name;

                if (state.AssertDecodeGenericMember(data.Args[0], out parent) &&
                    state.AssertDecodeSimpleName(data.Args[1], out name))
                {
                    var types = state.TypeResolver.ResolveGenericParameters(parent, name);
                    if (AssertSingleChildType(types, data, state, "generic declaration"))
                    {
                        return(types[0]);
                    }
                }
                return(ErrorType.Instance);
            }
            else if (data.Calls(CodeSymbols.Of))
            {
                if (!FeedbackHelpers.AssertMinArgCount(data, 2, state.Log))
                {
                    return(ErrorType.Instance);
                }

                var genericDecl = state.DecodeType(data.Args[0]);
                var genericArgs = data.Args.Slice(1).EagerSelect <LNode, IType>(state.DecodeType);

                int count = genericDecl.GenericParameters.Count;
                if (count != genericArgs.Count)
                {
                    FeedbackHelpers.LogSyntaxError(
                        state.Log,
                        data,
                        FeedbackHelpers.QuoteEven(
                            "type ",
                            FeedbackHelpers.Print(data.Args[0]),
                            " is instantiated with ",
                            genericArgs.Count.ToString(),
                            " arguments but has only ",
                            count.ToString(),
                            " parameters."));
                    return(ErrorType.Instance);
                }

                return(genericDecl.MakeGenericType(genericArgs));
            }
            else if (data.Calls(CodeSymbols.Dot))
            {
                if (!FeedbackHelpers.AssertArgCount(data, 2, state.Log))
                {
                    return(ErrorType.Instance);
                }

                SimpleName childName;
                if (!state.AssertDecodeSimpleName(data.Args[1], out childName))
                {
                    return(ErrorType.Instance);
                }

                var parentType = state.DecodeType(data.Args[0]);
                if (parentType == ErrorType.Instance)
                {
                    // Make sure that we don't log an additional error
                    // just because the parent type was wrong.
                    return(ErrorType.Instance);
                }

                var childTypes = state.TypeResolver.ResolveNestedTypes(parentType, childName);
                if (AssertSingleChildType(childTypes, data, state, "type"))
                {
                    return(childTypes[0]);
                }
                else
                {
                    return(ErrorType.Instance);
                }
            }
            else
            {
                QualifiedName fullName;
                if (state.AssertDecodeQualifiedName(data, out fullName))
                {
                    var types = state.TypeResolver.ResolveTypes(fullName);
                    if (AssertSingleGlobalType(types, data, state))
                    {
                        return(types[0]);
                    }
                    else
                    {
                        return(ErrorType.Instance);
                    }
                }
                else
                {
                    return(ErrorType.Instance);
                }
            }
        }