示例#1
0
        protected override bool CheckBase()
        {
            if (!base.CheckBase())
            {
                return(false);
            }

            MemberSpec candidate;
            bool       overrides       = false;
            var        conflict_symbol = MemberCache.FindBaseMember(this, out candidate, ref overrides);

            if (conflict_symbol == null)
            {
                conflict_symbol = candidate;
            }

            if (conflict_symbol == null)
            {
                if ((ModFlags & Modifiers.NEW) != 0)
                {
                    Report.Warning(109, 4, Location, "The member `{0}' does not hide an inherited member. The new keyword is not required",
                                   GetSignatureForError());
                }
            }
            else
            {
                if ((ModFlags & (Modifiers.NEW | Modifiers.OVERRIDE | Modifiers.BACKING_FIELD)) == 0)
                {
                    Report.SymbolRelatedToPreviousError(conflict_symbol);
                    Report.Warning(108, 2, Location, "`{0}' hides inherited member `{1}'. Use the new keyword if hiding was intended",
                                   GetSignatureForError(), conflict_symbol.GetSignatureForError());
                }

                if (conflict_symbol.IsAbstract)
                {
                    Report.SymbolRelatedToPreviousError(conflict_symbol);
                    Report.Error(533, Location, "`{0}' hides inherited abstract member `{1}'",
                                 GetSignatureForError(), conflict_symbol.GetSignatureForError());
                }
            }

            return(true);
        }
示例#2
0
        XmlNode GetDocCommentNode(MemberCore mc, string name)
        {
            // FIXME: It could be even optimizable as not
            // to use XmlDocument. But anyways the nodes
            // are not kept in memory.
            XmlDocument doc = XmlDocumentation;

            try {
                XmlElement el = doc.CreateElement("member");
                el.SetAttribute("name", name);
                string normalized = mc.DocComment;
                el.InnerXml = normalized;
                // csc keeps lines as written in the sources
                // and inserts formatting indentation (which
                // is different from XmlTextWriter.Formatting
                // one), but when a start tag contains an
                // endline, it joins the next line. We don't
                // have to follow such a hacky behavior.
                string [] split =
                    normalized.Split('\n');
                int j = 0;
                for (int i = 0; i < split.Length; i++)
                {
                    string s = split [i].TrimEnd();
                    if (s.Length > 0)
                    {
                        split [j++] = s;
                    }
                }
                el.InnerXml = line_head + String.Join(
                    line_head, split, 0, j);
                return(el);
            } catch (Exception ex) {
                Report.Warning(1570, 1, mc.Location, "XML documentation comment on `{0}' is not well-formed XML markup ({1})",
                               mc.GetSignatureForError(), ex.Message);

                return(doc.CreateComment(String.Format("FIXME: Invalid documentation markup was found for member {0}", name)));
            }
        }
