Browse Source

Parser now inserts documentation into the AST.

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@185 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 21 years ago
parent
commit
5ca1f5bdc2
  1. 1
      src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/Parser.cs
  2. 5
      src/Main/Base/Project/Src/Dom/IDecoration.cs
  3. 59
      src/Main/Base/Project/Src/Dom/IReturnType.cs
  4. 28
      src/Main/Base/Project/Src/Dom/Implementations/AbstractDecoration.cs
  5. 2
      src/Main/Base/Project/Src/Dom/Implementations/GenericReturnType.cs
  6. 97
      src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryASTConvertVisitor.cs
  7. 8
      src/Main/Base/Project/Src/Gui/Workbench/Layouts/SdiWorkspaceWindow.cs
  8. 2
      src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs
  9. 10
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/CompletionWindow/CodeCompletionData.cs
  10. 2
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/InsightWindow/IndexerInsightDataProvider.cs
  11. 2
      src/Main/Base/Project/Src/TextEditor/Gui/Editor/InsightWindow/MethodInsightDataProvider.cs
  12. 6
      src/Main/Base/Test/ReflectionLayerTests.cs

1
src/AddIns/BackendBindings/CSharpBinding/Project/Src/Parser/Parser.cs

@ -99,6 +99,7 @@ namespace CSharpBinding.Parser @@ -99,6 +99,7 @@ namespace CSharpBinding.Parser
p.Parse();
NRefactoryASTConvertVisitor visitor = new NRefactoryASTConvertVisitor(projectContent);
visitor.Specials = p.Lexer.SpecialTracker.CurrentSpecials;
visitor.Visit(p.CompilationUnit, null);
visitor.Cu.FileName = fileName;
visitor.Cu.ErrorsDuringCompile = p.Errors.count > 0;

5
src/Main/Base/Project/Src/Dom/IDecoration.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
// <file>
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
@ -24,7 +24,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -24,7 +24,7 @@ namespace ICSharpCode.SharpDevelop.Dom
get;
}
string DocumentationTag {
string Documentation {
get;
}
@ -104,6 +104,5 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -104,6 +104,5 @@ namespace ICSharpCode.SharpDevelop.Dom
bool IsAccessible(IClass callingClass, bool isClassInInheritanceTree);
bool MustBeShown(IClass callingClass, bool showStatic, bool isClassInInheritanceTree);
}
}

59
src/Main/Base/Project/Src/Dom/IReturnType.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
// <file>
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
@ -10,20 +10,54 @@ using System.Collections.Generic; @@ -10,20 +10,54 @@ using System.Collections.Generic;
namespace ICSharpCode.SharpDevelop.Dom
{
/// <summary>
/// Interface for reference to types (classes).
/// Such a reference can be direct (DefaultReturnType), lazy (SearchClassReturnType) or
/// returns types that stand for special references (e.g. ArrayReturnType)
/// </summary>
public interface IReturnType
{
/// <summary>
/// Gets the fully qualified name of the class the return type is pointing to.
/// </summary>
/// <returns>
/// "System.Int32" for int[]<br/>
/// "System.Collections.Generic.List" for List&lt;string&gt;
/// </returns>
string FullyQualifiedName {
get;
}
/// <summary>
/// Gets the short name of the class the return type is pointing to.
/// </summary>
/// <returns>
/// "Int32" or "int" (depending how the return type was created) for int[]<br/>
/// "List" for List&lt;string&gt;
/// </returns>
string Name {
get;
}
/// <summary>
/// Gets the namespace of the class the return type is pointing to.
/// </summary>
/// <returns>
/// "System" for int[]<br/>
/// "System.Collections.Generic" for List&lt;string&gt;
/// </returns>
string Namespace {
get;
}
/// <summary>
/// Gets the full dotnet name of the return type. The DotnetName is used for the
/// documentation tags.
/// </summary>
/// <returns>
/// "System.Int[]" for int[]<br/>
/// "System.Collections.Generic.List{System.String}" for List&lt;string&gt;
/// </returns>
string DotNetName {
get;
}
@ -39,6 +73,10 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -39,6 +73,10 @@ namespace ICSharpCode.SharpDevelop.Dom
/// <summary>
/// Gets if the return type is a default type, i.e. no array, generic etc.
/// </summary>
/// <returns>
/// True for SearchClassReturnType, GetClassReturnType and DefaultReturnType.<br/>
/// False for ArrayReturnType, SpecificReturnType etc.
/// </returns>
bool IsDefaultReturnType {
get;
}
@ -48,10 +86,29 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -48,10 +86,29 @@ namespace ICSharpCode.SharpDevelop.Dom
/// </summary>
IClass GetUnderlyingClass();
/// <summary>
/// Gets all methods that can be called on this return type.
/// </summary>
List<IMethod> GetMethods();
/// <summary>
/// Gets all properties that can be called on this return type.
/// </summary>
List<IProperty> GetProperties();
/// <summary>
/// Gets all fields that can be called on this return type.
/// </summary>
List<IField> GetFields();
/// <summary>
/// Gets all events that can be called on this return type.
/// </summary>
List<IEvent> GetEvents();
/// <summary>
/// Gets all indexers that can be called on this return type.
/// </summary>
List<IIndexer> GetIndexers();
}
}

