📄 codedomvisitor.cs
字号:
// CodeDOMVisitor.cs
// Copyright (C) 2003 Mike Krueger (mike@icsharpcode.net)
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
using System;
using System.Reflection;
using System.CodeDom;
using System.Text;
using System.Collections;
using ICSharpCode.SharpRefactory.Parser.AST;
namespace ICSharpCode.SharpRefactory.Parser
{
public class CodeDOMVisitor : AbstractASTVisitor
{
Stack namespaceDeclarations = new Stack();
Stack typeDeclarations = new Stack();
Stack codeStack = new Stack();
TypeDeclaration currentTypeDeclaration;
// dummy collection used to swallow statements
System.CodeDom.CodeStatementCollection NullStmtCollection = new CodeStatementCollection();
public CodeCompileUnit codeCompileUnit = new CodeCompileUnit();
public ArrayList namespaces = new ArrayList();
static string[,] typeConversionList = new string[,] {
{"System.Void", "void"},
{"System.Object", "object"},
{"System.Boolean", "bool"},
{"System.Byte", "byte"},
{"System.SByte", "sbyte"},
{"System.Char", "char"},
{"System.Enum", "enum"},
{"System.Int16", "short"},
{"System.Int32", "int"},
{"System.Int64", "long"},
{"System.UInt16", "ushort"},
{"System.UInt32", "uint"},
{"System.UInt64", "ulong"},
{"System.Single", "float"},
{"System.Double", "double"},
{"System.Decimal", "decimal"},
{"System.String", "string"}
};
static Hashtable typeConversionTable = new Hashtable();
static CodeDOMVisitor()
{
for (int i = 0; i < typeConversionList.GetLength(0); ++i) {
typeConversionTable[typeConversionList[i, 1]] = typeConversionList[i, 0];
}
}
string ConvType(string type)
{
if (typeConversionTable[type] != null) {
return typeConversionTable[type].ToString();
}
return type;
}
void AddStmt(System.CodeDom.CodeStatement stmt)
{
System.CodeDom.CodeStatementCollection stmtCollection = codeStack.Peek() as System.CodeDom.CodeStatementCollection;
if (stmtCollection != null) {
stmtCollection.Add(stmt);
}
}
void AddStmt(System.CodeDom.CodeExpression expr)
{
System.CodeDom.CodeStatementCollection stmtCollection = codeStack.Peek() as System.CodeDom.CodeStatementCollection;
if (stmtCollection != null) {
stmtCollection.Add(expr);
}
}
// FIXME: map all modifiers correctly
MemberAttributes ConvMemberAttributes(Modifier modifier)
{
MemberAttributes attr = (MemberAttributes)0;
if ((modifier & Modifier.Abstract) != 0)
attr |= MemberAttributes.Abstract;
// if ((modifier & Modifier.None) != 0)
// attr |= MemberAttributes.AccessMask;
if ((modifier & Modifier.Internal) != 0)
attr |= MemberAttributes.Assembly;
if ((modifier & Modifier.Const) != 0)
attr |= MemberAttributes.Const;
if ((modifier & Modifier.Protected) != 0)
attr |= MemberAttributes.Family;
if ((modifier & Modifier.Protected) != 0 && (modifier & Modifier.Internal) != 0)
attr |= MemberAttributes.FamilyAndAssembly;
// if ((modifier & Modifier.None) != 0)
// attr |= MemberAttributes.FamilyOrAssembly;
if ((modifier & Modifier.Sealed) != 0)
attr |= MemberAttributes.Final;
if ((modifier & Modifier.New) != 0)
attr |= MemberAttributes.New;
if ((modifier & Modifier.Virtual) != 0)
attr |= MemberAttributes.Overloaded;
if ((modifier & Modifier.Override) != 0)
attr |= MemberAttributes.Override;
if ((modifier & Modifier.Private) != 0)
attr |= MemberAttributes.Private;
if ((modifier & Modifier.Public) != 0)
attr |= MemberAttributes.Public;
// if ((modifier & Modifier.None) != 0)
// attr |= MemberAttributes.ScopeMask;
if ((modifier & Modifier.Static) != 0)
attr |= MemberAttributes.Static;
// if ((modifier & Modifier.None) != 0)
// attr |= MemberAttributes.VTableMask;
return attr;
}
void ProcessSpecials(Hashtable specials)
{
if (specials == null) {
return;
}
foreach (object special in specials) {
if (special is BlankLine) {
AddStmt(new CodeSnippetStatement());
} else if (special is PreProcessingDirective) {
// TODO
} else if (special is Comment) {
Comment comment = (Comment)special;
switch (comment.CommentType) {
case CommentType.SingleLine:
AddStmt(new CodeCommentStatement(comment.CommentText, false));
break;
case CommentType.Documentation:
AddStmt(new CodeCommentStatement(comment.CommentText, true));
break;
case CommentType.Block:
AddStmt(new CodeCommentStatement(comment.CommentText, false));
break;
}
}
}
}
#region ICSharpCode.SharpRefactory.Parser.IASTVisitor interface implementation
public override object Visit(CompilationUnit compilationUnit, object data)
{
CodeNamespace globalNamespace = new CodeNamespace("Global");
namespaces.Add(globalNamespace);
namespaceDeclarations.Push(globalNamespace);
compilationUnit.AcceptChildren(this, data);
codeCompileUnit.Namespaces.Add(globalNamespace);
return globalNamespace;
}
public override object Visit(NamespaceDeclaration namespaceDeclaration, object data)
{
ProcessSpecials(namespaceDeclaration.Specials);
CodeNamespace currentNamespace = new CodeNamespace(namespaceDeclaration.NameSpace);
namespaces.Add(currentNamespace);
// add imports from mother namespace
foreach (CodeNamespaceImport import in ((CodeNamespace)namespaceDeclarations.Peek()).Imports) {
currentNamespace.Imports.Add(import);
}
namespaceDeclarations.Push(currentNamespace);
namespaceDeclaration.AcceptChildren(this, data);
namespaceDeclarations.Pop();
codeCompileUnit.Namespaces.Add(currentNamespace);
// TODO : Nested namespaces allowed in CodeDOM ? Doesn't seem so :(
return null;
}
public override object Visit(UsingDeclaration usingDeclaration, object data)
{
ProcessSpecials(usingDeclaration.Specials);
((CodeNamespace)namespaceDeclarations.Peek()).Imports.Add(new CodeNamespaceImport(usingDeclaration.Namespace));
return null;
}
public override object Visit(UsingAliasDeclaration usingAliasDeclaration, object data)
{
return null;
}
public override object Visit(AttributeSection attributeSection, object data)
{
return null;
}
public override object Visit(TypeDeclaration typeDeclaration, object data)
{
ProcessSpecials(typeDeclaration.Specials);
this.currentTypeDeclaration = typeDeclaration;
CodeTypeDeclaration codeTypeDeclaration = new CodeTypeDeclaration(typeDeclaration.Name);
codeTypeDeclaration.IsClass = typeDeclaration.Type == Types.Class;
codeTypeDeclaration.IsEnum = typeDeclaration.Type == Types.Enum;
codeTypeDeclaration.IsInterface = typeDeclaration.Type == Types.Interface;
codeTypeDeclaration.IsStruct = typeDeclaration.Type == Types.Struct;
if (typeDeclaration.BaseTypes != null) {
foreach (object o in typeDeclaration.BaseTypes) {
codeTypeDeclaration.BaseTypes.Add(new CodeTypeReference(o.ToString()));
}
}
typeDeclarations.Push(codeTypeDeclaration);
typeDeclaration.AcceptChildren(this,data);
// ((INode)typeDeclaration.Children[0]).(this, data);
typeDeclarations.Pop();
((CodeNamespace)namespaceDeclarations.Peek()).Types.Add(codeTypeDeclaration);
return null;
}
public override object Visit(DelegateDeclaration delegateDeclaration, object data)
{
// CodeTypeDelegate codeTypeDelegate = new CodeTypeDelegate(delegateDeclaration.Name);
// codeTypeDelegate.Parameters
//
// ((CodeNamespace)namespaceDeclarations.Peek()).Types.Add(codeTypeDelegate);
return null;
}
public override object Visit(VariableDeclaration variableDeclaration, object data)
{
return null;
}
public override object Visit(FieldDeclaration fieldDeclaration, object data)
{
ProcessSpecials(fieldDeclaration.Specials);
for (int i = 0; i < fieldDeclaration.Fields.Count; ++i)
{
VariableDeclaration field = (VariableDeclaration)fieldDeclaration.Fields[i];
CodeMemberField memberField = new CodeMemberField(new CodeTypeReference(ConvType(fieldDeclaration.TypeReference.Type)), field.Name);
memberField.Attributes = ConvMemberAttributes(fieldDeclaration.Modifier);
if (field.Initializer != null) {
memberField.InitExpression = (CodeExpression)((INode)field.Initializer).AcceptVisitor(this, data);
}
((CodeTypeDeclaration)typeDeclarations.Peek()).Members.Add(memberField);
}
return null;
}
public override object Visit(MethodDeclaration methodDeclaration, object data)
{
ProcessSpecials(methodDeclaration.Specials);
CodeMemberMethod memberMethod = new CodeMemberMethod();
memberMethod.Name = methodDeclaration.Name;
memberMethod.Attributes = ConvMemberAttributes(methodDeclaration.Modifier);
codeStack.Push(memberMethod.Statements);
((CodeTypeDeclaration)typeDeclarations.Peek()).Members.Add(memberMethod);
// Add Method Parameters
foreach (ParameterDeclarationExpression parameter in methodDeclaration.Parameters)
{
memberMethod.Parameters.Add((CodeParameterDeclarationExpression)Visit(parameter, data));
}
methodDeclaration.Body.AcceptChildren(this, data);
codeStack.Pop();
return null;
}
public override object Visit(PropertyDeclaration propertyDeclaration, object data)
{
return null;
}
public override object Visit(PropertyGetRegion propertyGetRegion, object data)
{
return null;
}
public override object Visit(PropertySetRegion PropertySetRegion, object data)
{
return null;
}
public override object Visit(EventDeclaration eventDeclaration, object data)
{
return null;
}
public override object Visit(EventAddRegion eventAddRegion, object data)
{
return null;
}
public override object Visit(EventRemoveRegion eventRemoveRegion, object data)
{
return null;
}
public override object Visit(ConstructorDeclaration constructorDeclaration, object data)
{
ProcessSpecials(constructorDeclaration.Specials);
CodeMemberMethod memberMethod = new CodeConstructor();
codeStack.Push(memberMethod.Statements);
((CodeTypeDeclaration)typeDeclarations.Peek()).Members.Add(memberMethod);
// constructorDeclaration.AcceptChildren(this, data);
codeStack.Pop();
return null;
}
public override object Visit(DestructorDeclaration destructorDeclaration, object data)
{
return null;
}
public override object Visit(OperatorDeclaration operatorDeclaration, object data)
{
return null;
}
public override object Visit(IndexerDeclaration indexerDeclaration, object data)
{
return null;
}
public override object Visit(BlockStatement blockStatement, object data)
{
ProcessSpecials(blockStatement.Specials);
blockStatement.AcceptChildren(this, data);
return null;
}
public override object Visit(StatementExpression statementExpression, object data)
{
object exp = statementExpression.Expression.AcceptVisitor(this, data);
if (exp is CodeExpression) {
AddStmt(new CodeExpressionStatement((CodeExpression)exp));
}
return exp;
}
public string Convert(TypeReference typeRef)
{
StringBuilder builder = new StringBuilder();
builder.Append(ConvType(typeRef.Type));
for (int i = 0; i < typeRef.PointerNestingLevel; ++i) {
builder.Append('*');
}
for (int i = 0; i < typeRef.RankSpecifier.Length; ++i) {
builder.Append('[');
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -