internal void SetContainer(ISampleVariableContainer container)
 {
     // Variables can be moved to a different scope under some conditions (e.g. if the Globals scope is disabled), but
     //  we want them to remain associated with their original container to avoid conficts
     if (this.Container == null)
     {
         this.Container = container;
     }
 }
        internal SetVariableResponse HandleSetVariableRequest(SetVariableArguments args)
        {
            ISampleVariableContainer container = this.GetVariableContainer(args.VariablesReference);

            if (container == null)
            {
                throw new ProtocolException(Invariant($"Invalid variable reference '{args.VariablesReference}'!"));
            }

            return(container.HandleSetVariableRequest(args));
        }
        internal string GetEvaluateName()
        {
            // Purposefully using a weird format to avoid looking like other languages
            string evalName = this.Name;
            ISampleVariableContainer container = this.Container;

            while (container != null)
            {
                evalName  = Invariant($"{container.Name}~{evalName}");
                container = container.Container;
            }

            return(evalName);
        }
        private ISampleVariableContainer FindVariableReference(ISampleVariableContainer container, int variablesReference)
        {
            if (container.VariableReference == variablesReference)
            {
                return(container);
            }

            if (container.ChildContainers != null)
            {
                foreach (ISampleVariableContainer childContainer in container.ChildContainers)
                {
                    ISampleVariableContainer found = this.FindVariableReference(childContainer, variablesReference);
                    if (found != null)
                    {
                        return(found);
                    }
                }
            }

            return(null);
        }
        private EvaluateResponse Evaluate(string expression, string value, ValueFormat format)
        {
            ISampleVariableContainer container = null;
            string variableName = null;

            if (!expression.Contains("~"))
            {
                // Not a delimted expression = assume we're using the locals scope
                container    = this.localsScope;
                variableName = expression;
            }
            else
            {
                List <string> evalParts = expression.Split('~').Select(p => p.Trim()).ToList();
                variableName = evalParts.Last();

                // Right now, we only support expressions that retrieve variables
                foreach (string part in evalParts.Take(evalParts.Count - 1))
                {
                    if (container == null)
                    {
                        container = this.AllScopes.FirstOrDefault(s => String.Equals(s.Name, part, StringComparison.Ordinal));
                    }
                    else
                    {
                        container = container.ChildContainers.FirstOrDefault(c => String.Equals(c.Name, part, StringComparison.Ordinal));
                    }

                    if (container == null)
                    {
                        throw new ProtocolException("Evaluation failed!");
                    }
                }
            }

            SampleVariable variable = container.Variables.FirstOrDefault(v => String.Equals(v.Name, variableName, StringComparison.Ordinal));

            if (variable == null)
            {
                throw new ProtocolException("Evaluation failed!");
            }

            if (value != null)
            {
                if (variable.IsReadOnly)
                {
                    throw new ProtocolException("Expression is read-only.");
                }
                variable.SetValue(value);
            }

            VariablePresentationHint presentationHint = null;

            if (variable.IsReadOnly)
            {
                presentationHint = new VariablePresentationHint
                {
                    Attributes = VariablePresentationHint.AttributesValue.ReadOnly
                };
            }

            return(new EvaluateResponse(
                       presentationHint: presentationHint,
                       result: variable.GetValue(format?.Hex ?? false),
                       variablesReference: variable.VariableReference,
                       type: variable.Type));
        }