tovbnetconvertvisitor.cs
来自「SharpDevelop2.0.0 c#开发免费工具」· CS 代码 · 共 270 行
CS
270 行
// <file>
// <copyright see="prj:///doc/copyright.txt"/>
// <license see="prj:///doc/license.txt"/>
// <owner name="Daniel Grunwald" email="daniel@danielgrunwald.de"/>
// <version>$Revision: 1018 $</version>
// </file>
using System;
using System.Text;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using ICSharpCode.NRefactory.Parser;
using ICSharpCode.NRefactory.Parser.AST;
using Attribute = ICSharpCode.NRefactory.Parser.AST.Attribute;
namespace ICSharpCode.NRefactory.Parser
{
/// <summary>
/// Converts elements not supported by VB to their VB representation.
/// Not all elements are converted here, most simple elements (e.g. ConditionalExpression)
/// are converted in the output visitor.
/// </summary>
public class ToVBNetConvertVisitor : AbstractAstTransformer
{
// The following conversions are implemented:
// Conflicting field/property names -> m_field
// Anonymous methods are put into new methods
// Simple event handler creation is replaced with AddressOfExpression
TypeDeclaration currentType;
public override object Visit(TypeDeclaration td, object data)
{
TypeDeclaration outerType = currentType;
currentType = td;
// Conflicting field/property names -> m_field
List<string> properties = new List<string>();
foreach (object o in td.Children) {
PropertyDeclaration pd = o as PropertyDeclaration;
if (pd != null) {
properties.Add(pd.Name);
}
}
List<VariableDeclaration> conflicts = new List<VariableDeclaration>();
foreach (object o in td.Children) {
FieldDeclaration fd = o as FieldDeclaration;
if (fd != null) {
foreach (VariableDeclaration var in fd.Fields) {
string name = var.Name;
foreach (string propertyName in properties) {
if (name.Equals(propertyName, StringComparison.InvariantCultureIgnoreCase)) {
conflicts.Add(var);
}
}
}
}
}
new PrefixFieldsVisitor(conflicts, "m_").Run(td);
base.Visit(td, data);
currentType = outerType;
return null;
}
string GetAnonymousMethodName()
{
for (int i = 1;; i++) {
string name = "ConvertedAnonymousMethod" + i;
bool ok = true;
foreach (object c in currentType.Children) {
MethodDeclaration method = c as MethodDeclaration;
if (method != null && method.Name == name) {
ok = false;
break;
}
}
if (ok)
return name;
}
}
public override object Visit(StatementExpression statementExpression, object data)
{
base.Visit(statementExpression, data);
AssignmentExpression ass = statementExpression.Expression as AssignmentExpression;
if (ass != null && ass.Right is AddressOfExpression) {
if (ass.Op == AssignmentOperatorType.Add) {
ReplaceCurrentNode(new AddHandlerStatement(ass.Left, ass.Right));
} else if (ass.Op == AssignmentOperatorType.Subtract) {
ReplaceCurrentNode(new RemoveHandlerStatement(ass.Left, ass.Right));
}
}
return null;
}
string GetMemberNameOnThisReference(Expression expr)
{
IdentifierExpression ident = expr as IdentifierExpression;
if (ident != null)
return ident.Identifier;
FieldReferenceExpression fre = expr as FieldReferenceExpression;
if (fre != null && fre.TargetObject is ThisReferenceExpression)
return fre.FieldName;
return null;
}
string GetMethodNameOfDelegateCreation(Expression expr)
{
string name = GetMemberNameOnThisReference(expr);
if (name != null)
return name;
ObjectCreateExpression oce = expr as ObjectCreateExpression;
if (oce != null && oce.Parameters.Count == 1) {
return GetMemberNameOnThisReference(oce.Parameters[0]);
}
return null;
}
public override object Visit(AnonymousMethodExpression anonymousMethodExpression, object data)
{
MethodDeclaration method = new MethodDeclaration(GetAnonymousMethodName(), Modifier.Private, new TypeReference("System.Void"), anonymousMethodExpression.Parameters, null);
method.Body = anonymousMethodExpression.Body;
currentType.Children.Add(method);
ReplaceCurrentNode(new AddressOfExpression(new IdentifierExpression(method.Name)));
return null;
}
public override object Visit(AssignmentExpression assignmentExpression, object data)
{
if (assignmentExpression.Op == AssignmentOperatorType.Add
|| assignmentExpression.Op == AssignmentOperatorType.Subtract)
{
string methodName = GetMethodNameOfDelegateCreation(assignmentExpression.Right);
if (methodName != null) {
foreach (object c in currentType.Children) {
MethodDeclaration method = c as MethodDeclaration;
if (method != null && method.Name == methodName) {
// this statement is registering an event
assignmentExpression.Right = new AddressOfExpression(new IdentifierExpression(methodName));
break;
}
}
}
}
return base.Visit(assignmentExpression, data);
}
public override object Visit(MethodDeclaration methodDeclaration, object data)
{
if ((methodDeclaration.Modifier & Modifier.Visibility) == 0)
methodDeclaration.Modifier |= Modifier.Private;
base.Visit(methodDeclaration, data);
const Modifier externStatic = Modifier.Static | Modifier.Extern;
if ((methodDeclaration.Modifier & externStatic) == externStatic
&& methodDeclaration.Body.IsNull)
{
foreach (AttributeSection sec in methodDeclaration.Attributes) {
foreach (Attribute att in sec.Attributes) {
if ("DllImport".Equals(att.Name, StringComparison.InvariantCultureIgnoreCase)) {
if (ConvertPInvoke(methodDeclaration, att)) {
sec.Attributes.Remove(att);
break;
}
}
}
if (sec.Attributes.Count == 0) {
methodDeclaration.Attributes.Remove(sec);
break;
}
}
}
return null;
}
bool ConvertPInvoke(MethodDeclaration method, ICSharpCode.NRefactory.Parser.AST.Attribute att)
{
if (att.PositionalArguments.Count != 1)
return false;
PrimitiveExpression pe = att.PositionalArguments[0] as PrimitiveExpression;
if (pe == null || !(pe.Value is string))
return false;
string libraryName = (string)pe.Value;
string alias = null;
bool setLastError = false;
bool exactSpelling = false;
CharsetModifier charSet = CharsetModifier.Auto;
foreach (NamedArgumentExpression arg in att.NamedArguments) {
switch (arg.Name) {
case "SetLastError":
pe = arg.Expression as PrimitiveExpression;
if (pe != null && pe.Value is bool)
setLastError = (bool)pe.Value;
else
return false;
break;
case "ExactSpelling":
pe = arg.Expression as PrimitiveExpression;
if (pe != null && pe.Value is bool)
exactSpelling = (bool)pe.Value;
else
return false;
break;
case "CharSet":
{
FieldReferenceExpression fre = arg.Expression as FieldReferenceExpression;
if (fre == null || !(fre.TargetObject is IdentifierExpression))
return false;
if ((fre.TargetObject as IdentifierExpression).Identifier != "CharSet")
return false;
switch (fre.FieldName) {
case "Unicode":
charSet = CharsetModifier.Unicode;
break;
case "Auto":
charSet = CharsetModifier.Auto;
break;
case "Ansi":
charSet = CharsetModifier.ANSI;
break;
default:
return false;
}
}
break;
case "EntryPoint":
pe = arg.Expression as PrimitiveExpression;
if (pe != null)
alias = pe.Value as string;
break;
default:
return false;
}
}
if (setLastError && exactSpelling) {
// Only P/Invokes with SetLastError and ExactSpelling can be converted to a DeclareDeclaration
const Modifier removeModifiers = Modifier.Static | Modifier.Extern;
DeclareDeclaration decl = new DeclareDeclaration(method.Name, method.Modifier &~ removeModifiers,
method.TypeReference,
method.Parameters,
method.Attributes,
libraryName, alias, charSet);
ReplaceCurrentNode(decl);
base.Visit(decl, null);
return true;
} else {
return false;
}
}
public override object Visit(PropertyDeclaration propertyDeclaration, object data)
{
if ((propertyDeclaration.Modifier & Modifier.Visibility) == 0)
propertyDeclaration.Modifier |= Modifier.Private;
return base.Visit(propertyDeclaration, data);
}
public override object Visit(ConstructorDeclaration constructorDeclaration, object data)
{
if ((constructorDeclaration.Modifier & Modifier.Visibility) == 0)
constructorDeclaration.Modifier |= Modifier.Private;
return base.Visit(constructorDeclaration, data);
}
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?