Exemple #1
0
        public static TypeSpec Resolve(ModuleContainer module, MemberKind kind, string ns, string name, int arity, bool reportErrors)
        {
            Namespace type_ns = module.GlobalRootNamespace.GetNamespace(ns, true);
            var       found   = type_ns.GetAllTypes(name);

            if (found == null)
            {
                if (reportErrors)
                {
                    module.Compiler.Report.Error(518, "The predefined type `{0}.{1}' is not defined or imported", ns, name);
                }

                return(null);
            }

            TypeSpec best_match = null;

            foreach (var candidate in found)
            {
                if (candidate.Kind != kind)
                {
                    if (candidate.Kind == MemberKind.Struct && kind == MemberKind.Void && candidate.MemberDefinition is TypeContainer)
                    {
                        // Void is declared as struct but we keep it internally as
                        // special kind, the swap will be done by caller
                    }
                    else
                    {
                        continue;
                    }
                }

                if (candidate.Arity != arity)
                {
                    continue;
                }

                if ((candidate.Modifiers & Modifiers.INTERNAL) != 0 && !candidate.MemberDefinition.IsInternalAsPublic(module.DeclaringAssembly))
                {
                    continue;
                }

                if (best_match == null)
                {
                    best_match = candidate;
                    continue;
                }

                var other_match = best_match;
                if (!best_match.MemberDefinition.IsImported &&
                    module.Compiler.BuiltinTypes.Object.MemberDefinition.DeclaringAssembly == candidate.MemberDefinition.DeclaringAssembly)
                {
                    best_match = candidate;
                }

                string location;
                if (best_match.MemberDefinition is MemberCore)
                {
                    location = ((MemberCore)best_match.MemberDefinition).Location.Name;
                }
                else
                {
                    var assembly = (ImportedAssemblyDefinition)best_match.MemberDefinition.DeclaringAssembly;
                    location = Path.GetFileName(assembly.Location);
                }

                module.Compiler.Report.SymbolRelatedToPreviousError(other_match);
                module.Compiler.Report.SymbolRelatedToPreviousError(candidate);

                module.Compiler.Report.Warning(1685, 1,
                                               "The predefined type `{0}.{1}' is defined multiple times. Using definition from `{2}'",
                                               ns, name, location);

                break;
            }

            if (best_match == null && reportErrors)
            {
                Location loc;
                if (found[0].MemberDefinition is MemberCore)
                {
                    loc = ((MemberCore)found[0].MemberDefinition).Location;
                }
                else
                {
                    loc = Location.Null;
                    module.Compiler.Report.SymbolRelatedToPreviousError(found[0]);
                }

                module.Compiler.Report.Error(520, loc, "The predefined type `{0}.{1}' is not declared correctly", ns, name);
            }

            return(best_match);
        }
		public static TypeSpec Resolve (ModuleContainer module, MemberKind kind, string ns, string name, int arity, bool required, bool reportErrors)
		{
			//
			// Cannot call it with true because it could create non-existent namespaces for
			// predefined types. It's set to true only for build-in types which all must
			// exist therefore it does not matter, for predefined types we don't want to create
			// fake namespaces when type is optional and does not exist (e.g. System.Linq).
			//
			Namespace type_ns = module.GlobalRootNamespace.GetNamespace (ns, required);

			IList<TypeSpec> found = null;
			if (type_ns != null)
				found = type_ns.GetAllTypes (name);

			if (found == null) {
				if (reportErrors)
					module.Compiler.Report.Error (518, "The predefined type `{0}.{1}' is not defined or imported", ns, name);

				return null;
			}

			TypeSpec best_match = null;
			foreach (var candidate in found) {
				if (candidate.Kind != kind) {
					if (candidate.Kind == MemberKind.Struct && kind == MemberKind.Void && candidate.MemberDefinition is TypeContainer) {
						// Void is declared as struct but we keep it internally as
						// special kind, the swap will be done by caller
					} else {
						continue;
					}
				}

				if (candidate.Arity != arity)
					continue;

				if ((candidate.Modifiers & Modifiers.INTERNAL) != 0 && !candidate.MemberDefinition.IsInternalAsPublic (module.DeclaringAssembly))
					continue;

				if (best_match == null) {
					best_match = candidate;
					continue;
				}

				var other_match = best_match;
				if (!best_match.MemberDefinition.IsImported &&
					module.Compiler.BuiltinTypes.Object.MemberDefinition.DeclaringAssembly == candidate.MemberDefinition.DeclaringAssembly) {
					best_match = candidate;
				}

				string location;
				if (best_match.MemberDefinition is MemberCore) {
					location = ((MemberCore) best_match.MemberDefinition).Location.Name;
				} else {
					var assembly = (ImportedAssemblyDefinition) best_match.MemberDefinition.DeclaringAssembly;
					location = Path.GetFileName (assembly.Location);
				}

				module.Compiler.Report.SymbolRelatedToPreviousError (other_match);
				module.Compiler.Report.SymbolRelatedToPreviousError (candidate);

				module.Compiler.Report.Warning (1685, 1,
					"The predefined type `{0}.{1}' is defined multiple times. Using definition from `{2}'",
					ns, name, location);

				break;
			}

			if (best_match == null && reportErrors) {
				var found_member = found[0];

				if (found_member.Kind == MemberKind.MissingType) {
					// CSC: should be different error number
					module.Compiler.Report.Error (518, "The predefined type `{0}.{1}' is defined in an assembly that is not referenced.", ns, name);
				} else {
					Location loc;
					if (found_member.MemberDefinition is MemberCore) {
						loc = ((MemberCore) found_member.MemberDefinition).Location;
					} else {
						loc = Location.Null;
						module.Compiler.Report.SymbolRelatedToPreviousError (found_member);
					}

					module.Compiler.Report.Error (520, loc, "The predefined type `{0}.{1}' is not declared correctly", ns, name);
				}
			}

			return best_match;
		}