示例#3
0
        //
        // Generates xml doc comments (if any), and if required,
        // handle warning report.
        //
        internal virtual void GenerateDocComment(DocumentationBuilder builder)
        {
            if (DocComment == null)
            {
                if (IsExposedFromAssembly())
                {
                    Constructor c = this as Constructor;
                    if (c == null || !c.IsDefault())
                    {
                        Report.Warning(1591, 4, Location,
                                       "Missing XML comment for publicly visible type or member `{0}'", GetSignatureForError());
                    }
                }

                return;
            }

            try {
                builder.GenerateDocumentationForMember(this);
            } catch (Exception e) {
                throw new InternalErrorException(this, e);
            }
        }
		public void Warning_UselessOptionalParameter (Report Report)
		{
			Report.Warning (1066, 1, Location,
				"The default value specified for optional parameter `{0}' will never be used",
				Name);
		}
        protected void ResolveAssemblySecurityAttributes()
        {
            string key_file      = null;
            string key_container = null;

            if (module.OptAttributes != null)
            {
                foreach (Attribute a in module.OptAttributes.Attrs)
                {
                    // cannot rely on any resolve-based members before you call Resolve
                    if (a.ExplicitTarget != "assembly")
                    {
                        continue;
                    }

                    // TODO: This code is buggy: comparing Attribute name without resolving is wrong.
                    //       However, this is invoked by CodeGen.Init, when none of the namespaces
                    //       are loaded yet.
                    // TODO: Does not handle quoted attributes properly
                    switch (a.Name)
                    {
                    case "AssemblyKeyFile":
                    case "AssemblyKeyFileAttribute":
                    case "System.Reflection.AssemblyKeyFileAttribute":
                        if (Compiler.Settings.StrongNameKeyFile != null)
                        {
                            Report.SymbolRelatedToPreviousError(a.Location, a.GetSignatureForError());
                            Report.Warning(1616, 1, "Option `{0}' overrides attribute `{1}' given in a source file or added module",
                                           "keyfile", "System.Reflection.AssemblyKeyFileAttribute");
                        }
                        else
                        {
                            string value = a.GetString();
                            if (!string.IsNullOrEmpty(value))
                            {
                                Error_ObsoleteSecurityAttribute(a, "keyfile");
                                key_file = value;
                            }
                        }
                        break;

                    case "AssemblyKeyName":
                    case "AssemblyKeyNameAttribute":
                    case "System.Reflection.AssemblyKeyNameAttribute":
                        if (Compiler.Settings.StrongNameKeyContainer != null)
                        {
                            Report.SymbolRelatedToPreviousError(a.Location, a.GetSignatureForError());
                            Report.Warning(1616, 1, "Option `{0}' overrides attribute `{1}' given in a source file or added module",
                                           "keycontainer", "System.Reflection.AssemblyKeyNameAttribute");
                        }
                        else
                        {
                            string value = a.GetString();
                            if (!string.IsNullOrEmpty(value))
                            {
                                Error_ObsoleteSecurityAttribute(a, "keycontainer");
                                key_container = value;
                            }
                        }
                        break;

                    case "AssemblyDelaySign":
                    case "AssemblyDelaySignAttribute":
                    case "System.Reflection.AssemblyDelaySignAttribute":
                        bool b = a.GetBoolean();
                        if (b)
                        {
                            Error_ObsoleteSecurityAttribute(a, "delaysign");
                        }

                        delay_sign = b;
                        break;
                    }
                }
            }

            // We came here only to report assembly attributes warnings
            if (public_key != null)
            {
                return;
            }

            //
            // Load the strong key file found in attributes when no
            // command line key was given
            //
            if (key_file != null || key_container != null)
            {
                LoadPublicKey(key_file, key_container);
            }
            else if (delay_sign)
            {
                Report.Warning(1607, 1, "Delay signing was requested but no key file was given");
            }
        }
        public void ApplyAttributeBuilder(Attribute a, MethodSpec ctor, byte[] cdata, PredefinedAttributes pa)
        {
            if (a.IsValidSecurityAttribute())
            {
                a.ExtractSecurityPermissionSet(ctor, ref declarative_security);
                return;
            }

            if (a.Type == pa.AssemblyCulture)
            {
                string value = a.GetString();
                if (value == null || value.Length == 0)
                {
                    return;
                }

                if (Compiler.Settings.Target == Target.Exe)
                {
                    a.Error_AttributeEmitError("The executables cannot be satelite assemblies, remove the attribute or keep it empty");
                    return;
                }

                if (value == "neutral")
                {
                    value = "";
                }

                if (Compiler.Settings.Target == Target.Module)
                {
                    SetCustomAttribute(ctor, cdata);
                }
                else
                {
                    builder_extra.SetCulture(value, a.Location);
                }

                IsSatelliteAssembly = true;
                return;
            }

            if (a.Type == pa.AssemblyVersion)
            {
                string value = a.GetString();
                if (value == null || value.Length == 0)
                {
                    return;
                }

                var vinfo = IsValidAssemblyVersion(value, true);
                if (vinfo == null)
                {
                    a.Error_AttributeEmitError(string.Format("Specified version `{0}' is not valid", value));
                    return;
                }

                if (Compiler.Settings.Target == Target.Module)
                {
                    SetCustomAttribute(ctor, cdata);
                }
                else
                {
                    builder_extra.SetVersion(vinfo, a.Location);
                }

                return;
            }

            if (a.Type == pa.AssemblyAlgorithmId)
            {
                const int pos = 2;                 // skip CA header
                uint      alg = (uint)cdata [pos];
                alg |= ((uint)cdata [pos + 1]) << 8;
                alg |= ((uint)cdata [pos + 2]) << 16;
                alg |= ((uint)cdata [pos + 3]) << 24;

                if (Compiler.Settings.Target == Target.Module)
                {
                    SetCustomAttribute(ctor, cdata);
                }
                else
                {
                    builder_extra.SetAlgorithmId(alg, a.Location);
                }

                return;
            }

            if (a.Type == pa.AssemblyFlags)
            {
                const int pos   = 2;               // skip CA header
                uint      flags = (uint)cdata[pos];
                flags |= ((uint)cdata [pos + 1]) << 8;
                flags |= ((uint)cdata [pos + 2]) << 16;
                flags |= ((uint)cdata [pos + 3]) << 24;

                // Ignore set PublicKey flag if assembly is not strongnamed
                if ((flags & (uint)AssemblyNameFlags.PublicKey) != 0 && public_key == null)
                {
                    flags &= ~(uint)AssemblyNameFlags.PublicKey;
                }

                if (Compiler.Settings.Target == Target.Module)
                {
                    SetCustomAttribute(ctor, cdata);
                }
                else
                {
                    builder_extra.SetFlags(flags, a.Location);
                }

                return;
            }

            if (a.Type == pa.TypeForwarder)
            {
                TypeSpec t = a.GetArgumentType();
                if (t == null || TypeManager.HasElementType(t))
                {
                    Report.Error(735, a.Location, "Invalid type specified as an argument for TypeForwardedTo attribute");
                    return;
                }

                if (emitted_forwarders == null)
                {
                    emitted_forwarders = new Dictionary <ITypeDefinition, Attribute> ();
                }
                else if (emitted_forwarders.ContainsKey(t.MemberDefinition))
                {
                    Report.SymbolRelatedToPreviousError(emitted_forwarders[t.MemberDefinition].Location, null);
                    Report.Error(739, a.Location, "A duplicate type forward of type `{0}'",
                                 TypeManager.CSharpName(t));
                    return;
                }

                emitted_forwarders.Add(t.MemberDefinition, a);

                if (t.MemberDefinition.DeclaringAssembly == this)
                {
                    Report.SymbolRelatedToPreviousError(t);
                    Report.Error(729, a.Location, "Cannot forward type `{0}' because it is defined in this assembly",
                                 TypeManager.CSharpName(t));
                    return;
                }

                if (t.IsNested)
                {
                    Report.Error(730, a.Location, "Cannot forward type `{0}' because it is a nested type",
                                 TypeManager.CSharpName(t));
                    return;
                }

                builder_extra.AddTypeForwarder(t.GetDefinition(), a.Location);
                return;
            }

            if (a.Type == pa.Extension)
            {
                a.Error_MisusedExtensionAttribute();
                return;
            }

            if (a.Type == pa.InternalsVisibleTo)
            {
                string assembly_name = a.GetString();
                if (assembly_name.Length == 0)
                {
                    return;
                }
#if STATIC
                ParsedAssemblyName  aname;
                ParseAssemblyResult r = Fusion.ParseAssemblyName(assembly_name, out aname);
                if (r != ParseAssemblyResult.OK)
                {
                    Report.Warning(1700, 3, a.Location, "Assembly reference `{0}' is invalid and cannot be resolved",
                                   assembly_name);
                    return;
                }

                if (aname.Version != null || aname.Culture != null || aname.ProcessorArchitecture != ProcessorArchitecture.None)
                {
                    Report.Error(1725, a.Location,
                                 "Friend assembly reference `{0}' is invalid. InternalsVisibleTo declarations cannot have a version, culture or processor architecture specified",
                                 assembly_name);

                    return;
                }

                if (public_key != null && !aname.HasPublicKey)
                {
                    Report.Error(1726, a.Location,
                                 "Friend assembly reference `{0}' is invalid. Strong named assemblies must specify a public key in their InternalsVisibleTo declarations",
                                 assembly_name);
                    return;
                }
#endif
            }
            else if (a.Type == pa.RuntimeCompatibility)
            {
                wrap_non_exception_throws_custom = true;
            }
            else if (a.Type == pa.AssemblyFileVersion)
            {
                string value = a.GetString();
                if (string.IsNullOrEmpty(value) || IsValidAssemblyVersion(value, false) == null)
                {
                    Report.Warning(1607, 1, a.Location, "The version number `{0}' specified for `{1}' is invalid",
                                   value, a.Name);
                    return;
                }
            }


            SetCustomAttribute(ctor, cdata);
        }
 void Error_ObsoleteSecurityAttribute(Attribute a, string option)
 {
     Report.Warning(1699, 1, a.Location,
                    "Use compiler option `{0}' or appropriate project settings instead of `{1}' attribute",
                    option, a.Name);
 }
		public static string GetPackageFlags (string packages, Report report)
		{
			ProcessStartInfo pi = new ProcessStartInfo ();
			pi.FileName = "pkg-config";
			pi.RedirectStandardOutput = true;
			pi.UseShellExecute = false;
			pi.Arguments = "--libs " + packages;
			Process p = null;
			try {
				p = Process.Start (pi);
			} catch (Exception e) {
				if (report == null)
					throw;

				report.Error (-27, "Couldn't run pkg-config: " + e.Message);
				return null;
			}
			
			if (p.StandardOutput == null) {
				if (report == null)
					throw new ApplicationException ("Specified package did not return any information");

				report.Warning (-27, 1, "Specified package did not return any information");
				p.Close ();
				return null;
			}

			string pkgout = p.StandardOutput.ReadToEnd ();
			p.WaitForExit ();
			if (p.ExitCode != 0) {
				if (report == null)
					throw new ApplicationException (pkgout);

				report.Error (-27, "Error running pkg-config. Check the above output.");
				p.Close ();
				return null;
			}

			p.Close ();
			return pkgout;
		}
示例#9
0
 protected void Warning_IdentifierNotCompliant()
 {
     Report.Warning(3008, 1, MemberName.Location, "Identifier `{0}' is not CLS-compliant", GetSignatureForError());
 }
示例#10
0
        /// <summary>
        /// The main virtual method for CLS-Compliant verifications.
        /// The method returns true if member is CLS-Compliant and false if member is not
        /// CLS-Compliant which means that CLS-Compliant tests are not necessary. A descendants override it
        /// and add their extra verifications.
        /// </summary>
        protected virtual bool VerifyClsCompliance()
        {
            if (HasClsCompliantAttribute)
            {
                if (!Module.DeclaringAssembly.HasCLSCompliantAttribute)
                {
                    Attribute a = OptAttributes.Search(Module.PredefinedAttributes.CLSCompliant);
                    if ((caching_flags & Flags.ClsCompliantAttributeFalse) != 0)
                    {
                        Report.Warning(3021, 2, a.Location,
                                       "`{0}' does not need a CLSCompliant attribute because the assembly is not marked as CLS-compliant",
                                       GetSignatureForError());
                    }
                    else
                    {
                        Report.Warning(3014, 1, a.Location,
                                       "`{0}' cannot be marked as CLS-compliant because the assembly is not marked as CLS-compliant",
                                       GetSignatureForError());
                    }
                    return(false);
                }

                if (!IsExposedFromAssembly())
                {
                    Attribute a = OptAttributes.Search(Module.PredefinedAttributes.CLSCompliant);
                    Report.Warning(3019, 2, a.Location, "CLS compliance checking will not be performed on `{0}' because it is not visible from outside this assembly", GetSignatureForError());
                    return(false);
                }

                if ((caching_flags & Flags.ClsCompliantAttributeFalse) != 0)
                {
                    if (Parent is Interface && Parent.IsClsComplianceRequired())
                    {
                        Report.Warning(3010, 1, Location, "`{0}': CLS-compliant interfaces must have only CLS-compliant members", GetSignatureForError());
                    }
                    else if (Parent.Kind == MemberKind.Class && (ModFlags & Modifiers.ABSTRACT) != 0 && Parent.IsClsComplianceRequired())
                    {
                        Report.Warning(3011, 1, Location, "`{0}': only CLS-compliant members can be abstract", GetSignatureForError());
                    }

                    return(false);
                }

                if (Parent.Kind != MemberKind.Namespace && Parent.Kind != 0 && !Parent.IsClsComplianceRequired())
                {
                    Attribute a = OptAttributes.Search(Module.PredefinedAttributes.CLSCompliant);
                    Report.Warning(3018, 1, a.Location, "`{0}' cannot be marked as CLS-compliant because it is a member of non CLS-compliant type `{1}'",
                                   GetSignatureForError(), Parent.GetSignatureForError());
                    return(false);
                }
            }
            else
            {
                if (!IsExposedFromAssembly())
                {
                    return(false);
                }

                if (!Parent.IsClsComplianceRequired())
                {
                    return(false);
                }
            }

            if (member_name.Name [0] == '_')
            {
                Warning_IdentifierNotCompliant();
            }

            if (member_name.TypeParameters != null)
            {
                member_name.TypeParameters.VerifyClsCompliance();
            }

            return(true);
        }
示例#11
0
        //
        // Processes "see" or "seealso" elements from cref attribute.
        //
        void HandleXrefCommon(MemberCore mc, TypeContainer ds, XmlElement xref)
        {
            string cref = xref.GetAttribute("cref");

            // when, XmlReader, "if (cref == null)"
            if (!xref.HasAttribute("cref"))
            {
                return;
            }

            // Nothing to be resolved the reference is marked explicitly
            if (cref.Length > 2 && cref [1] == ':')
            {
                return;
            }

            // Additional symbols for < and > are allowed for easier XML typing
            cref = cref.Replace('{', '<').Replace('}', '>');

            var encoding = module.Compiler.Settings.Encoding;
            var s        = new MemoryStream(encoding.GetBytes(cref));

            var source_file = new CompilationSourceFile(doc_module, mc.Location.SourceFile);
            var report      = new Report(doc_module.Compiler, new NullReportPrinter());

            if (session == null)
            {
                session = new ParserSession()
                {
                    UseJayGlobalArrays = true
                }
            }
            ;

            SeekableStreamReader seekable = new SeekableStreamReader(s, encoding, session.StreamReaderBuffer);

            var parser = new CSharpParser(seekable, source_file, report, session);

            ParsedParameters          = null;
            ParsedName                = null;
            ParsedBuiltinType         = null;
            ParsedOperator            = null;
            parser.Lexer.putback_char = Tokenizer.DocumentationXref;
            parser.Lexer.parsing_generic_declaration_doc = true;
            parser.parse();
            if (report.Errors > 0)
            {
                Report.Warning(1584, 1, mc.Location, "XML comment on `{0}' has syntactically incorrect cref attribute `{1}'",
                               mc.GetSignatureForError(), cref);

                xref.SetAttribute("cref", "!:" + cref);
                return;
            }

            MemberSpec          member;
            string              prefix = null;
            FullNamedExpression fne    = null;

            //
            // Try built-in type first because we are using ParsedName as identifier of
            // member names on built-in types
            //
            if (ParsedBuiltinType != null && (ParsedParameters == null || ParsedName != null))
            {
                member = ParsedBuiltinType.Type;
            }
            else
            {
                member = null;
            }

            if (ParsedName != null || ParsedOperator.HasValue)
            {
                TypeSpec type        = null;
                string   member_name = null;

                if (member == null)
                {
                    if (ParsedOperator.HasValue)
                    {
                        type = mc.CurrentType;
                    }
                    else if (ParsedName.Left != null)
                    {
                        fne = ResolveMemberName(mc, ParsedName.Left);
                        if (fne != null)
                        {
                            var ns = fne as Namespace;
                            if (ns != null)
                            {
                                fne = ns.LookupTypeOrNamespace(mc, ParsedName.Name, ParsedName.Arity, LookupMode.Probing, Location.Null);
                                if (fne != null)
                                {
                                    member = fne.Type;
                                }
                            }
                            else
                            {
                                type = fne.Type;
                            }
                        }
                    }
                    else
                    {
                        fne = ResolveMemberName(mc, ParsedName);
                        if (fne == null)
                        {
                            type = mc.CurrentType;
                        }
                        else if (ParsedParameters == null)
                        {
                            member = fne.Type;
                        }
                        else if (fne.Type.MemberDefinition == mc.CurrentType.MemberDefinition)
                        {
                            member_name = Constructor.ConstructorName;
                            type        = fne.Type;
                        }
                    }
                }
                else
                {
                    type   = (TypeSpec)member;
                    member = null;
                }

                if (ParsedParameters != null)
                {
                    var old_printer = mc.Module.Compiler.Report.SetPrinter(new NullReportPrinter());
                    try {
                        var context = new DocumentationMemberContext(mc, ParsedName ?? MemberName.Null);

                        foreach (var pp in ParsedParameters)
                        {
                            pp.Resolve(context);
                        }
                    } finally {
                        mc.Module.Compiler.Report.SetPrinter(old_printer);
                    }
                }

                if (type != null)
                {
                    if (member_name == null)
                    {
                        member_name = ParsedOperator.HasValue ?
                                      Operator.GetMetadataName(ParsedOperator.Value) : ParsedName.Name;
                    }

                    int parsed_param_count;
                    if (ParsedOperator == Operator.OpType.Explicit || ParsedOperator == Operator.OpType.Implicit)
                    {
                        parsed_param_count = ParsedParameters.Count - 1;
                    }
                    else if (ParsedParameters != null)
                    {
                        parsed_param_count = ParsedParameters.Count;
                    }
                    else
                    {
                        parsed_param_count = 0;
                    }

                    int parameters_match = -1;
                    do
                    {
                        var members = MemberCache.FindMembers(type, member_name, true);
                        if (members != null)
                        {
                            foreach (var m in members)
                            {
                                if (ParsedName != null && m.Arity != ParsedName.Arity)
                                {
                                    continue;
                                }

                                if (ParsedParameters != null)
                                {
                                    IParametersMember pm = m as IParametersMember;
                                    if (pm == null)
                                    {
                                        continue;
                                    }

                                    if (m.Kind == MemberKind.Operator && !ParsedOperator.HasValue)
                                    {
                                        continue;
                                    }

                                    var pm_params = pm.Parameters;

                                    int i;
                                    for (i = 0; i < parsed_param_count; ++i)
                                    {
                                        var pparam = ParsedParameters[i];

                                        if (i >= pm_params.Count || pparam == null || pparam.TypeSpec == null ||
                                            !TypeSpecComparer.Override.IsEqual(pparam.TypeSpec, pm_params.Types[i]) ||
                                            (pparam.Modifier & Parameter.Modifier.RefOutMask) != (pm_params.FixedParameters[i].ModFlags & Parameter.Modifier.RefOutMask))
                                        {
                                            if (i > parameters_match)
                                            {
                                                parameters_match = i;
                                            }

                                            i = -1;
                                            break;
                                        }
                                    }

                                    if (i < 0)
                                    {
                                        continue;
                                    }

                                    if (ParsedOperator == Operator.OpType.Explicit || ParsedOperator == Operator.OpType.Implicit)
                                    {
                                        if (pm.MemberType != ParsedParameters[parsed_param_count].TypeSpec)
                                        {
                                            parameters_match = parsed_param_count + 1;
                                            continue;
                                        }
                                    }
                                    else
                                    {
                                        if (parsed_param_count != pm_params.Count)
                                        {
                                            continue;
                                        }
                                    }
                                }

                                if (member != null)
                                {
                                    Report.Warning(419, 3, mc.Location,
                                                   "Ambiguous reference in cref attribute `{0}'. Assuming `{1}' but other overloads including `{2}' have also matched",
                                                   cref, member.GetSignatureForError(), m.GetSignatureForError());

                                    break;
                                }

                                member = m;
                            }
                        }

                        // Continue with parent type for nested types
                        if (member == null)
                        {
                            type = type.DeclaringType;
                        }
                        else
                        {
                            type = null;
                        }
                    } while (type != null);

                    if (member == null && parameters_match >= 0)
                    {
                        for (int i = parameters_match; i < parsed_param_count; ++i)
                        {
                            Report.Warning(1580, 1, mc.Location, "Invalid type for parameter `{0}' in XML comment cref attribute `{1}'",
                                           (i + 1).ToString(), cref);
                        }

                        if (parameters_match == parsed_param_count + 1)
                        {
                            Report.Warning(1581, 1, mc.Location, "Invalid return type in XML comment cref attribute `{0}'", cref);
                        }
                    }
                }
            }

            if (member == null)
            {
                Report.Warning(1574, 1, mc.Location, "XML comment on `{0}' has cref attribute `{1}' that could not be resolved",
                               mc.GetSignatureForError(), cref);
                cref = "!:" + cref;
            }
            else if (member == InternalType.Namespace)
            {
                cref = "N:" + fne.GetSignatureForError();
            }
            else
            {
                prefix = GetMemberDocHead(member);
                cref   = prefix + member.GetSignatureForDocumentation();
            }

            xref.SetAttribute("cref", cref);
        }
