📄 vbnetvisitor.cs
字号:
// VBNetVisitor.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;
using ICSharpCode.SharpRefactory.Parser.AST;
namespace ICSharpCode.SharpRefactory.PrettyPrinter
{
public class VBNetVisitor : AbstractASTVisitor
{
readonly string newLineSep = Environment.NewLine;
StringBuilder sourceText = new StringBuilder();
int indentLevel = 0;
Errors errors = new Errors();
TypeDeclaration currentType = null;
bool generateAttributeUnderScore = false;
public StringBuilder SourceText {
get {
return sourceText;
}
}
#region ICSharpCode.SharpRefactory.Parser.IASTVisitor interface implementation
public override object Visit(INode node, object data)
{
errors.Error(-1, -1, String.Format("Visited INode (should NEVER HAPPEN)"));
Console.WriteLine("Visitor was: " + this.GetType());
Console.WriteLine("Node was : " + node.GetType());
return node.AcceptChildren(this, data);
}
public void AppendIndentation()
{
for (int i = 0; i < indentLevel; ++i) {
sourceText.Append("\t");
}
}
public void AppendNewLine()
{
sourceText.Append(newLineSep);
}
void DebugOutput(object o)
{
// Console.WriteLine(o.ToString());
}
public override object Visit(CompilationUnit compilationUnit, object data)
{
DebugOutput(compilationUnit);
new VBNetRefactory().Refactor(compilationUnit);
compilationUnit.AcceptChildren(this, data);
return null;
}
public override object Visit(NamespaceDeclaration namespaceDeclaration, object data)
{
DebugOutput(namespaceDeclaration);
AppendIndentation();
sourceText.Append("Namespace ");
sourceText.Append(namespaceDeclaration.NameSpace);
AppendNewLine();
++indentLevel;
namespaceDeclaration.AcceptChildren(this, data);
--indentLevel;
AppendIndentation();
sourceText.Append("End Namespace");
AppendNewLine();
return null;
}
public override object Visit(UsingDeclaration usingDeclaration, object data)
{
DebugOutput(usingDeclaration);
AppendIndentation();
sourceText.Append("Imports ");
sourceText.Append(usingDeclaration.Namespace);
AppendNewLine();
return null;
}
public override object Visit(UsingAliasDeclaration usingAliasDeclaration, object data)
{
DebugOutput(usingAliasDeclaration);
AppendIndentation();
sourceText.Append("Imports ");
sourceText.Append(usingAliasDeclaration.Alias);
sourceText.Append(" = ");
sourceText.Append(usingAliasDeclaration.Namespace);
AppendNewLine();
return null;
}
public override object Visit(AttributeSection attributeSection, object data)
{
DebugOutput(attributeSection);
AppendIndentation();
sourceText.Append("<");
if (attributeSection.AttributeTarget != null && attributeSection.AttributeTarget.Length > 0) {
sourceText.Append(attributeSection.AttributeTarget);
sourceText.Append(": ");
}
for (int j = 0; j < attributeSection.Attributes.Count; ++j) {
ICSharpCode.SharpRefactory.Parser.AST.Attribute attr = (ICSharpCode.SharpRefactory.Parser.AST.Attribute)attributeSection.Attributes[j];
sourceText.Append(attr.Name);
sourceText.Append("(");
for (int i = 0; i < attr.PositionalArguments.Count; ++i) {
Expression expr = (Expression)attr.PositionalArguments[i];
sourceText.Append(expr.AcceptVisitor(this, data).ToString());
if (i + 1 < attr.PositionalArguments.Count) {
sourceText.Append(", ");
}
}
for (int i = 0; i < attr.NamedArguments.Count; ++i) {
NamedArgument named = (NamedArgument)attr.NamedArguments[i];
sourceText.Append(named.Name);
sourceText.Append("=");
sourceText.Append(named.Expr.AcceptVisitor(this, data).ToString());
if (i + 1 < attr.NamedArguments.Count) {
sourceText.Append(", ");
}
}
sourceText.Append(")");
if (j + 1 < attributeSection.Attributes.Count) {
sourceText.Append(", ");
}
}
sourceText.Append("> ");
if (generateAttributeUnderScore) {
sourceText.Append("_");
}
AppendNewLine();
return null;
}
public override object Visit(TypeDeclaration typeDeclaration, object data)
{
DebugOutput(typeDeclaration);
AppendNewLine();
generateAttributeUnderScore = true;
AppendAttributes(typeDeclaration.Attributes);
string modifier = GetModifier(typeDeclaration.Modifier);
string type = String.Empty;
if ((typeDeclaration.Modifier & Modifier.Abstract) == Modifier.Abstract)
modifier = modifier.Replace("MustOverride", "MustInherit");
switch (typeDeclaration.Type) {
case Types.Class:
type = "Class ";
break;
case Types.Enum:
type = "Enum ";
break;
case Types.Interface:
type = "Interface ";
break;
case Types.Struct:
// this should be better in VBNetRefactory class because it is an AST transformation, but currently I'm too lazy
if (TypeHasOnlyStaticMembers(typeDeclaration)) {
goto case Types.Class;
}
type = "Structure ";
break;
}
AppendIndentation();
sourceText.Append(modifier);
sourceText.Append(type);
sourceText.Append(typeDeclaration.Name);
AppendNewLine();
if (typeDeclaration.BaseTypes != null) {
foreach (string baseType in typeDeclaration.BaseTypes) {
AppendIndentation();
bool baseTypeIsInterface = baseType.StartsWith("I") && (baseType.Length <= 1 || Char.IsUpper(baseType[1]));
if (!baseTypeIsInterface || typeDeclaration.Type == Types.Interface) {
sourceText.Append("Inherits ");
} else {
sourceText.Append("Implements ");
}
sourceText.Append(baseType);
AppendNewLine();
}
}
++indentLevel;
TypeDeclaration oldType = currentType;
currentType = typeDeclaration;
typeDeclaration.AcceptChildren(this, data);
currentType = oldType;
--indentLevel;
AppendIndentation();
sourceText.Append("End ");
sourceText.Append(type);
AppendNewLine();
generateAttributeUnderScore = false;
return null;
}
public override object Visit(DelegateDeclaration delegateDeclaration, object data)
{
DebugOutput(delegateDeclaration);
AppendNewLine();
AppendAttributes(delegateDeclaration.Attributes);
AppendIndentation();
sourceText.Append(GetModifier(delegateDeclaration.Modifier));
sourceText.Append("Delegate ");
bool isFunction = (delegateDeclaration.ReturnType.Type != "void");
if (isFunction) {
sourceText.Append("Function ");
} else {
sourceText.Append("Sub ");
}
sourceText.Append(delegateDeclaration.Name);
sourceText.Append("(");
AppendParameters(delegateDeclaration.Parameters);
sourceText.Append(")");
if (isFunction) {
sourceText.Append(" As ");
sourceText.Append(GetTypeString(delegateDeclaration.ReturnType));
}
AppendNewLine();
return null;
}
public override 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 override object Visit(FieldDeclaration fieldDeclaration, object data)
{
DebugOutput(fieldDeclaration);
foreach (VariableDeclaration field in fieldDeclaration.Fields) {
AppendAttributes(fieldDeclaration.Attributes);
AppendIndentation();
if (fieldDeclaration.Modifier == Modifier.None) {
sourceText.Append("Private ");
} else {
sourceText.Append(GetModifier(fieldDeclaration.Modifier));
}
sourceText.Append(field.Name);
// the type can be null (enum members)
if(fieldDeclaration.TypeReference != null) {
sourceText.Append(" As ");
sourceText.Append(GetTypeString(fieldDeclaration.TypeReference));
}
if (field.Initializer != null) {
sourceText.Append(" = ");
sourceText.Append(field.Initializer.AcceptVisitor(this, data).ToString());
}
AppendNewLine();
}
return null;
}
public override object Visit(MethodDeclaration methodDeclaration, object data)
{
DebugOutput(methodDeclaration);
AppendNewLine();
AppendAttributes(methodDeclaration.Attributes);
AppendIndentation();
sourceText.Append(GetModifier(methodDeclaration.Modifier));
bool isFunction = methodDeclaration.TypeReference.Type != "void";
string defStr = isFunction ? "Function" : "Sub";
sourceText.Append(defStr);
sourceText.Append(" ");
sourceText.Append(methodDeclaration.Name);
sourceText.Append("(");
AppendParameters(methodDeclaration.Parameters);
sourceText.Append(")");
if (isFunction) {
sourceText.Append(" As ");
sourceText.Append(GetTypeString(methodDeclaration.TypeReference));
}
AppendNewLine();
if (currentType.Type != Types.Interface) {
if (methodDeclaration.Body != null) {
++indentLevel;
methodDeclaration.Body.AcceptVisitor(this, data);
--indentLevel;
}
if ((methodDeclaration.Modifier & Modifier.Abstract) != Modifier.Abstract) {
AppendIndentation();
sourceText.Append("End ");
sourceText.Append(defStr);
AppendNewLine();
}
}
return null;
}
public override object Visit(PropertyDeclaration propertyDeclaration, object data)
{
DebugOutput(propertyDeclaration);
AppendNewLine();
AppendAttributes(propertyDeclaration.Attributes);
AppendIndentation();
sourceText.Append(GetModifier(propertyDeclaration.Modifier));
if (propertyDeclaration.IsReadOnly) {
sourceText.Append("ReadOnly ");
} else if (propertyDeclaration.IsWriteOnly) {
sourceText.Append("WriteOnly ");
}
sourceText.Append("Property ");
sourceText.Append(propertyDeclaration.Name);
sourceText.Append("() As ");
sourceText.Append(GetTypeString(propertyDeclaration.TypeReference));
AppendNewLine();
bool isAbstract = (propertyDeclaration.Modifier & Modifier.Abstract) == Modifier.Abstract;
if (currentType.Type != Types.Interface && !isAbstract) {
if (propertyDeclaration.GetRegion != null) {
++indentLevel;
propertyDeclaration.GetRegion.AcceptVisitor(this, data);
--indentLevel;
}
if (propertyDeclaration.SetRegion != null) {
++indentLevel;
propertyDeclaration.SetRegion.AcceptVisitor(this, data);
--indentLevel;
}
AppendIndentation();
sourceText.Append("End Property");
AppendNewLine();
}
return null;
}
public override object Visit(PropertyGetRegion propertyGetRegion, object data)
{
DebugOutput(propertyGetRegion);
AppendAttributes(propertyGetRegion.Attributes);
AppendIndentation();
sourceText.Append("Get");
AppendNewLine();
if (propertyGetRegion.Block != null) {
++indentLevel;
propertyGetRegion.Block.AcceptVisitor(this, data);
--indentLevel;
}
AppendIndentation();
sourceText.Append("End Get");
AppendNewLine();
return null;
}
public override object Visit(PropertySetRegion propertySetRegion, object data)
{
DebugOutput(propertySetRegion);
AppendAttributes(propertySetRegion.Attributes);
AppendIndentation();
sourceText.Append("Set");
AppendNewLine();
if (propertySetRegion.Block != null) {
++indentLevel;
propertySetRegion.Block.AcceptVisitor(this, data);
--indentLevel;
}
AppendIndentation();
sourceText.Append("End Set");
AppendNewLine();
return null;
}
public override object Visit(EventDeclaration eventDeclaration, object data)
{
DebugOutput(eventDeclaration);
AppendNewLine();
if (eventDeclaration.Name == null) {
foreach (VariableDeclaration field in eventDeclaration.VariableDeclarators) {
AppendAttributes(eventDeclaration.Attributes);
AppendIndentation();
sourceText.Append(GetModifier(eventDeclaration.Modifier));
sourceText.Append("Event ");
sourceText.Append(field.Name);
sourceText.Append(" As ");
sourceText.Append(GetTypeString(eventDeclaration.TypeReference));
}
} else {
AppendAttributes(eventDeclaration.Attributes);
AppendIndentation();
sourceText.Append(GetModifier(eventDeclaration.Modifier));
sourceText.Append("Event ");
sourceText.Append(eventDeclaration.Name);
sourceText.Append(" As ");
sourceText.Append(GetTypeString(eventDeclaration.TypeReference));
if (eventDeclaration.HasAddRegion) {
errors.Error(-1, -1, String.Format("Event add region can't be converted"));
}
if (eventDeclaration.HasRemoveRegion) {
errors.Error(-1, -1, String.Format("Event remove region can't be converted"));
}
}
AppendNewLine();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -