Example #1
0
        /*********
        ** Private methods
        *********/
        /// <summary>Force a context update.</summary>
        /// <param name="context">Provides access to contextual tokens.</param>
        /// <param name="forceUpdate">Update even if the state hasn't changed.</param>
        /// <returns>Returns whether the context changed.</returns>
        private bool UpdateContext(IContext context, bool forceUpdate)
        {
            if (!forceUpdate && (!this.IsMutable || this.State.InvalidTokens.Any() || this.State.UnavailableModTokens.Any()))
            {
                return(false);
            }

            // reset
            string wasValue = this.Value;
            bool   wasReady = this.State.IsReady;

            this.State.Reset();

            // update value
            InvariantHashSet unavailableTokens = new InvariantHashSet();
            InvariantHashSet errors            = new InvariantHashSet();

            {
                StringBuilder str = new StringBuilder();
                foreach (TokenStringPart part in this.Parts)
                {
                    str.Append(this.TryGetTokenText(context, part, unavailableTokens, errors, out string text) ? text : part.LexToken.ToString());
                }

                this.Value = !unavailableTokens.Any() && !errors.Any()
                    ? str.ToString().Trim()
                    : null;
            }

            // reapply
            if (this.Value == null)
            {
                if (!unavailableTokens.Any() && !errors.Any())
                {
                    throw new InvalidOperationException($"Could not apply tokens to string '{this.Raw}', but no invalid tokens or errors were reported."); // sanity check, should never happen
                }
                this.State.AddUnreadyTokens(unavailableTokens.ToArray());
                this.State.AddErrors(errors.ToArray());
            }

            return
                (this.Value != wasValue ||
                 this.State.IsReady != wasReady);
        }