Browse Source

Using CodeDom to generate metadata files.

Add Option dialog for expand references
pull/15/head
Eusebiu Marcu 15 years ago
parent
commit
b648951f54
  1. 9
      data/resources/StringResources.resx
  2. 3
      src/Main/Base/Project/ICSharpCode.SharpDevelop.addin
  3. 5
      src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj
  4. 115
      src/Main/Base/Project/Src/Editor/Commands/GoToDefinition.cs
  5. 15
      src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/IDEOptions/SharpDevelopUIOptions.xaml
  6. 21
      src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/IDEOptions/SharpDevelopUIOptions.xaml.cs
  7. 10
      src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/InnerExpand/MemberNodes.cs
  8. 10
      src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/InnerExpand/TypeNodes.cs
  9. 5
      src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/ReferenceNode.cs
  10. 431
      src/Main/Base/Project/Src/Services/DecompilerService/DecompilerService.cs

9
data/resources/StringResources.resx

@ -2596,6 +2596,15 @@ Do you want to add the new file to the project ${CurrentProjectName}?</value> @@ -2596,6 +2596,15 @@ Do you want to add the new file to the project ${CurrentProjectName}?</value>
<data name="Dialog.Options.IDEOptions.SelectCulture.UILanguageSetToLabel" xml:space="preserve">
<value>UI language set to:</value>
</data>
<data name="Dialog.Options.IDEOptions.SharpDevelop.GeneralUI.PanelName" xml:space="preserve">
<value>Sharp Develop UI options</value>
</data>
<data name="Dialog.Options.IDEOptions.SharpDevelop.GeneralUI.GroupBoxHeader" xml:space="preserve">
<value>Sharp Develop UI options</value>
</data>
<data name="Dialog.Options.IDEOptions.SharpDevelop.GeneralUI.ExpandReferences" xml:space="preserve">
<value>Expand project references (reflect references)</value>
</data>
<data name="Dialog.Options.IDEOptions.SelectStyle.SelectAmbienceLabel" xml:space="preserve">
<value>Select your preferred &amp;ambience:</value>
</data>

3
src/Main/Base/Project/ICSharpCode.SharpDevelop.addin

@ -1079,6 +1079,9 @@ @@ -1079,6 +1079,9 @@
<OptionPanel id = "SelectStyle"
label = "${res:Dialog.Options.IDEOptions.SelectVisualStyle.PanelName}"
class = "ICSharpCode.SharpDevelop.Gui.OptionPanels.SelectStylePanel"/>
<OptionPanel id = "IDEUIOptions"
label = "${res:Dialog.Options.IDEOptions.SharpDevelop.GeneralUI.PanelName}"
class = "ICSharpCode.SharpDevelop.Gui.OptionPanels.SharpDevelopUIOptions"/>
<OptionPanel id = "LoadSave"
label = "${res:Dialog.Options.IDEOptions.LoadSaveOptions.PanelName}"
class = "ICSharpCode.SharpDevelop.Gui.OptionPanels.LoadSaveOptions"/>

5
src/Main/Base/Project/ICSharpCode.SharpDevelop.csproj

@ -247,6 +247,10 @@ @@ -247,6 +247,10 @@
<DependentUpon>SelectCulturePanel.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Src\Gui\Dialogs\OptionPanels\IDEOptions\SharpDevelopUIOptions.xaml.cs">
<DependentUpon>SharpDevelopUIOptions.xaml</DependentUpon>
<SubType>Code</SubType>
</Compile>
<Compile Include="Src\Gui\Dialogs\OptionPanels\ProjectOptions\WebProjectOptions\WebProjectOptions.cs" />
<Compile Include="Src\Gui\Dialogs\OptionPanels\ProjectOptions\WebProjectOptions\WebProjectOptionsPanel.xaml.cs">
<DependentUpon>WebProjectOptionsPanel.xaml</DependentUpon>
@ -823,6 +827,7 @@ @@ -823,6 +827,7 @@
</ItemGroup>
<ItemGroup>
<Page Include="Src\Bookmarks\Pad\Controls\ListViewPad.xaml" />
<Page Include="Src\Gui\Dialogs\OptionPanels\IDEOptions\SharpDevelopUIOptions.xaml" />
<Page Include="Src\Gui\Dialogs\OptionPanels\ProjectOptions\WebProjectOptions\WebProjectOptionsPanel.xaml" />
<Page Include="Src\Services\RefactoringService\ContextActions\ContextActionsBulbControl.xaml" />
<Page Include="Src\Services\RefactoringService\ContextActions\ContextActionsControl.xaml" />

