Browse Source

add conversion of DllImports to ExternalMethodDeclarations

pull/254/head
Siegfried Pammer 14 years ago
parent
commit
6e7b1d27fb
  1. 12
      NRefactory/ICSharpCode.NRefactory.VB/Ast/Enums.cs
  2. 2
      NRefactory/ICSharpCode.NRefactory.VB/Ast/Expressions/PrimitiveExpression.cs
  3. 71
      NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeMembers/ExternalMethodDeclaration.cs
  4. 3
      NRefactory/ICSharpCode.NRefactory.VB/IAstVisitor.cs
  5. 1
      NRefactory/ICSharpCode.NRefactory.VB/ICSharpCode.NRefactory.VB.csproj
  6. 64
      NRefactory/ICSharpCode.NRefactory.VB/OutputVisitor/OutputVisitor.cs
  7. 123
      NRefactory/ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs

12
NRefactory/ICSharpCode.NRefactory.VB/Ast/Enums.cs

@ -115,18 +115,6 @@ namespace ICSharpCode.NRefactory.VB.Ast @@ -115,18 +115,6 @@ namespace ICSharpCode.NRefactory.VB.Ast
Explicit
}
///<summary>
/// Charset types, used in external methods
/// declarations (VB only).
///</summary>
public enum CharsetModifier
{
None,
Auto,
Unicode,
Ansi
}
/// <summary>
/// Specifies the ordering direction of a QueryExpressionOrdering node.
/// </summary>

2
NRefactory/ICSharpCode.NRefactory.VB/Ast/Expressions/PrimitiveExpression.cs

@ -32,7 +32,7 @@ namespace ICSharpCode.NRefactory.VB.Ast @@ -32,7 +32,7 @@ namespace ICSharpCode.NRefactory.VB.Ast
string stringValue;
public string StringValue {
get { return stringValue; } // TODO ?? VBNetOutputVisitor.ToVBNetString(this); }
get { return stringValue ?? OutputVisitor.ToVBNetString(this); }
}
public PrimitiveExpression(object value)

71
NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeMembers/ExternalMethodDeclaration.cs

@ -0,0 +1,71 @@ @@ -0,0 +1,71 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Runtime.InteropServices;
namespace ICSharpCode.NRefactory.VB.Ast
{
public class ExternalMethodDeclaration : MemberDeclaration
{
public ExternalMethodDeclaration()
{
}
public CharsetModifier CharsetModifier { get; set; }
public bool IsSub { get; set; }
public Identifier Name {
get { return GetChildByRole(Roles.Identifier); }
set { SetChildByRole(Roles.Identifier, value); }
}
public string Library { get; set; }
public string Alias { get; set; }
public AstNodeCollection<ParameterDeclaration> Parameters {
get { return GetChildrenByRole(Roles.Parameter); }
}
public AstNodeCollection<AttributeBlock> ReturnTypeAttributes {
get { return GetChildrenByRole(AttributeBlock.ReturnTypeAttributeBlockRole); }
}
public AstType ReturnType {
get { return GetChildByRole(Roles.Type); }
set { SetChildByRole(Roles.Type, value); }
}
protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match)
{
// TODO : finish
var method = other as ExternalMethodDeclaration;
return method != null &&
MatchAttributesAndModifiers(method, match) &&
IsSub == method.IsSub &&
Name.DoMatch(method.Name, match) &&
Parameters.DoMatch(method.Parameters, match) &&
ReturnTypeAttributes.DoMatch(method.ReturnTypeAttributes, match) &&
ReturnType.DoMatch(method.ReturnType, match);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitExternalMethodDeclaration(this, data);
}
}
///<summary>
/// Charset types, used in external methods
/// declarations (VB only).
///</summary>
public enum CharsetModifier
{
None,
Auto,
Unicode,
Ansi
}
}

3
NRefactory/ICSharpCode.NRefactory.VB/IAstVisitor.cs

@ -35,6 +35,7 @@ namespace ICSharpCode.NRefactory.VB { @@ -35,6 +35,7 @@ namespace ICSharpCode.NRefactory.VB {
// TypeMember scope
S VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration, T data);
S VisitMethodDeclaration(MethodDeclaration methodDeclaration, T data);
S VisitExternalMethodDeclaration(ExternalMethodDeclaration externalMethodDeclaration, T data);
S VisitFieldDeclaration(FieldDeclaration fieldDeclaration, T data);
S VisitVariableDeclaratorWithTypeAndInitializer(VariableDeclaratorWithTypeAndInitializer variableDeclaratorWithTypeAndInitializer, T data);
S VisitVariableDeclaratorWithObjectCreation(VariableDeclaratorWithObjectCreation variableDeclaratorWithObjectCreation, T data);
@ -110,5 +111,7 @@ namespace ICSharpCode.NRefactory.VB { @@ -110,5 +111,7 @@ namespace ICSharpCode.NRefactory.VB {
S VisitSingleLineFunctionLambdaExpression(SingleLineFunctionLambdaExpression singleLineFunctionLambdaExpression, T data);
S VisitQueryExpression(QueryExpression queryExpression, T data);
}
}

1
NRefactory/ICSharpCode.NRefactory.VB/ICSharpCode.NRefactory.VB.csproj

@ -118,6 +118,7 @@ @@ -118,6 +118,7 @@
<Compile Include="Ast\TypeMembers\Accessor.cs" />
<Compile Include="Ast\TypeMembers\ConstructorDeclaration.cs" />
<Compile Include="Ast\TypeMembers\EventDeclaration.cs" />
<Compile Include="Ast\TypeMembers\ExternalMethodDeclaration.cs" />
<Compile Include="Ast\TypeMembers\FieldDeclaration.cs" />
<Compile Include="Ast\TypeMembers\MethodDeclaration.cs" />
<Compile Include="Ast\TypeMembers\OperatorDeclaration.cs" />

64
NRefactory/ICSharpCode.NRefactory.VB/OutputVisitor/OutputVisitor.cs

@ -113,6 +113,7 @@ namespace ICSharpCode.NRefactory.VB @@ -113,6 +113,7 @@ namespace ICSharpCode.NRefactory.VB
public object VisitParameterDeclaration(ParameterDeclaration parameterDeclaration, object data)
{
StartNode(parameterDeclaration);
WriteAttributes(parameterDeclaration.Attributes);
WriteModifiers(parameterDeclaration.ModifierTokens);
WriteIdentifier(parameterDeclaration.Name.Name);
if (!parameterDeclaration.Type.IsNull) {
@ -164,7 +165,10 @@ namespace ICSharpCode.NRefactory.VB @@ -164,7 +165,10 @@ namespace ICSharpCode.NRefactory.VB
WriteToken("<", AttributeBlock.Roles.LChevron);
WriteCommaSeparatedList(attributeBlock.Attributes);
WriteToken(">", AttributeBlock.Roles.RChevron);
NewLine();
if (attributeBlock.Parent is ParameterDeclaration)
Space();
else
NewLine();
return EndNode(attributeBlock);
}
@ -1766,7 +1770,7 @@ namespace ICSharpCode.NRefactory.VB @@ -1766,7 +1770,7 @@ namespace ICSharpCode.NRefactory.VB
Space();
WriteKeyword("As");
eventDeclaration.ReturnType.AcceptVisitor(this, data);
}
}
WriteImplementsClause(eventDeclaration.ImplementsClause);
if (eventDeclaration.IsCustom) {
@ -2342,5 +2346,61 @@ namespace ICSharpCode.NRefactory.VB @@ -2342,5 +2346,61 @@ namespace ICSharpCode.NRefactory.VB
return EndNode(continueStatement);
}
public object VisitExternalMethodDeclaration(ExternalMethodDeclaration externalMethodDeclaration, object data)
{
StartNode(externalMethodDeclaration);
WriteAttributes(externalMethodDeclaration.Attributes);
WriteModifiers(externalMethodDeclaration.ModifierTokens);
WriteKeyword("Declare");
switch (externalMethodDeclaration.CharsetModifier) {
case CharsetModifier.None:
break;
case CharsetModifier.Auto:
WriteKeyword("Auto");
break;
case CharsetModifier.Unicode:
WriteKeyword("Unicode");
break;
case CharsetModifier.Ansi:
WriteKeyword("Ansi");
break;
default:
throw new Exception("Invalid value for CharsetModifier");
}
if (externalMethodDeclaration.IsSub)
WriteKeyword("Sub");
else
WriteKeyword("Function");
externalMethodDeclaration.Name.AcceptVisitor(this, data);
WriteKeyword("Lib");
Space();
WritePrimitiveValue(externalMethodDeclaration.Library);
Space();
if (externalMethodDeclaration.Alias != null) {
WriteKeyword("Alias");
Space();
WritePrimitiveValue(externalMethodDeclaration.Alias);
Space();
}
WriteCommaSeparatedListInParenthesis(externalMethodDeclaration.Parameters, false);
if (!externalMethodDeclaration.IsSub && !externalMethodDeclaration.ReturnType.IsNull) {
Space();
WriteKeyword("As");
WriteAttributes(externalMethodDeclaration.ReturnTypeAttributes);
externalMethodDeclaration.ReturnType.AcceptVisitor(this, data);
}
NewLine();
return EndNode(externalMethodDeclaration);
}
public static string ToVBNetString(PrimitiveExpression primitiveExpression)
{
var writer = new StringWriter();
new OutputVisitor(writer, new VBFormattingOptions()).WritePrimitiveValue(primitiveExpression.Value);
return writer.ToString();
}
}
}

123
NRefactory/ICSharpCode.NRefactory.VB/Visitors/CSharpToVBConverterVisitor.cs

@ -4,7 +4,7 @@ @@ -4,7 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using ICSharpCode.NRefactory.PatternMatching;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.VB.Ast;
@ -1302,30 +1302,113 @@ namespace ICSharpCode.NRefactory.VB.Visitors @@ -1302,30 +1302,113 @@ namespace ICSharpCode.NRefactory.VB.Visitors
public AstNode VisitMethodDeclaration(CSharp.MethodDeclaration methodDeclaration, object data)
{
var result = new MethodDeclaration();
CSharp.Attribute attr;
if ((methodDeclaration.Modifiers & CSharp.Modifiers.Extern) == CSharp.Modifiers.Extern && HasAttribute(methodDeclaration.Attributes, "System.Runtime.InteropServices.DllImportAttribute", out attr)) {
var result = new ExternalMethodDeclaration();
members.Push(new MemberInfo());
// remove AttributeSection if only one attribute is present
var attrSec = (CSharp.AttributeSection)attr.Parent;
if (attrSec.Attributes.Count == 1)
attrSec.Remove();
else
attr.Remove();
result.Library = (attr.Arguments.First().AcceptVisitor(this, data) as PrimitiveExpression).Value.ToString();
result.CharsetModifier = ConvertCharset(attr.Arguments);
result.Alias = ConvertAlias(attr.Arguments);
ConvertNodes(methodDeclaration.Attributes.Where(section => section.AttributeTarget != "return"), result.Attributes);
ConvertNodes(methodDeclaration.ModifierTokens, result.ModifierTokens);
result.Name = new Identifier(methodDeclaration.Name, AstLocation.Empty);
result.IsSub = IsSub(methodDeclaration.ReturnType);
ConvertNodes(methodDeclaration.Parameters, result.Parameters);
ConvertNodes(methodDeclaration.Attributes.Where(section => section.AttributeTarget == "return"), result.ReturnTypeAttributes);
if (!result.IsSub)
result.ReturnType = (AstType)methodDeclaration.ReturnType.AcceptVisitor(this, data);
if (members.Pop().inIterator) {
result.Modifiers |= Modifiers.Iterator;
}
return EndNode(methodDeclaration, result);
} else {
var result = new MethodDeclaration();
members.Push(new MemberInfo());
ConvertNodes(methodDeclaration.Attributes.Where(section => section.AttributeTarget != "return"), result.Attributes);
ConvertNodes(methodDeclaration.ModifierTokens, result.ModifierTokens);
result.Name = new Identifier(methodDeclaration.Name, AstLocation.Empty);
result.IsSub = IsSub(methodDeclaration.ReturnType);
ConvertNodes(methodDeclaration.Parameters, result.Parameters);
ConvertNodes(methodDeclaration.TypeParameters, result.TypeParameters);
ConvertNodes(methodDeclaration.Attributes.Where(section => section.AttributeTarget == "return"), result.ReturnTypeAttributes);
if (!methodDeclaration.PrivateImplementationType.IsNull)
result.ImplementsClause.Add(
new InterfaceMemberSpecifier((AstType)methodDeclaration.PrivateImplementationType.AcceptVisitor(this, data),
methodDeclaration.Name));
if (!result.IsSub)
result.ReturnType = (AstType)methodDeclaration.ReturnType.AcceptVisitor(this, data);
result.Body = (BlockStatement)methodDeclaration.Body.AcceptVisitor(this, data);
if (members.Pop().inIterator) {
result.Modifiers |= Modifiers.Iterator;
}
return EndNode(methodDeclaration, result);
}
}
string ConvertAlias(CSharp.AstNodeCollection<CSharp.Expression> arguments)
{
var pattern = new CSharp.AssignmentExpression() {
Left = new CSharp.IdentifierExpression("EntryPoint"),
Operator = CSharp.AssignmentOperatorType.Assign,
Right = new AnyNode("alias")
};
members.Push(new MemberInfo());
var result = arguments
.Select(expr => pattern.Match(expr))
.FirstOrDefault(r => r.Success);
ConvertNodes(methodDeclaration.Attributes.Where(section => section.AttributeTarget != "return"), result.Attributes);
ConvertNodes(methodDeclaration.ModifierTokens, result.ModifierTokens);
result.Name = new Identifier(methodDeclaration.Name, AstLocation.Empty);
result.IsSub = IsSub(methodDeclaration.ReturnType);
ConvertNodes(methodDeclaration.Parameters, result.Parameters);
ConvertNodes(methodDeclaration.TypeParameters, result.TypeParameters);
ConvertNodes(methodDeclaration.Attributes.Where(section => section.AttributeTarget == "return"), result.ReturnTypeAttributes);
if (!methodDeclaration.PrivateImplementationType.IsNull)
result.ImplementsClause.Add(
new InterfaceMemberSpecifier((AstType)methodDeclaration.PrivateImplementationType.AcceptVisitor(this, data),
methodDeclaration.Name));
if (!result.IsSub)
result.ReturnType = (AstType)methodDeclaration.ReturnType.AcceptVisitor(this, data);
result.Body = (BlockStatement)methodDeclaration.Body.AcceptVisitor(this, data);
if (result.Success && result.Has("alias")) {
return result.Get<CSharp.PrimitiveExpression>("alias")
.First().Value.ToString();
}
if (members.Pop().inIterator) {
result.Modifiers |= Modifiers.Iterator;
return null;
}
CharsetModifier ConvertCharset(CSharp.AstNodeCollection<CSharp.Expression> arguments)
{
var pattern = new CSharp.AssignmentExpression() {
Left = new CSharp.IdentifierExpression("CharSet"),
Operator = CSharp.AssignmentOperatorType.Assign,
Right = new NamedNode(
"modifier",
new CSharp.MemberReferenceExpression() {
Target = new CSharp.IdentifierExpression("CharSet")
})
};
var result = arguments
.Select(expr => pattern.Match(expr))
.FirstOrDefault(r => r.Success);
if (result.Success && result.Has("modifier")) {
switch (result.Get<CSharp.MemberReferenceExpression>("modifier").First().MemberName) {
case "Auto":
return CharsetModifier.Auto;
case "Ansi":
return CharsetModifier.Ansi;
case "Unicode":
return CharsetModifier.Unicode;
}
}
return EndNode(methodDeclaration, result);
return CharsetModifier.None;
}
bool IsSub(CSharp.AstType returnType)

Loading…
Cancel
Save