Browse Source

Fixed SD2-596: C# to VB conversion should use CType instead of DirectCast for casts to primitives

git-svn-id: svn://svn.sharpdevelop.net/sharpdevelop/trunk@2035 1ccf3a8d-04fe-1044-b7c0-cef0b8235c61
shortcuts
Daniel Grunwald 19 years ago
parent
commit
47ae6603d0
  1. 110
      src/Libraries/NRefactory/Project/Src/Ast/TypeReference.cs
  2. 46
      src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs
  3. 45
      src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputVisitor.cs
  4. 19
      src/Libraries/NRefactory/Project/Src/Visitors/CSharpConstructsVisitor.cs
  5. 6
      src/Libraries/NRefactory/Test/Output/VBNet/CSharpToVBConverterTest.cs
  6. 10
      src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/ProjectNode.cs
  7. 52
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CSharp/CSharpAmbience.cs
  8. 9
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs
  9. 42
      src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/VBNet/VBNetAmbience.cs

110
src/Libraries/NRefactory/Project/Src/Ast/TypeReference.cs

@ -26,8 +26,11 @@ namespace ICSharpCode.NRefactory.Ast
List<TypeReference> genericTypes = new List<TypeReference>(); List<TypeReference> genericTypes = new List<TypeReference>();
bool isGlobal; bool isGlobal;
#region Static primitive type list
static Dictionary<string, string> types = new Dictionary<string, string>(); static Dictionary<string, string> types = new Dictionary<string, string>();
static Dictionary<string, string> vbtypes = new Dictionary<string, string>(); static Dictionary<string, string> vbtypes = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase);
static Dictionary<string, string> typesReverse = new Dictionary<string, string>();
static Dictionary<string, string> vbtypesReverse = new Dictionary<string, string>();
static TypeReference() static TypeReference()
{ {
@ -50,33 +53,74 @@ namespace ICSharpCode.NRefactory.Ast
types.Add("void", "System.Void"); types.Add("void", "System.Void");
// VB.NET types // VB.NET types
vbtypes.Add("boolean", "System.Boolean"); vbtypes.Add("Boolean", "System.Boolean");
vbtypes.Add("byte", "System.Byte"); vbtypes.Add("Byte", "System.Byte");
vbtypes.Add("sbyte", "System.SByte"); vbtypes.Add("SByte", "System.SByte");
vbtypes.Add("date", "System.DateTime"); vbtypes.Add("Date", "System.DateTime");
vbtypes.Add("char", "System.Char"); vbtypes.Add("Char", "System.Char");
vbtypes.Add("decimal", "System.Decimal"); vbtypes.Add("Decimal", "System.Decimal");
vbtypes.Add("double", "System.Double"); vbtypes.Add("Double", "System.Double");
vbtypes.Add("single", "System.Single"); vbtypes.Add("Single", "System.Single");
vbtypes.Add("integer", "System.Int32"); vbtypes.Add("Integer", "System.Int32");
vbtypes.Add("long", "System.Int64"); vbtypes.Add("Long", "System.Int64");
vbtypes.Add("uinteger","System.UInt32"); vbtypes.Add("UInteger","System.UInt32");
vbtypes.Add("ulong", "System.UInt64"); vbtypes.Add("ULong", "System.UInt64");
vbtypes.Add("object", "System.Object"); vbtypes.Add("Object", "System.Object");
vbtypes.Add("short", "System.Int16"); vbtypes.Add("Short", "System.Int16");
vbtypes.Add("ushort", "System.UInt16"); vbtypes.Add("UShort", "System.UInt16");
vbtypes.Add("string", "System.String"); vbtypes.Add("String", "System.String");
}
foreach (KeyValuePair<string, string> pair in types) {
public static IEnumerable<KeyValuePair<string, string>> GetPrimitiveTypesCSharp() typesReverse.Add(pair.Value, pair.Key);
{ }
return types; foreach (KeyValuePair<string, string> pair in vbtypes) {
vbtypesReverse.Add(pair.Value, pair.Key);
}
}
/// <summary>
/// Gets a shortname=>full name dictionary of C# types.
/// </summary>
public static IDictionary<string, string> PrimitiveTypesCSharp {
get { return types; }
}
/// <summary>
/// Gets a shortname=>full name dictionary of VB types.
/// </summary>
public static IDictionary<string, string> PrimitiveTypesVB {
get { return vbtypes; }
}
/// <summary>
/// Gets a full name=>shortname dictionary of C# types.
/// </summary>
public static IDictionary<string, string> PrimitiveTypesCSharpReverse {
get { return typesReverse; }
}
/// <summary>
/// Gets a full name=>shortname dictionary of VB types.
/// </summary>
public static IDictionary<string, string> PrimitiveTypesVBReverse {
get { return vbtypesReverse; }
} }
public static IEnumerable<KeyValuePair<string, string>> GetPrimitiveTypesVB()
static string GetSystemType(string type)
{ {
return vbtypes; if (types == null) return type;
string systemType;
if (types.TryGetValue(type, out systemType)) {
return systemType;
}
if (vbtypes.TryGetValue(type, out systemType)) {
return systemType;
}
return type;
} }
#endregion
object ICloneable.Clone() object ICloneable.Clone()
{ {
@ -213,20 +257,6 @@ namespace ICSharpCode.NRefactory.Ast
} }
} }
static string GetSystemType(string type)
{
if (types == null) return type;
if (types.ContainsKey(type)) {
return types[type];
}
string lowerType = type.ToLower(CultureInfo.InvariantCulture);
if (vbtypes.ContainsKey(lowerType)) {
return vbtypes[lowerType];
}
return type;
}
public TypeReference(string type) public TypeReference(string type)
{ {
this.Type = type; this.Type = type;
@ -323,7 +353,7 @@ namespace ICSharpCode.NRefactory.Ast
return true; return true;
} }
} }
public class NullTypeReference : TypeReference public class NullTypeReference : TypeReference
{ {
static NullTypeReference nullTypeReference = new NullTypeReference(); static NullTypeReference nullTypeReference = new NullTypeReference();
@ -347,7 +377,7 @@ namespace ICSharpCode.NRefactory.Ast
return String.Format("[NullTypeReference]"); return String.Format("[NullTypeReference]");
} }
} }
/// <summary> /// <summary>
/// We need this special type reference for cases like /// We need this special type reference for cases like
/// OuterClass(Of T1).InnerClass(Of T2) (in expression or type context) /// OuterClass(Of T1).InnerClass(Of T2) (in expression or type context)

