📄 csharpvisitor.cs
字号:
// CSharpVisitor.cs
// Copyright (C) 2004 Markus Palme (markuspalme@gmx.de)
//
// 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.VB;
using ICSharpCode.SharpRefactory.Parser.AST.VB;
namespace ICSharpCode.SharpRefactory.PrettyPrinter.VB
{
public class CSharpVisitor : IASTVisitor
{
readonly string newLineSep = Environment.NewLine;
StringBuilder sourceText = new StringBuilder();
int indentLevel = 0;
Errors errors = new Errors();
TypeDeclaration currentType = null;
Stack withExpressionStack = new Stack();
public StringBuilder SourceText {
get {
return sourceText;
}
}
public void AppendIndentation()
{
for (int i = 0; i < indentLevel; ++i) {
sourceText.Append("\t");
}
}
public void AppendNewLine()
{
sourceText.Append(newLineSep);
}
public void AppendStatementEnd()
{
sourceText.Append(";");
AppendNewLine();
}
void DebugOutput(object o)
{
// Console.WriteLine(o.ToString());
}
#region ICSharpCode.SharpRefactory.Parser.VB.IASTVisitor interface implementation
public object Visit(INode node, object data)
{
AppendIndentation();
sourceText.Append("// warning visited unknown node :");
sourceText.Append(node);
AppendNewLine();
return String.Empty;
}
public object Visit(CompilationUnit compilationUnit, object data)
{
DebugOutput(compilationUnit);
compilationUnit.AcceptChildren(this, data);
return null;
}
#region GlobalScope
public object Visit(NamespaceDeclaration namespaceDeclaration, object data)
{
DebugOutput(namespaceDeclaration);
AppendIndentation();
sourceText.Append("namespace ");
sourceText.Append(namespaceDeclaration.NameSpace);
AppendNewLine();
sourceText.Append("{");
AppendNewLine();
++indentLevel;
namespaceDeclaration.AcceptChildren(this, data);
--indentLevel;
AppendIndentation();
sourceText.Append("}");
AppendNewLine();
return null;
}
public object Visit(ImportsStatement importsStatement, object data)
{
foreach (INode node in importsStatement.ImportClauses) {
node.AcceptVisitor(this, data);
}
return null;
}
public object Visit(ImportsDeclaration importsDeclaration, object data)
{
DebugOutput(importsDeclaration);
AppendIndentation();
sourceText.Append("using ");
sourceText.Append(importsDeclaration.Namespace);
sourceText.Append(";");
AppendNewLine();
return null;
}
public object Visit(ImportsAliasDeclaration importsAliasDeclaration, object data)
{
DebugOutput(importsAliasDeclaration);
AppendIndentation();
sourceText.Append("using ");
sourceText.Append(importsAliasDeclaration.Alias);
sourceText.Append(" = ");
sourceText.Append(importsAliasDeclaration.Namespace);
sourceText.Append(";");
AppendNewLine();
return null;
}
public object Visit(TypeDeclaration typeDeclaration, object data)
{
DebugOutput(typeDeclaration);
AppendAttributes(typeDeclaration.Attributes);
string modifier = GetModifier(typeDeclaration.Modifier);
string type = String.Empty;
switch (typeDeclaration.Type) {
case Types.Class:
type = "class ";
break;
case Types.Enum:
type = "enum ";
break;
case Types.Interface:
type = "interface ";
break;
case Types.Module:
case Types.Structure:
type = "struct ";
break;
}
AppendIndentation();
sourceText.Append(modifier);
sourceText.Append(type);
sourceText.Append(typeDeclaration.Name);
bool hasBaseType = typeDeclaration.BaseType != null;
if (hasBaseType) {
sourceText.Append(" : ");
sourceText.Append(ConvertTypeString(typeDeclaration.BaseType));
}
if (typeDeclaration.BaseInterfaces != null && typeDeclaration.BaseInterfaces.Count > 0) {
if (!hasBaseType) {
sourceText.Append(" : ");
} else {
sourceText.Append(", ");
}
for (int i = 0; i < typeDeclaration.BaseInterfaces.Count; ++i) {
if (typeDeclaration.BaseInterfaces[i] is TypeReference) {
sourceText.Append((typeDeclaration.BaseInterfaces[i] as TypeReference).Type);
} else {
sourceText.Append(typeDeclaration.BaseInterfaces[i].ToString());
}
if (i + 1 < typeDeclaration.BaseInterfaces.Count) {
sourceText.Append(", ");
}
}
}
AppendNewLine();
AppendIndentation();
sourceText.Append("{");
AppendNewLine();
++indentLevel;
TypeDeclaration oldType = currentType;
currentType = typeDeclaration;
typeDeclaration.AcceptChildren(this, data);
currentType = oldType;
--indentLevel;
AppendIndentation();
sourceText.Append("}");
AppendNewLine();
return null;
}
public object Visit(DelegateDeclaration delegateDeclaration, object data)
{
DebugOutput(delegateDeclaration);
AppendAttributes(delegateDeclaration.Attributes);
AppendIndentation();
sourceText.Append(GetModifier(delegateDeclaration.Modifier));
sourceText.Append("delegate ");
sourceText.Append(GetTypeString(delegateDeclaration.ReturnType));
sourceText.Append(" ");
sourceText.Append(delegateDeclaration.Name);
sourceText.Append("(");
AppendParameters(delegateDeclaration.Parameters);
sourceText.Append(");");
AppendNewLine();
return null;
}
public object Visit(EventDeclaration eventDeclaration, object data)
{
DebugOutput(eventDeclaration);
AppendAttributes(eventDeclaration.Attributes);
AppendIndentation();
sourceText.Append(GetModifier(eventDeclaration.Modifier));
sourceText.Append("event ");
if (eventDeclaration.TypeReference == null) {
sourceText.Append(eventDeclaration.Name);
sourceText.Append("EventHandler");
} else {
sourceText.Append(GetTypeString(eventDeclaration.TypeReference));
}
sourceText.Append(" ");
sourceText.Append(eventDeclaration.Name);
sourceText.Append(";");
AppendNewLine();
return null;
}
#endregion
#region TypeLevel
public object Visit(VariableDeclaration variableDeclaration, object data)
{
// called inside ENUMS
// AppendAttributes(field.Attributes);
AppendIndentation();
sourceText.Append(variableDeclaration.Name);
if (variableDeclaration.Initializer != null) {
sourceText.Append(" = ");
sourceText.Append(variableDeclaration.Initializer.AcceptVisitor(this, data));
}
AppendNewLine();
return null;
}
public object Visit(FieldDeclaration fieldDeclaration, object data)
{
DebugOutput(fieldDeclaration);
foreach (VariableDeclaration field in fieldDeclaration.Fields) {
AppendAttributes(fieldDeclaration.Attributes);
AppendIndentation();
if (currentType.Type == Types.Enum) {
if (fieldDeclaration.Fields.IndexOf(field) > 0) {
sourceText.Append(", ");
}
sourceText.Append(field.Name);
if (field.Initializer != null) {
sourceText.Append(" = ");
sourceText.Append(field.Initializer.AcceptVisitor(this, data).ToString());
}
} else {
if (fieldDeclaration.Modifier == Modifier.None) {
sourceText.Append(" private ");
} else {
sourceText.Append(GetModifier(fieldDeclaration.Modifier));
}
if (field.Type == null)
sourceText.Append("object");
else
sourceText.Append(GetTypeString(field.Type));
sourceText.Append(" ");
sourceText.Append(field.Name);
if (field.Initializer != null) {
sourceText.Append(" = ");
sourceText.Append(field.Initializer.AcceptVisitor(this, data).ToString());
} else {
if (field.Type != null && field.Type.Dimension != null) {
sourceText.Append(" = new ");
sourceText.Append(ConvertTypeString(field.Type.Type));
sourceText.Append("[");
sourceText.Append(GetExpressionList(field.Type.Dimension));
sourceText.Append("]");
}
}
sourceText.Append(";");
AppendNewLine();
}
}
// if that's not the last enum member, add a comma
if (currentType.Type == Types.Enum) {
int pos = currentType.Children.IndexOf(fieldDeclaration);
if (pos >= 0) {
for (int i = pos+1; i < currentType.Children.Count; i++) {
if (currentType.Children[i] is FieldDeclaration) {
sourceText.Append(",");
break;
}
}
}
AppendNewLine();
}
return null;
}
public object Visit(MethodDeclaration methodDeclaration, object data)
{
DebugOutput(methodDeclaration);
exitConstructStack.Push(new DictionaryEntry(typeof(MethodDeclaration), null));
AppendNewLine();
AppendAttributes(methodDeclaration.Attributes);
AppendIndentation();
sourceText.Append(GetModifier(methodDeclaration.Modifier));
sourceText.Append(GetTypeString(methodDeclaration.TypeReference));
sourceText.Append(" ");
sourceText.Append(methodDeclaration.Name);
sourceText.Append("(");
AppendParameters(methodDeclaration.Parameters);
sourceText.Append(")");
if (currentType.Type != Types.Interface &&
(methodDeclaration.Modifier & Modifier.MustOverride) != Modifier.MustOverride)
{
AppendNewLine();
AppendIndentation();
sourceText.Append("{");
AppendNewLine();
if (methodDeclaration.Body != null) {
++indentLevel;
methodDeclaration.Body.AcceptVisitor(this, data);
GenerateExitConstructLabel();
--indentLevel;
}
AppendIndentation();
sourceText.Append("}");
} else {
sourceText.Append(";");
}
AppendNewLine();
return null;
}
public object Visit(ConstructorDeclaration constructorDeclaration, object data)
{
DebugOutput(constructorDeclaration);
exitConstructStack.Push(new DictionaryEntry(typeof(MethodDeclaration), null));
AppendNewLine();
AppendAttributes(constructorDeclaration.Attributes);
AppendIndentation();
sourceText.Append(GetModifier(constructorDeclaration.Modifier));
sourceText.Append(this.currentType.Name);
sourceText.Append("(");
AppendParameters(constructorDeclaration.Parameters);
sourceText.Append(")");
AppendNewLine();
AppendIndentation();
sourceText.Append("{");
AppendNewLine();
if (constructorDeclaration.Body != null) {
++indentLevel;
constructorDeclaration.Body.AcceptVisitor(this, data);
GenerateExitConstructLabel();
--indentLevel;
}
AppendIndentation();
sourceText.Append("}");
AppendNewLine();
return null;
}
public object Visit(DeclareDeclaration declareDeclaration, object data)
{
DebugOutput(declareDeclaration);
AppendAttributes(declareDeclaration.Attributes);
AppendIndentation();
sourceText.Append(String.Format("[System.Runtime.InteropServices.DllImport({0}", declareDeclaration.Library));
if (declareDeclaration.Alias != null) {
sourceText.Append(String.Format(", EntryPoint={0}", declareDeclaration.Alias));
}
switch (declareDeclaration.Charset) {
case CharsetModifier.ANSI:
sourceText.Append(", CharSet=System.Runtime.InteropServices.CharSet.Ansi");
break;
case CharsetModifier.Unicode:
sourceText.Append(", CharSet=System.Runtime.InteropServices.CharSet.Unicode");
break;
case CharsetModifier.Auto:
sourceText.Append(", CharSet=System.Runtime.InteropServices.CharSet.Auto");
break;
}
sourceText.Append(")]");
AppendNewLine();
AppendIndentation();
sourceText.Append(GetModifier(declareDeclaration.Modifier));
sourceText.Append("static extern ");
sourceText.Append(GetTypeString(declareDeclaration.ReturnType));
sourceText.Append(" ");
sourceText.Append(declareDeclaration.Name);
sourceText.Append("(");
AppendParameters(declareDeclaration.Parameters);
sourceText.Append(");");
AppendNewLine();
return null;
}
public object Visit(PropertyDeclaration propertyDeclaration, object data)
{
DebugOutput(propertyDeclaration);
AppendNewLine();
AppendAttributes(propertyDeclaration.Attributes);
AppendIndentation();
sourceText.Append(GetModifier(propertyDeclaration.Modifier & ~Modifier.ReadOnly));
sourceText.Append(GetTypeString(propertyDeclaration.TypeReference));
sourceText.Append(" ");
sourceText.Append(propertyDeclaration.Name);
sourceText.Append(" {");
AppendNewLine();
if (currentType.Type != Types.Interface) {
if (propertyDeclaration.GetRegion != null) {
++indentLevel;
propertyDeclaration.GetRegion.AcceptVisitor(this, data);
--indentLevel;
}
if (propertyDeclaration.SetRegion != null) {
++indentLevel;
propertyDeclaration.SetRegion.AcceptVisitor(this, data);
--indentLevel;
}
}
// if abstract, add default get/set
if ((propertyDeclaration.Modifier & Modifier.MustOverride) == Modifier.MustOverride &&
propertyDeclaration.GetRegion == null &&
propertyDeclaration.SetRegion == null) {
AppendIndentation();
sourceText.Append("get;");
AppendNewLine();
AppendIndentation();
sourceText.Append("set;");
AppendNewLine();
}
AppendIndentation();
sourceText.Append("}");
AppendNewLine();
return null;
}
public object Visit(PropertyGetRegion propertyGetRegion, object data)
{
DebugOutput(propertyGetRegion);
exitConstructStack.Push(new DictionaryEntry(typeof(PropertyDeclaration), null));
AppendAttributes(propertyGetRegion.Attributes);
AppendIndentation();
sourceText.Append("get {");
AppendNewLine();
if (propertyGetRegion.Block != null) {
++indentLevel;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -