Esempio n. 1
0
        //#endregion

        #region Name Resolving

        /// <summary>
        /// Resolves a function or type name using aliases and imported namespaces of the source unit.
        /// </summary>
        /// <param name="qualifiedName">Function qualified name to resolve. Doesn't resolve special names ("self", "parent").</param>
        /// <param name="kind">Declaration kind.</param>
        /// <param name="currentScope">Current scope.</param>
        /// <param name="alias">
        /// <B>null</B>, if the function name is resolved immediately.
        /// Otherwise, if the <paramref name="qualifiedName"/> is simple and an alias exists, contains its qualified target.
        /// </param>
        /// <param name="errors">Error sink or <B>null</B> if errors shouldn't be reported.</param>
        /// <param name="position">Position where to report an error.</param>
        /// <param name="mustResolve">Whether name must be resolved if possible.</param>
        /// <returns>
        /// Resolved member, the unknown member, or <B>null</B> if error reporting is disabled (errors == null).
        /// </returns>
        /// <remarks>
        /// If the name is simple, is not resolved and has an alias then the run-time resolve should be run on the alias.
        /// If the name is simple, is not resolved and hasn't an alias, the run-time resolve should be run on the name
        ///		within the naming context of the source unit (i.e. imported namespaces should be considered).
        /// If the name is fully qualified and is not resolved then then the run-time resolve should be run on the name itself.
        /// </remarks>
        private DMember ResolveName(QualifiedName qualifiedName, DeclarationKind kind, Scope currentScope,
                                    out QualifiedName?alias, ErrorSink errors, Position position, bool mustResolve)
        {
            string  full_name = null;
            DMember result;

            alias = null;

            // try exact match:
            result = ResolveExactName(qualifiedName, ref full_name, kind, currentScope, mustResolve);
            if (result != null)
            {
                return(result);
            }

            /*  // aliases are resolved in parse-time
             *          // try explicit aliases:
             *          if (qualifiedName.IsSimpleName)
             *          {
             *                  QualifiedName alias_qualified_name;
             *
             *                  Dictionary<Name, QualifiedName> aliases = null;
             *                  switch (kind)
             *                  {
             *                          case DeclarationKind.Type: aliases = typeAliases; break;
             *                          case DeclarationKind.Function: aliases = functionAliases; break;
             *                          case DeclarationKind.Constant: aliases = constantAliases; break;
             *                  }
             *
             *                  // try alias:
             *                  if (aliases != null && aliases.TryGetValue(qualifiedName.Name, out alias_qualified_name))
             *                  {
             *                          // alias exists //
             *
             *                          full_name = null;
             *                          result = ResolveExactName(alias_qualified_name, ref full_name, kind, currentScope, mustResolve);
             *                          if (result != null)
             *                                  return result;
             *
             *                          alias = alias_qualified_name;
             *
             *                          switch (kind)
             *                          {
             *                                  case DeclarationKind.Type: result = new UnknownType(full_name); break;
             *                                  case DeclarationKind.Function: result = new UnknownFunction(full_name); break;
             *                                  case DeclarationKind.Constant: result = new UnknownGlobalConstant(full_name); break;
             *                          }
             *
             *                          return result;
             *                  }
             *          }
             */

            // try imported namespaces:
            if (!qualifiedName.IsFullyQualifiedName && HasImportedNamespaces)
            {
                result = null;

                foreach (QualifiedName imported_ns in importedNamespaces)
                {
                    QualifiedName combined_qualified_name = new QualifiedName(qualifiedName, imported_ns);
                    full_name = null;

                    DMember candidate = ResolveExactName(combined_qualified_name, ref full_name, kind, currentScope, mustResolve);
                    if (candidate != null)
                    {
                        if (result != null)
                        {
                            if (errors != null)
                            {
                                ErrorInfo error;
                                switch (kind)
                                {
                                case DeclarationKind.Type: error = Errors.AmbiguousTypeMatch; break;

                                case DeclarationKind.Function: error = Errors.AmbiguousFunctionMatch; break;

                                case DeclarationKind.Constant: error = Errors.AmbiguousConstantMatch; break;

                                default: throw null;
                                }

                                errors.Add(error, this, position, result.FullName, candidate.FullName, qualifiedName.Name);
                            }
                        }
                        else
                        {
                            result = candidate;
                        }
                    }
                }

                if (result != null)
                {
                    return(result);
                }
            }

            // unknown qualified name:
            if (errors != null)
            {
                switch (kind)
                {
                case DeclarationKind.Type: result = new UnknownType(qualifiedName.ToString()); break;

                case DeclarationKind.Function: result = new UnknownFunction(qualifiedName.ToString()); break;

                case DeclarationKind.Constant: result = new UnknownGlobalConstant(qualifiedName.ToString()); break;
                }

                return(result);
            }

            return(null);
        }
