Esempio n. 1
0
        public DMemberRef(DMember /*!*/ member, DType /*!*/ type)
        {
            Debug.Assert(member != null && type != null);

            this.member = member;
            this.type   = type;
        }
Esempio n. 2
0
        /// <summary>
        /// Used by all subclasses except for <see cref="GlobalTypeDesc"/>.
        /// </summary>
        protected DMemberDesc(DTypeDesc /*!*/ declaringType, PhpMemberAttributes memberAttributes)
        {
            Debug.Assert(declaringType != null);

            this.declaringType    = declaringType;
            this.memberAttributes = memberAttributes;
            this.member           = null;   // to be filled by DMember or at run-time (if applicable)
        }
Esempio n. 3
0
 protected DMemberDesc()
 {
     this.declaringType    = (DTypeDesc)this;
     this.memberAttributes = PhpMemberAttributes.None;
     this.member           = null;   // to be filled by DMember (if applicable)
 }
Esempio n. 4
0
		protected DMemberDesc()
		{
			this.declaringType = (DTypeDesc)this;
			this.memberAttributes = PhpMemberAttributes.None;
			this.member = null; // to be filled by DMember (if applicable)
		}
Esempio n. 5
0
		public DMemberRef(DMember/*!*/ member, DType/*!*/ type)
		{
			Debug.Assert(member != null && type != null);

			this.member = member;
			this.type = type;
		}
Esempio n. 6
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. 7
0
		/// <summary>
		/// Used by all subclasses except for <see cref="GlobalTypeDesc"/>.
		/// </summary>
		protected DMemberDesc(DTypeDesc/*!*/ declaringType, PhpMemberAttributes memberAttributes)
		{
			Debug.Assert(declaringType != null);

			this.declaringType = declaringType;
			this.memberAttributes = memberAttributes;
			this.member = null; // to be filled by DMember or at run-time (if applicable)
		}
Esempio n. 8
0
		/// <summary>
		/// Defines a property that &quot;exports;&quot; a given field or constant.
		/// </summary>
		/// <param name="name">The name of the property.</param>
		/// <param name="member">A <see cref="PhpField"/> or <see cref="ClassConstant"/>.</param>
		/// <returns>The export property builder.</returns>
		public static PropertyBuilder/*!*/ DefineFieldExport(string name, DMember/*!*/ member)
		{
			Debug.Assert(member is PhpField || member is ClassConstant);

			DTypeDesc declaring_type_desc = member.DeclaringType.TypeDesc;
			TypeBuilder type_builder = member.DeclaringPhpType.RealTypeBuilder;

			// determine name and type
			Type type = Types.Object[0]; // TODO: field/constant type hints?

			PropertyBuilder prop_builder = type_builder.DefineProperty(
				name,
				Reflection.Enums.ToPropertyAttributes(member.MemberDesc.MemberAttributes),
				type,
				Type.EmptyTypes);

			MethodAttributes accessor_attrs = Reflection.Enums.ToMethodAttributes(member.MemberDesc.MemberAttributes);
			bool changed;

			// define getter
			MethodBuilder getter = type_builder.DefineMethod(
				GetNonConflictingMethodName(declaring_type_desc, "get_" + name, out changed),
				accessor_attrs,
				type,
				Type.EmptyTypes);

			getter.SetCustomAttribute(AttributeBuilders.DebuggerHidden);
			prop_builder.SetGetMethod(getter);

			// generate setter
			if (member is PhpField)
			{
				MethodBuilder setter = type_builder.DefineMethod(
					GetNonConflictingMethodName(declaring_type_desc, "set_" + name, out changed),
					accessor_attrs,
					Types.Void,
					new Type[] { type });

				setter.SetCustomAttribute(AttributeBuilders.DebuggerHidden);
				prop_builder.SetSetMethod(setter);
			}

			return prop_builder;
		}
Esempio n. 9
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);
        }
Esempio n. 10
0
		private GenericParameterDesc[]/*!!*/ ToGenericParameters(DMember/*!*/ declaringMember, out int mandatoryCount)
		{
			Debug.Assert(declaringMember != null);

			if (typeParams.Count == 0)
			{
				mandatoryCount = 0;
				return GenericParameterDesc.EmptyArray;
			}

			GenericParameterDesc[] result = new GenericParameterDesc[typeParams.Count];
			mandatoryCount = 0;
			for (int i = 0; i < typeParams.Count; i++)
			{
				result[i] = new GenericParameter(typeParams[i].Name, i, declaringMember).GenericParameterDesc;
				if (typeParams[i].DefaultType == null)
					mandatoryCount++;
			}
			return result;
		}
Esempio n. 11
0
		/// <summary>
		/// Creates a <see cref="PhpRoutineSignature"/> partially initialized with the type parameters of this type signature. 
		/// Used by generic routines.
		/// </summary>
		internal PhpRoutineSignature/*!*/ ToPhpRoutineSignature(DMember/*!*/ declaringRoutine)
		{
			Debug.Assert(declaringRoutine != null);

			int mandatory_generic_param_count;
			GenericParameterDesc[] descs = this.ToGenericParameters(declaringRoutine, out mandatory_generic_param_count);

			GenericParameter[] types = new GenericParameter[descs.Length];
			for (int i = 0; i < descs.Length; i++)
				types[i] = descs[i].GenericParameter;

			return new PhpRoutineSignature(types, mandatory_generic_param_count);
		}
Esempio n. 12
0
		/// <summary>
		/// Creates an array of generic parameters. 
		/// Used by generic types.
		/// </summary>
		internal GenericParameterDesc[]/*!!*/ ToGenericParameters(DMember/*!*/ declaringType)
		{
			int mandatory_generic_param_count;
			return this.ToGenericParameters(declaringType, out mandatory_generic_param_count);
		}