46
src/Libraries/NRefactory/Project/Src/PrettyPrinter/CSharp/CSharpOutputVisitor.cs

@ -85,47 +85,19 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
return null; 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) static string ConvertTypeString(string typeString)
{ {
switch (typeString) { string primitiveType;
case "System.Boolean": if (TypeReference.PrimitiveTypesCSharpReverse.TryGetValue(typeString, out primitiveType))
return "bool"; return primitiveType;
case "System.String": else
return "string"; return typeString;
case "System.Char":
return "char";
case "System.Double":
return "double";
case "System.Single":
return "float";
case "System.Decimal":
return "decimal";
case "System.Int64":
return "long";
case "System.Int32":
return "int";
case "System.Int16":
return "short";
case "System.Byte":
return "byte";
case "System.Void":
return "void";
case "System.Object":
return "object";
case "System.UInt64":
return "ulong";
case "System.UInt32":
return "uint";
case "System.UInt16":
return "ushort";
case "System.SByte":
return "sbyte";
}
return typeString;
} }
void PrintTemplates(List<TemplateDefinition> templates) void PrintTemplates(List<TemplateDefinition> templates)
{ {
if (templates.Count == 0) return; if (templates.Count == 0) return;

45
src/Libraries/NRefactory/Project/Src/PrettyPrinter/VBNet/VBNetOutputVisitor.cs

@ -86,46 +86,15 @@ namespace ICSharpCode.NRefactory.PrettyPrinter
return null; 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) static string ConvertTypeString(string typeString)
{ {
switch (typeString) { string primitiveType;
case "System.Boolean": TypeReference.PrimitiveTypesVBReverse.TryGetValue(typeString, out primitiveType);
return "Boolean"; return primitiveType;
case "System.String":
return "String";
case "System.Char":
return "Char";
case "System.Double":
return "Double";
case "System.Single":
return "Single";
case "System.Decimal":
return "Decimal";
case "System.DateTime":
return "Date";
case "System.Int64":
return "Long";
case "System.Int32":
return "Integer";
case "System.Int16":
return "Short";
case "System.Byte":
return "Byte";
case "System.Void":
return "Void";
case "System.Object":
return "Object";
case "System.UInt64":
return "ULong";
case "System.UInt32":
return "UInteger";
case "System.UInt16":
return "UShort";
case "System.SByte":
return "SByte";
}
return null;
} }
public object VisitTypeReference(TypeReference typeReference, object data) public object VisitTypeReference(TypeReference typeReference, object data)

19
src/Libraries/NRefactory/Project/Src/Visitors/CSharpConstructsVisitor.cs

@ -21,9 +21,8 @@ namespace ICSharpCode.NRefactory.Visitors
// i++ / ++i as statement: convert to i += 1 // i++ / ++i as statement: convert to i += 1
// i-- / --i as statement: convert to i -= 1 // i-- / --i as statement: convert to i -= 1
// ForStatement -> ForNextStatement when for-loop is simple // ForStatement -> ForNextStatement when for-loop is simple
// The following conversions should be implemented in the future:
// if (Event != null) Event(this, bla); -> RaiseEvent Event(this, bla) // if (Event != null) Event(this, bla); -> RaiseEvent Event(this, bla)
// Casts to value types are marked as conversions
public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data) public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data)
{ {
@ -201,5 +200,21 @@ namespace ICSharpCode.NRefactory.Visitors
(step == 1) ? null : new PrimitiveExpression(step, step.ToString(System.Globalization.NumberFormatInfo.InvariantInfo)), (step == 1) ? null : new PrimitiveExpression(step, step.ToString(System.Globalization.NumberFormatInfo.InvariantInfo)),
forStatement.EmbeddedStatement, null)); forStatement.EmbeddedStatement, null));
} }
public override object VisitCastExpression(CastExpression castExpression, object data)
{
if (castExpression.CastType == CastType.Cast) {
// Casts to value types are marked as conversions
// currently only supporting primitive types...
string type;
if (TypeReference.PrimitiveTypesCSharpReverse.TryGetValue(castExpression.CastTo.SystemType, out type)) {
if (type != "object" && type != "string") {
// type is value type
castExpression.CastType = CastType.Conversion;
}
}
}
return base.VisitCastExpression(castExpression, data);
}
} }
} }