Esempio n. 2
0
        /// <summary>
        /// Resolves a function or type name using aliases and imported namespaces of the source unit.
        /// </summary>
        /// <param name="qualifiedName">Function qualified name to resolve. Doesn't resolve special names ("self", "parent").</param>
        /// <param name="kind">Declaration kind.</param>
        /// <param name="currentScope">Current scope.</param>
        /// <param name="alias">
        /// <B>null</B>, if the function name is resolved immediately.
        /// Otherwise, if the <paramref name="qualifiedName"/> is simple and an alias exists, contains its qualified target.
        /// </param>
        /// <param name="errors">Error sink or <B>null</B> if errors shouldn't be reported.</param>
        /// <param name="position">Position where to report an error.</param>
        /// <param name="mustResolve">Whether name must be resolved if possible.</param>
        /// <returns>
        /// Resolved member, the unknown member, or <B>null</B> if error reporting is disabled (errors == null).
        /// </returns>
        /// <remarks>
        /// If the name is simple, is not resolved and has an alias then the run-time resolve should be run on the alias.
        /// If the name is simple, is not resolved and hasn't an alias, the run-time resolve should be run on the name
        ///		within the naming context of the source unit (i.e. imported namespaces should be considered).
        /// If the name is fully qualified and is not resolved then then the run-time resolve should be run on the name itself.
        /// </remarks>
        private DMember ResolveName(QualifiedName qualifiedName, DeclarationKind kind, Scope currentScope,
                                    out QualifiedName?alias, ErrorSink errors, Text.Span position, bool mustResolve)
        {
            string  full_name = null;
            DMember result;

            alias = null;

            // try exact match:
            result = ResolveExactName(qualifiedName, ref full_name, kind, currentScope, mustResolve);
            if (result != null)
            {
                return(result);
            }

            // try imported namespaces:
            if (!qualifiedName.IsFullyQualifiedName && HasImportedNamespaces)
            {
                result = null;

                foreach (QualifiedName imported_ns in this.ImportedNamespaces)
                {
                    QualifiedName combined_qualified_name = new QualifiedName(qualifiedName, imported_ns);
                    full_name = null;

                    DMember candidate = ResolveExactName(combined_qualified_name, ref full_name, kind, currentScope, mustResolve);
                    if (candidate != null)
                    {
                        if (result != null)
                        {
                            if (errors != null)
                            {
                                ErrorInfo error;
                                switch (kind)
                                {
                                case DeclarationKind.Type: error = Errors.AmbiguousTypeMatch; break;

                                case DeclarationKind.Function: error = Errors.AmbiguousFunctionMatch; break;

                                case DeclarationKind.Constant: error = Errors.AmbiguousConstantMatch; break;

                                default: throw null;
                                }

                                errors.Add(error, this, position, result.FullName, candidate.FullName, qualifiedName.Name);
                            }
                        }
                        else
                        {
                            result = candidate;
                        }
                    }
                }

                if (result != null)
                {
                    return(result);
                }
            }

            // unknown qualified name:
            if (errors != null)
            {
                switch (kind)
                {
                case DeclarationKind.Type: result = new UnknownType(qualifiedName.ToString()); break;

                case DeclarationKind.Function: result = new UnknownFunction(qualifiedName.ToString()); break;

                case DeclarationKind.Constant: result = new UnknownGlobalConstant(qualifiedName.ToString()); break;
                }

                return(result);
            }

            return(null);
        }