Example #1
0
        /// <summary>
        /// Gets module or namespace based on module id.
        /// </summary>
        public EvaluationResult GetNamespace(ImmutableContextBase context, FullSymbol fullName, bool recurs, ModuleLiteral origin, LineInfo location)
        {
            ModuleBinding binding = GetNamespaceBinding(context, fullName, recurs);

            if (binding == null)
            {
                context.Errors.ReportMissingNamespace(origin ?? this, fullName, this, location);
                return(EvaluationResult.Error);
            }

            return(EvaluationResult.Create(binding.Body));
        }
Example #2
0
        private void AddGetOrEvalFieldTasks(ImmutableContextBase context, List <Task <object> > list, ModuleLiteral origin)
        {
            Contract.Requires(origin.m_bindings != null);

            foreach (var binding in origin.m_bindings)
            {
                SymbolAtom    name         = binding.Key;
                ModuleBinding bindingValue = binding.Value;

                list.Add(RunGetOrEvalFieldAsync(context, origin, name, bindingValue));
            }
        }
Example #3
0
        /// <summary>
        /// Gets the field body if exists.
        /// </summary>
        /// <remarks>
        /// This method does not evaluate the body of the field if exists, and moreover, does not recurs to the parent.
        /// </remarks>
        public bool TryGetField(SymbolAtom name, out object body)
        {
            ModuleBinding binding = null;

            // TODO:ST: sounds reasonable to add "warning" if name was resolved but it is not exposed!
            if (m_bindings?.TryGetValue(name, out binding) == true && binding.IsExported)
            {
                body = binding.Body;
                return(true);
            }

            body = null;
            return(false);
        }
Example #4
0
        /// <summary>
        /// Adds a binding.
        /// </summary>
        public bool AddBinding(SymbolAtom name, ModuleBinding binding)
        {
            Contract.Requires(name.IsValid);
            Contract.Requires(Qualifier == QualifierValue.Unqualified);
            Contract.Requires(binding != null);

            lock (m_syncRoot)
            {
                m_bindings = m_bindings ?? new BindingDictionary();
                if (m_bindings.ContainsKey(name))
                {
                    return(false);
                }

                m_bindings.Add(name, binding);
            }

            return(true);
        }
Example #5
0
        internal bool TryResolveExtendedName(ImmutableContextBase context, FullSymbol enclosingName, FullSymbol requestedName, out ModuleBinding result)
        {
            // Semantically nested namespaces forms hierarchical structure, when nested namespace is stored in the outer namespace.
            // For performance reasons, file module stores all names in one big map with combined keys.
            // This means that when looking for A.B we should look at the current scope for A, then need to combine A and B
            // and look for A.B in the file module.
            // This means that extended (or partial) names are only allowed if the enclosing name is valid.
            // In this case we will combine requested name with the enclosing one and look in the current file module.
            result = null;

            if (!enclosingName.IsValid)
            {
                return(false);
            }

            if (m_partialSymbolsCache.Value.TryGetValue(requestedName, out result))
            {
                return(true);
            }

            var extendedFullName = enclosingName.Combine(context.FrontEndContext.SymbolTable, requestedName);

            // Now trying to resolve extended name in the current file.
            result = GetNamespaceBinding(context, extendedFullName, recurs: false);

            // If resolution was successful, saving it in the cache.
            if (result != null)
            {
                m_partialSymbolsCache.Value.GetOrAdd(requestedName, result);
                return(true);
            }

            return(false);
        }
Example #6
0
 private object GetOrEvalField(ImmutableContextBase context, ModuleLiteral origin, SymbolAtom name, ModuleBinding bindingValue)
 {
     // This method may be invoked concurrently on the same context. Thus we may not mutate the context at hand, but must create a local mutable child context.
     using (var localMutableContext = context.CreateWithModule(this))
     {
         var result = origin.GetOrEvalField(
             localMutableContext,
             name,
             recurs: true,
             origin: origin,
             location: bindingValue.Location);
         Contract.Assert(!localMutableContext.HasChildren); // just before the newly created context get disposed, we want to assert that all of its child contexts have already been disposed
         return(result.Value);
     }
 }
Example #7
0
 /// <summary>
 /// Creates a task that runs GetOrEvalField taking into consideration concurrency settings
 /// </summary>
 protected Task <object> RunGetOrEvalFieldAsync(ImmutableContextBase context, ModuleLiteral origin, SymbolAtom name, ModuleBinding bindingValue)
 {
     return(context.EvaluationScheduler.EvaluateValue(() => Task.FromResult(GetOrEvalField(context, origin, name, bindingValue))));
 }
Example #8
0
        private EvaluationResult GetOrEvalFieldBindingThunk(ImmutableContextBase context, SymbolAtom name, ModuleBinding binding, Thunk thunk)
        {
            // Keep this call in a separate method to avoid always creating a closure object on the heap in the caller
            // If the thunk hasn't been evaluated yet for the current qualifier, then its evaluation gets kicked off in a newly allocated mutable named context.
            // We must not mutate the context at hand directly, as there might be other concurrent child contexts alive.
            var contextName = GetFullyQualifiedBindingName(context.FrontEndContext.SymbolTable, this, name);

            return(thunk.LegacyEvaluateWithNewNamedContext(context, this, contextName, binding.Location));
        }
Example #9
0
        /// <summary>
        /// Evaluates given <paramref name="binding"/> that corresponds to field <paramref name="name"/>
        /// (<seealso cref="GetOrEvalField(Context, SymbolAtom, bool, ModuleLiteral, LineInfo)"/>)
        /// </summary>
        public EvaluationResult GetOrEvalFieldBinding(Context context, SymbolAtom name, ModuleBinding binding, LineInfo callingLocation)
        {
            object o = binding.Body;

            if (o is Thunk thunk)
            {
                return(GetOrEvalFieldBindingThunk(context, name, binding, thunk));
            }

            if (o is Expression expr)
            {
                using (var frame = EvaluationStackFrame.Empty())
                {
                    return(expr.Eval(context, this, frame));
                }
            }

            return(EvaluationResult.Create(o));
        }