6
src/Libraries/NRefactory/Test/Output/VBNet/CSharpToVBConverterTest.cs

@ -441,5 +441,11 @@ End Class
{ {
TestStatement("((IDisposable)o).Dispose();", "DirectCast(o, IDisposable).Dispose()"); TestStatement("((IDisposable)o).Dispose();", "DirectCast(o, IDisposable).Dispose()");
} }
[Test]
public void PrimitiveCast()
{
TestStatement("a = (int)number;", "a = CInt(number)");
}
} }
} }

10
src/Main/Base/Project/Src/Gui/Pads/ProjectBrowser/TreeNodes/ProjectNode.cs

@ -66,14 +66,18 @@ namespace ICSharpCode.SharpDevelop.Project
} }
Tag = project; Tag = project;
project.ParentSolution.Preferences.StartupProjectChanged += OnStartupProjectChanged; if (project.ParentSolution != null) {
OnStartupProjectChanged(null, null); project.ParentSolution.Preferences.StartupProjectChanged += OnStartupProjectChanged;
OnStartupProjectChanged(null, null);
}
} }
public override void Dispose() public override void Dispose()
{ {
base.Dispose(); base.Dispose();
project.ParentSolution.Preferences.StartupProjectChanged -= OnStartupProjectChanged; if (project.ParentSolution != null) {
project.ParentSolution.Preferences.StartupProjectChanged -= OnStartupProjectChanged;
}
} }
bool isStartupProject; bool isStartupProject;