示例#12
0
        //
        // Processes "include" element. Check included file and
        // embed the document content inside this documentation node.
        //
        bool HandleInclude(MemberCore mc, XmlElement el)
        {
            bool   keep_include_node = false;
            string file = el.GetAttribute("file");
            string path = el.GetAttribute("path");

            if (file == "")
            {
                Report.Warning(1590, 1, mc.Location, "Invalid XML `include' element. Missing `file' attribute");
                el.ParentNode.InsertBefore(el.OwnerDocument.CreateComment(" Include tag is invalid "), el);
                keep_include_node = true;
            }
            else if (path.Length == 0)
            {
                Report.Warning(1590, 1, mc.Location, "Invalid XML `include' element. Missing `path' attribute");
                el.ParentNode.InsertBefore(el.OwnerDocument.CreateComment(" Include tag is invalid "), el);
                keep_include_node = true;
            }
            else
            {
                XmlDocument doc;
                Exception   exception = null;
                var         full_path = Path.Combine(Path.GetDirectoryName(mc.Location.NameFullPath), file);

                if (!StoredDocuments.TryGetValue(full_path, out doc))
                {
                    try {
                        doc = new XmlDocument();
                        doc.Load(full_path);
                        StoredDocuments.Add(full_path, doc);
                    } catch (Exception e) {
                        exception = e;
                        el.ParentNode.InsertBefore(el.OwnerDocument.CreateComment(String.Format(" Badly formed XML in at comment file `{0}': cannot be included ", file)), el);
                    }
                }

                if (doc != null)
                {
                    try {
                        XmlNodeList nl = doc.SelectNodes(path);
                        if (nl.Count == 0)
                        {
                            el.ParentNode.InsertBefore(el.OwnerDocument.CreateComment(" No matching elements were found for the include tag embedded here. "), el);

                            keep_include_node = true;
                        }
                        foreach (XmlNode n in nl)
                        {
                            el.ParentNode.InsertBefore(el.OwnerDocument.ImportNode(n, true), el);
                        }
                    } catch (Exception ex) {
                        exception = ex;
                        el.ParentNode.InsertBefore(el.OwnerDocument.CreateComment(" Failed to insert some or all of included XML "), el);
                    }
                }

                if (exception != null)
                {
                    Report.Warning(1589, 1, mc.Location, "Unable to include XML fragment `{0}' of file `{1}'. {2}",
                                   path, file, exception.Message);
                }
            }

            return(keep_include_node);
        }