28
src/Main/Base/Project/Src/Dom/Implementations/AbstractDecoration.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
// <file>
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
@ -8,6 +8,7 @@ using System; @@ -8,6 +8,7 @@ using System;
using System.Collections;
using System.Reflection;
using System.Collections.Generic;
using ICSharpCode.Core;
namespace ICSharpCode.SharpDevelop.Dom
{
@ -53,6 +54,31 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -53,6 +54,31 @@ namespace ICSharpCode.SharpDevelop.Dom
}
}
string documentation;
public string Documentation {
get {
if (documentation == null) {
string documentationTag = this.DocumentationTag;
if (documentationTag != null) {
IProjectContent pc = null;
if (this is IClass) {
pc = ((IClass)this).ProjectContent;
} else if (declaringType != null) {
pc = declaringType.ProjectContent;
}
if (pc != null) {
return pc.GetXmlDocumentation(documentationTag);
}
}
}
return documentation;
}
set {
documentation = value;
}
}
public abstract string DocumentationTag {
get;
}

2
src/Main/Base/Project/Src/Dom/Implementations/GenericReturnType.cs

@ -31,7 +31,7 @@ namespace ICSharpCode.SharpDevelop.Dom @@ -31,7 +31,7 @@ namespace ICSharpCode.SharpDevelop.Dom
return typeParameter.Equals(rt.typeParameter);
}
public override bool IsDefaultReturnType {
public override bool IsDefaultReturnType {
get {
return false;
}

97
src/Main/Base/Project/Src/Dom/NRefactoryResolver/NRefactoryASTConvertVisitor.cs

@ -52,6 +52,86 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -52,6 +52,86 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
return r;
}
List<RefParser.ISpecial> specials;
/// <summary>
/// Gets/Sets the list of specials used to read the documentation.
/// The list must be sorted by the start position of the specials!
/// </summary>
public List<RefParser.ISpecial> Specials {
get {
return specials;
}
set {
specials = value;
}
}
string GetDocumentation(int line)
{
List<string> lines = new List<string>();
int length = 0;
while (line > 0) {
string doku = GetDocumentationFromLine(--line);
if (doku == null)
break;
length += 2 + doku.Length;
lines.Add(doku);
}
StringBuilder b = new StringBuilder(length);
for (int i = lines.Count - 1; i >= 0; --i) {
b.AppendLine(lines[i]);
}
return b.ToString();
}
string GetDocumentationFromLine(int line)
{
if (specials == null) return null;
if (line < 0) return null;
// specials is a sorted list: use interpolation search
int left = 0;
int right = specials.Count - 1;
int m;
while (left <= right) {
int leftLine = specials[left].StartPosition.Y;
if (line < leftLine)
break;
int rightLine = specials[right].StartPosition.Y;
if (line > rightLine)
break;
if (leftLine == rightLine) {
if (leftLine == line)
m = left;
else
break;
} else {
m = left + (line - leftLine) * (right - left) / (rightLine - leftLine);
}
int mLine = specials[m].StartPosition.Y;
if (mLine < line) { // found line smaller than line we are looking for
left = m + 1;
} else if (mLine > line) {
right = m - 1;
} else {
// correct line found,
// look for first special in that line
while (--m >= 0 && specials[m].StartPosition.Y == line);
// look at all specials in that line: find doku-comment
while (++m < specials.Count && specials[m].StartPosition.Y == line) {
RefParser.Comment comment = specials[m] as RefParser.Comment;
if (comment != null && comment.CommentType == RefParser.CommentType.Documentation) {
return comment.CommentText;
}
}
break;
}
}
return null;
}
public override object Visit(AST.CompilationUnit compilationUnit, object data)
{
//TODO: usings, Comments
@ -177,6 +257,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -177,6 +257,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
DefaultRegion region = GetRegion(typeDeclaration.StartLocation, typeDeclaration.EndLocation);
DefaultClass c = new DefaultClass(cu, TranslateClassType(typeDeclaration.Type), ConvertModifier(typeDeclaration.Modifier, ModifierEnum.Internal), region, GetCurrentClass());
c.Attributes.AddRange(VisitAttributes(typeDeclaration.Attributes));
c.Documentation = GetDocumentation(region.BeginLine);
if (currentClass.Count > 0) {
DefaultClass cur = GetCurrentClass();
@ -222,6 +303,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -222,6 +303,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
{
DefaultRegion region = GetRegion(delegateDeclaration.StartLocation, delegateDeclaration.EndLocation);
DefaultClass c = new DefaultClass(cu, ClassType.Delegate, ConvertModifier(delegateDeclaration.Modifier, ModifierEnum.Internal), region, GetCurrentClass());
c.Documentation = GetDocumentation(region.BeginLine);
c.Attributes.AddRange(VisitAttributes(delegateDeclaration.Attributes));
c.BaseTypes.Add("System.Delegate");
if (currentClass.Count > 0) {
@ -270,6 +352,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -270,6 +352,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
DefaultClass c = GetCurrentClass();
DefaultMethod method = new DefaultMethod(methodDeclaration.Name, null, ConvertModifier(methodDeclaration.Modifier), region, bodyRegion, GetCurrentClass());
method.Documentation = GetDocumentation(region.BeginLine);
ConvertTemplates(methodDeclaration.Templates, method);
method.ReturnType = CreateReturnType(methodDeclaration.TypeReference, method);
method.Attributes.AddRange(VisitAttributes(methodDeclaration.Attributes));
@ -291,6 +374,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -291,6 +374,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
DefaultClass c = GetCurrentClass();
Constructor constructor = new Constructor(ConvertModifier(constructorDeclaration.Modifier), region, bodyRegion, GetCurrentClass());
constructor.Documentation = GetDocumentation(region.BeginLine);
constructor.Attributes.AddRange(VisitAttributes(constructorDeclaration.Attributes));
if (constructorDeclaration.Parameters != null) {
foreach (AST.ParameterDeclarationExpression par in constructorDeclaration.Parameters) {
@ -321,6 +405,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -321,6 +405,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
{
DefaultRegion region = GetRegion(fieldDeclaration.StartLocation, fieldDeclaration.EndLocation);
DefaultClass c = GetCurrentClass();
string doku = GetDocumentation(region.BeginLine);
if (currentClass.Count > 0) {
for (int i = 0; i < fieldDeclaration.Fields.Count; ++i) {
AST.VariableDeclaration field = (AST.VariableDeclaration)fieldDeclaration.Fields[i];
@ -332,6 +417,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -332,6 +417,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
retType = CreateReturnType(fieldDeclaration.GetTypeForField(i));
DefaultField f = new DefaultField(retType, field.Name, ConvertModifier(fieldDeclaration.Modifier), region, c);
f.Attributes.AddRange(VisitAttributes(fieldDeclaration.Attributes));
f.Documentation = doku;
if (c.ClassType == ClassType.Enum) {
f.Modifiers = ModifierEnum.Const | ModifierEnum.Public;
}
@ -351,6 +437,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -351,6 +437,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
DefaultClass c = GetCurrentClass();
DefaultProperty property = new DefaultProperty(propertyDeclaration.Name, type, ConvertModifier(propertyDeclaration.Modifier), region, bodyRegion, GetCurrentClass());
property.Documentation = GetDocumentation(region.BeginLine);
property.Attributes.AddRange(VisitAttributes(propertyDeclaration.Attributes));
c.Properties.Add(property);
return null;
@ -363,8 +450,8 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -363,8 +450,8 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
IReturnType type = CreateReturnType(eventDeclaration.TypeReference);
DefaultClass c = GetCurrentClass();
DefaultEvent e = null;
if (eventDeclaration.VariableDeclarators != null) {
if (eventDeclaration.VariableDeclarators != null && eventDeclaration.VariableDeclarators.Count > 0) {
foreach (ICSharpCode.NRefactory.Parser.AST.VariableDeclaration varDecl in eventDeclaration.VariableDeclarators) {
e = new DefaultEvent(varDecl.Name, type, ConvertModifier(eventDeclaration.Modifier), region, bodyRegion, GetCurrentClass());
e.Attributes.AddRange(VisitAttributes(eventDeclaration.Attributes));
@ -375,6 +462,11 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -375,6 +462,11 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
e.Attributes.AddRange(VisitAttributes(eventDeclaration.Attributes));
c.Events.Add(e);
}
if (e != null) {
e.Documentation = GetDocumentation(region.BeginLine);
} else {
Console.WriteLine("Warning: " + eventDeclaration + " has no events!");
}
return null;
}
@ -384,6 +476,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver @@ -384,6 +476,7 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
DefaultRegion bodyRegion = GetRegion(indexerDeclaration.BodyStart, indexerDeclaration.BodyEnd);
List<IParameter> parameters = new List<IParameter>();
DefaultIndexer i = new DefaultIndexer(CreateReturnType(indexerDeclaration.TypeReference), parameters, ConvertModifier(indexerDeclaration.Modifier), region, bodyRegion, GetCurrentClass());
i.Documentation = GetDocumentation(region.BeginLine);
i.Attributes.AddRange(VisitAttributes(indexerDeclaration.Attributes));
if (indexerDeclaration.Parameters != null) {
foreach (AST.ParameterDeclarationExpression par in indexerDeclaration.Parameters) {

8
src/Main/Base/Project/Src/Gui/Workbench/Layouts/SdiWorkspaceWindow.cs

@ -1,4 +1,4 @@ @@ -1,4 +1,4 @@
// <file>
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Mike Krüger" email="mike@icsharpcode.net"/>
@ -66,7 +66,9 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -66,7 +66,9 @@ namespace ICSharpCode.SharpDevelop.Gui
if (viewTabControl != null) {
int selectedIndex = 0;
if (viewTabControl.InvokeRequired) {
selectedIndex = (int)viewTabControl.Invoke(new MyDelegate(GetSelectedIndex));
// the window might have been disposed just here, invoke on the
// Workbench instead
selectedIndex = (int)WorkbenchSingleton.SafeThreadCall(this, "GetSelectedIndex");
} else {
selectedIndex = GetSelectedIndex();
}
@ -77,7 +79,7 @@ namespace ICSharpCode.SharpDevelop.Gui @@ -77,7 +79,7 @@ namespace ICSharpCode.SharpDevelop.Gui
return content;
}
}
delegate int MyDelegate();
int GetSelectedIndex()
{
return viewTabControl.SelectedIndex;

2
src/Main/Base/Project/Src/Services/Debugger/DebuggerService.cs

@ -650,7 +650,7 @@ namespace ICSharpCode.Core @@ -650,7 +650,7 @@ namespace ICSharpCode.Core
text.Append("unknown member ");
text.Append(member.ToString());
}
string documentation = ParserService.CurrentProjectContent.GetXmlDocumentation(member.DocumentationTag);
string documentation = member.Documentation;
if (documentation != null && documentation.Length > 0) {
text.Append('\n');
text.Append(ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor.CodeCompletionData.GetDocumentation(documentation));

10
src/Main/Base/Project/Src/TextEditor/Gui/Editor/CompletionWindow/CodeCompletionData.cs

@ -97,7 +97,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -97,7 +97,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
ambience.ConversionFlags = ConversionFlags.UseFullyQualifiedNames | ConversionFlags.ShowReturnType | ConversionFlags.ShowModifiers;
// Console.WriteLine("Convert : " + c);
description = ambience.Convert(c);
documentation = ParserService.CurrentProjectContent.GetXmlDocumentation(c.DocumentationTag);
documentation = c.Documentation;
}
public CodeCompletionData(IMethod method)
@ -109,7 +109,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -109,7 +109,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
text = method.Name;
description = ambience.Convert(method);
completionString = method.Name;
documentation = ParserService.CurrentProjectContent.GetXmlDocumentation(method.DocumentationTag);
documentation = method.Documentation;
}
public CodeCompletionData(IField field)
@ -121,7 +121,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -121,7 +121,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
text = field.Name;
description = ambience.Convert(field);
completionString = field.Name;
documentation = ParserService.CurrentProjectContent.GetXmlDocumentation(field.DocumentationTag);
documentation = field.Documentation;
}
public CodeCompletionData(IProperty property)
@ -133,7 +133,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -133,7 +133,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
text = property.Name;
description = ambience.Convert(property);
completionString = property.Name;
documentation = ParserService.CurrentProjectContent.GetXmlDocumentation(property.DocumentationTag);
documentation = property.Documentation;
}
public CodeCompletionData(IEvent e)
@ -145,7 +145,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -145,7 +145,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
text = e.Name;
description = ambience.Convert(e);
completionString = e.Name;
documentation = ParserService.CurrentProjectContent.GetXmlDocumentation(e.DocumentationTag);
documentation = e.Documentation;
}
public void InsertAction(TextEditorControl control)

2
src/Main/Base/Project/Src/TextEditor/Gui/Editor/InsightWindow/IndexerInsightDataProvider.cs

@ -41,7 +41,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -41,7 +41,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
IIndexer method = methods[number];
IAmbience conv = AmbienceService.CurrentAmbience;
conv.ConversionFlags = ConversionFlags.StandardConversionFlags;
string documentation = ParserService.CurrentProjectContent.GetXmlDocumentation(method.DocumentationTag);
string documentation = method.Documentation;
return conv.Convert(method) +
"\n" +
CodeCompletionData.GetDocumentation(documentation); // new (by G.B.)

2
src/Main/Base/Project/Src/TextEditor/Gui/Editor/InsightWindow/MethodInsightDataProvider.cs

@ -41,7 +41,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor @@ -41,7 +41,7 @@ namespace ICSharpCode.SharpDevelop.DefaultEditor.Gui.Editor
IMethod method = methods[number];
IAmbience conv = AmbienceService.CurrentAmbience;
conv.ConversionFlags = ConversionFlags.StandardConversionFlags;
string documentation = ParserService.CurrentProjectContent.GetXmlDocumentation(method.DocumentationTag);
string documentation = method.Documentation;
return conv.Convert(method) +
"\n" +
CodeCompletionData.GetDocumentation(documentation); // new (by G.B.)

6
src/Main/Base/Test/ReflectionLayerTests.cs

@ -55,16 +55,16 @@ namespace ICSharpCode.SharpDevelop.Tests @@ -55,16 +55,16 @@ namespace ICSharpCode.SharpDevelop.Tests
Assert.AreEqual(0, DiffUtility.Compare(a1, a2));
}
IMethod GetMethod(IClass c, string name) {
DefaultMethod GetMethod(IClass c, string name) {
IMethod result = c.Methods.Find(delegate(IMethod m) { return m.Name == name; });
Assert.IsNotNull(result, "Method " + name + " not found");
return result;
return (DefaultMethod)result;
}
[Test]
public void GenericDocumentationTagNamesTest()
{
IClass c = pc.GetClass("System.Collections.Generic.List");
DefaultClass c = (DefaultClass)pc.GetClass("System.Collections.Generic.List");
Assert.AreEqual("T:System.Collections.Generic.List`1",
c.DocumentationTag);
Assert.AreEqual("M:System.Collections.Generic.List`1.Add(`0)",

Loading…
Cancel
Save