52
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/CSharp/CSharpAmbience.cs

@ -14,48 +14,14 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp
{ {
public class CSharpAmbience : AbstractAmbience public class CSharpAmbience : AbstractAmbience
{ {
static string[,] typeConversionList = new string[,] { public static IDictionary<string, string> TypeConversionTable {
{"System.Void", "void"}, get { return ICSharpCode.NRefactory.Ast.TypeReference.PrimitiveTypesCSharpReverse; }
{"System.Object", "object"},
{"System.Boolean", "bool"},
{"System.Byte", "byte"},
{"System.SByte", "sbyte"},
{"System.Char", "char"},
{"System.Enum", "enum"},
{"System.Int16", "short"},
{"System.Int32", "int"},
{"System.Int64", "long"},
{"System.UInt16", "ushort"},
{"System.UInt32", "uint"},
{"System.UInt64", "ulong"},
{"System.Single", "float"},
{"System.Double", "double"},
{"System.Decimal", "decimal"},
{"System.String", "string"}
};
static Hashtable typeConversionTable = new Hashtable();
public static Hashtable TypeConversionTable {
get {
return typeConversionTable;
}
} }
static CSharpAmbience instance; static CSharpAmbience instance = new CSharpAmbience();
public static CSharpAmbience Instance { public static CSharpAmbience Instance {
get { get { return instance; }
if (instance == null) instance = new CSharpAmbience();
return instance;
}
}
static CSharpAmbience()
{
for (int i = 0; i < typeConversionList.GetLength(0); ++i) {
typeConversionTable[typeConversionList[i, 0]] = typeConversionList[i, 1];
}
} }
bool ModifierIsSet(ModifierEnum modifier, ModifierEnum query) bool ModifierIsSet(ModifierEnum modifier, ModifierEnum query)
@ -478,8 +444,9 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
string fullName = returnType.FullyQualifiedName; string fullName = returnType.FullyQualifiedName;
if (fullName != null && typeConversionTable[fullName] != null) { string shortName;
builder.Append(typeConversionTable[fullName].ToString()); if (fullName != null && TypeConversionTable.TryGetValue(fullName, out shortName)) {
builder.Append(shortName);
} else { } else {
if (UseFullyQualifiedNames) { if (UseFullyQualifiedNames) {
builder.Append(fullName); builder.Append(fullName);
@ -556,8 +523,9 @@ namespace ICSharpCode.SharpDevelop.Dom.CSharp
public override string GetIntrinsicTypeName(string dotNetTypeName) public override string GetIntrinsicTypeName(string dotNetTypeName)
{ {
if (typeConversionTable[dotNetTypeName] != null) { string shortName;
return (string)typeConversionTable[dotNetTypeName]; if (TypeConversionTable.TryGetValue(dotNetTypeName, out shortName)) {
return shortName;
} }
return dotNetTypeName; return dotNetTypeName;
} }

9
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/NRefactoryResolver/NRefactoryResolver.cs

@ -997,16 +997,15 @@ namespace ICSharpCode.SharpDevelop.Dom.NRefactoryResolver
{ {
ArrayList result = new ArrayList(); ArrayList result = new ArrayList();
if (language == NR.SupportedLanguage.VBNet) { if (language == NR.SupportedLanguage.VBNet) {
foreach (KeyValuePair<string, string> pair in TypeReference.GetPrimitiveTypesVB()) { foreach (KeyValuePair<string, string> pair in TypeReference.PrimitiveTypesVB) {
string primitive = Char.ToUpper(pair.Key[0]) + pair.Key.Substring(1); if ("System." + pair.Key != pair.Value) {
if ("System." + primitive != pair.Value) { result.Add(GetPrimitiveClass(pair.Value, pair.Key));
result.Add(GetPrimitiveClass(pair.Value, primitive));
} }
} }
result.Add("Global"); result.Add("Global");
result.Add("New"); result.Add("New");
} else { } else {
foreach (KeyValuePair<string, string> pair in TypeReference.GetPrimitiveTypesCSharp()) { foreach (KeyValuePair<string, string> pair in TypeReference.PrimitiveTypesCSharp) {
result.Add(GetPrimitiveClass(pair.Value, pair.Key)); result.Add(GetPrimitiveClass(pair.Value, pair.Key));
} }
} }

42
src/Main/ICSharpCode.SharpDevelop.Dom/Project/Src/VBNet/VBNetAmbience.cs

@ -14,38 +14,14 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet
{ {
public class VBNetAmbience : AbstractAmbience public class VBNetAmbience : AbstractAmbience
{ {
static string[,] typeConversionList = new string[,] { public static IDictionary<string, string> TypeConversionTable {
{"System.String", "String"}, get { return ICSharpCode.NRefactory.Ast.TypeReference.PrimitiveTypesVBReverse; }
{"System.Single", "Single"},
{"System.Int16", "Short"},
{"System.Void", "Void"},
{"System.Object", "Object"},
{"System.Int64", "Long"},
{"System.Int32", "Integer"},
{"System.Double", "Double"},
{"System.Char", "Char"},
{"System.Boolean", "Boolean"},
{"System.Byte", "Byte"},
{"System.Decimal", "Decimal"},
{"System.DateTime", "Date"},
};
static Hashtable typeConversionTable = new Hashtable();
static VBNetAmbience()
{
for (int i = 0; i < typeConversionList.GetLength(0); ++i) {
typeConversionTable[typeConversionList[i, 0]] = typeConversionList[i, 1];
}
} }
static VBNetAmbience instance; static VBNetAmbience instance = new VBNetAmbience();
public static VBNetAmbience Instance { public static VBNetAmbience Instance {
get { get { return instance; }
if (instance == null) instance = new VBNetAmbience();
return instance;
}
} }
string GetModifier(IDecoration decoration) string GetModifier(IDecoration decoration)
@ -472,8 +448,9 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet
StringBuilder builder = new StringBuilder(); StringBuilder builder = new StringBuilder();
string fullName = returnType.FullyQualifiedName; string fullName = returnType.FullyQualifiedName;
if (fullName != null && typeConversionTable[fullName] != null) { string shortName;
builder.Append(typeConversionTable[fullName].ToString()); if (fullName != null && TypeConversionTable.TryGetValue(fullName, out shortName)) {
builder.Append(shortName);
} else { } else {
if (UseFullyQualifiedNames) { if (UseFullyQualifiedNames) {
builder.Append(fullName); builder.Append(fullName);
@ -551,8 +528,9 @@ namespace ICSharpCode.SharpDevelop.Dom.VBNet
public override string GetIntrinsicTypeName(string dotNetTypeName) public override string GetIntrinsicTypeName(string dotNetTypeName)
{ {
if (typeConversionTable[dotNetTypeName] != null) { string shortName;
return (string)typeConversionTable[dotNetTypeName]; if (TypeConversionTable.TryGetValue(dotNetTypeName, out shortName)) {
return shortName;
} }
return dotNetTypeName; return dotNetTypeName;
} }

Loading…
Cancel
Save