📄 vbnetoutputvisitor.cs
字号:
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision: 2200 $</version>
// </file>
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Text;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.Parser;
using ICSharpCode.NRefactory.Parser.VB;
namespace ICSharpCode.NRefactory.PrettyPrinter
{
public class VBNetOutputVisitor : IOutputAstVisitor
{
Errors errors = new Errors();
VBNetOutputFormatter outputFormatter;
VBNetPrettyPrintOptions prettyPrintOptions = new VBNetPrettyPrintOptions();
NodeTracker nodeTracker;
TypeDeclaration currentType;
bool printFullSystemType;
Stack<int> exitTokenStack = new Stack<int>();
public string Text {
get {
return outputFormatter.Text;
}
}
public Errors Errors {
get {
return errors;
}
}
AbstractPrettyPrintOptions IOutputAstVisitor.Options {
get { return prettyPrintOptions; }
}
public VBNetPrettyPrintOptions Options {
get { return prettyPrintOptions; }
}
public NodeTracker NodeTracker {
get {
return nodeTracker;
}
}
public IOutputFormatter OutputFormatter {
get {
return outputFormatter;
}
}
public VBNetOutputVisitor()
{
outputFormatter = new VBNetOutputFormatter(prettyPrintOptions);
nodeTracker = new NodeTracker(this);
}
void Error(string text, Location position)
{
errors.Error(position.Y, position.X, text);
}
void UnsupportedNode(INode node)
{
Error(node.GetType().Name + " is unsupported", node.StartLocation);
}
#region ICSharpCode.NRefactory.Parser.IASTVisitor interface implementation
public object VisitCompilationUnit(CompilationUnit compilationUnit, object data)
{
nodeTracker.TrackedVisitChildren(compilationUnit, data);
outputFormatter.EndFile();
return null;
}
/// <summary>
/// Converts type name to primitive type name. Returns null if typeString is not
/// a primitive type.
/// </summary>
static string ConvertTypeString(string typeString)
{
string primitiveType;
TypeReference.PrimitiveTypesVBReverse.TryGetValue(typeString, out primitiveType);
return primitiveType;
}
public object VisitTypeReference(TypeReference typeReference, object data)
{
if (typeReference == TypeReference.ClassConstraint) {
outputFormatter.PrintToken(Tokens.Class);
} else if (typeReference == TypeReference.StructConstraint) {
outputFormatter.PrintToken(Tokens.Structure);
} else if (typeReference == TypeReference.NewConstraint) {
outputFormatter.PrintToken(Tokens.New);
} else {
PrintTypeReferenceWithoutArray(typeReference);
if (typeReference.IsArrayType) {
PrintArrayRank(typeReference.RankSpecifier, 0);
}
}
return null;
}
void PrintTypeReferenceWithoutArray(TypeReference typeReference)
{
if (typeReference.IsGlobal) {
outputFormatter.PrintToken(Tokens.Global);
outputFormatter.PrintToken(Tokens.Dot);
}
if (typeReference.Type == null || typeReference.Type.Length ==0) {
outputFormatter.PrintText("Void");
} else if (printFullSystemType || typeReference.IsGlobal) {
outputFormatter.PrintIdentifier(typeReference.SystemType);
} else {
string shortTypeName = ConvertTypeString(typeReference.SystemType);
if (shortTypeName != null) {
outputFormatter.PrintText(shortTypeName);
} else {
outputFormatter.PrintIdentifier(typeReference.Type);
}
}
if (typeReference.GenericTypes != null && typeReference.GenericTypes.Count > 0) {
outputFormatter.PrintToken(Tokens.OpenParenthesis);
outputFormatter.PrintToken(Tokens.Of);
outputFormatter.Space();
AppendCommaSeparatedList(typeReference.GenericTypes);
outputFormatter.PrintToken(Tokens.CloseParenthesis);
}
for (int i = 0; i < typeReference.PointerNestingLevel; ++i) {
outputFormatter.PrintToken(Tokens.Times);
}
}
void PrintArrayRank(int[] rankSpecifier, int startRank)
{
for (int i = startRank; i < rankSpecifier.Length; ++i) {
outputFormatter.PrintToken(Tokens.OpenParenthesis);
for (int j = 0; j < rankSpecifier[i]; ++j) {
outputFormatter.PrintToken(Tokens.Comma);
}
outputFormatter.PrintToken(Tokens.CloseParenthesis);
}
}
public object VisitInnerClassTypeReference(InnerClassTypeReference innerClassTypeReference, object data)
{
nodeTracker.TrackedVisit(innerClassTypeReference.BaseType, data);
outputFormatter.PrintToken(Tokens.Dot);
return VisitTypeReference((TypeReference)innerClassTypeReference, data);
}
#region Global scope
public object VisitAttributeSection(AttributeSection attributeSection, object data)
{
outputFormatter.Indent();
outputFormatter.PrintText("<");
if (attributeSection.AttributeTarget != null && attributeSection.AttributeTarget.Length > 0) {
outputFormatter.PrintIdentifier(attributeSection.AttributeTarget);
outputFormatter.PrintToken(Tokens.Colon);
outputFormatter.Space();
}
Debug.Assert(attributeSection.Attributes != null);
AppendCommaSeparatedList(attributeSection.Attributes);
outputFormatter.PrintText(">");
if ("assembly".Equals(attributeSection.AttributeTarget, StringComparison.InvariantCultureIgnoreCase)
|| "module".Equals(attributeSection.AttributeTarget, StringComparison.InvariantCultureIgnoreCase)) {
outputFormatter.NewLine();
} else {
outputFormatter.PrintLineContinuation();
}
return null;
}
public object VisitAttribute(ICSharpCode.NRefactory.Ast.Attribute attribute, object data)
{
outputFormatter.PrintIdentifier(attribute.Name);
outputFormatter.PrintToken(Tokens.OpenParenthesis);
AppendCommaSeparatedList(attribute.PositionalArguments);
if (attribute.NamedArguments != null && attribute.NamedArguments.Count > 0) {
if (attribute.PositionalArguments.Count > 0) {
outputFormatter.PrintToken(Tokens.Comma);
outputFormatter.Space();
}
AppendCommaSeparatedList(attribute.NamedArguments);
}
outputFormatter.PrintToken(Tokens.CloseParenthesis);
return null;
}
public object VisitNamedArgumentExpression(NamedArgumentExpression namedArgumentExpression, object data)
{
outputFormatter.PrintIdentifier(namedArgumentExpression.Name);
outputFormatter.Space();
outputFormatter.PrintToken(Tokens.Colon);
outputFormatter.PrintToken(Tokens.Assign);
outputFormatter.Space();
nodeTracker.TrackedVisit(namedArgumentExpression.Expression, data);
return null;
}
public object VisitUsing(Using @using, object data)
{
Debug.Fail("Should never be called. The usings should be handled in Visit(UsingDeclaration)");
return null;
}
public object VisitUsingDeclaration(UsingDeclaration usingDeclaration, object data)
{
outputFormatter.Indent();
outputFormatter.PrintToken(Tokens.Imports);
outputFormatter.Space();
for (int i = 0; i < usingDeclaration.Usings.Count; ++i) {
outputFormatter.PrintIdentifier(((Using)usingDeclaration.Usings[i]).Name);
if (((Using)usingDeclaration.Usings[i]).IsAlias) {
outputFormatter.Space();
outputFormatter.PrintToken(Tokens.Assign);
outputFormatter.Space();
printFullSystemType = true;
nodeTracker.TrackedVisit(((Using)usingDeclaration.Usings[i]).Alias, data);
printFullSystemType = false;
}
if (i + 1 < usingDeclaration.Usings.Count) {
outputFormatter.PrintToken(Tokens.Comma);
outputFormatter.Space();
}
}
outputFormatter.NewLine();
return null;
}
public object VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration, object data)
{
outputFormatter.Indent();
outputFormatter.PrintToken(Tokens.Namespace);
outputFormatter.Space();
outputFormatter.PrintIdentifier(namespaceDeclaration.Name);
outputFormatter.NewLine();
++outputFormatter.IndentationLevel;
nodeTracker.TrackedVisitChildren(namespaceDeclaration, data);
--outputFormatter.IndentationLevel;
outputFormatter.Indent();
outputFormatter.PrintToken(Tokens.End);
outputFormatter.Space();
outputFormatter.PrintToken(Tokens.Namespace);
outputFormatter.NewLine();
return null;
}
static int GetTypeToken(TypeDeclaration typeDeclaration)
{
switch (typeDeclaration.Type) {
case ClassType.Class:
return Tokens.Class;
case ClassType.Enum:
return Tokens.Enum;
case ClassType.Interface:
return Tokens.Interface;
case ClassType.Struct:
return Tokens.Structure;
default:
return Tokens.Class;
}
}
void PrintTemplates(List<TemplateDefinition> templates)
{
if (templates != null && templates.Count > 0) {
outputFormatter.PrintToken(Tokens.OpenParenthesis);
outputFormatter.PrintToken(Tokens.Of);
outputFormatter.Space();
AppendCommaSeparatedList(templates);
outputFormatter.PrintToken(Tokens.CloseParenthesis);
}
}
public object VisitTypeDeclaration(TypeDeclaration typeDeclaration, object data)
{
VisitAttributes(typeDeclaration.Attributes, data);
outputFormatter.Indent();
OutputModifier(typeDeclaration.Modifier, true);
int typeToken = GetTypeToken(typeDeclaration);
outputFormatter.PrintToken(typeToken);
outputFormatter.Space();
outputFormatter.PrintIdentifier(typeDeclaration.Name);
PrintTemplates(typeDeclaration.Templates);
if (typeDeclaration.Type == ClassType.Enum
&& typeDeclaration.BaseTypes != null && typeDeclaration.BaseTypes.Count > 0)
{
outputFormatter.Space();
outputFormatter.PrintToken(Tokens.As);
outputFormatter.Space();
foreach (TypeReference baseTypeRef in typeDeclaration.BaseTypes) {
nodeTracker.TrackedVisit(baseTypeRef, data);
}
}
outputFormatter.NewLine();
++outputFormatter.IndentationLevel;
if (typeDeclaration.BaseTypes != null && typeDeclaration.Type != ClassType.Enum) {
foreach (TypeReference baseTypeRef in typeDeclaration.BaseTypes) {
outputFormatter.Indent();
string baseType = baseTypeRef.Type;
if (baseType.IndexOf('.') >= 0) {
baseType = baseType.Substring(baseType.LastIndexOf('.') + 1);
}
bool baseTypeIsInterface = baseType.Length >= 2 && baseType[0] == 'I' && Char.IsUpper(baseType[1]);
if (!baseTypeIsInterface || typeDeclaration.Type == ClassType.Interface) {
outputFormatter.PrintToken(Tokens.Inherits);
} else {
outputFormatter.PrintToken(Tokens.Implements);
}
outputFormatter.Space();
nodeTracker.TrackedVisit(baseTypeRef, data);
outputFormatter.NewLine();
}
}
TypeDeclaration oldType = currentType;
currentType = typeDeclaration;
if (typeDeclaration.Type == ClassType.Enum) {
OutputEnumMembers(typeDeclaration, data);
} else {
nodeTracker.TrackedVisitChildren(typeDeclaration, data);
}
currentType = oldType;
--outputFormatter.IndentationLevel;
outputFormatter.Indent();
outputFormatter.PrintToken(Tokens.End);
outputFormatter.Space();
outputFormatter.PrintToken(typeToken);
outputFormatter.NewLine();
return null;
}
void OutputEnumMembers(TypeDeclaration typeDeclaration, object data)
{
foreach (FieldDeclaration fieldDeclaration in typeDeclaration.Children) {
nodeTracker.BeginNode(fieldDeclaration);
VariableDeclaration f = (VariableDeclaration)fieldDeclaration.Fields[0];
VisitAttributes(fieldDeclaration.Attributes, data);
outputFormatter.Indent();
outputFormatter.PrintIdentifier(f.Name);
if (f.Initializer != null && !f.Initializer.IsNull) {
outputFormatter.Space();
outputFormatter.PrintToken(Tokens.Assign);
outputFormatter.Space();
nodeTracker.TrackedVisit(f.Initializer, data);
}
outputFormatter.NewLine();
nodeTracker.EndNode(fieldDeclaration);
}
}
public object VisitTemplateDefinition(TemplateDefinition templateDefinition, object data)
{
outputFormatter.PrintIdentifier(templateDefinition.Name);
if (templateDefinition.Bases.Count > 0) {
outputFormatter.PrintText(" As ");
if (templateDefinition.Bases.Count == 1) {
nodeTracker.TrackedVisit(templateDefinition.Bases[0], data);
} else {
outputFormatter.PrintToken(Tokens.OpenCurlyBrace);
AppendCommaSeparatedList(templateDefinition.Bases);
outputFormatter.PrintToken(Tokens.CloseCurlyBrace);
}
}
return null;
}
public object VisitDelegateDeclaration(DelegateDeclaration delegateDeclaration, object data)
{
VisitAttributes(delegateDeclaration.Attributes, data);
outputFormatter.Indent();
OutputModifier(delegateDeclaration.Modifier, true);
outputFormatter.PrintToken(Tokens.Delegate);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -