/// <summary>Construct a token string and permanently apply config values.</summary> public TokenString Build() { TokenString tokenString = new TokenString(this.RawValue, this.ConditionTokens, TokenStringBuilder.TokenPattern); InvariantDictionary <string> configValues = new InvariantDictionary <string>(this.Config.ToDictionary(p => p.Key, p => p.Value.Value.FirstOrDefault())); tokenString.ApplyPermanently(configValues); return(tokenString); }
/// <summary>Construct an instance.</summary> /// <param name="lexTokens">The lexical tokens parsed from the raw string.</param> /// <param name="context">The available token context.</param> /// <param name="path">The path to the value from the root content file.</param> public TokenString(ILexToken[] lexTokens, IContext context, LogPathBuilder path) { // get lexical tokens this.Parts = ( from token in (lexTokens ?? new ILexToken[0]) let input = token is LexTokenToken lexToken && lexToken.HasInputArgs() ? new TokenString(lexToken.InputArgs.Parts, context, path.With(lexToken.Name)) : null select new TokenStringPart(token, input) ) .ToArray(); // set raw value this.Raw = string.Join("", this.Parts.Select(p => p.LexToken)).Trim(); if (string.IsNullOrWhiteSpace(this.Raw)) { this.Value = this.Raw; return; } // extract tokens bool isMutable = false; bool hasTokens = false; foreach (LexTokenToken lexToken in this.GetTokenPlaceholders(this.LexTokens, recursive: true)) { hasTokens = true; IToken token = context.GetToken(lexToken.Name, enforceContext: false); if (token != null) { this.TokensUsed.Add(token.Name); isMutable = isMutable || token.IsMutable; } else { string requiredModId = lexToken.GetProviderModId(); if (!string.IsNullOrWhiteSpace(requiredModId) && !context.IsModInstalled(requiredModId)) { this.State.AddUnavailableModTokens(requiredModId); } else { this.State.AddInvalidTokens(lexToken.Name); } isMutable = true; // can't optimize away the token value if it's invalid } } // set metadata this.IsMutable = isMutable; this.HasAnyTokens = hasTokens; this.IsSingleTokenOnly = TokenString.GetIsSingleTokenOnly(this.Parts); this.Path = path.ToString(); // set initial context if (this.State.IsReady) { this.UpdateContext(context, forceUpdate: true); } }
/********* ** Public methods *********/ /// <summary>Construct an instance.</summary> /// <param name="lexToken">The underlying lex token.</param> /// <param name="input">The parsed version of <see cref="Input"/>.</param> public TokenStringPart(ILexToken lexToken, TokenString input) { this.LexToken = lexToken; this.Input = input; this.InputArgs = new InputArguments(input); }