115
src/Main/Base/Project/Src/Editor/Commands/GoToDefinition.cs

@ -1,10 +1,13 @@ @@ -1,10 +1,13 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using ICSharpCode.SharpDevelop.Dom;
using System;
using System.IO;
using ICSharpCode.Core;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
using Mono.Cecil;
namespace ICSharpCode.SharpDevelop.Editor.Commands
{
@ -15,15 +18,111 @@ namespace ICSharpCode.SharpDevelop.Editor.Commands @@ -15,15 +18,111 @@ namespace ICSharpCode.SharpDevelop.Editor.Commands
if (symbol == null)
return;
FilePosition pos = symbol.GetDefinitionPosition();
if (pos.IsEmpty)
if (pos.IsEmpty) {
new GoToDecompiledDefinition().Run(symbol);
} else {
try {
if (pos.Position.IsEmpty)
FileService.OpenFile(pos.FileName);
else
FileService.JumpToFilePosition(pos.FileName, pos.Line, pos.Column);
} catch (Exception ex) {
MessageService.ShowException(ex, "Error jumping to '" + pos.FileName + "'.");
}
}
}
}
public class GoToDecompiledDefinition : AbstractMenuCommand
{
/// <summary>
/// Don't use this method; throws NotImplementedException.
/// </summary>
public override void Run()
{
throw new NotImplementedException();
}
public void Run(ResolveResult symbol)
{
if (ProjectService.CurrentProject == null)
return;
try {
if (pos.Position.IsEmpty)
FileService.OpenFile(pos.FileName);
string filePath = null;
if (symbol is MemberResolveResult) {
var s = (MemberResolveResult)symbol;
DecompilerService.ReadMetadata(s.ResolvedMember.DeclaringType, out filePath);
if (string.IsNullOrEmpty(filePath))
return;
// jump to definition
var info = ParserService.ParseFile(filePath);
int line = 0, col = 0;
foreach(var c in info.CompilationUnit.Classes) {
if (s.ResolvedMember.EntityType == EntityType.Event) {
foreach (var ev in c.Events) {
if (s.ResolvedMember.FullyQualifiedName == ev.FullyQualifiedName &&
s.ResolvedMember.ReturnType.FullyQualifiedName == ev.ReturnType.FullyQualifiedName) {
col = ev.Region.BeginColumn;
line = ev.Region.BeginLine;
}
}
if (col > 0 || line > 0)
break;
}
if (s.ResolvedMember.EntityType == EntityType.Method) {
foreach(var m1 in s.ResolvedMember.DeclaringType.Methods) {
if (s.ResolvedMember.ReturnType.FullyQualifiedName != m1.ReturnType.FullyQualifiedName ||
s.ResolvedMember.FullyQualifiedName != m1.FullyQualifiedName) continue;
foreach (var m in c.Methods) {
if (m1.FullyQualifiedName == m.FullyQualifiedName &&
m1.ReturnType.FullyQualifiedName == m1.ReturnType.FullyQualifiedName &&
m1.Parameters.Count == m.Parameters.Count) {
col = m.Region.BeginColumn;
line = m.Region.BeginLine;
break;
}
}
if (col > 0 || line > 0)
break;
}
if (col > 0 || line > 0)
break;
}
if (s.ResolvedMember.EntityType == EntityType.Property) {
foreach (var p in c.Properties) {
if (s.ResolvedMember.FullyQualifiedName == p.FullyQualifiedName &&
s.ResolvedMember.ReturnType.FullyQualifiedName == p.ReturnType.FullyQualifiedName) {
col = p.Region.BeginColumn;
line = p.Region.BeginLine;
break;
}
}
if (col > 0 || line > 0)
break;
}
}
if (col > 0 || line > 0)
FileService.JumpToFilePosition(filePath, line, col);
else
FileService.JumpToFilePosition(pos.FileName, pos.Line, pos.Column);
} catch (Exception ex) {
MessageService.ShowException(ex, "Error jumping to '" + pos.FileName + "'.");
FileService.OpenFile(filePath);
}
if (symbol is TypeResolveResult) {
var s = (TypeResolveResult)symbol;
DecompilerService.ReadMetadata(s.ResolvedClass, out filePath);
if (!string.IsNullOrEmpty(filePath))
FileService.OpenFile(filePath);
}
}
}

15
src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/IDEOptions/SharpDevelopUIOptions.xaml

@ -0,0 +1,15 @@ @@ -0,0 +1,15 @@
<gui:OptionPanel x:Class="ICSharpCode.SharpDevelop.Gui.OptionPanels.SharpDevelopUIOptions"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:gui="clr-namespace:ICSharpCode.SharpDevelop.Gui"
xmlns:widgets="http://icsharpcode.net/sharpdevelop/widgets"
xmlns:local="clr-namespace:ICSharpCode.SharpDevelop.Gui.OptionPanels"
xmlns:core="http://icsharpcode.net/sharpdevelop/core">
<GroupBox Header="{core:Localize Dialog.Options.IDEOptions.SharpDevelop.GeneralUI.GroupBoxHeader}">
<widgets:StackPanelWithSpacing SpaceBetweenItems="5">
<CheckBox x:Name="ExpandReferencesCheckBox"
Content="{core:Localize Dialog.Options.IDEOptions.SharpDevelop.GeneralUI.ExpandReferences}"
IsChecked="{core:OptionBinding local:SharpDevelopUIOptions.ExpandReferences}"/>
</widgets:StackPanelWithSpacing>
</GroupBox>
</gui:OptionPanel>

21
src/Main/Base/Project/Src/Gui/Dialogs/OptionPanels/IDEOptions/SharpDevelopUIOptions.xaml.cs

@ -0,0 +1,21 @@ @@ -0,0 +1,21 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Windows.Controls;
using ICSharpCode.Core;
namespace ICSharpCode.SharpDevelop.Gui.OptionPanels
{
public partial class SharpDevelopUIOptions : OptionPanel
{
public SharpDevelopUIOptions()
{
InitializeComponent();
}
public static bool ExpandReferences {
get { return PropertyService.Get("ExpandReferences", false); }
set { PropertyService.Set("ExpandReferences", value); }
}
}
}

10
src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/InnerExpand/MemberNodes.cs

@ -2,7 +2,6 @@ @@ -2,7 +2,6 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using Mono.Cecil;
using Services.DecompilerService;
namespace ICSharpCode.SharpDevelop.Project.InnerExpand
{
@ -18,15 +17,6 @@ namespace ICSharpCode.SharpDevelop.Project.InnerExpand @@ -18,15 +17,6 @@ namespace ICSharpCode.SharpDevelop.Project.InnerExpand
Text = name;
}
public override void ActivateItem()
{
string filePath = null;
DecompilerService.ReadMetadata(type, out filePath);
FileService.OpenFile(filePath);
base.ActivateItem();
}
public override object AcceptVisitor(ProjectBrowserTreeNodeVisitor visitor, object data)
{
return visitor.Visit(this, data);

10
src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/InnerExpand/TypeNodes.cs

@ -3,7 +3,6 @@ @@ -3,7 +3,6 @@
using System;
using System.Text;
using Mono.Cecil;
using Services.DecompilerService;
namespace ICSharpCode.SharpDevelop.Project.InnerExpand
{
@ -61,15 +60,6 @@ namespace ICSharpCode.SharpDevelop.Project.InnerExpand @@ -61,15 +60,6 @@ namespace ICSharpCode.SharpDevelop.Project.InnerExpand
}
}
public override void ActivateItem()
{
string filePath = null;
DecompilerService.ReadMetadata(type, out filePath);
FileService.OpenFile(filePath);
base.ActivateItem();
}
public override object AcceptVisitor(ProjectBrowserTreeNodeVisitor visitor, object data)
{
return visitor.Visit(this, data);

5
src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/ReferenceNode.cs

@ -5,6 +5,8 @@ using System; @@ -5,6 +5,8 @@ using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using ICSharpCode.SharpDevelop.Gui.OptionPanels;
using ICSharpCode.SharpDevelop.Project.InnerExpand;
using Mono.Cecil;
@ -38,6 +40,9 @@ namespace ICSharpCode.SharpDevelop.Project @@ -38,6 +40,9 @@ namespace ICSharpCode.SharpDevelop.Project
public void ShowNamespaces(bool forceRefresh = false)
{
if (!SharpDevelopUIOptions.ExpandReferences)
return;
if (namespaces.Count > 0 && !forceRefresh)
return;

431
src/Main/Base/Project/Src/Services/DecompilerService/DecompilerService.cs

@ -2,156 +2,22 @@ @@ -2,156 +2,22 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Windows.Navigation;
using ICSharpCode.SharpDevelop.Dom;
using ICSharpCode.SharpDevelop.Gui;
using ICSharpCode.SharpDevelop.Project;
using Mono.Cecil;
namespace Services.DecompilerService
namespace ICSharpCode.SharpDevelop
{
public static class DecompilerService
{
public static void ReadMetadata(TypeDefinition type, out string filePath)
{
if (type == null)
{
filePath = null;
return;
}
StringBuilder sb = new StringBuilder();
sb.Append("using System;");
sb.Append(Environment.NewLine);
sb.Append(Environment.NewLine);
sb.Append("namespace " + type.Namespace);
sb.Append(Environment.NewLine);
sb.Append("{");
sb.Append(Environment.NewLine);
// attributes
if (type.HasCustomAttributes) {
foreach (var attr in type.CustomAttributes) {
sb.Append("\t[");
sb.Append(attr.AttributeType.Name);
sb.Append("]");
sb.Append(Environment.NewLine);
}
}
// main definition
sb.Append("\tpublic ");
if (type.IsValueType)
sb.Append("struct ");
else
if (type.IsEnum)
sb.Append("enum ");
else {
if (type.IsClass) {
if (type.IsAbstract)
sb.Append("abstract ");
if (type.IsSealed)
sb.Append("sealed ");
sb.Append("class ");
}
if (type.IsInterface)
sb.Append("interface ");
}
sb.Append(type.Name);
// inheritance
if (type.BaseType != null) {
sb.Append(" : ");
sb.Append(type.BaseType.Name);
}
sb.Append(Environment.NewLine);
sb.Append("\t{");
sb.Append(Environment.NewLine);
if (type.HasEvents) {
sb.Append("\t");sb.Append("\t");sb.Append("// Public Events");
sb.Append(Environment.NewLine);
foreach (var ev in type.Events) {
sb.Append("\t");sb.Append("\t");
sb.Append("public event ");sb.Append(ev.EventType.FullName);sb.Append(" ");sb.Append(ev.Name);
sb.Append(Environment.NewLine);
sb.Append(Environment.NewLine);
}
}
if (type.HasProperties) {
sb.Append("\t");sb.Append("\t");sb.Append("// Public Properties");
sb.Append(Environment.NewLine);
foreach (var property in type.Properties) {
if (property.GetMethod != null && !property.GetMethod.IsPublic &&
property.SetMethod != null && !property.SetMethod.IsPublic)
continue;
sb.Append("\t");sb.Append("\t");
sb.Append("public ");sb.Append(property.PropertyType.FullName);sb.Append(" ");sb.Append(property.Name);
sb.Append(" {");
if (property.GetMethod != null && property.GetMethod.IsPublic)
sb.Append(" get;");
if (property.SetMethod != null && property.SetMethod.IsPublic)
sb.Append(" set;");
sb.Append(" }");
sb.Append(Environment.NewLine);
sb.Append(Environment.NewLine);
}
}
if (type.HasMethods) {
sb.Append("\t");sb.Append("\t");sb.Append("// Public Methods");
sb.Append(Environment.NewLine);
foreach (var method in type.Methods) {
if (method.IsPrivate) continue;
if (method.Name.StartsWith("get_") || method.Name.StartsWith("set_")) continue;
sb.Append("\t");sb.Append("\t");
sb.Append("public ");
if (method.IsStatic)
sb.Append("static ");
if (!method.IsConstructor) {
sb.Append(method.ReturnType.FullName);sb.Append(" ");sb.Append(method.Name);
} else {
sb.Append(type.Name);
}
sb.Append(GetParameters(method));
sb.Append(";");
sb.Append(Environment.NewLine);
sb.Append(Environment.NewLine);
}
}
sb.Append("\t}");
sb.Append(Environment.NewLine);
sb.Append("}");
// temp file
string tempFolder = Path.GetTempPath();
string file = type.Name + ".temp.cs";
filePath = Path.Combine(tempFolder, file);
using (StreamWriter sr = new StreamWriter(filePath)) {
sr.Write(sb.ToString());
}
}
public static string GetParameters(MethodDefinition method)
{
StringBuilder sb = new StringBuilder();
@ -182,5 +48,282 @@ namespace Services.DecompilerService @@ -182,5 +48,282 @@ namespace Services.DecompilerService
return sb.ToString();
}
public static void ReadMetadata(IClass c, out string filePath)
{
CodeCompileUnit compileUnit = new CodeCompileUnit();
// add namespace
CodeNamespace generatedNamespace = new CodeNamespace(c.Namespace);
generatedNamespace.Imports.Add(new CodeNamespaceImport("System"));
compileUnit.Namespaces.Add(generatedNamespace);
// add type
var targetClass = new CodeTypeDeclaration(c.Name);
// write attributes
AddAttributes(c, targetClass);
// write class definition
if (c.IsPublic) targetClass.TypeAttributes |= System.Reflection.TypeAttributes.Public;
if (c.IsSealed) targetClass.TypeAttributes |= System.Reflection.TypeAttributes.Sealed;
// static class limitation - c.IsStatic: https://connect.microsoft.com/VisualStudio/feedback/details/93653/codedom-unable-to-generate-static-events-and-classes
targetClass.IsPartial = c.IsPartial;
switch (c.ClassType) {
case ClassType.Class:
targetClass.IsClass = true;
break;
case ClassType.Enum:
targetClass.IsEnum = true;
break;
case ClassType.Interface:
targetClass.IsInterface = true;
break;
case ClassType.Struct:
targetClass.IsStruct = true;
break;
}
// generics
foreach (var typeParameter in c.TypeParameters) {
var tp = new CodeTypeParameter(typeParameter.Name);
foreach (var con in typeParameter.Constraints) {
tp.Constraints.Add(con.Name);
}
targetClass.TypeParameters.Add(tp);
}
// base types
foreach (var basetype in c.BaseTypes) {
if (basetype.FullyQualifiedName.Equals("System.Object", StringComparison.OrdinalIgnoreCase))
continue;
var baseType = AddGenericBaseTypes(basetype);
targetClass.BaseTypes.Add(baseType);
}
// field members
foreach (var f in c.Fields) {
if (!f.IsPublic && !f.IsProtected) continue;
CodeMemberField field = new CodeMemberField() { Name = f.Name,
Attributes = MemberAttributes.Public };
AddDefinition(f, field);
AddAttributes(f, field);
AddDocumentation(f, field);
field.Type = new CodeTypeReference(f.ReturnType.FullyQualifiedName);
targetClass.Members.Add(field);
}
// event members
foreach (var e in c.Events) {
if (!e.IsPublic && !e.IsProtected) continue;
CodeMemberEvent ev = new CodeMemberEvent() { Name = e.Name,
Attributes = MemberAttributes.Public,
Type = new CodeTypeReference(e.ReturnType.FullyQualifiedName) };
AddDefinition(e, ev);
AddDocumentation(e, ev);
targetClass.Members.Add(ev);
}
// properties
foreach (var property in c.Properties) {
if (!property.IsPublic && !property.IsProtected) continue;
CodeMemberProperty p = new CodeMemberProperty() {
Name = property.Name,
Attributes = MemberAttributes.Public,
Type = new CodeTypeReference(property.ReturnType.FullyQualifiedName),
HasGet = property.CanGet,
HasSet = property.CanSet
};
AddAttributes(property, p);
AddDefinition(property, p);
AddDocumentation(property, p);
if (property.IsIndexer) {
p.Parameters.Add(new CodeParameterDeclarationExpression("System.Int32", "index"));
}
targetClass.Members.Add(p);
}
// methods and constructors
foreach (var method in c.Methods) {
if (!method.IsPublic && !method.IsProtected) continue;
if (method.IsConstructor) {
CodeConstructor constructor = new CodeConstructor() { Name = c.Name,
Attributes = MemberAttributes.Public };
AddAttributes(method, constructor);
AddDefinition(method, constructor);
AddParameters(method, constructor);
AddDocumentation(method, constructor);
targetClass.Members.Add(constructor);
} else {
CodeMemberMethod m = new CodeMemberMethod() {
Name = method.Name,
Attributes = MemberAttributes.Public,
ReturnType = new CodeTypeReference(method.ReturnType.FullyQualifiedName),
};
AddAttributes(method, m);
AddDefinition(method, m);
AddParameters(method, m);
AddDocumentation(method, m);
targetClass.Members.Add(m);
}
}
// delegates
foreach (var inner in c.InnerClasses) {
if (inner.ClassType == ClassType.Delegate) {
IMethod invoker = inner.Methods.Where(method => method.Name == "Invoke").FirstOrDefault();
CodeTypeDelegate del = new CodeTypeDelegate(inner.Name) {
Attributes = MemberAttributes.Public,
ReturnType = new CodeTypeReference(invoker.ReturnType.FullyQualifiedName)
};
AddDocumentation(invoker, del);
foreach (var p in invoker.Parameters)
del.Parameters.Add(new CodeParameterDeclarationExpression(p.ReturnType.FullyQualifiedName, p.Name));
targetClass.Members.Add(del);
}
}
// add class
generatedNamespace.Types.Add(targetClass);
filePath = WriteTempFile(c.Name, compileUnit);
}
static CodeTypeReference AddGenericBaseTypes(IReturnType basetype)
{
string type = basetype.FullyQualifiedName;
CodeTypeReference baseType = new CodeTypeReference(type);
if (basetype.IsConstructedReturnType)
{
var constructed = basetype as ConstructedReturnType;
int i = 0;
foreach (var typearg in constructed.TypeArguments) {
baseType.TypeArguments.Add(new CodeTypeReference(typearg.Name, CodeTypeReferenceOptions.GenericTypeParameter));
if (typearg is ConstructedReturnType) {
CodeTypeReference baseType1 = new CodeTypeReference(typearg.FullyQualifiedName);
baseType1.TypeArguments.Add(AddGenericBaseTypes(typearg));
baseType.TypeArguments[i].TypeArguments.Add(baseType1);
}
++i;
}
}
return baseType;
}
static void AddParameters(IMethod method, CodeMemberMethod m)
{
foreach (var p in method.Parameters) {
string returnType = p.ReturnType.FullyQualifiedName;
var par = new CodeParameterDeclarationExpression(returnType, p.Name);
if (p.ReturnType.IsConstructedReturnType)
{
CodeTypeReference baseType = new CodeTypeReference(returnType);
var c = p.ReturnType as ConstructedReturnType;
foreach (var typearg in c.TypeArguments) {
baseType.TypeArguments.Add(new CodeTypeReference(typearg.Name, CodeTypeReferenceOptions.GenericTypeParameter));
}
par.Type = baseType;
}
if (p.IsRef)
par.Direction = FieldDirection.Ref;
if (p.IsOut)
par.Direction = FieldDirection.Out;
if (p.IsParams)
par.CustomAttributes.Add(new CodeAttributeDeclaration(new CodeTypeReference(typeof(System.ParamArrayAttribute))));
// TODO: if (p.IsOptional)
m.Parameters.Add(par);
}
}
static void AddDocumentation(IEntity entity, CodeTypeMember member)
{
if (string.IsNullOrEmpty(entity.Documentation) || string.IsNullOrEmpty(entity.Documentation.Trim()))
return;
member.Comments.Add(new CodeCommentStatement(entity.Documentation.Replace(" ", string.Empty), true));
}
static void AddDefinition(IEntity entity, CodeTypeMember member)
{
if (entity.IsProtected)
member.Attributes = MemberAttributes.Family;
if (entity.IsStatic)
member.Attributes |= MemberAttributes.Static;
if (entity.IsNew)
member.Attributes |= MemberAttributes.New;
if (entity.IsOverride)
member.Attributes |= MemberAttributes.Override;
if (entity.IsAbstract)
member.Attributes |= MemberAttributes.Abstract;
if (entity.IsVirtual)
member.Attributes |= MemberAttributes.Final;
if (entity.IsConst)
member.Attributes |= MemberAttributes.Const;
}
static void AddAttributes(IEntity entity, CodeTypeMember member)
{
// write attributes
foreach (var attr in entity.Attributes) {
List<CodeAttributeArgument> list = new List<CodeAttributeArgument>();
for (int i = 0; i < attr.PositionalArguments.Count; i++) {
if (!(attr.PositionalArguments[i] is IReturnType))
list.Add(new CodeAttributeArgument(new CodePrimitiveExpression(attr.PositionalArguments[i])));
}
if (list.Count == 0) {
member.CustomAttributes.Add(
new CodeAttributeDeclaration(attr.AttributeType.FullyQualifiedName));
} else {
member.CustomAttributes.Add(
new CodeAttributeDeclaration(attr.AttributeType.FullyQualifiedName, list.ToArray()));
}
}
}
static string WriteTempFile(string fileName, CodeCompileUnit compileUnit)
{
// temp file
string tempFolder = Path.GetTempPath();
string file = fileName + ".temp.cs";
string filePath = Path.Combine(tempFolder, file);
if (File.Exists(filePath))
File.Delete(filePath);
// write file
using (var sw = new StreamWriter(filePath, false))
{
ProjectService
.CurrentProject
.LanguageProperties
.CodeDomProvider.GenerateCodeFromCompileUnit(
compileUnit,
sw,
new CodeGeneratorOptions());
}
return filePath;
}
}
}
}
Loading…
Cancel
Save