Exemplo n.º 1
0
        protected void SetNodeCreator <TCollectionStaticType, TElementStaticType>(Func <TCollectionStaticType> createCollection, Action <TCollectionStaticType, TElementStaticType> addElementToCollection)
        {
            this.AstConfig.NodeCreator = (context, parseTreeNode) =>
            {
                Lazy <TCollectionStaticType> collection = new Lazy <TCollectionStaticType>(() => createCollection());

                bool collectionHasElements = false;
                foreach (var element in GetFlattenedElements <TElementStaticType>(parseTreeNode, context))
                {
                    collectionHasElements = true;
                    addElementToCollection(collection.Value, element);
                }

                TCollectionStaticType astValue = !collectionHasElements && this.EmptyCollectionHandling == EmptyCollectionHandling.ReturnNull
                    ? default(TCollectionStaticType)
                    : collection.Value;

                parseTreeNode.AstNode = GrammarHelper.ValueToAstNode(astValue, context, parseTreeNode);
            };
        }
Exemplo n.º 2
0
        protected BnfiTermConversion(Type domainType, BnfTerm bnfTerm, ValueIntroducer <object> valueIntroducer, ValueConverter <object, object> inverseValueConverterForUnparse,
                                     object defaultValue, bool isOptionalValue, string name, bool astForChild)
            : base(domainType, name)
        {
            this.IsContractible  = true;
            this.bnfTerm         = bnfTerm;
            this.isOptionalValue = isOptionalValue;
            this.defaultValue    = defaultValue;

            if (!astForChild)
            {
                bnfTerm.SetFlag(TermFlags.NoAstNode);
            }

            this.RuleRawWithMove = isOptionalValue
                ? GrammarHelper.PreferShiftHere() + bnfTerm | Irony.Parsing.Grammar.CurrentGrammar.Empty
                : bnfTerm.ToBnfExpression();

            this.AstConfig.NodeCreator =
                (context, parseTreeNode) =>
            {
                try
                {
                    parseTreeNode.AstNode = GrammarHelper.ValueToAstNode(valueIntroducer(context, new ParseTreeNodeWithoutAst(parseTreeNode)), context, parseTreeNode);
                }
                catch (AstException e)
                {
                    context.AddMessage(AstException.ErrorLevel, parseTreeNode.Span.Location, e.Message);
                }
                catch (FatalAstException e)
                {
                    context.AddMessage(FatalAstException.ErrorLevel, parseTreeNode.Span.Location, e.Message); // although it will be abandoned anyway
                    e.Location = parseTreeNode.Span.Location;
                    throw;                                                                                    // handle in MultiParser
                }
            };

            this.inverseValueConverterForUnparse = inverseValueConverterForUnparse;
        }
Exemplo n.º 3
0
        protected BnfiTermRecord(Type domainType, string name)
            : base(domainType, name)
        {
#if !WINDOWS_STORE
#if PCL
            if (domainType.GetConstructor(new Type[0]) == null)
#else
            if (domainType.GetConstructor(bindingAttrInstanceAll, binder: null, types: Type.EmptyTypes, modifiers: null) == null)
#endif
            { throw new ArgumentException("Type has no default constructor (neither public nor nonpublic)", "type"); }
#endif

            this.AstConfig.NodeCreator = (context, parseTreeNode) =>
            {
                try
                {
                    object astValue;
                    try
                    {
#if PCL
                        astValue = ActivatorEx.CreateInstance(domainType, nonPublic: true);
#else
                        astValue = Activator.CreateInstance(domainType, nonPublic: true);
#endif
                    }
                    catch (MissingMemberException)
                    {
                        throw new AstException(string.Format("Type '{0}' does not have a parameterless public or internal constructor", domainType.FullName));
                    }

                    var parseChildBnfTerms = parseTreeNode.ChildNodes.Select(childParseTreeNode => childParseTreeNode.Term).ToList();

                    var parseChildValues = parseTreeNode.ChildNodes
                                           .Select(
                        (parseChildNode, parseChildNodeIndex) => new
                    {
                        ReferredBnfTerm = new ReferredBnfTermEL(parseChildBnfTerms, parseChildNode.Term, parseChildNodeIndex),
                        Value           = GrammarHelper.AstNodeToValue(parseChildNode.AstNode)
                    }
                        )
                                           .Where(parseChildValue => parseChildValue.Value != null)
                                           .ToList();

                    // 1. memberwise copy for BnfiTermCopy items
                    foreach (var parseChildValue in parseChildValues)
                    {
                        if (!IsMemberAtParse(parseChildValue.ReferredBnfTerm) && IsMemberwiseCopyable(astValue, parseChildValue.Value))
                        {
                            MemberwiseCopyExceptNullAndEmptyCollectionValues(astValue, parseChildValue.Value);
                        }
                    }

                    // 2. set member values for member items (it's the second step, so that we can overwrite the copied members if we want)
                    foreach (var parseChildValue in parseChildValues)
                    {
                        if (IsMemberAtParse(parseChildValue.ReferredBnfTerm))
                        {
                            SetValue(GetMemberAtParse(parseChildValue.ReferredBnfTerm).MemberInfo, astValue, parseChildValue.Value);
                        }
                    }

                    parseTreeNode.AstNode = GrammarHelper.ValueToAstNode(astValue, context, parseTreeNode);
                }
                catch (AstException e)
                {
                    context.AddMessage(AstException.ErrorLevel, parseTreeNode.Span.Location, e.Message);
                }
                catch (FatalAstException e)
                {
                    context.AddMessage(FatalAstException.ErrorLevel, parseTreeNode.Span.Location, e.Message);   // although it will be abandoned anyway
                    e.Location = parseTreeNode.Span.Location;
                    throw;
                }
            };
        }