Ejemplo n.º 1
0
        public IVariableResolution ResolveVariables(SourceLineNumber sourceLineNumbers, string value, bool errorOnUnknown)
        {
            var start     = 0;
            var defaulted = true;
            var delayed   = false;
            var updated   = false;

            while (Common.TryParseWixVariable(value, start, out var parsed))
            {
                var variableNamespace    = parsed.Namespace;
                var variableId           = parsed.Name;
                var variableDefaultValue = parsed.DefaultValue;

                // check for an escape sequence of !! indicating the match is not a variable expression
                if (0 < parsed.Index && '!' == value[parsed.Index - 1])
                {
                    var sb = new StringBuilder(value);
                    sb.Remove(parsed.Index - 1, 1);
                    value = sb.ToString();

                    updated = true;
                    start   = parsed.Index + parsed.Length - 1;

                    continue;
                }

                string resolvedValue = null;

                if ("loc" == variableNamespace)
                {
                    // localization variables do not support inline default values
                    if (variableDefaultValue != null)
                    {
                        this.Messaging.Write(ErrorMessages.IllegalInlineLocVariable(sourceLineNumbers, variableId, variableDefaultValue));
                        continue;
                    }

                    if (this.locVariables.TryGetValue(variableId, out var bindVariable))
                    {
                        resolvedValue = bindVariable.Value;
                    }
                }
                else if ("wix" == variableNamespace)
                {
                    if (this.wixVariables.TryGetValue(variableId, out var bindVariable))
                    {
                        resolvedValue = bindVariable.Value ?? String.Empty;
                        defaulted     = false;
                    }
                    else if (null != variableDefaultValue) // default the resolved value to the inline value if one was specified
                    {
                        resolvedValue = variableDefaultValue;
                    }
                }

                if ("bind" == variableNamespace)
                {
                    // Can't resolve these yet, but keep track of where we find them so they can be resolved later with less effort.
                    delayed = true;
                    start   = parsed.Index + parsed.Length - 1;
                }
                else
                {
                    // insert the resolved value if it was found or display an error
                    if (null != resolvedValue)
                    {
                        if (parsed.Index == 0 && parsed.Length == value.Length)
                        {
                            value = resolvedValue;
                        }
                        else
                        {
                            var sb = new StringBuilder(value);
                            sb.Remove(parsed.Index, parsed.Length);
                            sb.Insert(parsed.Index, resolvedValue);
                            value = sb.ToString();
                        }

                        updated = true;
                        start   = parsed.Index;
                    }
                    else
                    {
                        if ("loc" == variableNamespace && errorOnUnknown) // unresolved loc variable
                        {
                            this.Messaging.Write(ErrorMessages.LocalizationVariableUnknown(sourceLineNumbers, variableId));
                        }
                        else if ("wix" == variableNamespace && errorOnUnknown) // unresolved wix variable
                        {
                            this.Messaging.Write(ErrorMessages.WixVariableUnknown(sourceLineNumbers, variableId));
                        }

                        start = parsed.Index + parsed.Length;
                    }
                }
            }

            return(new VariableResolution
            {
                DelayedResolve = delayed,
                IsDefault = defaulted,
                UpdatedValue = updated,
                Value = value,
            });
        }