Browse Source

Merge branch 'master' of git://github.com/icsharpcode/ILSpy into Debugger

pull/191/merge
Eusebiu Marcu 14 years ago
parent
commit
5f34bf473b
  1. 117
      ICSharpCode.Decompiler/Ast/AstBuilder.cs
  2. 219
      ICSharpCode.Decompiler/Ast/TypesHierarchyHelpers.cs
  3. 15
      ICSharpCode.Decompiler/DecompilerSettings.cs
  4. 4
      ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj
  5. 460
      ICSharpCode.Decompiler/Tests/Types/S_TypeMemberDeclarations.cs
  6. 2
      ILSpy/AboutPage.cs
  7. 24
      ILSpy/CSharpLanguage.cs
  8. 1
      ILSpy/ILSpy.csproj
  9. 24
      ILSpy/LoadedAssembly.cs
  10. 1
      ILSpy/Options/DecompilerSettingsPanel.xaml
  11. 2
      ILSpy/Options/DecompilerSettingsPanel.xaml.cs
  12. 6
      ILSpy/TextView/DecompilerTextView.cs
  13. 80
      ILSpy/XmlDoc/AddXmlDocTransform.cs
  14. 151
      NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.Designer.cs
  15. 232
      NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.cs
  16. 120
      NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.resx
  17. 25
      NRefactory/ICSharpCode.NRefactory.Demo/ICSharpCode.NRefactory.Demo.csproj
  18. 162
      NRefactory/ICSharpCode.NRefactory.Demo/MainForm.Designer.cs
  19. 194
      NRefactory/ICSharpCode.NRefactory.Demo/MainForm.cs
  20. 172
      NRefactory/ICSharpCode.NRefactory.Demo/VBAstView.cs
  21. 67
      NRefactory/ICSharpCode.NRefactory.Demo/VBDemo.Designer.cs
  22. 120
      NRefactory/ICSharpCode.NRefactory.Demo/VBDemo.cs
  23. 85
      NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ConditionalOperatorTests.cs
  24. 2
      NRefactory/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj
  25. 22
      NRefactory/ICSharpCode.NRefactory.Tests/TypeSystem/StructureTests.cs
  26. 2
      NRefactory/ICSharpCode.NRefactory.Tests/TypeSystem/TestInterningProvider.cs
  27. 26
      NRefactory/ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs
  28. 149
      NRefactory/ICSharpCode.NRefactory.VB.Tests/General/UnitTest.cs
  29. 79
      NRefactory/ICSharpCode.NRefactory.VB.Tests/ICSharpCode.NRefactory.VB.Tests.csproj
  30. 2
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Lexer/CustomLexerTests.cs
  31. 2
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Lexer/ImplicitLineContinuationTests.cs
  32. 2
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Lexer/LexerContextTests.cs
  33. 42
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Lexer/LexerPositionTests.cs
  34. 2
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Lexer/LexerTests.cs
  35. 2
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Lexer/LiteralsTests.cs
  36. 4
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Lexer/XmlModeLexerTests.cs
  37. 4
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Output/CodeDOM/InvocationExpressionTest.cs
  38. 2
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Output/SpecialOutputVisitorTest.cs
  39. 35
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/CheckParentVisitor.cs
  40. 72
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/Expressions/BinaryOperatorExpressionTests.cs
  41. 14
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/Expressions/CastExpressionTests.cs
  42. 18
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/Expressions/InvocationExpressionTests.cs
  43. 8
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/Expressions/MemberReferenceExpressionTests.cs
  44. 8
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/Expressions/ObjectCreateExpressionTests.cs
  45. 4
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/Expressions/QueryExpressionTests.cs
  46. 4
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/Expressions/TypeOfIsExpressionTests.cs
  47. 2
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/Expressions/UnaryOperatorExpressionTests.cs
  48. 4
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/Expressions/XmlExpressionTests.cs
  49. 116
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/GlobalScope/AttributeSectionTests.cs
  50. 42
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/GlobalScope/DelegateDeclarationTests.cs
  51. 168
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/GlobalScope/ImportsStatementTests.cs
  52. 58
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/GlobalScope/NamespaceDeclarationTests.cs
  53. 87
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/GlobalScope/OptionDeclarationTests.cs
  54. 113
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/GlobalScope/OptionStatementTests.cs
  55. 378
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/GlobalScope/TypeDeclarationTests.cs
  56. 207
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/GlobalScope/UsingDeclarationTests.cs
  57. 26
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/LocationAssignmentCheckVisitor.cs
  58. 148
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/ParseUtil.cs
  59. 16
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/SnippetParserTests.cs
  60. 4
      NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/Statements/SwitchStatementTests.cs
  61. 73
      NRefactory/ICSharpCode.NRefactory.VB/Ast/AbstractNode.cs
  62. 137
      NRefactory/ICSharpCode.NRefactory.VB/Ast/AstLocation.cs
  63. 730
      NRefactory/ICSharpCode.NRefactory.VB/Ast/AstNode.cs
  64. 209
      NRefactory/ICSharpCode.NRefactory.VB/Ast/AstNodeCollection.cs
  65. 111
      NRefactory/ICSharpCode.NRefactory.VB/Ast/Enums.cs
  66. 33
      NRefactory/ICSharpCode.NRefactory.VB/Ast/Expressions/Expression.cs
  67. 75
      NRefactory/ICSharpCode.NRefactory.VB/Ast/Expressions/PrimitiveExpression.cs
  68. 27
      NRefactory/ICSharpCode.NRefactory.VB/Ast/Expressions/SimpleNameExpression.cs
  69. 72
      NRefactory/ICSharpCode.NRefactory.VB/Ast/Expressions/XmlIdentifier.cs
  70. 69
      NRefactory/ICSharpCode.NRefactory.VB/Ast/Expressions/XmlLiteralString.cs
  71. 93
      NRefactory/ICSharpCode.NRefactory.VB/Ast/General/Attribute.cs
  72. 36
      NRefactory/ICSharpCode.NRefactory.VB/Ast/General/AttributeBlock.cs
  73. 67
      NRefactory/ICSharpCode.NRefactory.VB/Ast/General/AttributedNode.cs
  74. 58
      NRefactory/ICSharpCode.NRefactory.VB/Ast/General/BlockStatement.cs
  75. 73
      NRefactory/ICSharpCode.NRefactory.VB/Ast/General/CompilationUnit.cs
  76. 103
      NRefactory/ICSharpCode.NRefactory.VB/Ast/General/Expression.cs
  77. 99
      NRefactory/ICSharpCode.NRefactory.VB/Ast/General/LocalVariableDeclaration.cs
  78. 40
      NRefactory/ICSharpCode.NRefactory.VB/Ast/General/ParameterDeclaration.cs
  79. 53
      NRefactory/ICSharpCode.NRefactory.VB/Ast/General/PrimitiveExpression.cs
  80. 62
      NRefactory/ICSharpCode.NRefactory.VB/Ast/General/Statement.cs
  81. 44
      NRefactory/ICSharpCode.NRefactory.VB/Ast/General/TypeParameterDeclaration.cs
  82. 10017
      NRefactory/ICSharpCode.NRefactory.VB/Ast/Generated.cs
  83. 52
      NRefactory/ICSharpCode.NRefactory.VB/Ast/GlobalScope/DelegateDeclaration.cs
  84. 44
      NRefactory/ICSharpCode.NRefactory.VB/Ast/GlobalScope/EnumDeclaration.cs
  85. 39
      NRefactory/ICSharpCode.NRefactory.VB/Ast/GlobalScope/EnumMemberDeclaration.cs
  86. 113
      NRefactory/ICSharpCode.NRefactory.VB/Ast/GlobalScope/ImportsClause.cs
  87. 36
      NRefactory/ICSharpCode.NRefactory.VB/Ast/GlobalScope/ImportsStatement.cs
  88. 78
      NRefactory/ICSharpCode.NRefactory.VB/Ast/GlobalScope/NamespaceDeclaration.cs
  89. 60
      NRefactory/ICSharpCode.NRefactory.VB/Ast/GlobalScope/OptionStatement.cs
  90. 58
      NRefactory/ICSharpCode.NRefactory.VB/Ast/GlobalScope/TypeDeclaration.cs
  91. 51
      NRefactory/ICSharpCode.NRefactory.VB/Ast/INode.cs
  92. 91
      NRefactory/ICSharpCode.NRefactory.VB/Ast/Identifier.cs
  93. 125
      NRefactory/ICSharpCode.NRefactory.VB/Ast/Statements/BlockStatement.cs
  94. 132
      NRefactory/ICSharpCode.NRefactory.VB/Ast/Statements/Statement.cs
  95. 145
      NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeName/AstType.cs
  96. 119
      NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeName/ComposedType.cs
  97. 57
      NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeName/PrimitiveType.cs
  98. 66
      NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeName/QualifiedType.cs
  99. 87
      NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeName/SimpleType.cs
  100. 427
      NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeReference.cs
  101. Some files were not shown because too many files have changed in this diff Show More

117
ICSharpCode.Decompiler/Ast/AstBuilder.cs

@ -230,7 +230,9 @@ namespace ICSharpCode.Decompiler.Ast @@ -230,7 +230,9 @@ namespace ICSharpCode.Decompiler.Ast
foreach (TypeDefinition nestedTypeDef in typeDef.NestedTypes) {
if (MemberIsHidden(nestedTypeDef, context.Settings))
continue;
astType.AddChild(CreateType(nestedTypeDef), TypeDeclaration.MemberRole);
var nestedType = CreateType(nestedTypeDef);
SetNewModifier(nestedType);
astType.AddChild(nestedType, TypeDeclaration.MemberRole);
}
AttributedNode result = astType;
@ -626,7 +628,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -626,7 +628,7 @@ namespace ICSharpCode.Decompiler.Ast
CreateCodeMappings(methodDef.MetadataToken.ToInt32(), methodDef);
MemberMapping methodMapping = methodDef.CreateCodeMapping(this.CodeMappings[methodDef.MetadataToken.ToInt32()]);
MethodDeclaration astMethod = new MethodDeclaration();
MethodDeclaration astMethod = new MethodDeclaration().WithAnnotation(methodMapping);
astMethod.AddAnnotation(methodDef);
astMethod.ReturnType = ConvertType(methodDef.ReturnType, methodDef.MethodReturnType);
astMethod.Name = CleanName(methodDef.Name);
@ -637,14 +639,8 @@ namespace ICSharpCode.Decompiler.Ast @@ -637,14 +639,8 @@ namespace ICSharpCode.Decompiler.Ast
if (!methodDef.DeclaringType.IsInterface) {
if (!methodDef.HasOverrides) {
astMethod.Modifiers = ConvertModifiers(methodDef);
if (methodDef.IsVirtual ^ !methodDef.IsNewSlot) {
try {
if (TypesHierarchyHelpers.FindBaseMethods(methodDef).Any())
astMethod.Modifiers |= Modifiers.New;
} catch (ReferenceResolvingException) {
// TODO: add some kind of notification (a comment?) about possible problems with decompiled code due to unresolved references.
}
}
if (methodDef.IsVirtual == methodDef.IsNewSlot)
SetNewModifier(astMethod);
} else {
astMethod.PrivateImplementationType = ConvertType(methodDef.Overrides.First().DeclaringType);
}
@ -674,7 +670,6 @@ namespace ICSharpCode.Decompiler.Ast @@ -674,7 +670,6 @@ namespace ICSharpCode.Decompiler.Ast
return op;
}
}
astMethod.WithAnnotation(methodMapping);
return astMethod;
}
@ -775,10 +770,6 @@ namespace ICSharpCode.Decompiler.Ast @@ -775,10 +770,6 @@ namespace ICSharpCode.Decompiler.Ast
}
}
}
if (accessor.IsVirtual ^ !accessor.IsNewSlot) {
if (TypesHierarchyHelpers.FindBaseProperties(propDef).Any())
astProp.Modifiers |= Modifiers.New;
}
} catch (ReferenceResolvingException) {
// TODO: add some kind of notification (a comment?) about possible problems with decompiled code due to unresolved references.
}
@ -793,7 +784,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -793,7 +784,7 @@ namespace ICSharpCode.Decompiler.Ast
astProp.Getter = new Accessor();
astProp.Getter.Body = CreateMethodBody(propDef.GetMethod);
astProp.AddAnnotation(propDef.GetMethod);
astProp.Getter.AddAnnotation(propDef.GetMethod);
ConvertAttributes(astProp.Getter, propDef.GetMethod);
if ((getterModifiers & Modifiers.VisibilityMask) != (astProp.Modifiers & Modifiers.VisibilityMask))
@ -818,11 +809,14 @@ namespace ICSharpCode.Decompiler.Ast @@ -818,11 +809,14 @@ namespace ICSharpCode.Decompiler.Ast
astProp.Setter.WithAnnotation(methodMapping);
}
ConvertCustomAttributes(astProp, propDef);
MemberDeclaration member = astProp;
if(propDef.IsIndexer())
return ConvertPropertyToIndexer(astProp, propDef);
else
return astProp;
member = ConvertPropertyToIndexer(astProp, propDef);
if(!accessor.HasOverrides && !accessor.DeclaringType.IsInterface)
if (accessor.IsVirtual == accessor.IsNewSlot)
SetNewModifier(member);
return member;
}
IndexerDeclaration ConvertPropertyToIndexer(PropertyDeclaration astProp, PropertyDefinition propDef)
@ -888,9 +882,8 @@ namespace ICSharpCode.Decompiler.Ast @@ -888,9 +882,8 @@ namespace ICSharpCode.Decompiler.Ast
astEvent.RemoveAccessor.WithAnnotation(methodMapping);
}
MethodDefinition accessor = eventDef.AddMethod ?? eventDef.RemoveMethod;
if (accessor.IsVirtual ^ !accessor.IsNewSlot) {
if (TypesHierarchyHelpers.FindBaseMethods(accessor).Any())
astEvent.Modifiers |= Modifiers.New;
if (accessor.IsVirtual == accessor.IsNewSlot) {
SetNewModifier(astEvent);
}
return astEvent;
}
@ -920,6 +913,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -920,6 +913,7 @@ namespace ICSharpCode.Decompiler.Ast
initializer.Initializer = CreateExpressionForConstant(fieldDef.Constant, fieldDef.FieldType, fieldDef.DeclaringType.IsEnum);
}
ConvertAttributes(astField, fieldDef);
SetNewModifier(astField);
return astField;
}
@ -1387,6 +1381,83 @@ namespace ICSharpCode.Decompiler.Ast @@ -1387,6 +1381,83 @@ namespace ICSharpCode.Decompiler.Ast
return type.CustomAttributes.Any(attr => attr.AttributeType.FullName == "System.FlagsAttribute");
}
/// <summary>
/// Sets new modifier if the member hides some other member from a base type.
/// </summary>
/// <param name="member">The node of the member which new modifier state should be determined.</param>
static void SetNewModifier(AttributedNode member)
{
try {
bool addNewModifier = false;
if (member is IndexerDeclaration) {
var propertyDef = member.Annotation<PropertyDefinition>();
var baseProperties =
TypesHierarchyHelpers.FindBaseProperties(propertyDef);
addNewModifier = baseProperties.Any();
} else
addNewModifier = HidesBaseMember(member);
if (addNewModifier)
member.Modifiers |= Modifiers.New;
}
catch (ReferenceResolvingException) {
// TODO: add some kind of notification (a comment?) about possible problems with decompiled code due to unresolved references.
}
}
private static bool HidesBaseMember(AttributedNode member)
{
var memberDefinition = member.Annotation<IMemberDefinition>();
bool addNewModifier = false;
var methodDefinition = memberDefinition as MethodDefinition;
if (methodDefinition != null) {
addNewModifier = HidesByName(memberDefinition, includeBaseMethods: false);
if (!addNewModifier)
addNewModifier = TypesHierarchyHelpers.FindBaseMethods(methodDefinition).Any();
} else
addNewModifier = HidesByName(memberDefinition, includeBaseMethods: true);
return addNewModifier;
}
/// <summary>
/// Determines whether any base class member has the same name as the given member.
/// </summary>
/// <param name="member">The derived type's member.</param>
/// <param name="includeBaseMethods">true if names of methods declared in base types should also be checked.</param>
/// <returns>true if any base member has the same name as given member, otherwise false.</returns>
static bool HidesByName(IMemberDefinition member, bool includeBaseMethods)
{
Debug.Assert(!(member is PropertyDefinition) || !((PropertyDefinition)member).IsIndexer());
if (member.DeclaringType.BaseType != null) {
var baseTypeRef = member.DeclaringType.BaseType;
while (baseTypeRef != null) {
var baseType = baseTypeRef.ResolveOrThrow();
if (baseType.HasProperties && AnyIsHiddenBy(baseType.Properties, member, m => !m.IsIndexer()))
return true;
if (baseType.HasEvents && AnyIsHiddenBy(baseType.Events, member))
return true;
if (baseType.HasFields && AnyIsHiddenBy(baseType.Fields, member))
return true;
if (includeBaseMethods && baseType.HasMethods
&& AnyIsHiddenBy(baseType.Methods, member, m => !m.IsSpecialName))
return true;
if (baseType.HasNestedTypes && AnyIsHiddenBy(baseType.NestedTypes, member))
return true;
baseTypeRef = baseType.BaseType;
}
}
return false;
}
static bool AnyIsHiddenBy<T>(IEnumerable<T> members, IMemberDefinition derived, Predicate<T> condition = null)
where T : IMemberDefinition
{
return members.Any(m => m.Name == derived.Name
&& (condition == null || condition(m))
&& TypesHierarchyHelpers.IsVisibleFromDerived(m, derived.DeclaringType));
}
/// <summary>
/// Gets the local variables for the current decompiled type, method, etc.

219
ICSharpCode.Decompiler/Ast/TypesHierarchyHelpers.cs

@ -27,6 +27,13 @@ namespace ICSharpCode.Decompiler.Ast @@ -27,6 +27,13 @@ namespace ICSharpCode.Decompiler.Ast
}
}
/// <summary>
/// Determines whether one method overrides or hides another method.
/// </summary>
/// <param name="parentMethod">The method declared in a base type.</param>
/// <param name="childMethod">The method declared in a derived type.</param>
/// <returns>true if <paramref name="childMethod"/> hides or overrides <paramref name="parentMethod"/>,
/// otherwise false.</returns>
public static bool IsBaseMethod(MethodDefinition parentMethod, MethodDefinition childMethod)
{
if (parentMethod == null)
@ -44,6 +51,13 @@ namespace ICSharpCode.Decompiler.Ast @@ -44,6 +51,13 @@ namespace ICSharpCode.Decompiler.Ast
return FindBaseMethods(childMethod).Any(m => m == parentMethod);// || (parentMethod.HasGenericParameters && m.);
}
/// <summary>
/// Determines whether a property overrides or hides another property.
/// </summary>
/// <param name="parentProperty">The property declared in a base type.</param>
/// <param name="childProperty">The property declared in a derived type.</param>
/// <returns>true if the <paramref name="childProperty"/> hides or overrides <paramref name="parentProperty"/>,
/// otherwise false.</returns>
public static bool IsBaseProperty(PropertyDefinition parentProperty, PropertyDefinition childProperty)
{
if (parentProperty == null)
@ -69,6 +83,11 @@ namespace ICSharpCode.Decompiler.Ast @@ -69,6 +83,11 @@ namespace ICSharpCode.Decompiler.Ast
return FindBaseEvents(childEvent).Any(m => m == parentEvent);
}
/// <summary>
/// Finds all methods from base types overridden or hidden by the specified method.
/// </summary>
/// <param name="method">The method which overrides or hides methods from base types.</param>
/// <returns>Methods overriden or hidden by the specified method.</returns>
public static IEnumerable<MethodDefinition> FindBaseMethods(MethodDefinition method)
{
if (method == null)
@ -79,30 +98,41 @@ namespace ICSharpCode.Decompiler.Ast @@ -79,30 +98,41 @@ namespace ICSharpCode.Decompiler.Ast
foreach (var baseType in BaseTypes(method.DeclaringType))
foreach (var baseMethod in baseType.Item.Methods)
if (MatchMethod(baseType.ApplyTo(baseMethod), gMethod) && IsVisbleFrom(baseMethod, method)) {
if (MatchMethod(baseType.ApplyTo(baseMethod), gMethod) && IsVisibleFromDerived(baseMethod, method.DeclaringType)) {
yield return baseMethod;
if (!(baseMethod.IsNewSlot ^ baseMethod.IsVirtual))
if (baseMethod.IsNewSlot == baseMethod.IsVirtual)
yield break;
}
}
public static IEnumerable<PropertyDefinition> FindBaseProperties(PropertyDefinition property, bool ignoreResolveExceptions = false)
/// <summary>
/// Finds all properties from base types overridden or hidden by the specified property.
/// </summary>
/// <param name="property">The property which overrides or hides properties from base types.</param>
/// <returns>Properties overriden or hidden by the specified property.</returns>
public static IEnumerable<PropertyDefinition> FindBaseProperties(PropertyDefinition property)
{
if (property == null)
throw new ArgumentNullException("property");
if ((property.GetMethod ?? property.SetMethod).HasOverrides)
yield break;
var typeContext = CreateGenericContext(property.DeclaringType);
var gProperty = typeContext.ApplyTo(property);
bool isIndexer = property.IsIndexer();
foreach (var baseType in BaseTypes(property.DeclaringType))
foreach (var baseProperty in baseType.Item.Properties)
if (MatchProperty(baseType.ApplyTo(baseProperty), gProperty) && IsVisbleFrom(baseProperty, property)) {
if (MatchProperty(baseType.ApplyTo(baseProperty), gProperty)
&& IsVisibleFromDerived(baseProperty, property.DeclaringType)) {
if (isIndexer != baseProperty.IsIndexer())
continue;
yield return baseProperty;
var anyPropertyAccessor = baseProperty.GetMethod ?? baseProperty.SetMethod;
if (!(anyPropertyAccessor.IsNewSlot ^ anyPropertyAccessor.IsVirtual))
if (anyPropertyAccessor.IsNewSlot == anyPropertyAccessor.IsVirtual)
yield break;
}
}
public static IEnumerable<EventDefinition> FindBaseEvents(EventDefinition eventDef)
@ -115,40 +145,78 @@ namespace ICSharpCode.Decompiler.Ast @@ -115,40 +145,78 @@ namespace ICSharpCode.Decompiler.Ast
foreach (var baseType in BaseTypes(eventDef.DeclaringType))
foreach (var baseEvent in baseType.Item.Events)
if (MatchEvent(baseType.ApplyTo(baseEvent), gEvent) && IsVisbleFrom(baseEvent, eventDef)) {
if (MatchEvent(baseType.ApplyTo(baseEvent), gEvent) && IsVisibleFromDerived(baseEvent, eventDef.DeclaringType)) {
yield return baseEvent;
var anyEventAccessor = baseEvent.AddMethod ?? baseEvent.RemoveMethod;
if (!(anyEventAccessor.IsNewSlot ^ anyEventAccessor.IsVirtual))
if (anyEventAccessor.IsNewSlot == anyEventAccessor.IsVirtual)
yield break;
}
}
private static bool IsVisbleFrom(MethodDefinition baseCandidate, MethodDefinition method)
/// <summary>
/// Determinates whether member of the base type is visible from a derived type.
/// </summary>
/// <param name="baseMember">The member which visibility is checked.</param>
/// <param name="derivedType">The derived type.</param>
/// <returns>true if the member is visible from derived type, othewise false.</returns>
public static bool IsVisibleFromDerived(IMemberDefinition baseMember, TypeDefinition derivedType)
{
if (baseCandidate.IsPrivate)
return false;
if ((baseCandidate.IsAssembly || baseCandidate.IsFamilyAndAssembly) && baseCandidate.Module != method.Module)
if (baseMember == null)
throw new ArgumentNullException("baseMember");
if (derivedType == null)
throw new ArgumentNullException("derivedType");
var visibility = IsVisibleFromDerived(baseMember);
if (visibility.HasValue)
return visibility.Value;
if (baseMember.DeclaringType.Module == derivedType.Module)
return true;
// TODO: Check also InternalsVisibleToAttribute.
return false;
return true;
}
private static bool IsVisbleFrom(PropertyDefinition baseCandidate, PropertyDefinition property)
private static bool? IsVisibleFromDerived(IMemberDefinition member)
{
if (baseCandidate.GetMethod != null && property.GetMethod != null && IsVisbleFrom(baseCandidate.GetMethod, property.GetMethod))
return true;
if (baseCandidate.SetMethod != null && property.SetMethod != null && IsVisbleFrom(baseCandidate.SetMethod, property.SetMethod))
MethodAttributes attrs = GetAccessAttributes(member) & MethodAttributes.MemberAccessMask;
if (attrs == MethodAttributes.Private)
return false;
if (attrs == MethodAttributes.Assembly || attrs == MethodAttributes.FamANDAssem)
return null;
return true;
return false;
}
private static bool IsVisbleFrom(EventDefinition baseCandidate, EventDefinition eventDef)
private static MethodAttributes GetAccessAttributes(IMemberDefinition member)
{
if (baseCandidate.AddMethod != null && eventDef.AddMethod != null && IsVisbleFrom(baseCandidate.AddMethod, eventDef.AddMethod))
return true;
if (baseCandidate.RemoveMethod != null && eventDef.RemoveMethod != null && IsVisbleFrom(baseCandidate.RemoveMethod, eventDef.RemoveMethod))
return true;
return false;
var fld = member as FieldDefinition;
if (fld != null)
return (MethodAttributes)fld.Attributes;
var method = member as MethodDefinition;
if (method != null)
return method.Attributes;
var prop = member as PropertyDefinition;
if (prop != null) {
return (prop.GetMethod ?? prop.SetMethod).Attributes;
}
var evnt = member as EventDefinition;
if (evnt != null) {
return (evnt.AddMethod ?? evnt.RemoveMethod).Attributes;
}
var nestedType = member as TypeDefinition;
if (nestedType != null) {
if (nestedType.IsNestedPrivate)
return MethodAttributes.Private;
if (nestedType.IsNestedAssembly || nestedType.IsNestedFamilyAndAssembly)
return MethodAttributes.Assembly;
return MethodAttributes.Public;
}
throw new NotSupportedException();
}
private static bool MatchMethod(GenericContext<MethodDefinition> candidate, GenericContext<MethodDefinition> method)
@ -161,7 +229,7 @@ namespace ICSharpCode.Decompiler.Ast @@ -161,7 +229,7 @@ namespace ICSharpCode.Decompiler.Ast
if (mCandidate.HasOverrides)
return false;
if (!IsSameType(candidate.ResolveWithContext(mCandidate.ReturnType), method.ResolveWithContext(mMethod.ReturnType)))
if (mCandidate.IsSpecialName != method.Item.IsSpecialName)
return false;
if (mCandidate.HasGenericParameters || mMethod.HasGenericParameters) {
@ -208,9 +276,6 @@ namespace ICSharpCode.Decompiler.Ast @@ -208,9 +276,6 @@ namespace ICSharpCode.Decompiler.Ast
if ((mCandidate.GetMethod ?? mCandidate.SetMethod).HasOverrides)
return false;
if (!IsSameType(candidate.ResolveWithContext(mCandidate.PropertyType), property.ResolveWithContext(mProperty.PropertyType)))
return false;
if (mCandidate.HasParameters || mProperty.HasParameters) {
if (!mCandidate.HasParameters || !mProperty.HasParameters || mCandidate.Parameters.Count != mProperty.Parameters.Count)
return false;
@ -242,6 +307,9 @@ namespace ICSharpCode.Decompiler.Ast @@ -242,6 +307,9 @@ namespace ICSharpCode.Decompiler.Ast
private static bool MatchParameters(GenericContext<ParameterDefinition> baseParameterType, GenericContext<ParameterDefinition> parameterType)
{
if (baseParameterType.Item.IsIn != parameterType.Item.IsIn ||
baseParameterType.Item.IsOut != parameterType.Item.IsOut)
return false;
var baseParam = baseParameterType.ResolveWithContext(baseParameterType.Item.ParameterType);
var param = parameterType.ResolveWithContext(parameterType.Item.ParameterType);
return IsSameType(baseParam, param);
@ -254,8 +322,12 @@ namespace ICSharpCode.Decompiler.Ast @@ -254,8 +322,12 @@ namespace ICSharpCode.Decompiler.Ast
if (tr1 == null || tr2 == null)
return false;
if (tr1.GetType() != tr2.GetType())
return false;
if (tr1.Name == tr2.Name && tr1.FullName == tr2.FullName)
return true;
return false;
}
@ -288,6 +360,10 @@ namespace ICSharpCode.Decompiler.Ast @@ -288,6 +360,10 @@ namespace ICSharpCode.Decompiler.Ast
struct GenericContext<T> where T : class
{
private static readonly ReadOnlyCollection<TypeReference> Empty = new ReadOnlyCollection<TypeReference>(new List<TypeReference>());
private static readonly GenericParameter UnresolvedGenericTypeParameter =
new DummyGenericParameterProvider(false).DummyParameter;
private static readonly GenericParameter UnresolvedGenericMethodParameter =
new DummyGenericParameterProvider(true).DummyParameter;
public readonly T Item;
public readonly ReadOnlyCollection<TypeReference> TypeArguments;
@ -324,28 +400,99 @@ namespace ICSharpCode.Decompiler.Ast @@ -324,28 +400,99 @@ namespace ICSharpCode.Decompiler.Ast
public TypeReference ResolveWithContext(TypeReference type)
{
var genericParameter = type as GenericParameter;
if (genericParameter != null && genericParameter.Owner.GenericParameterType == GenericParameterType.Type) {
if (genericParameter != null)
if (genericParameter.Owner.GenericParameterType == GenericParameterType.Type)
return this.TypeArguments[genericParameter.Position];
else
return genericParameter.Owner.GenericParameterType == GenericParameterType.Type
? UnresolvedGenericTypeParameter : UnresolvedGenericMethodParameter;
var typeSpecification = type as TypeSpecification;
if (typeSpecification != null) {
var resolvedElementType = ResolveWithContext(typeSpecification.ElementType);
return ReplaceElementType(typeSpecification, resolvedElementType);
}
var arrayType = type as ArrayType;
return type.ResolveOrThrow();
}
private TypeReference ReplaceElementType(TypeSpecification ts, TypeReference newElementType)
{
var arrayType = ts as ArrayType;
if (arrayType != null) {
var resolvedElementType = ResolveWithContext(arrayType.ElementType);
if (resolvedElementType == null)
return null;
if (resolvedElementType == arrayType.ElementType)
if (newElementType == arrayType.ElementType)
return arrayType;
var newArrayType = new ArrayType(resolvedElementType, arrayType.Rank);
var newArrayType = new ArrayType(newElementType, arrayType.Rank);
for (int dimension = 0; dimension < arrayType.Rank; dimension++)
newArrayType.Dimensions[dimension] = arrayType.Dimensions[dimension];
return newArrayType;
}
return type.ResolveOrThrow();
var byReferenceType = ts as ByReferenceType;
if (byReferenceType != null) {
return new ByReferenceType(newElementType);
}
// TODO: should we throw an exception instead calling Resolve method?
return ts.ResolveOrThrow();
}
public GenericContext<T2> ApplyTo<T2>(T2 item) where T2 : class
{
return new GenericContext<T2>(item, this.TypeArguments);
}
private class DummyGenericParameterProvider : IGenericParameterProvider
{
readonly Mono.Cecil.GenericParameterType type;
readonly Mono.Collections.Generic.Collection<GenericParameter> parameters;
public DummyGenericParameterProvider(bool methodTypeParameter)
{
type = methodTypeParameter ? Mono.Cecil.GenericParameterType.Method :
Mono.Cecil.GenericParameterType.Type;
parameters = new Mono.Collections.Generic.Collection<GenericParameter>(1);
parameters.Add(new GenericParameter(this));
}
public GenericParameter DummyParameter
{
get { return parameters[0]; }
}
bool IGenericParameterProvider.HasGenericParameters
{
get { throw new NotImplementedException(); }
}
bool IGenericParameterProvider.IsDefinition
{
get { throw new NotImplementedException(); }
}
ModuleDefinition IGenericParameterProvider.Module
{
get { throw new NotImplementedException(); }
}
Mono.Collections.Generic.Collection<GenericParameter> IGenericParameterProvider.GenericParameters
{
get { return parameters; }
}
GenericParameterType IGenericParameterProvider.GenericParameterType
{
get { return type; }
}
MetadataToken IMetadataTokenProvider.MetadataToken
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
}
}
}
}

15
ICSharpCode.Decompiler/DecompilerSettings.cs

@ -209,6 +209,21 @@ namespace ICSharpCode.Decompiler @@ -209,6 +209,21 @@ namespace ICSharpCode.Decompiler
}
}
bool showXmlDocumentation = true;
/// <summary>
/// Gets/Sets whether to include XML documentation comments in the decompiled code
/// </summary>
public bool ShowXmlDocumentation {
get { return showXmlDocumentation; }
set {
if (showXmlDocumentation != value) {
showXmlDocumentation = value;
OnPropertyChanged("ShowXmlDocumentation");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)

4
ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj

@ -69,7 +69,7 @@ @@ -69,7 +69,7 @@
<None Include="Types\S_EnumSamples.cs" />
<None Include="CustomAttributes\S_AssemblyCustomAttribute.cs" />
<Compile Include="Helpers\RemoveCompilerAttribute.cs" />
<None Include="Types\S_TypeMemberDeclarations.cs" />
<Compile Include="Types\S_TypeMemberDeclarations.cs" />
<Compile Include="Types\EnumTests.cs" />
<Compile Include="Types\TypeTests.cs" />
<Compile Include="DelegateConstruction.cs" />
@ -107,4 +107,4 @@ @@ -107,4 +107,4 @@
<None Include="StackTests\StackTests.il" />
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
</Project>
</Project>

460
ICSharpCode.Decompiler/Tests/Types/S_TypeMemberDeclarations.cs

@ -428,8 +428,8 @@ namespace IndexerOverrideRestrictedAccessorOnly @@ -428,8 +428,8 @@ namespace IndexerOverrideRestrictedAccessorOnly
}
}
}
//$$ PropertyHiding
namespace PropertyHiding
//$$ HideProperty
namespace HideProperty
{
public class A
{
@ -467,8 +467,397 @@ namespace PropertyHiding @@ -467,8 +467,397 @@ namespace PropertyHiding
}
}
}
//$$ IndexerHidingGeneric
namespace IndexerHidingGeneric
//$$ HideMembers
namespace HideMembers
{
public class A
{
public int F;
public int Prop
{
get
{
return 3;
}
}
public int G
{
get
{
return 3;
}
}
}
public class B : A
{
public new int F
{
get
{
return 3;
}
}
public new string Prop
{
get
{
return "a";
}
}
}
public class C : A
{
public new int G;
}
public class D : A
{
public new void F()
{
}
}
public class D1 : D
{
public new int F;
}
public class E : A
{
private new class F
{
}
}
}
//$$ HideMembers2
namespace HideMembers2
{
public class G
{
public int Item
{
get
{
return 1;
}
}
}
public class G2 : G
{
public int this[int i]
{
get
{
return 2;
}
}
}
public class G3 : G2
{
public new int Item
{
get
{
return 4;
}
}
}
public class H
{
public int this[int j]
{
get
{
return 0;
}
}
}
public class H2 : H
{
public int Item
{
get
{
return 2;
}
}
}
public class H3 : H2
{
public new string this[int j]
{
get
{
return null;
}
}
}
}
//$$ HideMembers2a
namespace HideMembers2a
{
public interface IA
{
int this[int i]
{
get;
}
}
public class A : IA
{
int IA.this[int i]
{
get
{
throw new NotImplementedException();
}
}
}
public class A1 : A
{
public int this[int i]
{
get
{
return 3;
}
}
}
}
//$$ HideMembers3
namespace HideMembers3
{
public class G<T>
{
public void M1(T p)
{
}
public int M2(int t)
{
return 3;
}
}
public class G1<T> : G<int>
{
public new int M1(int i)
{
return 0;
}
public int M2(T i)
{
return 2;
}
}
public class G2<T> : G<int>
{
public int M1(T p)
{
return 4;
}
}
public class J
{
public int P
{
get
{
return 2;
}
}
}
public class J2 : J
{
public int get_P;
}
}
//$$ HideMembers4
namespace HideMembers4
{
public class A
{
public void M<T>(T t)
{
}
}
public class A1 : A
{
public new void M<K>(K t)
{
}
public void M(int t)
{
}
}
public class B
{
public void M<T>()
{
}
public void M1<T>()
{
}
public void M2<T>(T t)
{
}
}
public class B1 : B
{
public void M<T1, T2>()
{
}
public new void M1<R>()
{
}
public new void M2<R>(R r)
{
}
}
public class C<T>
{
public void M<TT>(T t)
{
}
}
public class C1<K> : C<K>
{
public void M<TT>(TT t)
{
}
}
}
//$$ HideMembers5
namespace HideMembers5
{
public class A
{
public void M(int t)
{
}
}
public class A1 : A
{
public void M(ref int t)
{
}
}
public class B
{
public void M(ref int l)
{
}
}
public class B1 : B
{
public void M(out int l)
{
l = 2;
}
public void M(ref long l)
{
}
}
}
//$$ HideMemberSkipNotVisible
namespace HideMemberSkipNotVisible
{
public class A
{
protected int F;
protected string P
{
get
{
return null;
}
}
}
public class B : A
{
private new string F;
private new int P
{
set
{
}
}
}
}
//$$ HideNestedClass
namespace HideNestedClass
{
public class A
{
public class N1
{
}
protected class N2
{
}
private class N3
{
}
internal class N4
{
}
protected internal class N5
{
}
}
public class B : A
{
public new int N1;
public new int N2;
public int N3;
public new int N4;
public new int N5;
}
}
//$$ HidePropertyReservedMethod
namespace HidePropertyReservedMethod
{
public class A
{
public int P
{
get
{
return 1;
}
}
}
public class B : A
{
public int get_P()
{
return 2;
}
public void set_P(int value)
{
}
}
}
//$$ HideIndexerDiffAccessor
namespace HideIndexerDiffAccessor
{
public class A
{
public int this[int i]
{
get
{
return 2;
}
}
}
public class B : A
{
public new int this[int j]
{
set
{
}
}
}
}
//$$ HideIndexerGeneric
namespace HideIndexerGeneric
{
public class A<T>
{
@ -515,8 +904,8 @@ namespace IndexerHidingGeneric @@ -515,8 +904,8 @@ namespace IndexerHidingGeneric
}
}
}
//$$ MethodHiding
namespace MethodHiding
//$$ HideMethod
namespace HideMethod
{
public class A
{
@ -539,8 +928,8 @@ namespace MethodHiding @@ -539,8 +928,8 @@ namespace MethodHiding
}
}
}
//$$ MethodHideGeneric
namespace MethodHideGeneric
//$$ HideMethodGeneric
namespace HideMethodGeneric
{
public class A<T>
{
@ -583,8 +972,8 @@ namespace MethodHideGeneric @@ -583,8 +972,8 @@ namespace MethodHideGeneric
}
}
}
//$$ MethodHideGenericSkipPrivate
namespace MethodHideGenericSkipPrivate
//$$ HideMethodGenericSkipPrivate
namespace HideMethodGenericSkipPrivate
{
public class A<T>
{
@ -617,8 +1006,8 @@ namespace MethodHideGenericSkipPrivate @@ -617,8 +1006,8 @@ namespace MethodHideGenericSkipPrivate
}
}
}
//$$ MethodHideGeneric2
namespace MethodHideGeneric2
//$$ HideMethodGeneric2
namespace HideMethodGeneric2
{
public class A
{
@ -669,8 +1058,51 @@ namespace MethodHideGeneric2 @@ -669,8 +1058,51 @@ namespace MethodHideGeneric2
}
}
}
//$$ EventHiding
namespace EventHiding
//$$ HideMethodDiffSignatures
namespace HideMethodDiffSignatures
{
public class C1<T>
{
public virtual void M(T arg)
{
}
}
public class C2<T1, T2> : C1<T2>
{
public new virtual void M(T2 arg)
{
}
}
public class C3 : C2<int, bool>
{
public new virtual void M(bool arg)
{
}
}
}
//$$ HideMethodStatic
namespace HideMethodStatic
{
public class A
{
public int N
{
get
{
return 0;
}
}
}
public class B
{
public int N()
{
return 0;
}
}
}
//$$ HideEvent
namespace HideEvent
{
public class A
{

2
ILSpy/AboutPage.cs

@ -178,7 +178,7 @@ namespace ICSharpCode.ILSpy @@ -178,7 +178,7 @@ namespace ICSharpCode.ILSpy
{
var tcs = new TaskCompletionSource<AvailableVersionInfo>();
WebClient wc = new WebClient();
wc.Proxy = new WebProxy() { UseDefaultCredentials = true };
wc.UseDefaultCredentials = true;
wc.DownloadDataCompleted += delegate(object sender, DownloadDataCompletedEventArgs e) {
if (e.Error != null) {
tcs.SetException(e.Error);

24
ILSpy/CSharpLanguage.cs

@ -32,6 +32,7 @@ using ICSharpCode.Decompiler; @@ -32,6 +32,7 @@ using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Ast;
using ICSharpCode.Decompiler.Ast.Transforms;
using ICSharpCode.ILSpy.Baml;
using ICSharpCode.ILSpy.XmlDoc;
using ICSharpCode.NRefactory.CSharp;
using Mono.Cecil;
@ -89,8 +90,7 @@ namespace ICSharpCode.ILSpy @@ -89,8 +90,7 @@ namespace ICSharpCode.ILSpy
WriteCommentLine(output, TypeToString(method.DeclaringType, includeNamespace: true));
AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: method.DeclaringType, isSingleMember: true);
codeDomBuilder.AddMethod(method);
codeDomBuilder.RunTransformations(transformAbortCondition);
codeDomBuilder.GenerateCode(output);
RunTransformsAndGenerateCode(codeDomBuilder, output, options);
OnDecompilationFinished(new DecompileEventArgs { CodeMappings = codeDomBuilder.CodeMappings, LocalVariables = codeDomBuilder.LocalVariables, DecompiledMemberReferences = codeDomBuilder.DecompiledMemberReferences });
}
@ -99,8 +99,7 @@ namespace ICSharpCode.ILSpy @@ -99,8 +99,7 @@ namespace ICSharpCode.ILSpy
WriteCommentLine(output, TypeToString(property.DeclaringType, includeNamespace: true));
AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: property.DeclaringType, isSingleMember: true);
codeDomBuilder.AddProperty(property);
codeDomBuilder.RunTransformations(transformAbortCondition);
codeDomBuilder.GenerateCode(output);
RunTransformsAndGenerateCode(codeDomBuilder, output, options);
OnDecompilationFinished(new DecompileEventArgs { CodeMappings = codeDomBuilder.CodeMappings, LocalVariables = codeDomBuilder.LocalVariables, DecompiledMemberReferences = codeDomBuilder.DecompiledMemberReferences });
}
@ -109,8 +108,7 @@ namespace ICSharpCode.ILSpy @@ -109,8 +108,7 @@ namespace ICSharpCode.ILSpy
WriteCommentLine(output, TypeToString(field.DeclaringType, includeNamespace: true));
AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: field.DeclaringType, isSingleMember: true);
codeDomBuilder.AddField(field);
codeDomBuilder.RunTransformations(transformAbortCondition);
codeDomBuilder.GenerateCode(output);
RunTransformsAndGenerateCode(codeDomBuilder, output, options);
OnDecompilationFinished(new DecompileEventArgs { DecompiledMemberReferences = codeDomBuilder.DecompiledMemberReferences });
}
@ -119,8 +117,7 @@ namespace ICSharpCode.ILSpy @@ -119,8 +117,7 @@ namespace ICSharpCode.ILSpy
WriteCommentLine(output, TypeToString(ev.DeclaringType, includeNamespace: true));
AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: ev.DeclaringType, isSingleMember: true);
codeDomBuilder.AddEvent(ev);
codeDomBuilder.RunTransformations(transformAbortCondition);
codeDomBuilder.GenerateCode(output);
RunTransformsAndGenerateCode(codeDomBuilder, output, options);
OnDecompilationFinished(new DecompileEventArgs { CodeMappings = codeDomBuilder.CodeMappings, LocalVariables = codeDomBuilder.LocalVariables, DecompiledMemberReferences = codeDomBuilder.DecompiledMemberReferences });
}
@ -128,11 +125,18 @@ namespace ICSharpCode.ILSpy @@ -128,11 +125,18 @@ namespace ICSharpCode.ILSpy
{
AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: type);
codeDomBuilder.AddType(type);
codeDomBuilder.RunTransformations(transformAbortCondition);
codeDomBuilder.GenerateCode(output);
RunTransformsAndGenerateCode(codeDomBuilder, output, options);
OnDecompilationFinished(new DecompileEventArgs { CodeMappings = codeDomBuilder.CodeMappings, LocalVariables = codeDomBuilder.LocalVariables, DecompiledMemberReferences = codeDomBuilder.DecompiledMemberReferences });
}
void RunTransformsAndGenerateCode(AstBuilder astBuilder, ITextOutput output, DecompilationOptions options)
{
astBuilder.RunTransformations(transformAbortCondition);
if (options.DecompilerSettings.ShowXmlDocumentation)
AddXmlDocTransform.Run(astBuilder.CompilationUnit);
astBuilder.GenerateCode(output);
}
public override void DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)
{
if (options.FullDecompilation && options.SaveAsProjectDirectory != null) {

1
ILSpy/ILSpy.csproj

@ -162,6 +162,7 @@ @@ -162,6 +162,7 @@
<Compile Include="TreeNodes\Analyzer\AnalyzedPropertyAccessorsTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedPropertyOverridesTreeNode.cs" />
<Compile Include="TreeNodes\Analyzer\AnalyzedPropertyTreeNode.cs" />
<Compile Include="XmlDoc\AddXmlDocTransform.cs" />
<Compile Include="XmlDoc\XmlDocKeyProvider.cs" />
<Compile Include="XmlDoc\XmlDocLoader.cs" />
<Compile Include="XmlDoc\XmlDocRenderer.cs" />

24
ILSpy/LoadedAssembly.cs

@ -88,24 +88,28 @@ namespace ICSharpCode.ILSpy @@ -88,24 +88,28 @@ namespace ICSharpCode.ILSpy
// runs on background thread
ReaderParameters p = new ReaderParameters();
p.AssemblyResolver = new MyAssemblyResolver(this);
try {
if (DecompilerSettingsPanel.CurrentDecompilerSettings.UseDebugSymbols) {
SetSymbolSettings(p);
AssemblyDefinition asm = AssemblyDefinition.ReadAssembly(fileName, p);
if (DecompilerSettingsPanel.CurrentDecompilerSettings.UseDebugSymbols) {
try {
LoadSymbols(asm.MainModule);
} catch (IOException) {
} catch (UnauthorizedAccessException) {
} catch (InvalidOperationException) {
// ignore any errors during symbol loading
}
return AssemblyDefinition.ReadAssembly(fileName, p);
} finally {
if (p.SymbolStream != null)
p.SymbolStream.Dispose();
}
return asm;
}
private void SetSymbolSettings(ReaderParameters p)
private void LoadSymbols(ModuleDefinition module)
{
// search for pdb in same directory as dll
string pdbName = Path.Combine(Path.GetDirectoryName(fileName), Path.GetFileNameWithoutExtension(fileName) + ".pdb");
if (File.Exists(pdbName)) {
p.ReadSymbols = true;
p.SymbolStream = File.OpenRead(pdbName);
using (Stream s = File.OpenRead(pdbName)) {
module.ReadSymbols(new Mono.Cecil.Pdb.PdbReaderProvider().GetSymbolReader(module, s));
}
return;
}
// TODO: use symbol cache, get symbols from microsoft

1
ILSpy/Options/DecompilerSettingsPanel.xaml

@ -7,5 +7,6 @@ @@ -7,5 +7,6 @@
<CheckBox IsChecked="{Binding YieldReturn}">Decompile enumerators (yield return)</CheckBox>
<CheckBox IsChecked="{Binding QueryExpressions}" IsEnabled="{Binding AnonymousMethods}">Decompile query expressions</CheckBox>
<CheckBox IsChecked="{Binding UseDebugSymbols}">Use variable names from debug symbols, if available</CheckBox>
<CheckBox IsChecked="{Binding ShowXmlDocumentation}">Show XML documentation in decompiled code</CheckBox>
</StackPanel>
</UserControl>

2
ILSpy/Options/DecompilerSettingsPanel.xaml.cs

@ -62,6 +62,7 @@ namespace ICSharpCode.ILSpy @@ -62,6 +62,7 @@ namespace ICSharpCode.ILSpy
s.YieldReturn = (bool?)e.Attribute("yieldReturn") ?? s.YieldReturn;
s.QueryExpressions = (bool?)e.Attribute("queryExpressions") ?? s.QueryExpressions;
s.UseDebugSymbols = (bool?)e.Attribute("useDebugSymbols") ?? s.UseDebugSymbols;
s.ShowXmlDocumentation = (bool?)e.Attribute("xmlDoc") ?? s.ShowXmlDocumentation;
return s;
}
@ -73,6 +74,7 @@ namespace ICSharpCode.ILSpy @@ -73,6 +74,7 @@ namespace ICSharpCode.ILSpy
section.SetAttributeValue("yieldReturn", s.YieldReturn);
section.SetAttributeValue("queryExpressions", s.QueryExpressions);
section.SetAttributeValue("useDebugSymbols", s.UseDebugSymbols);
section.SetAttributeValue("xmlDoc", s.ShowXmlDocumentation);
XElement existingElement = root.Element("DecompilerSettings");
if (existingElement != null)

6
ILSpy/TextView/DecompilerTextView.cs

@ -167,17 +167,17 @@ namespace ICSharpCode.ILSpy.TextView @@ -167,17 +167,17 @@ namespace ICSharpCode.ILSpy.TextView
} else if (mr is MethodReference) {
mr = ((MethodReference)mr).Resolve() ?? mr;
}
XmlDocRenderer renderer = new XmlDocRenderer();
renderer.AppendText(MainWindow.Instance.CurrentLanguage.GetTooltip(mr));
XmlDocumentationProvider docProvider = XmlDocLoader.LoadDocumentation(mr.Module);
if (docProvider != null) {
XmlDocRenderer renderer = new XmlDocRenderer();
renderer.AppendText(MainWindow.Instance.CurrentLanguage.GetTooltip(mr));
string documentation = docProvider.GetDocumentation(XmlDocKeyProvider.GetKey(mr));
if (documentation != null) {
renderer.AppendText(Environment.NewLine);
renderer.AddXmlDocumentation(documentation);
}
return renderer.CreateTextBlock();
}
return renderer.CreateTextBlock();
}
return null;
}

80
ILSpy/XmlDoc/AddXmlDocTransform.cs

@ -0,0 +1,80 @@ @@ -0,0 +1,80 @@
// Copyright (c) 2011 AlphaSierraPapa for the SharpDevelop Team
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
// FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
using System;
using System.IO;
using ICSharpCode.NRefactory.CSharp;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.XmlDoc
{
/// <summary>
/// Adds XML documentation for member definitions.
/// </summary>
static class AddXmlDocTransform
{
public static void Run(AstNode node)
{
if (node is AttributedNode) {
MemberReference mr = node.Annotation<MemberReference>();
if (mr != null && mr.Module != null) {
var xmldoc = XmlDocLoader.LoadDocumentation(mr.Module);
if (xmldoc != null) {
string doc = xmldoc.GetDocumentation(XmlDocKeyProvider.GetKey(mr));
if (doc != null) {
InsertXmlDocumentation(node, new StringReader(doc));
}
}
}
if (!(node is TypeDeclaration))
return; // don't recurse into attributed nodes, except for type definitions
}
foreach (AstNode child in node.Children)
Run(child);
}
static void InsertXmlDocumentation(AstNode node, StringReader r)
{
// Find the first non-empty line:
string firstLine;
do {
firstLine = r.ReadLine();
if (firstLine == null)
return;
} while (string.IsNullOrWhiteSpace(firstLine));
string indentation = firstLine.Substring(0, firstLine.Length - firstLine.TrimStart().Length);
string line = firstLine;
int skippedWhitespaceLines = 0;
// Copy all lines from input to output, except for empty lines at the end.
while (line != null) {
if (string.IsNullOrWhiteSpace(line)) {
skippedWhitespaceLines++;
} else {
while (skippedWhitespaceLines > 0) {
node.Parent.InsertChildBefore(node, new Comment(string.Empty, CommentType.Documentation), AstNode.Roles.Comment);
skippedWhitespaceLines--;
}
if (line.StartsWith(indentation, StringComparison.Ordinal))
line = line.Substring(indentation.Length);
node.Parent.InsertChildBefore(node, new Comment(" " + line, CommentType.Documentation), AstNode.Roles.Comment);
}
line = r.ReadLine();
}
}
}
}

151
NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.Designer.cs generated

@ -0,0 +1,151 @@ @@ -0,0 +1,151 @@
// 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)
namespace ICSharpCode.NRefactory.Demo
{
partial class CSDemo
{
/// <summary>
/// Designer variable used to keep track of non-visual components.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Disposes resources used by the control.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing) {
if (components != null) {
components.Dispose();
}
}
base.Dispose(disposing);
}
/// <summary>
/// This method is required for Windows Forms designer support.
/// Do not change the method contents inside the source code editor. The Forms designer might
/// not be able to load this method if it was changed manually.
/// </summary>
private void InitializeComponent()
{
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.csharpCodeTextBox = new System.Windows.Forms.TextBox();
this.resolveButton = new System.Windows.Forms.Button();
this.csharpTreeView = new System.Windows.Forms.TreeView();
this.csharpGenerateCodeButton = new System.Windows.Forms.Button();
this.csharpParseButton = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout();
this.SuspendLayout();
//
// splitContainer1
//
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer1.Location = new System.Drawing.Point(0, 0);
this.splitContainer1.Name = "splitContainer1";
this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
//
// splitContainer1.Panel1
//
this.splitContainer1.Panel1.Controls.Add(this.csharpCodeTextBox);
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.resolveButton);
this.splitContainer1.Panel2.Controls.Add(this.csharpTreeView);
this.splitContainer1.Panel2.Controls.Add(this.csharpGenerateCodeButton);
this.splitContainer1.Panel2.Controls.Add(this.csharpParseButton);
this.splitContainer1.Size = new System.Drawing.Size(475, 406);
this.splitContainer1.SplitterDistance = 178;
this.splitContainer1.TabIndex = 1;
//
// csharpCodeTextBox
//
this.csharpCodeTextBox.AcceptsReturn = true;
this.csharpCodeTextBox.AcceptsTab = true;
this.csharpCodeTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.csharpCodeTextBox.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.csharpCodeTextBox.HideSelection = false;
this.csharpCodeTextBox.Location = new System.Drawing.Point(0, 0);
this.csharpCodeTextBox.Multiline = true;
this.csharpCodeTextBox.Name = "csharpCodeTextBox";
this.csharpCodeTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.csharpCodeTextBox.Size = new System.Drawing.Size(475, 178);
this.csharpCodeTextBox.TabIndex = 0;
this.csharpCodeTextBox.Text = "using System;\r\nclass Test\r\n{\r\n public void Main(string[] args)\r\n {\r\n " +
" Console.WriteLine(\"Hello, World\");\r\n }\r\n}";
this.csharpCodeTextBox.WordWrap = false;
this.csharpCodeTextBox.TextChanged += new System.EventHandler(this.CsharpCodeTextBoxTextChanged);
//
// resolveButton
//
this.resolveButton.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.resolveButton.Location = new System.Drawing.Point(187, 3);
this.resolveButton.Name = "resolveButton";
this.resolveButton.Size = new System.Drawing.Size(100, 23);
this.resolveButton.TabIndex = 3;
this.resolveButton.Text = "Resolve";
this.resolveButton.UseVisualStyleBackColor = true;
this.resolveButton.Click += new System.EventHandler(this.ResolveButtonClick);
//
// csharpTreeView
//
this.csharpTreeView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.csharpTreeView.HideSelection = false;
this.csharpTreeView.Location = new System.Drawing.Point(3, 32);
this.csharpTreeView.Name = "csharpTreeView";
this.csharpTreeView.Size = new System.Drawing.Size(467, 189);
this.csharpTreeView.TabIndex = 2;
this.csharpTreeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.CSharpTreeViewAfterSelect);
//
// csharpGenerateCodeButton
//
this.csharpGenerateCodeButton.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.csharpGenerateCodeButton.Location = new System.Drawing.Point(293, 2);
this.csharpGenerateCodeButton.Name = "csharpGenerateCodeButton";
this.csharpGenerateCodeButton.Size = new System.Drawing.Size(100, 23);
this.csharpGenerateCodeButton.TabIndex = 1;
this.csharpGenerateCodeButton.Text = "Generate";
this.csharpGenerateCodeButton.UseVisualStyleBackColor = true;
this.csharpGenerateCodeButton.Click += new System.EventHandler(this.CSharpGenerateCodeButtonClick);
//
// csharpParseButton
//
this.csharpParseButton.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.csharpParseButton.Location = new System.Drawing.Point(81, 3);
this.csharpParseButton.Name = "csharpParseButton";
this.csharpParseButton.Size = new System.Drawing.Size(100, 23);
this.csharpParseButton.TabIndex = 0;
this.csharpParseButton.Text = "Parse";
this.csharpParseButton.UseVisualStyleBackColor = true;
this.csharpParseButton.Click += new System.EventHandler(this.CSharpParseButtonClick);
//
// CSDemo
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.splitContainer1);
this.Name = "CSDemo";
this.Size = new System.Drawing.Size(475, 406);
this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel1.PerformLayout();
this.splitContainer1.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
this.splitContainer1.ResumeLayout(false);
this.ResumeLayout(false);
}
private System.Windows.Forms.Button csharpParseButton;
private System.Windows.Forms.Button csharpGenerateCodeButton;
private System.Windows.Forms.TreeView csharpTreeView;
private System.Windows.Forms.Button resolveButton;
private System.Windows.Forms.TextBox csharpCodeTextBox;
private System.Windows.Forms.SplitContainer splitContainer1;
}
}

232
NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.cs

@ -0,0 +1,232 @@ @@ -0,0 +1,232 @@
// 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.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using ICSharpCode.NRefactory.CSharp;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
namespace ICSharpCode.NRefactory.Demo
{
/// <summary>
/// Description of CSDemo.
/// </summary>
public partial class CSDemo : UserControl
{
public CSDemo()
{
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
if (LicenseManager.UsageMode != LicenseUsageMode.Designtime) {
csharpCodeTextBox.SelectAll();
CSharpParseButtonClick(null, null);
resolveButton.UseWaitCursor = true;
ThreadPool.QueueUserWorkItem(
delegate {
builtInLibs.Value.ToString();
BeginInvoke(new Action(delegate { resolveButton.UseWaitCursor = false; }));
});
}
}
CompilationUnit compilationUnit;
void CSharpParseButtonClick(object sender, EventArgs e)
{
CSharpParser parser = new CSharpParser();
compilationUnit = parser.Parse(new StringReader(csharpCodeTextBox.Text));
csharpTreeView.Nodes.Clear();
foreach (var element in compilationUnit.Children) {
csharpTreeView.Nodes.Add(MakeTreeNode(element));
}
SelectCurrentNode(csharpTreeView.Nodes);
resolveButton.Enabled = true;
}
TreeNode MakeTreeNode(AstNode node)
{
TreeNode t = new TreeNode(GetNodeTitle(node));
t.Tag = node;
foreach (AstNode child in node.Children) {
t.Nodes.Add(MakeTreeNode(child));
}
return t;
}
string GetNodeTitle(AstNode node)
{
StringBuilder b = new StringBuilder();
b.Append(node.Role.ToString());
b.Append(": ");
b.Append(node.GetType().Name);
bool hasProperties = false;
foreach (PropertyInfo p in node.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
if (p.Name == "NodeType" || p.Name == "IsNull")
continue;
if (p.PropertyType == typeof(string) || p.PropertyType.IsEnum || p.PropertyType == typeof(bool)) {
if (!hasProperties) {
hasProperties = true;
b.Append(" (");
} else {
b.Append(", ");
}
b.Append(p.Name);
b.Append(" = ");
try {
object val = p.GetValue(node, null);
b.Append(val != null ? val.ToString() : "**null**");
} catch (TargetInvocationException ex) {
b.Append("**" + ex.InnerException.GetType().Name + "**");
}
}
}
if (hasProperties)
b.Append(")");
return b.ToString();
}
bool SelectCurrentNode(TreeNodeCollection c)
{
int selectionStart = csharpCodeTextBox.SelectionStart;
int selectionEnd = selectionStart + csharpCodeTextBox.SelectionLength;
foreach (TreeNode t in c) {
AstNode node = t.Tag as AstNode;
if (node != null
&& selectionStart >= GetOffset(csharpCodeTextBox, node.StartLocation)
&& selectionEnd <= GetOffset(csharpCodeTextBox, node.EndLocation))
{
if (selectionStart == selectionEnd
&& (selectionStart == GetOffset(csharpCodeTextBox, node.StartLocation)
|| selectionStart == GetOffset(csharpCodeTextBox, node.EndLocation)))
{
// caret is on border of this node; don't expand
csharpTreeView.SelectedNode = t;
} else {
t.Expand();
if (!SelectCurrentNode(t.Nodes))
csharpTreeView.SelectedNode = t;
}
return true;
}
}
return false;
}
void CSharpGenerateCodeButtonClick(object sender, EventArgs e)
{
StringWriter w = new StringWriter();
OutputVisitor output = new OutputVisitor(w, new CSharpFormattingOptions());
compilationUnit.AcceptVisitor(output, null);
csharpCodeTextBox.Text = w.ToString();
}
int GetOffset(TextBox textBox, AstLocation location)
{
return textBox.GetFirstCharIndexFromLine(location.Line - 1) + location.Column - 1;
}
void CSharpTreeViewAfterSelect(object sender, TreeViewEventArgs e)
{
AstNode node = e.Node.Tag as AstNode;
if (node != null) {
int startOffset = GetOffset(csharpCodeTextBox, node.StartLocation);
int endOffset = GetOffset(csharpCodeTextBox, node.EndLocation);
csharpCodeTextBox.Select(startOffset, endOffset - startOffset);
}
}
Lazy<IList<IProjectContent>> builtInLibs = new Lazy<IList<IProjectContent>>(
delegate {
Assembly[] assemblies = {
typeof(object).Assembly, // mscorlib
typeof(Uri).Assembly, // System.dll
typeof(System.Linq.Enumerable).Assembly, // System.Core.dll
// typeof(System.Xml.XmlDocument).Assembly, // System.Xml.dll
// typeof(System.Drawing.Bitmap).Assembly, // System.Drawing.dll
// typeof(Form).Assembly, // System.Windows.Forms.dll
typeof(ICSharpCode.NRefactory.TypeSystem.IProjectContent).Assembly,
};
IProjectContent[] projectContents = new IProjectContent[assemblies.Length];
Stopwatch total = Stopwatch.StartNew();
Parallel.For(
0, assemblies.Length,
delegate (int i) {
Stopwatch w = Stopwatch.StartNew();
CecilLoader loader = new CecilLoader();
projectContents[i] = loader.LoadAssemblyFile(assemblies[i].Location);
Debug.WriteLine(Path.GetFileName(assemblies[i].Location) + ": " + w.Elapsed);
});
Debug.WriteLine("Total: " + total.Elapsed);
return projectContents;
});
void ResolveButtonClick(object sender, EventArgs e)
{
SimpleProjectContent project = new SimpleProjectContent();
TypeSystemConvertVisitor convertVisitor = new TypeSystemConvertVisitor(project, "dummy.cs");
compilationUnit.AcceptVisitor(convertVisitor, null);
project.UpdateProjectContent(null, convertVisitor.ParsedFile.TopLevelTypeDefinitions, null, null);
List<ITypeResolveContext> projects = new List<ITypeResolveContext>();
projects.Add(project);
projects.AddRange(builtInLibs.Value);
using (var context = new CompositeTypeResolveContext(projects).Synchronize()) {
CSharpResolver resolver = new CSharpResolver(context);
IResolveVisitorNavigator navigator = null;
if (csharpTreeView.SelectedNode != null) {
navigator = new NodeListResolveVisitorNavigator(new[] { (AstNode)csharpTreeView.SelectedNode.Tag });
}
ResolveVisitor visitor = new ResolveVisitor(resolver, convertVisitor.ParsedFile, navigator);
visitor.Scan(compilationUnit);
csharpTreeView.BeginUpdate();
ShowResolveResultsInTree(csharpTreeView.Nodes, visitor);
csharpTreeView.EndUpdate();
}
}
void ShowResolveResultsInTree(TreeNodeCollection c, ResolveVisitor v)
{
foreach (TreeNode t in c) {
AstNode node = t.Tag as AstNode;
if (node != null) {
ResolveResult rr = v.GetResolveResult(node);
if (rr != null)
t.Text = GetNodeTitle(node) + " " + rr.ToString();
else
t.Text = GetNodeTitle(node);
}
ShowResolveResultsInTree(t.Nodes, v);
}
}
void CSharpCodeTextBoxKeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.A) {
e.Handled = true;
csharpCodeTextBox.SelectAll();
}
}
void CsharpCodeTextBoxTextChanged(object sender, EventArgs e)
{
resolveButton.Enabled = false;
}
}
}

120
NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.resx

@ -0,0 +1,120 @@ @@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

25
NRefactory/ICSharpCode.NRefactory.Demo/ICSharpCode.NRefactory.Demo.csproj

@ -40,17 +40,9 @@ @@ -40,17 +40,9 @@
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="VBEditDialog.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="VBEditDialog.Designer.cs">
<DependentUpon>VBEditDialog.cs</DependentUpon>
</Compile>
<Compile Include="VBAstView.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="VBAstView.Designer.cs">
<DependentUpon>VBAstView.cs</DependentUpon>
<Compile Include="CSDemo.cs" />
<Compile Include="CSDemo.Designer.cs">
<DependentUpon>CSDemo.cs</DependentUpon>
</Compile>
<Compile Include="MainForm.cs">
<SubType>Form</SubType>
@ -60,9 +52,7 @@ @@ -60,9 +52,7 @@
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="VBDemo.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="VBDemo.cs" />
<Compile Include="VBDemo.Designer.cs">
<DependentUpon>VBDemo.cs</DependentUpon>
</Compile>
@ -78,11 +68,8 @@ @@ -78,11 +68,8 @@
</ProjectReference>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="VBEditDialog.resx">
<DependentUpon>VBEditDialog.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="VBAstView.resx">
<DependentUpon>VBAstView.cs</DependentUpon>
<EmbeddedResource Include="CSDemo.resx">
<DependentUpon>CSDemo.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon>

162
NRefactory/ICSharpCode.NRefactory.Demo/MainForm.Designer.cs generated

@ -30,40 +30,32 @@ namespace ICSharpCode.NRefactory.Demo @@ -30,40 +30,32 @@ namespace ICSharpCode.NRefactory.Demo
/// </summary>
private void InitializeComponent()
{
this.tabPage2 = new System.Windows.Forms.TabPage();
this.miniToolStrip = new System.Windows.Forms.ToolStrip();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.csharpCodeTextBox = new System.Windows.Forms.TextBox();
this.resolveButton = new System.Windows.Forms.Button();
this.csharpTreeView = new System.Windows.Forms.TreeView();
this.csharpGenerateCodeButton = new System.Windows.Forms.Button();
this.csharpParseButton = new System.Windows.Forms.Button();
this.csDemo1 = new ICSharpCode.NRefactory.Demo.CSDemo();
this.tabControl1 = new System.Windows.Forms.TabControl();
this.miniToolStrip = new System.Windows.Forms.ToolStrip();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.vbDemo1 = new ICSharpCode.NRefactory.Demo.VBDemo();
this.tabPage2.SuspendLayout();
this.tabPage1.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout();
this.tabControl1.SuspendLayout();
this.tabPage2.SuspendLayout();
this.SuspendLayout();
//
// tabPage2
// miniToolStrip
//
this.tabPage2.Controls.Add(this.vbDemo1);
this.tabPage2.Location = new System.Drawing.Point(4, 22);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
this.tabPage2.Size = new System.Drawing.Size(507, 458);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "VB";
this.tabPage2.UseVisualStyleBackColor = true;
this.miniToolStrip.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.miniToolStrip.AutoSize = false;
this.miniToolStrip.CanOverflow = false;
this.miniToolStrip.Dock = System.Windows.Forms.DockStyle.None;
this.miniToolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
this.miniToolStrip.Location = new System.Drawing.Point(13, 3);
this.miniToolStrip.Name = "miniToolStrip";
this.miniToolStrip.Size = new System.Drawing.Size(16, 25);
this.miniToolStrip.TabIndex = 3;
//
// tabPage1
//
this.tabPage1.Controls.Add(this.splitContainer1);
this.tabPage1.Controls.Add(this.csDemo1);
this.tabPage1.Location = new System.Drawing.Point(4, 22);
this.tabPage1.Name = "tabPage1";
this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
@ -72,90 +64,13 @@ namespace ICSharpCode.NRefactory.Demo @@ -72,90 +64,13 @@ namespace ICSharpCode.NRefactory.Demo
this.tabPage1.Text = "C#";
this.tabPage1.UseVisualStyleBackColor = true;
//
// splitContainer1
//
this.splitContainer1.Dock = System.Windows.Forms.DockStyle.Fill;
this.splitContainer1.Location = new System.Drawing.Point(3, 3);
this.splitContainer1.Name = "splitContainer1";
this.splitContainer1.Orientation = System.Windows.Forms.Orientation.Horizontal;
//
// splitContainer1.Panel1
//
this.splitContainer1.Panel1.Controls.Add(this.csharpCodeTextBox);
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.resolveButton);
this.splitContainer1.Panel2.Controls.Add(this.csharpTreeView);
this.splitContainer1.Panel2.Controls.Add(this.csharpGenerateCodeButton);
this.splitContainer1.Panel2.Controls.Add(this.csharpParseButton);
this.splitContainer1.Size = new System.Drawing.Size(501, 452);
this.splitContainer1.SplitterDistance = 201;
this.splitContainer1.TabIndex = 0;
//
// csharpCodeTextBox
// csDemo1
//
this.csharpCodeTextBox.AcceptsReturn = true;
this.csharpCodeTextBox.AcceptsTab = true;
this.csharpCodeTextBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.csharpCodeTextBox.Font = new System.Drawing.Font("Courier New", 9.75F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.csharpCodeTextBox.HideSelection = false;
this.csharpCodeTextBox.Location = new System.Drawing.Point(0, 0);
this.csharpCodeTextBox.Multiline = true;
this.csharpCodeTextBox.Name = "csharpCodeTextBox";
this.csharpCodeTextBox.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.csharpCodeTextBox.Size = new System.Drawing.Size(501, 201);
this.csharpCodeTextBox.TabIndex = 0;
this.csharpCodeTextBox.Text = "using System;\r\nclass Test\r\n{\r\n public void Main(string[] args)\r\n {\r\n " +
" Console.WriteLine(\"Hello, World\");\r\n }\r\n}";
this.csharpCodeTextBox.WordWrap = false;
this.csharpCodeTextBox.TextChanged += new System.EventHandler(this.CsharpCodeTextBoxTextChanged);
this.csharpCodeTextBox.KeyDown += new System.Windows.Forms.KeyEventHandler(this.CSharpCodeTextBoxKeyDown);
//
// resolveButton
//
this.resolveButton.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.resolveButton.Location = new System.Drawing.Point(200, 3);
this.resolveButton.Name = "resolveButton";
this.resolveButton.Size = new System.Drawing.Size(100, 23);
this.resolveButton.TabIndex = 3;
this.resolveButton.Text = "Resolve";
this.resolveButton.UseVisualStyleBackColor = true;
this.resolveButton.Click += new System.EventHandler(this.ResolveButtonClick);
//
// csharpTreeView
//
this.csharpTreeView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.csharpTreeView.HideSelection = false;
this.csharpTreeView.Location = new System.Drawing.Point(3, 32);
this.csharpTreeView.Name = "csharpTreeView";
this.csharpTreeView.Size = new System.Drawing.Size(493, 212);
this.csharpTreeView.TabIndex = 2;
this.csharpTreeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.CSharpTreeViewAfterSelect);
//
// csharpGenerateCodeButton
//
this.csharpGenerateCodeButton.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.csharpGenerateCodeButton.Location = new System.Drawing.Point(306, 2);
this.csharpGenerateCodeButton.Name = "csharpGenerateCodeButton";
this.csharpGenerateCodeButton.Size = new System.Drawing.Size(100, 23);
this.csharpGenerateCodeButton.TabIndex = 1;
this.csharpGenerateCodeButton.Text = "Generate";
this.csharpGenerateCodeButton.UseVisualStyleBackColor = true;
this.csharpGenerateCodeButton.Click += new System.EventHandler(this.CSharpGenerateCodeButtonClick);
//
// csharpParseButton
//
this.csharpParseButton.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.csharpParseButton.Location = new System.Drawing.Point(94, 3);
this.csharpParseButton.Name = "csharpParseButton";
this.csharpParseButton.Size = new System.Drawing.Size(100, 23);
this.csharpParseButton.TabIndex = 0;
this.csharpParseButton.Text = "Parse";
this.csharpParseButton.UseVisualStyleBackColor = true;
this.csharpParseButton.Click += new System.EventHandler(this.CSharpParseButtonClick);
this.csDemo1.Dock = System.Windows.Forms.DockStyle.Fill;
this.csDemo1.Location = new System.Drawing.Point(3, 3);
this.csDemo1.Name = "csDemo1";
this.csDemo1.Size = new System.Drawing.Size(501, 452);
this.csDemo1.TabIndex = 0;
//
// tabControl1
//
@ -168,17 +83,16 @@ namespace ICSharpCode.NRefactory.Demo @@ -168,17 +83,16 @@ namespace ICSharpCode.NRefactory.Demo
this.tabControl1.Size = new System.Drawing.Size(515, 484);
this.tabControl1.TabIndex = 0;
//
// miniToolStrip
// tabPage2
//
this.miniToolStrip.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.miniToolStrip.AutoSize = false;
this.miniToolStrip.CanOverflow = false;
this.miniToolStrip.Dock = System.Windows.Forms.DockStyle.None;
this.miniToolStrip.GripStyle = System.Windows.Forms.ToolStripGripStyle.Hidden;
this.miniToolStrip.Location = new System.Drawing.Point(13, 3);
this.miniToolStrip.Name = "miniToolStrip";
this.miniToolStrip.Size = new System.Drawing.Size(16, 25);
this.miniToolStrip.TabIndex = 3;
this.tabPage2.Controls.Add(this.vbDemo1);
this.tabPage2.Location = new System.Drawing.Point(4, 22);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
this.tabPage2.Size = new System.Drawing.Size(507, 458);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "VB";
this.tabPage2.UseVisualStyleBackColor = true;
//
// vbDemo1
//
@ -196,25 +110,15 @@ namespace ICSharpCode.NRefactory.Demo @@ -196,25 +110,15 @@ namespace ICSharpCode.NRefactory.Demo
this.Controls.Add(this.tabControl1);
this.Name = "MainForm";
this.Text = "NRefactory Demo";
this.tabPage2.ResumeLayout(false);
this.tabPage1.ResumeLayout(false);
this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel1.PerformLayout();
this.splitContainer1.Panel2.ResumeLayout(false);
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).EndInit();
this.splitContainer1.ResumeLayout(false);
this.tabControl1.ResumeLayout(false);
this.tabPage2.ResumeLayout(false);
this.ResumeLayout(false);
}
private ICSharpCode.NRefactory.Demo.VBDemo vbDemo1;
private System.Windows.Forms.Button resolveButton;
private System.Windows.Forms.ToolStrip miniToolStrip;
private System.Windows.Forms.TreeView csharpTreeView;
private System.Windows.Forms.Button csharpParseButton;
private System.Windows.Forms.Button csharpGenerateCodeButton;
private System.Windows.Forms.TextBox csharpCodeTextBox;
private System.Windows.Forms.SplitContainer splitContainer1;
private System.Windows.Forms.TabPage tabPage2;
private ICSharpCode.NRefactory.Demo.CSDemo csDemo1;
private System.Windows.Forms.ToolStrip miniToolStrip;
private System.Windows.Forms.TabPage tabPage1;
private System.Windows.Forms.TabControl tabControl1;
}

194
NRefactory/ICSharpCode.NRefactory.Demo/MainForm.cs

@ -29,200 +29,6 @@ namespace ICSharpCode.NRefactory.Demo @@ -29,200 +29,6 @@ namespace ICSharpCode.NRefactory.Demo
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
csharpCodeTextBox.SelectAll();
CSharpParseButtonClick(null, null);
resolveButton.UseWaitCursor = true;
ThreadPool.QueueUserWorkItem(
delegate {
builtInLibs.Value.ToString();
BeginInvoke(new Action(delegate { resolveButton.UseWaitCursor = false; }));
});
}
CompilationUnit compilationUnit;
void CSharpParseButtonClick(object sender, EventArgs e)
{
CSharpParser parser = new CSharpParser();
compilationUnit = parser.Parse(new StringReader(csharpCodeTextBox.Text));
csharpTreeView.Nodes.Clear();
foreach (var element in compilationUnit.Children) {
csharpTreeView.Nodes.Add(MakeTreeNode(element));
}
SelectCurrentNode(csharpTreeView.Nodes);
resolveButton.Enabled = true;
}
TreeNode MakeTreeNode(AstNode node)
{
TreeNode t = new TreeNode(GetNodeTitle(node));
t.Tag = node;
foreach (AstNode child in node.Children) {
t.Nodes.Add(MakeTreeNode(child));
}
return t;
}
string GetNodeTitle(AstNode node)
{
StringBuilder b = new StringBuilder();
b.Append(node.Role.ToString());
b.Append(": ");
b.Append(node.GetType().Name);
bool hasProperties = false;
foreach (PropertyInfo p in node.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
if (p.Name == "NodeType" || p.Name == "IsNull")
continue;
if (p.PropertyType == typeof(string) || p.PropertyType.IsEnum || p.PropertyType == typeof(bool)) {
if (!hasProperties) {
hasProperties = true;
b.Append(" (");
} else {
b.Append(", ");
}
b.Append(p.Name);
b.Append(" = ");
try {
object val = p.GetValue(node, null);
b.Append(val != null ? val.ToString() : "**null**");
} catch (TargetInvocationException ex) {
b.Append("**" + ex.InnerException.GetType().Name + "**");
}
}
}
if (hasProperties)
b.Append(")");
return b.ToString();
}
bool SelectCurrentNode(TreeNodeCollection c)
{
int selectionStart = csharpCodeTextBox.SelectionStart;
int selectionEnd = selectionStart + csharpCodeTextBox.SelectionLength;
foreach (TreeNode t in c) {
AstNode node = t.Tag as AstNode;
if (node != null
&& selectionStart >= GetOffset(csharpCodeTextBox, node.StartLocation)
&& selectionEnd <= GetOffset(csharpCodeTextBox, node.EndLocation))
{
if (selectionStart == selectionEnd
&& (selectionStart == GetOffset(csharpCodeTextBox, node.StartLocation)
|| selectionStart == GetOffset(csharpCodeTextBox, node.EndLocation)))
{
// caret is on border of this node; don't expand
csharpTreeView.SelectedNode = t;
} else {
t.Expand();
if (!SelectCurrentNode(t.Nodes))
csharpTreeView.SelectedNode = t;
}
return true;
}
}
return false;
}
void CSharpGenerateCodeButtonClick(object sender, EventArgs e)
{
StringWriter w = new StringWriter();
OutputVisitor output = new OutputVisitor(w, new CSharpFormattingOptions());
compilationUnit.AcceptVisitor(output, null);
csharpCodeTextBox.Text = w.ToString();
}
int GetOffset(TextBox textBox, AstLocation location)
{
return textBox.GetFirstCharIndexFromLine(location.Line - 1) + location.Column - 1;
}
void CSharpTreeViewAfterSelect(object sender, TreeViewEventArgs e)
{
AstNode node = e.Node.Tag as AstNode;
if (node != null) {
int startOffset = GetOffset(csharpCodeTextBox, node.StartLocation);
int endOffset = GetOffset(csharpCodeTextBox, node.EndLocation);
csharpCodeTextBox.Select(startOffset, endOffset - startOffset);
}
}
Lazy<IList<IProjectContent>> builtInLibs = new Lazy<IList<IProjectContent>>(
delegate {
Assembly[] assemblies = {
typeof(object).Assembly, // mscorlib
typeof(Uri).Assembly, // System.dll
typeof(System.Linq.Enumerable).Assembly, // System.Core.dll
// typeof(System.Xml.XmlDocument).Assembly, // System.Xml.dll
// typeof(System.Drawing.Bitmap).Assembly, // System.Drawing.dll
// typeof(Form).Assembly, // System.Windows.Forms.dll
typeof(ICSharpCode.NRefactory.TypeSystem.IProjectContent).Assembly,
};
IProjectContent[] projectContents = new IProjectContent[assemblies.Length];
Stopwatch total = Stopwatch.StartNew();
Parallel.For(
0, assemblies.Length,
delegate (int i) {
Stopwatch w = Stopwatch.StartNew();
CecilLoader loader = new CecilLoader();
projectContents[i] = loader.LoadAssemblyFile(assemblies[i].Location);
Debug.WriteLine(Path.GetFileName(assemblies[i].Location) + ": " + w.Elapsed);
});
Debug.WriteLine("Total: " + total.Elapsed);
return projectContents;
});
void ResolveButtonClick(object sender, EventArgs e)
{
SimpleProjectContent project = new SimpleProjectContent();
TypeSystemConvertVisitor convertVisitor = new TypeSystemConvertVisitor(project, "dummy.cs");
compilationUnit.AcceptVisitor(convertVisitor, null);
project.UpdateProjectContent(null, convertVisitor.ParsedFile.TopLevelTypeDefinitions, null, null);
List<ITypeResolveContext> projects = new List<ITypeResolveContext>();
projects.Add(project);
projects.AddRange(builtInLibs.Value);
using (var context = new CompositeTypeResolveContext(projects).Synchronize()) {
CSharpResolver resolver = new CSharpResolver(context);
IResolveVisitorNavigator navigator = null;
if (csharpTreeView.SelectedNode != null) {
navigator = new NodeListResolveVisitorNavigator(new[] { (AstNode)csharpTreeView.SelectedNode.Tag });
}
ResolveVisitor visitor = new ResolveVisitor(resolver, convertVisitor.ParsedFile, navigator);
visitor.Scan(compilationUnit);
csharpTreeView.BeginUpdate();
ShowResolveResultsInTree(csharpTreeView.Nodes, visitor);
csharpTreeView.EndUpdate();
}
}
void ShowResolveResultsInTree(TreeNodeCollection c, ResolveVisitor v)
{
foreach (TreeNode t in c) {
AstNode node = t.Tag as AstNode;
if (node != null) {
ResolveResult rr = v.GetResolveResult(node);
if (rr != null)
t.Text = GetNodeTitle(node) + " " + rr.ToString();
else
t.Text = GetNodeTitle(node);
}
ShowResolveResultsInTree(t.Nodes, v);
}
}
void CSharpCodeTextBoxKeyDown(object sender, KeyEventArgs e)
{
if (e.Control && e.KeyCode == Keys.A) {
e.Handled = true;
csharpCodeTextBox.SelectAll();
}
}
void CsharpCodeTextBoxTextChanged(object sender, EventArgs e)
{
resolveButton.Enabled = false;
}
}
}

172
NRefactory/ICSharpCode.NRefactory.Demo/VBAstView.cs

@ -39,89 +39,89 @@ namespace ICSharpCode.NRefactory.Demo @@ -39,89 +39,89 @@ namespace ICSharpCode.NRefactory.Demo
InitializeComponent();
}
public void DeleteSelectedNode()
{
if (tree.SelectedNode is ElementNode) {
INode element = (tree.SelectedNode as ElementNode).element;
if (tree.SelectedNode.Parent is CollectionNode) {
if (MessageBox.Show("Remove selected node from parent collection?", "Remove node", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
== DialogResult.Yes)
{
IList col = (tree.SelectedNode.Parent as CollectionNode).collection;
col.Remove(element);
(tree.SelectedNode.Parent as CollectionNode).Update();
}
} else if (tree.SelectedNode.Parent is ElementNode) {
if (MessageBox.Show("Set selected property to null?", "Remove node", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
== DialogResult.Yes)
{
// get parent element
element = (tree.SelectedNode.Parent as ElementNode).element;
string propertyName = (string)tree.SelectedNode.Tag;
element.GetType().GetProperty(propertyName).SetValue(element, null, null);
(tree.SelectedNode.Parent as ElementNode).Update();
}
}
} else if (tree.SelectedNode is CollectionNode) {
if (MessageBox.Show("Remove all elements from selected collection?", "Clear collection", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
== DialogResult.Yes)
{
IList col = (tree.SelectedNode as CollectionNode).collection;
col.Clear();
(tree.SelectedNode as CollectionNode).Update();
}
}
}
public void EditSelectedNode()
{
TreeNode node = tree.SelectedNode;
while (!(node is ElementNode)) {
if (node == null) {
return;
}
node = node.Parent;
}
INode element = ((ElementNode)node).element;
using (VBEditDialog dlg = new VBEditDialog(element)) {
dlg.ShowDialog();
}
((ElementNode)node).Update();
}
public void ApplyTransformation(IAstVisitor visitor)
{
if (tree.SelectedNode == tree.Nodes[0]) {
unit.AcceptVisitor(visitor, null);
UpdateTree();
} else {
string name = visitor.GetType().Name;
ElementNode elementNode = tree.SelectedNode as ElementNode;
CollectionNode collectionNode = tree.SelectedNode as CollectionNode;
if (elementNode != null) {
if (MessageBox.Show(("Apply " + name + " to selected element '" + elementNode.Text + "'?"),
"Apply transformation", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
== DialogResult.Yes)
{
elementNode.element.AcceptVisitor(visitor, null);
elementNode.Update();
}
} else if (collectionNode != null) {
if (MessageBox.Show(("Apply " + name + " to all elements in selected collection '" + collectionNode.Text + "'?"),
"Apply transformation", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
== DialogResult.Yes)
{
foreach (TreeNode subNode in collectionNode.Nodes) {
if (subNode is ElementNode) {
(subNode as ElementNode).element.AcceptVisitor(visitor, null);
}
}
collectionNode.Update();
}
}
}
}
// public void DeleteSelectedNode()
// {
// if (tree.SelectedNode is ElementNode) {
// INode element = (tree.SelectedNode as ElementNode).element;
// if (tree.SelectedNode.Parent is CollectionNode) {
// if (MessageBox.Show("Remove selected node from parent collection?", "Remove node", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
// == DialogResult.Yes)
// {
// IList col = (tree.SelectedNode.Parent as CollectionNode).collection;
// col.Remove(element);
// (tree.SelectedNode.Parent as CollectionNode).Update();
// }
// } else if (tree.SelectedNode.Parent is ElementNode) {
// if (MessageBox.Show("Set selected property to null?", "Remove node", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
// == DialogResult.Yes)
// {
// // get parent element
// element = (tree.SelectedNode.Parent as ElementNode).element;
// string propertyName = (string)tree.SelectedNode.Tag;
// element.GetType().GetProperty(propertyName).SetValue(element, null, null);
// (tree.SelectedNode.Parent as ElementNode).Update();
// }
// }
// } else if (tree.SelectedNode is CollectionNode) {
// if (MessageBox.Show("Remove all elements from selected collection?", "Clear collection", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
// == DialogResult.Yes)
// {
// IList col = (tree.SelectedNode as CollectionNode).collection;
// col.Clear();
// (tree.SelectedNode as CollectionNode).Update();
// }
// }
// }
//
// public void EditSelectedNode()
// {
// TreeNode node = tree.SelectedNode;
// while (!(node is ElementNode)) {
// if (node == null) {
// return;
// }
// node = node.Parent;
// }
// INode element = ((ElementNode)node).element;
// using (VBEditDialog dlg = new VBEditDialog(element)) {
// dlg.ShowDialog();
// }
// ((ElementNode)node).Update();
// }
//
// public void ApplyTransformation(IAstVisitor visitor)
// {
// if (tree.SelectedNode == tree.Nodes[0]) {
// unit.AcceptVisitor(visitor, null);
// UpdateTree();
// } else {
// string name = visitor.GetType().Name;
// ElementNode elementNode = tree.SelectedNode as ElementNode;
// CollectionNode collectionNode = tree.SelectedNode as CollectionNode;
// if (elementNode != null) {
// if (MessageBox.Show(("Apply " + name + " to selected element '" + elementNode.Text + "'?"),
// "Apply transformation", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
// == DialogResult.Yes)
// {
// elementNode.element.AcceptVisitor(visitor, null);
// elementNode.Update();
// }
// } else if (collectionNode != null) {
// if (MessageBox.Show(("Apply " + name + " to all elements in selected collection '" + collectionNode.Text + "'?"),
// "Apply transformation", MessageBoxButtons.YesNo, MessageBoxIcon.Question)
// == DialogResult.Yes)
// {
// foreach (TreeNode subNode in collectionNode.Nodes) {
// if (subNode is ElementNode) {
// (subNode as ElementNode).element.AcceptVisitor(visitor, null);
// }
// }
// collectionNode.Update();
// }
// }
// }
// }
//
static TreeNode CreateNode(object child)
{
if (child == null) {
@ -164,9 +164,9 @@ namespace ICSharpCode.NRefactory.Demo @@ -164,9 +164,9 @@ namespace ICSharpCode.NRefactory.Demo
class ElementNode : TreeNode
{
internal INode element;
internal AstNode element;
public ElementNode(INode node)
public ElementNode(AstNode node)
{
this.element = node;
Update();
@ -188,7 +188,7 @@ namespace ICSharpCode.NRefactory.Demo @@ -188,7 +188,7 @@ namespace ICSharpCode.NRefactory.Demo
}
}
void AddProperties(Type type, INode node)
void AddProperties(Type type, AstNode node)
{
if (type == typeof(AbstractNode))
return;

67
NRefactory/ICSharpCode.NRefactory.Demo/VBDemo.Designer.cs generated

@ -33,11 +33,9 @@ namespace ICSharpCode.NRefactory.Demo @@ -33,11 +33,9 @@ namespace ICSharpCode.NRefactory.Demo
{
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.codeView = new System.Windows.Forms.TextBox();
this.editNodeButton = new System.Windows.Forms.Button();
this.clearSpecialsButton = new System.Windows.Forms.Button();
this.syntaxTree = new ICSharpCode.NRefactory.Demo.VBAstView();
this.generateCodeButton = new System.Windows.Forms.Button();
this.parseButton = new System.Windows.Forms.Button();
this.treeView = new System.Windows.Forms.TreeView();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
@ -57,11 +55,9 @@ namespace ICSharpCode.NRefactory.Demo @@ -57,11 +55,9 @@ namespace ICSharpCode.NRefactory.Demo
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.editNodeButton);
this.splitContainer1.Panel2.Controls.Add(this.clearSpecialsButton);
this.splitContainer1.Panel2.Controls.Add(this.syntaxTree);
this.splitContainer1.Panel2.Controls.Add(this.generateCodeButton);
this.splitContainer1.Panel2.Controls.Add(this.parseButton);
this.splitContainer1.Panel2.Controls.Add(this.treeView);
this.splitContainer1.Size = new System.Drawing.Size(462, 391);
this.splitContainer1.SplitterDistance = 173;
this.splitContainer1.TabIndex = 1;
@ -79,64 +75,41 @@ namespace ICSharpCode.NRefactory.Demo @@ -79,64 +75,41 @@ namespace ICSharpCode.NRefactory.Demo
this.codeView.ScrollBars = System.Windows.Forms.ScrollBars.Both;
this.codeView.Size = new System.Drawing.Size(462, 173);
this.codeView.TabIndex = 0;
this.codeView.Text = "Imports System\r\nClass Test\r\n Public Sub Main(ByVal args As String())\r\n " +
" Console.WriteLine(\"Hello, World\")\r\n End Sub\r\nEnd Class";
this.codeView.Text = "Option Explicit";
this.codeView.WordWrap = false;
//
// editNodeButton
//
this.editNodeButton.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.editNodeButton.Location = new System.Drawing.Point(331, 2);
this.editNodeButton.Name = "editNodeButton";
this.editNodeButton.Size = new System.Drawing.Size(100, 23);
this.editNodeButton.TabIndex = 4;
this.editNodeButton.Text = "Edit node";
this.editNodeButton.UseVisualStyleBackColor = true;
this.editNodeButton.Click += new System.EventHandler(this.EditNodeButtonClick);
//
// clearSpecialsButton
//
this.clearSpecialsButton.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.clearSpecialsButton.Location = new System.Drawing.Point(225, 2);
this.clearSpecialsButton.Name = "clearSpecialsButton";
this.clearSpecialsButton.Size = new System.Drawing.Size(100, 23);
this.clearSpecialsButton.TabIndex = 3;
this.clearSpecialsButton.Text = "Clear 0 specials";
this.clearSpecialsButton.UseVisualStyleBackColor = true;
this.clearSpecialsButton.Click += new System.EventHandler(this.ClearSpecialsButtonClick);
//
// syntaxTree
//
this.syntaxTree.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.syntaxTree.Location = new System.Drawing.Point(3, 32);
this.syntaxTree.Name = "syntaxTree";
this.syntaxTree.Size = new System.Drawing.Size(459, 182);
this.syntaxTree.TabIndex = 2;
this.syntaxTree.Unit = null;
//
// generateCodeButton
//
this.generateCodeButton.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.generateCodeButton.Location = new System.Drawing.Point(119, 2);
this.generateCodeButton.Location = new System.Drawing.Point(225, 2);
this.generateCodeButton.Name = "generateCodeButton";
this.generateCodeButton.Size = new System.Drawing.Size(100, 23);
this.generateCodeButton.TabIndex = 1;
this.generateCodeButton.Text = "Generate";
this.generateCodeButton.UseVisualStyleBackColor = true;
this.generateCodeButton.Click += new System.EventHandler(this.GenerateCodeButtonClick);
this.generateCodeButton.Click += new System.EventHandler(this.CSharpGenerateCodeButtonClick);
//
// parseButton
//
this.parseButton.Anchor = System.Windows.Forms.AnchorStyles.Top;
this.parseButton.Location = new System.Drawing.Point(13, 2);
this.parseButton.Location = new System.Drawing.Point(119, 2);
this.parseButton.Name = "parseButton";
this.parseButton.Size = new System.Drawing.Size(100, 23);
this.parseButton.TabIndex = 0;
this.parseButton.Text = "Parse";
this.parseButton.UseVisualStyleBackColor = true;
this.parseButton.Click += new System.EventHandler(this.ParseButtonClick);
this.parseButton.Click += new System.EventHandler(this.CSharpParseButtonClick);
//
// treeView
//
this.treeView.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.treeView.Location = new System.Drawing.Point(3, 31);
this.treeView.Name = "treeView";
this.treeView.Size = new System.Drawing.Size(459, 180);
this.treeView.TabIndex = 0;
this.treeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.CSharpTreeViewAfterSelect);
//
// VBDemo
//
@ -152,10 +125,8 @@ namespace ICSharpCode.NRefactory.Demo @@ -152,10 +125,8 @@ namespace ICSharpCode.NRefactory.Demo
this.splitContainer1.ResumeLayout(false);
this.ResumeLayout(false);
}
private System.Windows.Forms.Button clearSpecialsButton;
private System.Windows.Forms.Button editNodeButton;
private ICSharpCode.NRefactory.Demo.VBAstView syntaxTree;
private System.Windows.Forms.TextBox codeView;
private System.Windows.Forms.TreeView treeView;
private System.Windows.Forms.Button generateCodeButton;
private System.Windows.Forms.Button parseButton;
private System.Windows.Forms.SplitContainer splitContainer1;

120
NRefactory/ICSharpCode.NRefactory.Demo/VBDemo.cs

@ -7,10 +7,13 @@ using System.ComponentModel; @@ -7,10 +7,13 @@ using System.ComponentModel;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Windows.Forms;
using ICSharpCode.NRefactory.VB;
using ICSharpCode.NRefactory.VB.Ast;
using ICSharpCode.NRefactory.VB.Parser;
using ICSharpCode.NRefactory.VB.PrettyPrinter;
namespace ICSharpCode.NRefactory.Demo
{
@ -25,54 +28,113 @@ namespace ICSharpCode.NRefactory.Demo @@ -25,54 +28,113 @@ namespace ICSharpCode.NRefactory.Demo
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
ParseButtonClick(null, null);
}
IList<ISpecial> savedSpecials;
CompilationUnit compilationUnit;
void CSharpParseButtonClick(object sender, EventArgs e)
{
var parser = new VBParser();
compilationUnit = parser.Parse(new StringReader(codeView.Text));
if (parser.HasErrors)
MessageBox.Show(parser.Errors.ErrorOutput);
treeView.Nodes.Clear();
foreach (var element in compilationUnit.Children) {
treeView.Nodes.Add(MakeTreeNode(element));
}
SelectCurrentNode(treeView.Nodes);
}
TreeNode MakeTreeNode(AstNode node)
{
TreeNode t = new TreeNode(GetNodeTitle(node));
t.Tag = node;
foreach (AstNode child in node.Children) {
t.Nodes.Add(MakeTreeNode(child));
}
return t;
}
void ParseButtonClick(object sender, EventArgs e)
string GetNodeTitle(AstNode node)
{
using (VBParser parser = new VBParser(new VBLexer(new StringReader(codeView.Text)))) {
parser.Parse();
// this allows retrieving comments, preprocessor directives, etc. (stuff that isn't part of the syntax)
SetSpecials(parser.Lexer.SpecialTracker.RetrieveSpecials());
// this retrieves the root node of the result DOM
if (parser.Errors.Count > 0) {
MessageBox.Show(parser.Errors.ErrorOutput);
StringBuilder b = new StringBuilder();
b.Append(node.Role.ToString());
b.Append(": ");
b.Append(node.GetType().Name);
bool hasProperties = false;
foreach (PropertyInfo p in node.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance)) {
if (p.Name == "NodeType" || p.Name == "IsNull")
continue;
if (p.PropertyType == typeof(string) || p.PropertyType.IsEnum || p.PropertyType == typeof(bool)) {
if (!hasProperties) {
hasProperties = true;
b.Append(" (");
} else {
b.Append(", ");
}
b.Append(p.Name);
b.Append(" = ");
try {
object val = p.GetValue(node, null);
b.Append(val != null ? val.ToString() : "**null**");
} catch (TargetInvocationException ex) {
b.Append("**" + ex.InnerException.GetType().Name + "**");
}
}
syntaxTree.Unit = parser.CompilationUnit;
}
if (hasProperties)
b.Append(")");
return b.ToString();
}
void GenerateCodeButtonClick(object sender, EventArgs e)
bool SelectCurrentNode(TreeNodeCollection c)
{
if (syntaxTree.Unit != null) {
VBNetOutputVisitor visitor = new VBNetOutputVisitor();
// re-insert the comments we saved from the parser into the output
using (SpecialNodesInserter.Install(savedSpecials, visitor)) {
syntaxTree.Unit.AcceptVisitor(visitor, null);
int selectionStart = codeView.SelectionStart;
int selectionEnd = selectionStart + codeView.SelectionLength;
foreach (TreeNode t in c) {
AstNode node = t.Tag as AstNode;
if (node != null
&& selectionStart >= GetOffset(codeView, node.StartLocation)
&& selectionEnd <= GetOffset(codeView, node.EndLocation))
{
if (selectionStart == selectionEnd
&& (selectionStart == GetOffset(codeView, node.StartLocation)
|| selectionStart == GetOffset(codeView, node.EndLocation)))
{
// caret is on border of this node; don't expand
treeView.SelectedNode = t;
} else {
t.Expand();
if (!SelectCurrentNode(t.Nodes))
treeView.SelectedNode = t;
}
return true;
}
codeView.Text = visitor.Text.Replace("\t", " ");
}
return false;
}
void ClearSpecialsButtonClick(object sender, EventArgs e)
void CSharpGenerateCodeButtonClick(object sender, EventArgs e)
{
SetSpecials(new ISpecial[0]);
StringWriter w = new StringWriter();
OutputVisitor output = new OutputVisitor(w, new VBFormattingOptions());
compilationUnit.AcceptVisitor(output, null);
codeView.Text = w.ToString();
}
void EditNodeButtonClick(object sender, EventArgs e)
int GetOffset(TextBox textBox, AstLocation location)
{
syntaxTree.EditSelectedNode();
return textBox.GetFirstCharIndexFromLine(location.Line - 1) + location.Column - 1;
}
void SetSpecials(IList<ISpecial> specials)
void CSharpTreeViewAfterSelect(object sender, TreeViewEventArgs e)
{
savedSpecials = specials;
if (specials.Count == 1)
clearSpecialsButton.Text = "Clear 1 special";
else
clearSpecialsButton.Text = "Clear " + specials.Count + " specials";
AstNode node = e.Node.Tag as AstNode;
if (node != null) {
int startOffset = GetOffset(codeView, node.StartLocation);
int endOffset = GetOffset(codeView, node.EndLocation);
codeView.Select(startOffset, endOffset - startOffset);
}
}
}
}

85
NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ConditionalOperatorTests.cs

@ -0,0 +1,85 @@ @@ -0,0 +1,85 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using System.Collections.Generic;
using NUnit.Framework;
namespace ICSharpCode.NRefactory.CSharp.Resolver
{
// assign short name to the fake reflection type
using dynamic = ICSharpCode.NRefactory.TypeSystem.ReflectionHelper.Dynamic;
[TestFixture]
public class ConditionalOperatorTests : ResolverTestBase
{
[Test]
public void PickMoreGeneralOfTheTypes()
{
AssertType(typeof(object), resolver.ResolveConditional(
MakeResult(typeof(bool)), MakeResult(typeof(string)), MakeResult(typeof(object))));
AssertType(typeof(long), resolver.ResolveConditional(
MakeResult(typeof(bool)), MakeResult(typeof(int)), MakeResult(typeof(long))));
}
[Test]
public void Null()
{
AssertType(typeof(string), resolver.ResolveConditional(
MakeResult(typeof(bool)), MakeResult(typeof(string)), MakeConstant(null)));
AssertType(typeof(string), resolver.ResolveConditional(
MakeResult(typeof(bool)), MakeConstant(null), MakeResult(typeof(string))));
}
[Test]
public void DynamicInArguments()
{
AssertType(typeof(dynamic), resolver.ResolveConditional(
MakeResult(typeof(bool)), MakeResult(typeof(dynamic)), MakeResult(typeof(double))));
AssertType(typeof(dynamic), resolver.ResolveConditional(
MakeResult(typeof(bool)), MakeResult(typeof(double)), MakeResult(typeof(dynamic))));
}
[Test]
public void DynamicInCondition()
{
AssertType(typeof(double), resolver.ResolveConditional(
MakeResult(typeof(dynamic)), MakeResult(typeof(float)), MakeResult(typeof(double))));
}
[Test]
public void AllDynamic()
{
AssertType(typeof(dynamic), resolver.ResolveConditional(
MakeResult(typeof(dynamic)), MakeResult(typeof(dynamic)), MakeResult(typeof(dynamic))));
}
[Test]
public void ListOfDynamicAndListOfObject()
{
AssertError(typeof(List<dynamic>), resolver.ResolveConditional(
MakeResult(typeof(bool)), MakeResult(typeof(List<object>)), MakeResult(typeof(List<dynamic>))));
AssertError(typeof(List<object>), resolver.ResolveConditional(
MakeResult(typeof(bool)), MakeResult(typeof(List<dynamic>)), MakeResult(typeof(List<object>))));
}
[Test]
public void Constant()
{
AssertConstant(1L, resolver.ResolveConditional(
MakeConstant(true), MakeConstant(1), MakeConstant(2L)));
AssertConstant(2L, resolver.ResolveConditional(
MakeConstant(false), MakeConstant(1), MakeConstant(2L)));
}
[Test]
public void NotConstantIfFalsePortionNotConstant()
{
AssertType(typeof(long), resolver.ResolveConditional(
MakeConstant(true), MakeConstant(1), MakeResult(typeof(long))));
}
}
}

2
NRefactory/ICSharpCode.NRefactory.Tests/ICSharpCode.NRefactory.Tests.csproj

@ -120,6 +120,7 @@ @@ -120,6 +120,7 @@
<Compile Include="CSharp\Resolver\AttributeTests.cs" />
<Compile Include="CSharp\Resolver\BinaryOperatorTests.cs" />
<Compile Include="CSharp\Resolver\CastTests.cs" />
<Compile Include="CSharp\Resolver\ConditionalOperatorTests.cs" />
<Compile Include="CSharp\Resolver\ExtensionMethodTests.cs" />
<Compile Include="CSharp\Resolver\InvocationTests.cs" />
<Compile Include="CSharp\Resolver\LambdaTests.cs" />
@ -143,6 +144,7 @@ @@ -143,6 +144,7 @@
<Compile Include="TypeSystem\GetAllBaseTypesTest.cs" />
<Compile Include="TypeSystem\GetMembersTests.cs" />
<Compile Include="TypeSystem\ReflectionHelperTests.cs" />
<Compile Include="TypeSystem\StructureTests.cs" />
<Compile Include="TypeSystem\TestInterningProvider.cs" />
<Compile Include="TypeSystem\TypeSystemTests.cs" />
<Compile Include="TypeSystem\TypeSystemTests.TestCase.cs" />

22
NRefactory/ICSharpCode.NRefactory.Tests/TypeSystem/StructureTests.cs

@ -0,0 +1,22 @@ @@ -0,0 +1,22 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using NUnit.Framework;
namespace ICSharpCode.NRefactory.TypeSystem
{
[TestFixture]
public class StructureTests
{
[Test]
public void ClasesThatSupportInterningAreSealed()
{
foreach (Type type in typeof(ISupportsInterning).Assembly.GetTypes()) {
if (typeof(ISupportsInterning).IsAssignableFrom(type) && !type.IsInterface) {
Assert.IsTrue(type.IsSealed, type.FullName);
}
}
}
}
}

2
NRefactory/ICSharpCode.NRefactory.Tests/TypeSystem/TestInterningProvider.cs

@ -15,7 +15,7 @@ using NUnit.Framework; @@ -15,7 +15,7 @@ using NUnit.Framework;
namespace ICSharpCode.NRefactory.TypeSystem
{
//* Not a real unit test
/* Not a real unit test
[TestFixture]
public class TestInterningProvider
{

26
NRefactory/ICSharpCode.NRefactory.Tests/TypeSystem/TypeSystemTests.cs

@ -114,16 +114,17 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -114,16 +114,17 @@ namespace ICSharpCode.NRefactory.TypeSystem
{
var attributes = testCasePC.AssemblyAttributes;
var typeTest = attributes.First(a => a.AttributeType.Resolve(ctx).FullName == typeof(TypeTestAttribute).FullName);
Assert.AreEqual(3, typeTest.PositionalArguments.Count);
var posArgs = typeTest.GetPositionalArguments(ctx);
Assert.AreEqual(3, posArgs.Count);
// first argument is (int)42
Assert.AreEqual(42, (int)typeTest.PositionalArguments[0].GetValue(ctx));
Assert.AreEqual(42, (int)posArgs[0].GetValue(ctx));
// second argument is typeof(System.Action<>)
IType rt = (IType)typeTest.PositionalArguments[1].GetValue(ctx);
IType rt = (IType)posArgs[1].GetValue(ctx);
Assert.IsFalse(rt is ParameterizedType); // rt must not be constructed - it's just an unbound type
Assert.AreEqual("System.Action", rt.FullName);
Assert.AreEqual(1, rt.TypeParameterCount);
// third argument is typeof(IDictionary<string, IList<TestAttribute>>)
ParameterizedType crt = (ParameterizedType)typeTest.PositionalArguments[2].GetValue(ctx);
ParameterizedType crt = (ParameterizedType)posArgs[2].GetValue(ctx);
Assert.AreEqual("System.Collections.Generic.IDictionary", crt.FullName);
Assert.AreEqual("System.String", crt.TypeArguments[0].FullName);
// ? for NUnit.TestAttribute (because that assembly isn't in ctx)
@ -282,16 +283,17 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -282,16 +283,17 @@ namespace ICSharpCode.NRefactory.TypeSystem
{
IAttribute attr = ctx.GetClass(typeof(ExplicitFieldLayoutStruct)).Attributes.Single();
Assert.AreEqual("System.Runtime.InteropServices.StructLayoutAttribute", attr.AttributeType.Resolve(ctx).FullName);
IConstantValue arg1 = attr.PositionalArguments.Single();
IConstantValue arg1 = attr.GetPositionalArguments(ctx).Single();
Assert.AreEqual("System.Runtime.InteropServices.LayoutKind", arg1.GetValueType(ctx).FullName);
Assert.AreEqual((int)LayoutKind.Explicit, arg1.GetValue(ctx));
var arg2 = attr.NamedArguments[0];
var namedArgs = attr.GetNamedArguments(ctx);
var arg2 = namedArgs[0];
Assert.AreEqual("CharSet", arg2.Key);
Assert.AreEqual("System.Runtime.InteropServices.CharSet", arg2.Value.GetValueType(ctx).FullName);
Assert.AreEqual((int)CharSet.Unicode, arg2.Value.GetValue(ctx));
var arg3 = attr.NamedArguments[1];
var arg3 = namedArgs[1];
Assert.AreEqual("Pack", arg3.Key);
Assert.AreEqual("System.Int32", arg3.Value.GetValueType(ctx).FullName);
Assert.AreEqual(8, arg3.Value.GetValue(ctx));
@ -302,13 +304,13 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -302,13 +304,13 @@ namespace ICSharpCode.NRefactory.TypeSystem
{
IField field = ctx.GetClass(typeof(ExplicitFieldLayoutStruct)).Fields.Single(f => f.Name == "Field0");
Assert.AreEqual("System.Runtime.InteropServices.FieldOffsetAttribute", field.Attributes.Single().AttributeType.Resolve(ctx).FullName);
IConstantValue arg = field.Attributes.Single().PositionalArguments.Single();
IConstantValue arg = field.Attributes.Single().GetPositionalArguments(ctx).Single();
Assert.AreEqual("System.Int32", arg.GetValueType(ctx).FullName);
Assert.AreEqual(0, arg.GetValue(ctx));
field = ctx.GetClass(typeof(ExplicitFieldLayoutStruct)).Fields.Single(f => f.Name == "Field100");
Assert.AreEqual("System.Runtime.InteropServices.FieldOffsetAttribute", field.Attributes.Single().AttributeType.Resolve(ctx).FullName);
arg = field.Attributes.Single().PositionalArguments.Single();
arg = field.Attributes.Single().GetPositionalArguments(ctx).Single();
Assert.AreEqual("System.Int32", arg.GetValueType(ctx).FullName);
Assert.AreEqual(100, arg.GetValue(ctx));
}
@ -319,8 +321,8 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -319,8 +321,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
IMethod method = ctx.GetClass(typeof(NonCustomAttributes)).Methods.Single(m => m.Name == "DllMethod");
IAttribute dllImport = method.Attributes.Single();
Assert.AreEqual("System.Runtime.InteropServices.DllImportAttribute", dllImport.AttributeType.Resolve(ctx).FullName);
Assert.AreEqual("unmanaged.dll", dllImport.PositionalArguments[0].GetValue(ctx));
Assert.AreEqual((int)CharSet.Unicode, dllImport.NamedArguments.Single().Value.GetValue(ctx));
Assert.AreEqual("unmanaged.dll", dllImport.GetPositionalArguments(ctx)[0].GetValue(ctx));
Assert.AreEqual((int)CharSet.Unicode, dllImport.GetNamedArguments(ctx).Single().Value.GetValue(ctx));
}
[Test]
@ -339,7 +341,7 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -339,7 +341,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
{
IMethod method = ctx.GetClass(typeof(NonCustomAttributes)).Methods.Single(m => m.Name == "DllMethod");
IAttribute marshalAs = method.ReturnTypeAttributes.Single();
Assert.AreEqual((int)UnmanagedType.Bool, marshalAs.PositionalArguments.Single().GetValue(ctx));
Assert.AreEqual((int)UnmanagedType.Bool, marshalAs.GetPositionalArguments(ctx).Single().GetValue(ctx));
}
[Test]

149
NRefactory/ICSharpCode.NRefactory.VB.Tests/General/UnitTest.cs

@ -6,44 +6,43 @@ using System.Reflection; @@ -6,44 +6,43 @@ using System.Reflection;
using NUnit.Framework;
using ICSharpCode.NRefactory.VB.Ast;
using ICSharpCode.NRefactory.VB.Parser;
using ICSharpCode.NRefactory.VB.Visitors;
namespace ICSharpCode.NRefactory.VB.Tests
{
[TestFixture]
public class StructuralTest
{
[Test]
public void TestToStringMethods()
{
Type[] allTypes = typeof(INode).Assembly.GetTypes();
foreach (Type type in allTypes) {
if (type.IsClass && !type.IsAbstract && !type.IsNested && type.GetInterface(typeof(INode).FullName) != null) {
MethodInfo methodInfo = type.GetMethod("ToString", BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public);
Assert.IsNotNull(methodInfo, "ToString() not found in " + type.FullName);
}
}
}
[Test]
public void TestUnitTests()
{
Type[] allTypes = typeof(StructuralTest).Assembly.GetTypes();
foreach (Type type in allTypes) {
if (type.GetCustomAttributes(typeof(TestFixtureAttribute), true).Length > 0) {
foreach (MethodInfo m in type.GetMethods()) {
if (m.IsPublic && m.ReturnType == typeof(void) && m.GetParameters().Length == 0) {
if (m.GetCustomAttributes(typeof(TestAttribute), true).Length == 0) {
Assert.Fail(type.Name + "." + m.Name + " should have the [Test] attribute!");
}
}
}
}
}
}
// [Test]
// public void TestToStringMethods()
// {
// Type[] allTypes = typeof(INode).Assembly.GetTypes();
//
// foreach (Type type in allTypes) {
// if (type.IsClass && !type.IsAbstract && !type.IsNested && type.GetInterface(typeof(INode).FullName) != null) {
// MethodInfo methodInfo = type.GetMethod("ToString", BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public);
// Assert.IsNotNull(methodInfo, "ToString() not found in " + type.FullName);
// }
// }
// }
//
// [Test]
// public void TestUnitTests()
// {
// Type[] allTypes = typeof(StructuralTest).Assembly.GetTypes();
//
// foreach (Type type in allTypes) {
// if (type.GetCustomAttributes(typeof(TestFixtureAttribute), true).Length > 0) {
// foreach (MethodInfo m in type.GetMethods()) {
// if (m.IsPublic && m.ReturnType == typeof(void) && m.GetParameters().Length == 0) {
// if (m.GetCustomAttributes(typeof(TestAttribute), true).Length == 0) {
// Assert.Fail(type.Name + "." + m.Name + " should have the [Test] attribute!");
// }
// }
// }
// }
// }
// }
//
// [Test]
// public void TestAcceptVisitorMethods()
// {
@ -56,48 +55,48 @@ namespace ICSharpCode.NRefactory.VB.Tests @@ -56,48 +55,48 @@ namespace ICSharpCode.NRefactory.VB.Tests
// }
// }
// }
[Test]
public void TestIAstVisitor()
{
Type[] allTypes = typeof(AbstractNode).Assembly.GetTypes();
Type visitor = typeof(IAstVisitor);
foreach (Type type in allTypes) {
if (type.IsClass && !type.IsAbstract && !type.IsNested && type.GetInterface(typeof(INode).FullName) != null && !type.Name.StartsWith("Null")) {
MethodInfo methodInfo = visitor.GetMethod("Visit" + type.Name, BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.ExactBinding, null, new Type[] {type, typeof(object)}, null);
Assert.IsNotNull(methodInfo, "Visit with parameter " + type.FullName + " not found");
Assert.AreEqual(2, methodInfo.GetParameters().Length);
ParameterInfo first = methodInfo.GetParameters()[0];
Assert.AreEqual(Char.ToLower(first.ParameterType.Name[0]) + first.ParameterType.Name.Substring(1), first.Name);
ParameterInfo second = methodInfo.GetParameters()[1];
Assert.AreEqual(typeof(System.Object), second.ParameterType);
Assert.AreEqual("data", second.Name);
}
}
}
[Test]
public void TestAbstractAstVisitorVisitor()
{
Type[] allTypes = typeof(AbstractNode).Assembly.GetTypes();
Type visitor = typeof(AbstractAstVisitor);
foreach (Type type in allTypes) {
if (type.IsClass && !type.IsAbstract && !type.IsNested && type.GetInterface(typeof(INode).FullName) != null && !type.Name.StartsWith("Null")) {
MethodInfo methodInfo = visitor.GetMethod("Visit" + type.Name, BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.ExactBinding, null, new Type[] {type, typeof(object)}, null);
Assert.IsNotNull(methodInfo, "Visit with parameter " + type.FullName + " not found");
Assert.AreEqual(2, methodInfo.GetParameters().Length);
ParameterInfo first = methodInfo.GetParameters()[0];
Assert.AreEqual(Char.ToLower(first.ParameterType.Name[0]) + first.ParameterType.Name.Substring(1), first.Name);
ParameterInfo second = methodInfo.GetParameters()[1];
Assert.AreEqual(typeof(System.Object), second.ParameterType);
Assert.AreEqual("data", second.Name);
}
}
}
//
// [Test]
// public void TestIAstVisitor()
// {
// Type[] allTypes = typeof(AbstractNode).Assembly.GetTypes();
// Type visitor = typeof(IAstVisitor);
//
// foreach (Type type in allTypes) {
// if (type.IsClass && !type.IsAbstract && !type.IsNested && type.GetInterface(typeof(INode).FullName) != null && !type.Name.StartsWith("Null")) {
// MethodInfo methodInfo = visitor.GetMethod("Visit" + type.Name, BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.ExactBinding, null, new Type[] {type, typeof(object)}, null);
// Assert.IsNotNull(methodInfo, "Visit with parameter " + type.FullName + " not found");
// Assert.AreEqual(2, methodInfo.GetParameters().Length);
// ParameterInfo first = methodInfo.GetParameters()[0];
// Assert.AreEqual(Char.ToLower(first.ParameterType.Name[0]) + first.ParameterType.Name.Substring(1), first.Name);
//
// ParameterInfo second = methodInfo.GetParameters()[1];
// Assert.AreEqual(typeof(System.Object), second.ParameterType);
// Assert.AreEqual("data", second.Name);
// }
// }
// }
//
// [Test]
// public void TestAbstractAstVisitorVisitor()
// {
// Type[] allTypes = typeof(AbstractNode).Assembly.GetTypes();
// Type visitor = typeof(AbstractAstVisitor);
//
// foreach (Type type in allTypes) {
// if (type.IsClass && !type.IsAbstract && !type.IsNested && type.GetInterface(typeof(INode).FullName) != null && !type.Name.StartsWith("Null")) {
// MethodInfo methodInfo = visitor.GetMethod("Visit" + type.Name, BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.ExactBinding, null, new Type[] {type, typeof(object)}, null);
// Assert.IsNotNull(methodInfo, "Visit with parameter " + type.FullName + " not found");
//
// Assert.AreEqual(2, methodInfo.GetParameters().Length);
// ParameterInfo first = methodInfo.GetParameters()[0];
// Assert.AreEqual(Char.ToLower(first.ParameterType.Name[0]) + first.ParameterType.Name.Substring(1), first.Name);
//
// ParameterInfo second = methodInfo.GetParameters()[1];
// Assert.AreEqual(typeof(System.Object), second.ParameterType);
// Assert.AreEqual("data", second.Name);
// }
// }
// }
}
}

79
NRefactory/ICSharpCode.NRefactory.VB.Tests/ICSharpCode.NRefactory.VB.Tests.csproj

@ -66,90 +66,23 @@ @@ -66,90 +66,23 @@
<Compile Include="Lexer\LiteralsTests.cs" />
<Compile Include="Lexer\TokenTests.cs" />
<Compile Include="Lexer\XmlModeLexerTests.cs" />
<Compile Include="Output\CodeDOM\CodeDOMTypeReferenceTest.cs" />
<Compile Include="Parser\CheckParentVisitor.cs" />
<Compile Include="Parser\Expressions\AddressOfExpressionTests.cs" />
<Compile Include="Parser\Expressions\LambdaExpressionTests.cs" />
<Compile Include="Parser\Expressions\QueryExpressionTests.cs" />
<Compile Include="Parser\Expressions\XmlExpressionTests.cs" />
<Compile Include="Parser\Expressions\XmlMemberAccessExpressionTests.cs" />
<Compile Include="Parser\GlobalScope\AttributeSectionTests.cs" />
<Compile Include="Parser\Expressions\PrimitiveExpressionTests.cs" />
<Compile Include="Parser\Expressions\ParenthesizedExpressionTest.cs" />
<Compile Include="Parser\Expressions\ThisReferenceExpressionTests.cs" />
<Compile Include="Parser\Expressions\BaseReferenceExpressionTests.cs" />
<Compile Include="Parser\Expressions\IdentifierExpressionTests.cs" />
<Compile Include="Parser\GlobalScope\NamespaceDeclarationTests.cs" />
<Compile Include="Parser\Expressions\AssignmentExpressionTests.cs" />
<Compile Include="Parser\Expressions\BinaryOperatorExpressionTests.cs" />
<Compile Include="Parser\Expressions\UnaryOperatorExpressionTests.cs" />
<Compile Include="Parser\Expressions\CastExpressionTests.cs" />
<Compile Include="Parser\Expressions\MemberReferenceExpressionTests.cs" />
<Compile Include="Parser\Expressions\InvocationExpressionTests.cs" />
<Compile Include="Parser\Expressions\TypeOfExpressionTests.cs" />
<Compile Include="Parser\Expressions\ArrayCreateExpressionTests.cs" />
<Compile Include="Parser\Expressions\ObjectCreateExpressionTests.cs" />
<Compile Include="Parser\GlobalScope\DelegateDeclarationTests.cs" />
<Compile Include="Parser\Expressions\ConditionalExpressionTests.cs" />
<Compile Include="Parser\GlobalScope\UsingDeclarationTests.cs" />
<Compile Include="Parser\GlobalScope\ImportsStatementTests.cs" />
<Compile Include="Parser\GlobalScope\TypeDeclarationTests.cs" />
<Compile Include="Parser\LocationAssignmentCheckVisitor.cs" />
<Compile Include="Parser\SnippetParserTests.cs" />
<Compile Include="Parser\TypeLevel\ConstructorDeclarationTests.cs" />
<Compile Include="Parser\TypeLevel\EventDeclarationTests.cs" />
<Compile Include="Parser\TypeLevel\FieldDeclarationTests.cs" />
<Compile Include="Parser\TypeLevel\MethodDeclarationTests.cs" />
<Compile Include="Parser\TypeLevel\PropertyDeclarationTests.cs" />
<Compile Include="Parser\TypeLevel\OperatorDeclarationTests.cs" />
<Compile Include="Parser\Statements\BlockStatementTests.cs" />
<Compile Include="Parser\Statements\ContinueStatementTests.cs" />
<Compile Include="Parser\Statements\DoLoopStatementTests.cs" />
<Compile Include="Parser\Statements\ForeachStatementTests.cs" />
<Compile Include="Parser\Statements\GotoStatementTests.cs" />
<Compile Include="Parser\Statements\IfElseStatementTests.cs" />
<Compile Include="Parser\Statements\LabelStatementTests.cs" />
<Compile Include="Parser\Statements\LocalVariableDeclarationTests.cs" />
<Compile Include="Parser\Statements\LockStatementTests.cs" />
<Compile Include="Parser\Statements\ReturnStatementTests.cs" />
<Compile Include="Parser\Statements\ExpressionStatementTests.cs" />
<Compile Include="Parser\Statements\SwitchStatementTests.cs" />
<Compile Include="Parser\Statements\ThrowStatementTests.cs" />
<Compile Include="Parser\Statements\TryCatchStatementTests.cs" />
<Compile Include="Parser\Statements\UsingStatementTests.cs" />
<Compile Include="Parser\Expressions\ClassReferenceExpressionTests.cs" />
<Compile Include="Parser\Expressions\TypeOfIsExpressionTests.cs" />
<Compile Include="Parser\ParseUtil.cs" />
<Compile Include="Parser\GlobalScope\OptionDeclarationTests.cs" />
<Compile Include="Parser\TypeLevel\DeclareDeclarationTests.cs" />
<Compile Include="Parser\Statements\AddHandlerStatementTests.cs" />
<Compile Include="Parser\Statements\EndStatementTests.cs" />
<Compile Include="Parser\Statements\EraseStatementTests.cs" />
<Compile Include="Parser\Statements\ErrorStatementTests.cs" />
<Compile Include="Parser\Statements\ForNextStatementTests.cs" />
<Compile Include="Parser\Statements\OnErrorStatementTest.cs" />
<Compile Include="Parser\Statements\RaiseEventStatementTest.cs" />
<Compile Include="Parser\Statements\ReDimStatementTests.cs" />
<Compile Include="Parser\Statements\RemoveHandlerStatement.cs" />
<Compile Include="Parser\Statements\ResumeStatement.cs" />
<Compile Include="Parser\Statements\StopStatementTests.cs" />
<Compile Include="Parser\Statements\WithStatementTests.cs" />
<Compile Include="Output\CodeDOM\CodeDOMPrimitiveExpressionTest.cs" />
<Compile Include="Output\CodeDOM\CodeDOMParenthesizedExpressionTest.cs" />
<Compile Include="Output\CodeDOM\InvocationExpressionTest.cs" />
<Compile Include="Parser\Expressions\TypeReferenceExpressionTests.cs" />
<Compile Include="Parser\Expressions\GlobalReferenceExpressionTests.cs" />
<Compile Include="Parser\TypeLevel\CustomEventTests.cs" />
<Compile Include="Output\VBNet\VBNetOutputTest.cs" />
<Compile Include="Output\SpecialOutputVisitorTest.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="Output\VBNet" />
<Compile Include="Parser\GlobalScope\OptionStatementTests.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\ICSharpCode.NRefactory.VB\ICSharpCode.NRefactory.VB.csproj">
<Project>{7B82B671-419F-45F4-B778-D9286F996EFA}</Project>
<Name>ICSharpCode.NRefactory.VB</Name>
</ProjectReference>
<ProjectReference Include="..\ICSharpCode.NRefactory\ICSharpCode.NRefactory.csproj">
<Project>{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}</Project>
<Name>ICSharpCode.NRefactory</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSHARP.Targets" />
</Project>

2
NRefactory/ICSharpCode.NRefactory.VB.Tests/Lexer/CustomLexerTests.cs

@ -13,7 +13,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Lexer @@ -13,7 +13,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Lexer
{
VBLexer GenerateLexer(StringReader sr)
{
return ParserFactory.CreateLexer(sr);
return new VBLexer(sr);
}
[Test]

2
NRefactory/ICSharpCode.NRefactory.VB.Tests/Lexer/ImplicitLineContinuationTests.cs

@ -213,7 +213,7 @@ End Class"; @@ -213,7 +213,7 @@ End Class";
#region Helpers
VBLexer GenerateLexer(StringReader sr)
{
return ParserFactory.CreateLexer(sr);
return new VBLexer(sr);
}
void CheckTokens(VBLexer lexer, params int[] tokens)

2
NRefactory/ICSharpCode.NRefactory.VB.Tests/Lexer/LexerContextTests.cs

@ -556,7 +556,7 @@ exit Global @@ -556,7 +556,7 @@ exit Global
void RunTest(string code, string expectedOutput)
{
ExpressionFinder p = new ExpressionFinder();
VBLexer lexer = ParserFactory.CreateLexer(new StringReader(code));
VBLexer lexer = new VBLexer(new StringReader(code));
Token t;
do {

42
NRefactory/ICSharpCode.NRefactory.VB.Tests/Lexer/LexerPositionTests.cs

@ -13,7 +13,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Lexer @@ -13,7 +13,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Lexer
{
VBLexer GenerateLexer(string s)
{
return ParserFactory.CreateLexer(new StringReader(s));
return new VBLexer(new StringReader(s));
}
[Test]
@ -22,16 +22,16 @@ namespace ICSharpCode.NRefactory.VB.Tests.Lexer @@ -22,16 +22,16 @@ namespace ICSharpCode.NRefactory.VB.Tests.Lexer
VBLexer l = GenerateLexer("public\nstatic");
Token t = l.NextToken();
Assert.AreEqual(Tokens.Public, t.Kind);
Assert.AreEqual(new Location(1, 1), t.Location);
Assert.AreEqual(new Location(7, 1), t.EndLocation);
Assert.AreEqual(new AstLocation(1, 1), t.Location);
Assert.AreEqual(new AstLocation(7, 1), t.EndLocation);
t = l.NextToken();
Assert.AreEqual(Tokens.EOL, t.Kind);
Assert.AreEqual(new Location(7, 1), t.Location);
Assert.AreEqual(new Location(1, 2), t.EndLocation);
Assert.AreEqual(new AstLocation(7, 1), t.Location);
Assert.AreEqual(new AstLocation(1, 2), t.EndLocation);
t = l.NextToken();
Assert.AreEqual(Tokens.Static, t.Kind);
Assert.AreEqual(new Location(1, 2), t.Location);
Assert.AreEqual(new Location(7, 2), t.EndLocation);
Assert.AreEqual(new AstLocation(1, 2), t.Location);
Assert.AreEqual(new AstLocation(7, 2), t.EndLocation);
}
[Test]
@ -40,16 +40,16 @@ namespace ICSharpCode.NRefactory.VB.Tests.Lexer @@ -40,16 +40,16 @@ namespace ICSharpCode.NRefactory.VB.Tests.Lexer
VBLexer l = GenerateLexer("public\r\nstatic");
Token t = l.NextToken();
Assert.AreEqual(Tokens.Public, t.Kind);
Assert.AreEqual(new Location(1, 1), t.Location);
Assert.AreEqual(new Location(7, 1), t.EndLocation);
Assert.AreEqual(new AstLocation(1, 1), t.Location);
Assert.AreEqual(new AstLocation(7, 1), t.EndLocation);
t = l.NextToken();
Assert.AreEqual(Tokens.EOL, t.Kind);
Assert.AreEqual(new Location(7, 1), t.Location);
Assert.AreEqual(new Location(1, 2), t.EndLocation);
Assert.AreEqual(new AstLocation(7, 1), t.Location);
Assert.AreEqual(new AstLocation(1, 2), t.EndLocation);
t = l.NextToken();
Assert.AreEqual(Tokens.Static, t.Kind);
Assert.AreEqual(new Location(1, 2), t.Location);
Assert.AreEqual(new Location(7, 2), t.EndLocation);
Assert.AreEqual(new AstLocation(1, 2), t.Location);
Assert.AreEqual(new AstLocation(7, 2), t.EndLocation);
}
[Test]
@ -59,13 +59,13 @@ namespace ICSharpCode.NRefactory.VB.Tests.Lexer @@ -59,13 +59,13 @@ namespace ICSharpCode.NRefactory.VB.Tests.Lexer
l.NextToken(); // public
Token t = l.NextToken();
Assert.AreEqual(Tokens.EOL, t.Kind);
Assert.AreEqual(new Location(7, 1), t.Location);
Assert.AreEqual(new Location(7, 1), t.EndLocation);
Assert.AreEqual(new AstLocation(7, 1), t.Location);
Assert.AreEqual(new AstLocation(7, 1), t.EndLocation);
t = l.NextToken();
Assert.AreEqual(Tokens.EOF, t.Kind);
Assert.AreEqual(new Location(7, 1), t.Location);
Assert.AreEqual(new Location(7, 1), t.EndLocation);
Assert.AreEqual(new AstLocation(7, 1), t.Location);
Assert.AreEqual(new AstLocation(7, 1), t.EndLocation);
}
[Test]
@ -75,13 +75,13 @@ namespace ICSharpCode.NRefactory.VB.Tests.Lexer @@ -75,13 +75,13 @@ namespace ICSharpCode.NRefactory.VB.Tests.Lexer
l.NextToken(); // public
Token t = l.NextToken();
Assert.AreEqual(Tokens.EOL, t.Kind);
Assert.AreEqual(new Location(2, 2), t.Location);
Assert.AreEqual(new Location(2, 2), t.EndLocation);
Assert.AreEqual(new AstLocation(2, 2), t.Location);
Assert.AreEqual(new AstLocation(2, 2), t.EndLocation);
t = l.NextToken();
Assert.AreEqual(Tokens.EOF, t.Kind);
Assert.AreEqual(new Location(2, 2), t.Location);
Assert.AreEqual(new Location(2, 2), t.EndLocation);
Assert.AreEqual(new AstLocation(2, 2), t.Location);
Assert.AreEqual(new AstLocation(2, 2), t.EndLocation);
}
}
}

2
NRefactory/ICSharpCode.NRefactory.VB.Tests/Lexer/LexerTests.cs

@ -13,7 +13,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Lexer @@ -13,7 +13,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Lexer
{
VBLexer GenerateLexer(StringReader sr)
{
return ParserFactory.CreateLexer(sr);
return new VBLexer(sr);
}
[Test]

2
NRefactory/ICSharpCode.NRefactory.VB.Tests/Lexer/LiteralsTests.cs

@ -13,7 +13,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Lexer @@ -13,7 +13,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Lexer
{
VBLexer GenerateLexer(StringReader sr)
{
return ParserFactory.CreateLexer(sr);
return new VBLexer(sr);
}
Token GetSingleToken(string text)

4
NRefactory/ICSharpCode.NRefactory.VB.Tests/Lexer/XmlModeLexerTests.cs

@ -948,12 +948,12 @@ End Using"; @@ -948,12 +948,12 @@ End Using";
#region Helpers
VBLexer GenerateLexer(StringReader sr)
{
return ParserFactory.CreateLexer(sr);
return new VBLexer(sr);
}
VBLexer GenerateLexerForSnippet(StringReader sr, SnippetType type)
{
var lexer = ParserFactory.CreateLexer(sr);
var lexer = new VBLexer(sr);
lexer.SetInitialContext(type);
return lexer;
}

4
NRefactory/ICSharpCode.NRefactory.VB.Tests/Output/CodeDOM/InvocationExpressionTest.cs

@ -18,7 +18,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Output.CodeDom.Tests @@ -18,7 +18,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Output.CodeDom.Tests
public void IdentifierOnlyInvocation()
{
// InitializeComponents();
IdentifierExpression identifier = new IdentifierExpression("InitializeComponents");
SimpleNameExpression identifier = new SimpleNameExpression("InitializeComponents");
InvocationExpression invocation = new InvocationExpression(identifier, new List<Expression>());
object output = invocation.AcceptVisitor(new CodeDomVisitor(), null);
Assert.IsTrue(output is CodeMethodInvokeExpression);
@ -44,7 +44,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Output.CodeDom.Tests @@ -44,7 +44,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Output.CodeDom.Tests
public void InvocationOfStaticMethod()
{
// System.Drawing.Color.FromArgb();
MemberReferenceExpression field = new MemberReferenceExpression(new IdentifierExpression("System"), "Drawing");
MemberReferenceExpression field = new MemberReferenceExpression(new SimpleNameExpression("System"), "Drawing");
field = new MemberReferenceExpression(field, "Color");
field = new MemberReferenceExpression(field, "FromArgb");
InvocationExpression invocation = new InvocationExpression(field, new List<Expression>());

2
NRefactory/ICSharpCode.NRefactory.VB.Tests/Output/SpecialOutputVisitorTest.cs

@ -8,7 +8,7 @@ using System.IO; @@ -8,7 +8,7 @@ using System.IO;
using ICSharpCode.NRefactory.VB.Ast;
using ICSharpCode.NRefactory.VB.Parser;
using ICSharpCode.NRefactory.VB.PrettyPrinter;
using ICSharpCode.NRefactory.VB.Visitors;
using NUnit.Framework;
namespace ICSharpCode.NRefactory.VB.Tests.PrettyPrinter

35
NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/CheckParentVisitor.cs

@ -1,35 +0,0 @@ @@ -1,35 +0,0 @@
// 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 NUnit.Framework;
using System;
using System.Collections.Generic;
using ICSharpCode.NRefactory.VB.Ast;
using ICSharpCode.NRefactory.VB.Visitors;
namespace ICSharpCode.NRefactory.VB.Tests.Ast
{
/// <summary>
/// Ensures that all nodes have the Parent property correctly set.
/// </summary>
public class CheckParentVisitor : NodeTrackingAstVisitor
{
Stack<INode> nodeStack = new Stack<INode>();
public CheckParentVisitor()
{
nodeStack.Push(null);
}
protected override void BeginVisit(INode node)
{
nodeStack.Push(node);
}
protected override void EndVisit(INode node)
{
Assert.AreSame(node, nodeStack.Pop(), "nodeStack was corrupted!");
Assert.AreSame(nodeStack.Peek(), node.Parent, "node " + node + " is missing parent: " + nodeStack.Peek());
}
}
}

72
NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/Expressions/BinaryOperatorExpressionTests.cs

@ -20,20 +20,20 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -20,20 +20,20 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
BinaryOperatorExpression boe;
boe = ParseUtil.ParseExpression<BinaryOperatorExpression>(program);
Assert.AreEqual(weakOperatorType, boe.Op);
Assert.IsTrue(boe.Left is IdentifierExpression);
Assert.IsTrue(boe.Left is SimpleNameExpression);
boe = (BinaryOperatorExpression)boe.Right;
Assert.AreEqual(strongOperatorType, boe.Op);
Assert.IsTrue(boe.Left is IdentifierExpression);
Assert.IsTrue(boe.Right is IdentifierExpression);
Assert.IsTrue(boe.Left is SimpleNameExpression);
Assert.IsTrue(boe.Right is SimpleNameExpression);
program = "a " + strongOperator + " b " + weakOperator + " c";
boe = ParseUtil.ParseExpression<BinaryOperatorExpression>(program);
Assert.AreEqual(weakOperatorType, boe.Op);
Assert.IsTrue(boe.Right is IdentifierExpression);
Assert.IsTrue(boe.Right is SimpleNameExpression);
boe = (BinaryOperatorExpression)boe.Left;
Assert.AreEqual(strongOperatorType, boe.Op);
Assert.IsTrue(boe.Left is IdentifierExpression);
Assert.IsTrue(boe.Right is IdentifierExpression);
Assert.IsTrue(boe.Left is SimpleNameExpression);
Assert.IsTrue(boe.Right is SimpleNameExpression);
}
void SameOperatorPrecedenceTest(string firstOperator, BinaryOperatorType firstOperatorType,
@ -43,20 +43,20 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -43,20 +43,20 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
BinaryOperatorExpression boe;
boe = ParseUtil.ParseExpression<BinaryOperatorExpression>(program);
Assert.AreEqual(firstOperatorType, boe.Op);
Assert.IsTrue(boe.Right is IdentifierExpression);
Assert.IsTrue(boe.Right is SimpleNameExpression);
boe = (BinaryOperatorExpression)boe.Left;
Assert.AreEqual(secondOperatorType, boe.Op);
Assert.IsTrue(boe.Left is IdentifierExpression);
Assert.IsTrue(boe.Right is IdentifierExpression);
Assert.IsTrue(boe.Left is SimpleNameExpression);
Assert.IsTrue(boe.Right is SimpleNameExpression);
program = "a " + firstOperator + " b " + secondOperator + " c";
boe = ParseUtil.ParseExpression<BinaryOperatorExpression>(program);
Assert.AreEqual(secondOperatorType, boe.Op);
Assert.IsTrue(boe.Right is IdentifierExpression);
Assert.IsTrue(boe.Right is SimpleNameExpression);
boe = (BinaryOperatorExpression)boe.Left;
Assert.AreEqual(firstOperatorType, boe.Op);
Assert.IsTrue(boe.Left is IdentifierExpression);
Assert.IsTrue(boe.Right is IdentifierExpression);
Assert.IsTrue(boe.Left is SimpleNameExpression);
Assert.IsTrue(boe.Right is SimpleNameExpression);
}
#region VB.NET
@ -65,8 +65,8 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -65,8 +65,8 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
BinaryOperatorExpression boe = ParseUtil.ParseExpression<BinaryOperatorExpression>(program);
Assert.AreEqual(op, boe.Op);
Assert.IsTrue(boe.Left is IdentifierExpression);
Assert.IsTrue(boe.Right is IdentifierExpression);
Assert.IsTrue(boe.Left is SimpleNameExpression);
Assert.IsTrue(boe.Right is SimpleNameExpression);
}
[Test]
@ -251,7 +251,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -251,7 +251,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
{
BinaryOperatorExpression boe = ParseUtil.ParseExpression<BinaryOperatorExpression>("a!b");
Assert.AreEqual(BinaryOperatorType.DictionaryAccess, boe.Op);
Assert.IsTrue(boe.Left is IdentifierExpression);
Assert.IsTrue(boe.Left is SimpleNameExpression);
Assert.IsTrue(boe.Right is PrimitiveExpression);
}
@ -264,47 +264,5 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -264,47 +264,5 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
Assert.IsTrue(boe.Right is PrimitiveExpression);
}
#endregion
#region AddIntegerTests
string AddIntegerToBoe(string input, int number)
{
return AddInteger<BinaryOperatorExpression>(input, number);
}
string AddInteger<T>(string input, int number) where T : Expression
{
Expression e = ParseUtil.ParseExpression<T>(input);
e = Expression.AddInteger(e, number);
VBNetOutputVisitor v = new VBNetOutputVisitor();
e.AcceptVisitor(v, null);
return v.Text;
}
[Test]
public void AddInteger()
{
Assert.AreEqual("a + 2", AddIntegerToBoe("a + 1", 1));
Assert.AreEqual("a + 2", AddIntegerToBoe("a + 3", -1));
Assert.AreEqual("a + b + c + 2", AddIntegerToBoe("a + b + c + 1", 1));
Assert.AreEqual("a", AddIntegerToBoe("a + 1", -1));
Assert.AreEqual("2", AddInteger<PrimitiveExpression>("1", 1));
Assert.AreEqual("-1", AddInteger<PrimitiveExpression>("1", -2));
Assert.AreEqual("0", AddInteger<PrimitiveExpression>("1", -1));
Assert.AreEqual("a + 1", AddInteger<IdentifierExpression>("a", 1));
}
[Test]
public void AddIntegerWithNegativeResult()
{
Assert.AreEqual("a - 1", AddIntegerToBoe("a + 1", -2));
Assert.AreEqual("a - 2", AddIntegerToBoe("a - 1", -1));
Assert.AreEqual("a + b + c - 2", AddIntegerToBoe("a + b + c + 2", -4));
Assert.AreEqual("a + b + c - 6", AddIntegerToBoe("a + b + c - 2", -4));
Assert.AreEqual("a + b + c", AddIntegerToBoe("a + b + c + 2", -2));
Assert.AreEqual("a", AddIntegerToBoe("a - 1", 1));
Assert.AreEqual("a + 1", AddIntegerToBoe("a - 2", 3));
Assert.AreEqual("a - 1", AddInteger<IdentifierExpression>("a", -1));
}
#endregion
}
}

14
NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/Expressions/CastExpressionTests.cs

@ -17,7 +17,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -17,7 +17,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
{
CastExpression ce = ParseUtil.ParseExpression<CastExpression>(castExpression);
Assert.AreEqual(castType.FullName, ce.CastTo.Type);
Assert.IsTrue(ce.Expression is IdentifierExpression);
Assert.IsTrue(ce.Expression is SimpleNameExpression);
Assert.AreEqual(CastType.PrimitiveConversion, ce.CastType);
}
@ -27,7 +27,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -27,7 +27,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
{
CastExpression ce = ParseUtil.ParseExpression<CastExpression>("CType(o, MyObject)");
Assert.AreEqual("MyObject", ce.CastTo.Type);
Assert.IsTrue(ce.Expression is IdentifierExpression);
Assert.IsTrue(ce.Expression is SimpleNameExpression);
Assert.AreEqual(CastType.Conversion, ce.CastType);
}
@ -37,7 +37,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -37,7 +37,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
CastExpression ce = ParseUtil.ParseExpression<CastExpression>("CType(o, List(of T))");
Assert.AreEqual("List", ce.CastTo.Type);
Assert.AreEqual("T", ce.CastTo.GenericTypes[0].Type);
Assert.IsTrue(ce.Expression is IdentifierExpression);
Assert.IsTrue(ce.Expression is SimpleNameExpression);
Assert.AreEqual(CastType.Conversion, ce.CastType);
}
@ -46,7 +46,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -46,7 +46,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
{
CastExpression ce = ParseUtil.ParseExpression<CastExpression>("DirectCast(o, MyObject)");
Assert.AreEqual("MyObject", ce.CastTo.Type);
Assert.IsTrue(ce.Expression is IdentifierExpression);
Assert.IsTrue(ce.Expression is SimpleNameExpression);
Assert.AreEqual(CastType.Cast, ce.CastType);
}
@ -56,7 +56,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -56,7 +56,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
CastExpression ce = ParseUtil.ParseExpression<CastExpression>("DirectCast(o, List(of T))");
Assert.AreEqual("List", ce.CastTo.Type);
Assert.AreEqual("T", ce.CastTo.GenericTypes[0].Type);
Assert.IsTrue(ce.Expression is IdentifierExpression);
Assert.IsTrue(ce.Expression is SimpleNameExpression);
Assert.AreEqual(CastType.Cast, ce.CastType);
}
@ -65,7 +65,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -65,7 +65,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
{
CastExpression ce = ParseUtil.ParseExpression<CastExpression>("TryCast(o, MyObject)");
Assert.AreEqual("MyObject", ce.CastTo.Type);
Assert.IsTrue(ce.Expression is IdentifierExpression);
Assert.IsTrue(ce.Expression is SimpleNameExpression);
Assert.AreEqual(CastType.TryCast, ce.CastType);
}
@ -75,7 +75,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -75,7 +75,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
CastExpression ce = ParseUtil.ParseExpression<CastExpression>("TryCast(o, List(of T))");
Assert.AreEqual("List", ce.CastTo.Type);
Assert.AreEqual("T", ce.CastTo.GenericTypes[0].Type);
Assert.IsTrue(ce.Expression is IdentifierExpression);
Assert.IsTrue(ce.Expression is SimpleNameExpression);
Assert.AreEqual(CastType.TryCast, ce.CastType);
}

18
NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/Expressions/InvocationExpressionTests.cs

@ -15,15 +15,15 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -15,15 +15,15 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
void CheckSimpleInvoke(InvocationExpression ie)
{
Assert.AreEqual(0, ie.Arguments.Count);
Assert.IsTrue(ie.TargetObject is IdentifierExpression);
Assert.AreEqual("myMethod", ((IdentifierExpression)ie.TargetObject).Identifier);
Assert.IsTrue(ie.TargetObject is SimpleNameExpression);
Assert.AreEqual("myMethod", ((SimpleNameExpression)ie.TargetObject).Identifier);
}
void CheckGenericInvoke(InvocationExpression expr)
{
Assert.AreEqual(1, expr.Arguments.Count);
Assert.IsTrue(expr.TargetObject is IdentifierExpression);
IdentifierExpression ident = (IdentifierExpression)expr.TargetObject;
Assert.IsTrue(expr.TargetObject is SimpleNameExpression);
SimpleNameExpression ident = (SimpleNameExpression)expr.TargetObject;
Assert.AreEqual("myMethod", ident.Identifier);
Assert.AreEqual(1, ident.TypeArguments.Count);
Assert.AreEqual("System.Char", ident.TypeArguments[0].Type);
@ -32,8 +32,8 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -32,8 +32,8 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
void CheckGenericInvoke2(InvocationExpression expr)
{
Assert.AreEqual(0, expr.Arguments.Count);
Assert.IsTrue(expr.TargetObject is IdentifierExpression);
IdentifierExpression ident = (IdentifierExpression)expr.TargetObject;
Assert.IsTrue(expr.TargetObject is SimpleNameExpression);
SimpleNameExpression ident = (SimpleNameExpression)expr.TargetObject;
Assert.AreEqual("myMethod", ident.Identifier);
Assert.AreEqual(2, ident.TypeArguments.Count);
Assert.AreEqual("T", ident.TypeArguments[0].Type);
@ -74,7 +74,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -74,7 +74,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
InvocationExpression expr = ParseUtil.ParseExpression<InvocationExpression>("A(Of T).Foo()");
MemberReferenceExpression mre = (MemberReferenceExpression)expr.TargetObject;
Assert.AreEqual("Foo", mre.MemberName);
IdentifierExpression tre = (IdentifierExpression)mre.TargetObject;
SimpleNameExpression tre = (SimpleNameExpression)mre.TargetObject;
Assert.AreEqual("A", tre.Identifier);
Assert.AreEqual("T", tre.TypeArguments[0].Type);
}
@ -87,7 +87,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -87,7 +87,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
Assert.AreEqual("Foo", mre.MemberName);
MemberReferenceExpression mre2 = (MemberReferenceExpression)mre.TargetObject;
Assert.AreEqual("B", mre2.MemberName);
IdentifierExpression tre = (IdentifierExpression)mre2.TargetObject;
SimpleNameExpression tre = (SimpleNameExpression)mre2.TargetObject;
Assert.AreEqual("A", tre.Identifier);
Assert.AreEqual("T", tre.TypeArguments[0].Type);
}
@ -106,7 +106,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -106,7 +106,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
MemberReferenceExpression mre3 = (MemberReferenceExpression)mre2.TargetObject;
Assert.AreEqual("B", mre3.MemberName);
IdentifierExpression tre = (IdentifierExpression)mre3.TargetObject;
SimpleNameExpression tre = (SimpleNameExpression)mre3.TargetObject;
Assert.AreEqual("A", tre.Identifier);
Assert.AreEqual("T", tre.TypeArguments[0].Type);
}

8
NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/Expressions/MemberReferenceExpressionTests.cs

@ -18,8 +18,8 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -18,8 +18,8 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
{
MemberReferenceExpression fre = ParseUtil.ParseExpression<MemberReferenceExpression>("myTargetObject.myField");
Assert.AreEqual("myField", fre.MemberName);
Assert.IsTrue(fre.TargetObject is IdentifierExpression);
Assert.AreEqual("myTargetObject", ((IdentifierExpression)fre.TargetObject).Identifier);
Assert.IsTrue(fre.TargetObject is SimpleNameExpression);
Assert.AreEqual("myTargetObject", ((SimpleNameExpression)fre.TargetObject).Identifier);
}
[Test]
@ -35,8 +35,8 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -35,8 +35,8 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
{
MemberReferenceExpression fre = ParseUtil.ParseExpression<MemberReferenceExpression>("SomeClass(of string).myField");
Assert.AreEqual("myField", fre.MemberName);
Assert.IsInstanceOf(typeof(IdentifierExpression), fre.TargetObject);
TypeReference tr = ((IdentifierExpression)fre.TargetObject).TypeArguments[0];
Assert.IsInstanceOf(typeof(SimpleNameExpression), fre.TargetObject);
TypeReference tr = ((SimpleNameExpression)fre.TargetObject).TypeArguments[0];
Assert.AreEqual("System.String", tr.Type);
}

8
NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/Expressions/ObjectCreateExpressionTests.cs

@ -53,8 +53,8 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -53,8 +53,8 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
Assert.AreEqual(0, oce.Parameters.Count);
Assert.AreEqual(1, oce.ObjectInitializer.CreateExpressions.Count);
Assert.IsInstanceOf(typeof(IdentifierExpression), oce.ObjectInitializer.CreateExpressions[0]);
Assert.AreEqual("c", (oce.ObjectInitializer.CreateExpressions[0] as IdentifierExpression).Identifier);
Assert.IsInstanceOf(typeof(SimpleNameExpression), oce.ObjectInitializer.CreateExpressions[0]);
Assert.AreEqual("c", (oce.ObjectInitializer.CreateExpressions[0] as SimpleNameExpression).Identifier);
}
[Test]
@ -69,8 +69,8 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -69,8 +69,8 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
// this test was written because this bug caused the AbstractDomVisitor to crash
InvocationExpression expr = ParseUtil.ParseExpression<InvocationExpression>("WriteLine(New SomeGenericType(Of Integer, )())", true);
Assert.IsTrue(expr.TargetObject is IdentifierExpression);
Assert.AreEqual("WriteLine", ((IdentifierExpression)expr.TargetObject).Identifier);
Assert.IsTrue(expr.TargetObject is SimpleNameExpression);
Assert.AreEqual("WriteLine", ((SimpleNameExpression)expr.TargetObject).Identifier);
Assert.AreEqual(1, expr.Arguments.Count); // here a second null parameter was added incorrectly
Assert.IsTrue(expr.Arguments[0] is ObjectCreateExpression);

4
NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/Expressions/QueryExpressionTests.cs

@ -225,7 +225,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -225,7 +225,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
Action<QueryExpression> constraint = expr => {
var fromClause = expr.Clauses[0] as QueryExpressionFromClause;
var groupClause = expr.Clauses[1] as QueryExpressionGroupVBClause;
var letClause = expr.Clauses[2] as QueryExpressionLetVBClause;
var letClause = expr.Clauses[2] as QueryExpressionLetClause;
var selectClause = expr.Clauses[3] as QueryExpressionSelectVBClause;
// From
@ -276,7 +276,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -276,7 +276,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
Group p By p.Category Into Group _
Let minPrice = Group.Min(Function(p) p.UnitPrice) _
Select Category, CheapestProducts = Group.Where(Function(p) p.UnitPrice = minPrice)", 4, constraint,
typeof(QueryExpressionFromClause), typeof(QueryExpressionGroupVBClause), typeof(QueryExpressionLetVBClause), typeof(QueryExpressionSelectVBClause));
typeof(QueryExpressionFromClause), typeof(QueryExpressionGroupVBClause), typeof(QueryExpressionLetClause), typeof(QueryExpressionSelectVBClause));
}
[Test]

4
NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/Expressions/TypeOfIsExpressionTests.cs

@ -18,7 +18,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -18,7 +18,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
{
TypeOfIsExpression ce = ParseUtil.ParseExpression<TypeOfIsExpression>("TypeOf o Is MyObject");
Assert.AreEqual("MyObject", ce.TypeReference.Type);
Assert.IsTrue(ce.Expression is IdentifierExpression);
Assert.IsTrue(ce.Expression is SimpleNameExpression);
}
[Test]
@ -27,7 +27,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -27,7 +27,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
TypeOfIsExpression ce = ParseUtil.ParseExpression<TypeOfIsExpression>("TypeOf o Is List(of T)");
Assert.AreEqual("List", ce.TypeReference.Type);
Assert.AreEqual("T", ce.TypeReference.GenericTypes[0].Type);
Assert.IsTrue(ce.Expression is IdentifierExpression);
Assert.IsTrue(ce.Expression is SimpleNameExpression);
}
#endregion
}

2
NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/Expressions/UnaryOperatorExpressionTests.cs

@ -18,7 +18,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -18,7 +18,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
UnaryOperatorExpression uoe = ParseUtil.ParseExpression<UnaryOperatorExpression>(program);
Assert.AreEqual(op, uoe.Op);
Assert.IsTrue(uoe.Expression is IdentifierExpression);
Assert.IsTrue(uoe.Expression is SimpleNameExpression);
}
[Test]

4
NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/Expressions/XmlExpressionTests.cs

@ -230,7 +230,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -230,7 +230,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
}
#endregion
void CheckElement(INode node, string name, Location start, Location end)
void CheckElement(AstNode node, string name, AstLocation start, AstLocation end)
{
Assert.IsTrue(node is XmlElementExpression);
XmlElementExpression expr = node as XmlElementExpression;
@ -242,7 +242,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -242,7 +242,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
Assert.AreEqual(end, expr.EndLocation);
}
void CheckContent(INode node, string content, XmlContentType type, Location start, Location end)
void CheckContent(AstNode node, string content, XmlContentType type, AstLocation start, AstLocation end)
{
Assert.IsTrue(node is XmlContentExpression);
XmlContentExpression expr = node as XmlContentExpression;

116
NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/GlobalScope/AttributeSectionTests.cs

@ -12,63 +12,63 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -12,63 +12,63 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
[TestFixture]
public class AttributeSectionTests
{
[Test]
public void AttributeOnStructure()
{
string program = @"
<StructLayout( LayoutKind.Explicit )> _
Public Structure MyUnion
<FieldOffset( 0 )> Public i As Integer
< FieldOffset( 0 )> Public d As Double
End Structure 'MyUnion
";
TypeDeclaration decl = ParseUtil.ParseGlobal<TypeDeclaration>(program);
Assert.AreEqual("StructLayout", decl.Attributes[0].Attributes[0].Name);
}
[Test]
public void AttributeOnModule()
{
string program = @"
<HideModule> _
Public Module MyExtra
Public i As Integer
Public d As Double
End Module
";
TypeDeclaration decl = ParseUtil.ParseGlobal<TypeDeclaration>(program);
Assert.AreEqual("HideModule", decl.Attributes[0].Attributes[0].Name);
}
[Test]
public void GlobalAttribute()
{
string program = @"<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
Public Class Form1
End Class";
TypeDeclaration decl = ParseUtil.ParseGlobal<TypeDeclaration>(program);
Assert.AreEqual("Microsoft.VisualBasic.CompilerServices.DesignerGenerated", decl.Attributes[0].Attributes[0].Name);
}
[Test]
public void AssemblyAttribute()
{
string program = @"<assembly: System.Attribute()>";
AttributeSection decl = ParseUtil.ParseGlobal<AttributeSection>(program);
Assert.AreEqual(new Location(1, 1), decl.StartLocation);
Assert.AreEqual("assembly", decl.AttributeTarget);
}
[Test]
public void ModuleAttributeTargetEscaped()
{
// check that this doesn't crash the parser:
ParseUtil.ParseGlobal<AttributeSection>("<[Module]: SuppressMessageAttribute>", true);
}
// [Test]
// public void AttributeOnStructure()
// {
// string program = @"
//<StructLayout( LayoutKind.Explicit )> _
//Public Structure MyUnion
//
// <FieldOffset( 0 )> Public i As Integer
// < FieldOffset( 0 )> Public d As Double
//
//End Structure 'MyUnion
//";
// TypeDeclaration decl = ParseUtil.ParseGlobal<TypeDeclaration>(program);
// Assert.AreEqual("StructLayout", decl.Attributes[0].Attributes[0].Type);
// }
//
// [Test]
// public void AttributeOnModule()
// {
// string program = @"
//<HideModule> _
//Public Module MyExtra
//
// Public i As Integer
// Public d As Double
//
//End Module
//";
// TypeDeclaration decl = ParseUtil.ParseGlobal<TypeDeclaration>(program);
// Assert.AreEqual("HideModule", decl.Attributes[0].Attributes[0].Type);
// }
//
// [Test]
// public void GlobalAttribute()
// {
// string program = @"<Global.Microsoft.VisualBasic.CompilerServices.DesignerGenerated()> _
//Public Class Form1
//
//End Class";
// TypeDeclaration decl = ParseUtil.ParseGlobal<TypeDeclaration>(program);
// Assert.AreEqual("Microsoft.VisualBasic.CompilerServices.DesignerGenerated", decl.Attributes[0].Attributes[0].Type);
// }
//
// [Test]
// public void AssemblyAttribute()
// {
// string program = @"<assembly: System.Attribute()>";
// AttributeSection decl = ParseUtil.ParseGlobal<AttributeSection>(program);
// Assert.AreEqual(new Location(1, 1), decl.StartLocation);
// Assert.AreEqual("assembly", decl.AttributeTarget);
// }
//
// [Test]
// public void ModuleAttributeTargetEscaped()
// {
// // check that this doesn't crash the parser:
// ParseUtil.ParseGlobal<AttributeSection>("<[Module]: SuppressMessageAttribute>", true);
// }
}
}

42
NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/GlobalScope/DelegateDeclarationTests.cs

@ -1,42 +0,0 @@ @@ -1,42 +0,0 @@
// 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 ICSharpCode.NRefactory.VB.Ast;
using NUnit.Framework;
namespace ICSharpCode.NRefactory.VB.Tests.Ast
{
[TestFixture]
public class DelegateDeclarationTests
{
void TestDelegateDeclaration(DelegateDeclaration dd)
{
Assert.AreEqual("System.Void", dd.ReturnType.Type);
Assert.AreEqual("MyDelegate", dd.Name);
}
void TestParameters(DelegateDeclaration dd)
{
Assert.AreEqual(3, dd.Parameters.Count);
Assert.AreEqual("a", ((ParameterDeclarationExpression)dd.Parameters[0]).ParameterName);
Assert.AreEqual("System.Int32", ((ParameterDeclarationExpression)dd.Parameters[0]).TypeReference.Type);
Assert.AreEqual("secondParam", ((ParameterDeclarationExpression)dd.Parameters[1]).ParameterName);
Assert.AreEqual("System.Int32", ((ParameterDeclarationExpression)dd.Parameters[1]).TypeReference.Type);
Assert.AreEqual("lastParam", ((ParameterDeclarationExpression)dd.Parameters[2]).ParameterName);
Assert.AreEqual("MyObj", ((ParameterDeclarationExpression)dd.Parameters[2]).TypeReference.Type);
}
#region VB.NET
[Test]
public void SimpleVBNetDelegateDeclarationTest()
{
string program = "Public Delegate Sub MyDelegate(ByVal a As Integer, ByVal secondParam As Integer, ByVal lastParam As MyObj)\n";
TestDelegateDeclaration(ParseUtil.ParseGlobal<DelegateDeclaration>(program));
}
#endregion
}
}

168
NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/GlobalScope/ImportsStatementTests.cs

@ -0,0 +1,168 @@ @@ -0,0 +1,168 @@
// 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.IO;
using ICSharpCode.NRefactory.VB.Parser;
using ICSharpCode.NRefactory.VB.Ast;
using NUnit.Framework;
namespace ICSharpCode.NRefactory.VB.Tests.Ast
{
[TestFixture]
public class ImportsStatementTests
{
[Test]
public void InvalidImportsStatement()
{
string program = "Imports\n";
ParseUtil.ParseGlobal<ImportsStatement>(program, true);
}
[Test]
public void InvalidImportsStatement2()
{
string program = "Imports ,\n";
ParseUtil.ParseGlobal<ImportsStatement>(program, true);
}
[Test]
public void SimpleImportsStatement()
{
string program = "Imports System\n";
var clause1 = new MemberImportsClause {
Member = new SimpleType("System")
};
var node = new ImportsStatement();
node.AddChild(clause1, ImportsStatement.ImportsClauseRole);
ParseUtil.AssertGlobal(program, node);
}
[Test]
public void QualifiedTypeImportsStatement()
{
string program = "Imports My.Name.Space\n";
var clause2 = new MemberImportsClause {
Member = new QualifiedType(new QualifiedType(new SimpleType("My"), new Identifier("Name", AstLocation.Empty)), new Identifier("Space", AstLocation.Empty))
};
var node = new ImportsStatement();
node.AddChild(clause2, ImportsStatement.ImportsClauseRole);
ParseUtil.AssertGlobal(program, node);
}
//
// [Test]
// public void VBNetUsingAliasDeclarationTest()
// {
// string program = "Imports TESTME=System\n" +
// "Imports myAlias=My.Name.Space\n" +
// "Imports StringCollection = System.Collections.Generic.List(Of string)\n";
// VBParser parser = ParserFactory.CreateParser(new StringReader(program));
// parser.Parse();
//
// Assert.AreEqual("", parser.Errors.ErrorOutput);
// CheckAliases(parser.CompilationUnit);
// }
//
// [Test]
// public void VBNetComplexUsingAliasDeclarationTest()
// {
// string program = "Imports NS1, AL=NS2, NS3, AL2=NS4, NS5\n";
// VBParser parser = ParserFactory.CreateParser(new StringReader(program));
// parser.Parse();
//
// Assert.AreEqual("", parser.Errors.ErrorOutput);
// // TODO : Extend test ...
// }
//
// [Test]
// public void VBNetXmlNamespaceUsingTest()
// {
// string program = "Imports <xmlns=\"http://icsharpcode.net/sharpdevelop/avalonedit\">";
// VBParser parser = ParserFactory.CreateParser(new StringReader(program));
// parser.Parse();
//
// Assert.AreEqual("", parser.Errors.ErrorOutput);
// CompilationUnit unit = parser.CompilationUnit;
//
// Assert.AreEqual(1, unit.Children.Count);
// Assert.IsTrue(unit.Children[0] is ImportsStatement);
// ImportsStatement ud = (ImportsStatement)unit.Children[0];
// Assert.AreEqual(1, ud.ImportsClauses.Count);
// Assert.IsFalse(ud.ImportsClauses[0].IsAlias);
// Assert.IsTrue(ud.ImportsClauses[0].IsXml);
//
// Assert.AreEqual("xmlns", ud.ImportsClauses[0].XmlPrefix);
// Assert.AreEqual("http://icsharpcode.net/sharpdevelop/avalonedit", ud.ImportsClauses[0].Name);
// }
//
// [Test]
// public void VBNetXmlNamespaceWithPrefixUsingTest()
// {
// string program = "Imports <xmlns:avalonedit=\"http://icsharpcode.net/sharpdevelop/avalonedit\">";
// VBParser parser = ParserFactory.CreateParser(new StringReader(program));
// parser.Parse();
//
// Assert.AreEqual("", parser.Errors.ErrorOutput);
// CompilationUnit unit = parser.CompilationUnit;
//
// Assert.AreEqual(1, unit.Children.Count);
// Assert.IsTrue(unit.Children[0] is ImportsStatement);
// ImportsStatement ud = (ImportsStatement)unit.Children[0];
// Assert.AreEqual(1, ud.ImportsClauses.Count);
// Assert.IsFalse(ud.ImportsClauses[0].IsAlias);
// Assert.IsTrue(ud.ImportsClauses[0].IsXml);
//
// Assert.AreEqual("xmlns:avalonedit", ud.ImportsClauses[0].XmlPrefix);
// Assert.AreEqual("http://icsharpcode.net/sharpdevelop/avalonedit", ud.ImportsClauses[0].Name);
// }
//
// [Test]
// public void VBNetXmlNamespaceSingleQuotedUsingTest()
// {
// string program = "Imports <xmlns='http://icsharpcode.net/sharpdevelop/avalonedit'>";
// VBParser parser = ParserFactory.CreateParser(new StringReader(program));
// parser.Parse();
//
// Assert.AreEqual("", parser.Errors.ErrorOutput);
// CompilationUnit unit = parser.CompilationUnit;
//
// Assert.AreEqual(1, unit.Children.Count);
// Assert.IsTrue(unit.Children[0] is ImportsStatement);
// ImportsStatement ud = (ImportsStatement)unit.Children[0];
// Assert.AreEqual(1, ud.ImportsClauses.Count);
// Assert.IsFalse(ud.ImportsClauses[0].IsAlias);
// Assert.IsTrue(ud.ImportsClauses[0].IsXml);
//
// Assert.AreEqual("xmlns", ud.ImportsClauses[0].XmlPrefix);
// Assert.AreEqual("http://icsharpcode.net/sharpdevelop/avalonedit", ud.ImportsClauses[0].Name);
// }
//
// [Test]
// public void VBNetXmlNamespaceSingleQuotedWithPrefixUsingTest()
// {
// string program = "Imports <xmlns:avalonedit='http://icsharpcode.net/sharpdevelop/avalonedit'>";
// VBParser parser = ParserFactory.CreateParser(new StringReader(program));
// parser.Parse();
//
// Assert.AreEqual("", parser.Errors.ErrorOutput);
// CompilationUnit unit = parser.CompilationUnit;
//
// Assert.AreEqual(1, unit.Children.Count);
// Assert.IsTrue(unit.Children[0] is ImportsStatement);
// ImportsStatement ud = (ImportsStatement)unit.Children[0];
// Assert.AreEqual(1, ud.ImportsClauses.Count);
// Assert.IsFalse(ud.ImportsClauses[0].IsAlias);
// Assert.IsTrue(ud.ImportsClauses[0].IsXml);
//
// Assert.AreEqual("xmlns:avalonedit", ud.ImportsClauses[0].XmlPrefix);
// Assert.AreEqual("http://icsharpcode.net/sharpdevelop/avalonedit", ud.ImportsClauses[0].Name);
// }
// #endregion
}
}

58
NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/GlobalScope/NamespaceDeclarationTests.cs

@ -10,34 +10,34 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -10,34 +10,34 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
[TestFixture]
public class NamespaceDeclarationTests
{
#region VB.NET
[Test]
public void VBNetSimpleNamespaceTest()
{
string program = "Namespace TestNamespace" + Environment.NewLine +
"End Namespace" +Environment.NewLine;
NamespaceDeclaration ns = ParseUtil.ParseGlobal<NamespaceDeclaration>(program);
Assert.AreEqual("TestNamespace", ns.Name);
}
[Test]
public void VBNetJuggedNamespaceTest()
{
string program = "Namespace N1 'TestNamespace\n" +
" Namespace N2 ' Declares a namespace named N2 within N1.\n" +
" End Namespace\n" +
"End Namespace\n";
NamespaceDeclaration ns = ParseUtil.ParseGlobal<NamespaceDeclaration>(program);
Assert.AreEqual("N1", ns.Name);
Assert.IsTrue(ns.Children[0] is NamespaceDeclaration);
ns = (NamespaceDeclaration)ns.Children[0];
Assert.AreEqual("N2", ns.Name);
}
#endregion
// #region VB.NET
// [Test]
// public void VBNetSimpleNamespaceTest()
// {
// string program = "Namespace TestNamespace" + Environment.NewLine +
// "End Namespace" +Environment.NewLine;
// NamespaceDeclaration ns = ParseUtil.ParseGlobal<NamespaceDeclaration>(program);
// Assert.AreEqual("TestNamespace", ns.Name);
// }
//
// [Test]
// public void VBNetJuggedNamespaceTest()
// {
// string program = "Namespace N1 'TestNamespace\n" +
// " Namespace N2 ' Declares a namespace named N2 within N1.\n" +
// " End Namespace\n" +
// "End Namespace\n";
//
// NamespaceDeclaration ns = ParseUtil.ParseGlobal<NamespaceDeclaration>(program);
//
// Assert.AreEqual("N1", ns.Name);
//
// Assert.IsTrue(ns.Children[0] is NamespaceDeclaration);
//
// ns = (NamespaceDeclaration)ns.Children[0];
//
// Assert.AreEqual("N2", ns.Name);
// }
// #endregion
}
}

87
NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/GlobalScope/OptionDeclarationTests.cs

@ -1,87 +0,0 @@ @@ -1,87 +0,0 @@
// 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.IO;
using ICSharpCode.NRefactory.VB.Parser;
using ICSharpCode.NRefactory.VB.Ast;
using NUnit.Framework;
namespace ICSharpCode.NRefactory.VB.Tests.Ast
{
[TestFixture]
public class OptionDeclarationTests
{
[Test]
public void VBNetStrictOptionDeclarationTest()
{
string program = "Option Strict On\n";
OptionDeclaration opDec = ParseUtil.ParseGlobal<OptionDeclaration>(program);
Assert.AreEqual(OptionType.Strict, opDec.OptionType);
Assert.IsTrue(opDec.OptionValue);
}
[Test]
public void VBNetExplicitOptionDeclarationTest()
{
string program = "Option Explicit Off\n";
OptionDeclaration opDec = ParseUtil.ParseGlobal<OptionDeclaration>(program);
Assert.AreEqual(OptionType.Explicit, opDec.OptionType);
Assert.IsFalse(opDec.OptionValue, "Off option value excepted!");
}
[Test]
public void VBNetCompareBinaryOptionDeclarationTest()
{
string program = "Option Compare Binary\n";
OptionDeclaration opDec = ParseUtil.ParseGlobal<OptionDeclaration>(program);
Assert.AreEqual(OptionType.CompareBinary, opDec.OptionType);
Assert.IsTrue(opDec.OptionValue);
}
[Test]
public void VBNetCompareTextOptionDeclarationTest()
{
string program = "Option Compare Text\n";
OptionDeclaration opDec = ParseUtil.ParseGlobal<OptionDeclaration>(program);
Assert.AreEqual(OptionType.CompareText, opDec.OptionType);
Assert.IsTrue(opDec.OptionValue);
}
[Test]
public void VBNetInferOnOptionDeclarationTest()
{
string program = "Option Infer On\n";
OptionDeclaration opDec = ParseUtil.ParseGlobal<OptionDeclaration>(program);
Assert.AreEqual(OptionType.Infer, opDec.OptionType);
Assert.IsTrue(opDec.OptionValue);
}
[Test]
public void VBNetInferOffOptionDeclarationTest()
{
string program = "Option Infer\n";
OptionDeclaration opDec = ParseUtil.ParseGlobal<OptionDeclaration>(program);
Assert.AreEqual(OptionType.Infer, opDec.OptionType);
Assert.IsTrue(opDec.OptionValue);
}
[Test]
public void VBNetInferOptionDeclarationTest()
{
string program = "Option Infer\n";
OptionDeclaration opDec = ParseUtil.ParseGlobal<OptionDeclaration>(program);
Assert.AreEqual(OptionType.Infer, opDec.OptionType);
Assert.IsTrue(opDec.OptionValue);
}
[Test]
public void VBNetInvalidOptionDeclarationTest()
{
string program = "Option\n";
VBParser parser = ParserFactory.CreateParser(new StringReader(program));
parser.Parse();
Assert.IsFalse(parser.Errors.ErrorOutput.Length == 0, "Expected errors, but operation completed successfully");
}
}
}

113
NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/GlobalScope/OptionStatementTests.cs

@ -0,0 +1,113 @@ @@ -0,0 +1,113 @@
// 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.IO;
using ICSharpCode.NRefactory.VB.Parser;
using ICSharpCode.NRefactory.VB.Ast;
using NUnit.Framework;
namespace ICSharpCode.NRefactory.VB.Tests.Ast
{
[TestFixture]
public class OptionStatementTests
{
[Test]
public void InvalidOptionSyntax()
{
string program = "Option\n";
ParseUtil.ParseGlobal<OptionStatement>(program, true);
}
[Test]
public void StrictOption()
{
string program = "Option Strict On\n";
var node = new OptionStatement {
OptionType = OptionType.Strict,
OptionValue = OptionValue.On
};
ParseUtil.AssertGlobal(program, node);
}
[Test]
public void ExplicitOption()
{
string program = "Option Explicit Off\n";
var node = new OptionStatement {
OptionType = OptionType.Explicit,
OptionValue = OptionValue.Off
};
ParseUtil.AssertGlobal(program, node);
}
[Test]
public void CompareBinaryOption()
{
string program = "Option Compare Binary\n";
var node = new OptionStatement {
OptionType = OptionType.Compare,
OptionValue = OptionValue.Binary
};
ParseUtil.AssertGlobal(program, node);
}
[Test]
public void CompareTextOption()
{
string program = "Option Compare Text\n";
var node = new OptionStatement {
OptionType = OptionType.Compare,
OptionValue = OptionValue.Text
};
ParseUtil.AssertGlobal(program, node);
}
[Test]
public void InferOnOption()
{
string program = "Option Infer On\n";
var node = new OptionStatement {
OptionType = OptionType.Infer,
OptionValue = OptionValue.On
};
ParseUtil.AssertGlobal(program, node);
}
[Test]
public void InferOffOption()
{
string program = "Option Infer Off\n";
var node = new OptionStatement {
OptionType = OptionType.Infer,
OptionValue = OptionValue.Off
};
ParseUtil.AssertGlobal(program, node);
}
[Test]
public void InferOption()
{
string program = "Option Infer\n";
var node = new OptionStatement {
OptionType = OptionType.Infer,
OptionValue = OptionValue.On
};
ParseUtil.AssertGlobal(program, node);
}
}
}

378
NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/GlobalScope/TypeDeclarationTests.cs

@ -10,194 +10,194 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -10,194 +10,194 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
[TestFixture]
public class TypeDeclarationTests
{
#region VB.NET
[Test]
public void VBNetSimpleClassTypeDeclarationTest()
{
string program = "Class TestClass\n" +
"End Class\n";
TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>(program);
Assert.AreEqual("TestClass", td.Name);
Assert.AreEqual(ClassType.Class, td.Type);
Assert.AreEqual(1, td.StartLocation.Line, "start line");
Assert.AreEqual(1, td.BodyStartLocation.Line, "bodystart line");
Assert.AreEqual(16, td.BodyStartLocation.Column, "bodystart col");
Assert.AreEqual(2, td.EndLocation.Line, "end line");
Assert.AreEqual(10, td.EndLocation.Column, "end col");
}
[Test]
public void VBNetMissingBaseClassTest()
{
// SD2-1499: test that this invalid code doesn't crash
TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>("public class test inherits", true);
Assert.AreEqual(0, td.BaseTypes.Count);
}
[Test]
public void VBNetEnumWithBaseClassDeclarationTest()
{
string program = "Enum TestEnum As Byte\n" +
"End Enum\n";
TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>(program);
Assert.AreEqual("TestEnum", td.Name);
Assert.AreEqual(ClassType.Enum, td.Type);
Assert.AreEqual("System.Byte", td.BaseTypes[0].Type);
Assert.AreEqual(0, td.Children.Count);
}
[Test]
public void VBNetEnumOnSingleLine()
{
string program = "Enum TestEnum : A : B = 1 : C : End Enum";
TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>(program);
Assert.AreEqual("TestEnum", td.Name);
Assert.AreEqual(ClassType.Enum, td.Type);
Assert.AreEqual(3, td.Children.Count);
}
[Test]
public void VBNetEnumOnSingleLine2()
{
string program = "Enum TestEnum : A : : B = 1 :: C : End Enum";
TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>(program);
Assert.AreEqual("TestEnum", td.Name);
Assert.AreEqual(ClassType.Enum, td.Type);
Assert.AreEqual(3, td.Children.Count);
}
[Test]
public void VBNetEnumWithSystemBaseClassDeclarationTest()
{
string program = "Enum TestEnum As System.UInt16\n" +
"End Enum\n";
TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>(program);
Assert.AreEqual("TestEnum", td.Name);
Assert.AreEqual(ClassType.Enum, td.Type);
Assert.AreEqual("System.UInt16", td.BaseTypes[0].Type);
Assert.AreEqual(0, td.Children.Count);
}
[Test]
public void VBNetSimpleClassTypeDeclarationWithoutLastNewLineTest()
{
string program = "Class TestClass\n" +
"End Class";
TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>(program);
Assert.AreEqual("TestClass", td.Name);
Assert.AreEqual(ClassType.Class, td.Type);
Assert.AreEqual(1, td.StartLocation.Line, "start line");
Assert.AreEqual(2, td.EndLocation.Line, "end line");
}
[Test]
public void VBNetSimpleClassTypeDeclarationWithColon()
{
string program = "Class TestClass\n" +
" : \n" +
"End Class";
TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>(program);
Assert.AreEqual("TestClass", td.Name);
Assert.AreEqual(ClassType.Class, td.Type);
}
[Test]
public void VBNetSimplePartialClassTypeDeclarationTest()
{
string program = "Partial Class TestClass\n" +
"End Class\n";
TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>(program);
Assert.AreEqual("TestClass", td.Name);
Assert.AreEqual(ClassType.Class, td.Type);
Assert.AreEqual(Modifiers.Partial, td.Modifier);
}
[Test]
public void VBNetPartialPublicClass()
{
string program = "Partial Public Class TestClass\nEnd Class\n";
TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>(program);
Assert.AreEqual("TestClass", td.Name);
Assert.AreEqual(ClassType.Class, td.Type);
Assert.AreEqual(Modifiers.Partial | Modifiers.Public, td.Modifier);
}
[Test]
public void VBNetGenericClassTypeDeclarationTest()
{
string declr = @"
Public Class Test(Of T)
End Class
";
TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>(declr);
Assert.AreEqual(ClassType.Class, td.Type);
Assert.AreEqual("Test", td.Name);
Assert.AreEqual(Modifiers.Public, td.Modifier);
Assert.AreEqual(0, td.BaseTypes.Count);
Assert.AreEqual(1, td.Templates.Count);
Assert.AreEqual("T", td.Templates[0].Name);
}
[Test]
public void VBNetGenericClassWithConstraint()
{
string declr = @"
Public Class Test(Of T As IMyInterface)
End Class
";
TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>(declr);
Assert.AreEqual(ClassType.Class, td.Type);
Assert.AreEqual("Test", td.Name);
Assert.AreEqual(1, td.Templates.Count);
Assert.AreEqual("T", td.Templates[0].Name);
Assert.AreEqual("IMyInterface", td.Templates[0].Bases[0].Type);
}
[Test]
public void VBNetComplexGenericClassTypeDeclarationTest()
{
string declr = @"
Public Class Generic(Of T As MyNamespace.IMyInterface, S As {G(Of T()), IAnotherInterface})
Implements System.IComparable
End Class
";
TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>(declr);
Assert.AreEqual(ClassType.Class, td.Type);
Assert.AreEqual("Generic", td.Name);
Assert.AreEqual(Modifiers.Public, td.Modifier);
Assert.AreEqual(1, td.BaseTypes.Count);
Assert.AreEqual("System.IComparable", td.BaseTypes[0].Type);
Assert.AreEqual(2, td.Templates.Count);
Assert.AreEqual("T", td.Templates[0].Name);
Assert.AreEqual("MyNamespace.IMyInterface", td.Templates[0].Bases[0].Type);
Assert.AreEqual("S", td.Templates[1].Name);
Assert.AreEqual(2, td.Templates[1].Bases.Count);
Assert.AreEqual("G", td.Templates[1].Bases[0].Type);
Assert.AreEqual(1, td.Templates[1].Bases[0].GenericTypes.Count);
Assert.IsTrue(td.Templates[1].Bases[0].GenericTypes[0].IsArrayType);
Assert.AreEqual("T", td.Templates[1].Bases[0].GenericTypes[0].Type);
Assert.AreEqual(new int[] {0}, td.Templates[1].Bases[0].GenericTypes[0].RankSpecifier);
Assert.AreEqual("IAnotherInterface", td.Templates[1].Bases[1].Type);
}
#endregion
// #region VB.NET
// [Test]
// public void VBNetSimpleClassTypeDeclarationTest()
// {
// string program = "Class TestClass\n" +
// "End Class\n";
// TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>(program);
//
// Assert.AreEqual("TestClass", td.Name);
// Assert.AreEqual(ClassType.Class, td.Type);
// Assert.AreEqual(1, td.StartLocation.Line, "start line");
// Assert.AreEqual(1, td.BodyStartLocation.Line, "bodystart line");
// Assert.AreEqual(16, td.BodyStartLocation.Column, "bodystart col");
// Assert.AreEqual(2, td.EndLocation.Line, "end line");
// Assert.AreEqual(10, td.EndLocation.Column, "end col");
// }
//
// [Test]
// public void VBNetMissingBaseClassTest()
// {
// // SD2-1499: test that this invalid code doesn't crash
// TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>("public class test inherits", true);
// Assert.AreEqual(0, td.BaseTypes.Count);
// }
//
// [Test]
// public void VBNetEnumWithBaseClassDeclarationTest()
// {
// string program = "Enum TestEnum As Byte\n" +
// "End Enum\n";
// TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>(program);
//
// Assert.AreEqual("TestEnum", td.Name);
// Assert.AreEqual(ClassType.Enum, td.Type);
// Assert.AreEqual("System.Byte", td.BaseTypes[0].Type);
// Assert.AreEqual(0, td.Children.Count);
// }
//
// [Test]
// public void VBNetEnumOnSingleLine()
// {
// string program = "Enum TestEnum : A : B = 1 : C : End Enum";
// TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>(program);
//
// Assert.AreEqual("TestEnum", td.Name);
// Assert.AreEqual(ClassType.Enum, td.Type);
// Assert.AreEqual(3, td.Children.Count);
// }
//
// [Test]
// public void VBNetEnumOnSingleLine2()
// {
// string program = "Enum TestEnum : A : : B = 1 :: C : End Enum";
// TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>(program);
//
// Assert.AreEqual("TestEnum", td.Name);
// Assert.AreEqual(ClassType.Enum, td.Type);
// Assert.AreEqual(3, td.Children.Count);
// }
//
//
// [Test]
// public void VBNetEnumWithSystemBaseClassDeclarationTest()
// {
// string program = "Enum TestEnum As System.UInt16\n" +
// "End Enum\n";
// TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>(program);
//
// Assert.AreEqual("TestEnum", td.Name);
// Assert.AreEqual(ClassType.Enum, td.Type);
// Assert.AreEqual("System.UInt16", td.BaseTypes[0].Type);
// Assert.AreEqual(0, td.Children.Count);
// }
//
// [Test]
// public void VBNetSimpleClassTypeDeclarationWithoutLastNewLineTest()
// {
// string program = "Class TestClass\n" +
// "End Class";
// TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>(program);
//
// Assert.AreEqual("TestClass", td.Name);
// Assert.AreEqual(ClassType.Class, td.Type);
// Assert.AreEqual(1, td.StartLocation.Line, "start line");
// Assert.AreEqual(2, td.EndLocation.Line, "end line");
// }
//
// [Test]
// public void VBNetSimpleClassTypeDeclarationWithColon()
// {
// string program = "Class TestClass\n" +
// " : \n" +
// "End Class";
// TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>(program);
//
// Assert.AreEqual("TestClass", td.Name);
// Assert.AreEqual(ClassType.Class, td.Type);
// }
//
// [Test]
// public void VBNetSimplePartialClassTypeDeclarationTest()
// {
// string program = "Partial Class TestClass\n" +
// "End Class\n";
// TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>(program);
//
// Assert.AreEqual("TestClass", td.Name);
// Assert.AreEqual(ClassType.Class, td.Type);
// Assert.AreEqual(Modifiers.Partial, td.Modifier);
// }
//
// [Test]
// public void VBNetPartialPublicClass()
// {
// string program = "Partial Public Class TestClass\nEnd Class\n";
// TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>(program);
//
// Assert.AreEqual("TestClass", td.Name);
// Assert.AreEqual(ClassType.Class, td.Type);
// Assert.AreEqual(Modifiers.Partial | Modifiers.Public, td.Modifier);
// }
//
// [Test]
// public void VBNetGenericClassTypeDeclarationTest()
// {
// string declr = @"
//Public Class Test(Of T)
//
//End Class
//";
// TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>(declr);
//
// Assert.AreEqual(ClassType.Class, td.Type);
// Assert.AreEqual("Test", td.Name);
// Assert.AreEqual(Modifiers.Public, td.Modifier);
// Assert.AreEqual(0, td.BaseTypes.Count);
// Assert.AreEqual(1, td.Templates.Count);
// Assert.AreEqual("T", td.Templates[0].Name);
// }
//
// [Test]
// public void VBNetGenericClassWithConstraint()
// {
// string declr = @"
//Public Class Test(Of T As IMyInterface)
//
//End Class
//";
// TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>(declr);
//
// Assert.AreEqual(ClassType.Class, td.Type);
// Assert.AreEqual("Test", td.Name);
//
// Assert.AreEqual(1, td.Templates.Count);
// Assert.AreEqual("T", td.Templates[0].Name);
// Assert.AreEqual("IMyInterface", td.Templates[0].Bases[0].Type);
// }
//
// [Test]
// public void VBNetComplexGenericClassTypeDeclarationTest()
// {
// string declr = @"
//Public Class Generic(Of T As MyNamespace.IMyInterface, S As {G(Of T()), IAnotherInterface})
// Implements System.IComparable
//
//End Class
//";
// TypeDeclaration td = ParseUtil.ParseGlobal<TypeDeclaration>(declr);
//
// Assert.AreEqual(ClassType.Class, td.Type);
// Assert.AreEqual("Generic", td.Name);
// Assert.AreEqual(Modifiers.Public, td.Modifier);
// Assert.AreEqual(1, td.BaseTypes.Count);
// Assert.AreEqual("System.IComparable", td.BaseTypes[0].Type);
//
// Assert.AreEqual(2, td.Templates.Count);
// Assert.AreEqual("T", td.Templates[0].Name);
// Assert.AreEqual("MyNamespace.IMyInterface", td.Templates[0].Bases[0].Type);
//
// Assert.AreEqual("S", td.Templates[1].Name);
// Assert.AreEqual(2, td.Templates[1].Bases.Count);
// Assert.AreEqual("G", td.Templates[1].Bases[0].Type);
// Assert.AreEqual(1, td.Templates[1].Bases[0].GenericTypes.Count);
// Assert.IsTrue(td.Templates[1].Bases[0].GenericTypes[0].IsArrayType);
// Assert.AreEqual("T", td.Templates[1].Bases[0].GenericTypes[0].Type);
// Assert.AreEqual(new int[] {0}, td.Templates[1].Bases[0].GenericTypes[0].RankSpecifier);
// Assert.AreEqual("IAnotherInterface", td.Templates[1].Bases[1].Type);
// }
// #endregion
}
}

207
NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/GlobalScope/UsingDeclarationTests.cs

@ -1,207 +0,0 @@ @@ -1,207 +0,0 @@
// 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.IO;
using ICSharpCode.NRefactory.VB.Parser;
using ICSharpCode.NRefactory.VB.Ast;
using NUnit.Framework;
namespace ICSharpCode.NRefactory.VB.Tests.Ast
{
[TestFixture]
public class UsingDeclarationTests
{
void CheckTwoSimpleUsings(CompilationUnit u)
{
Assert.AreEqual(2, u.Children.Count);
Assert.IsTrue(u.Children[0] is UsingDeclaration);
UsingDeclaration ud = (UsingDeclaration)u.Children[0];
Assert.AreEqual(1, ud.Usings.Count);
Assert.IsTrue(!ud.Usings[0].IsAlias);
Assert.AreEqual("System", ud.Usings[0].Name);
Assert.IsTrue(u.Children[1] is UsingDeclaration);
ud = (UsingDeclaration)u.Children[1];
Assert.AreEqual(1, ud.Usings.Count);
Assert.IsTrue(!ud.Usings[0].IsAlias);
Assert.AreEqual("My.Name.Space", ud.Usings[0].Name);
}
void CheckAliases(CompilationUnit u)
{
Assert.AreEqual(3, u.Children.Count);
Assert.IsTrue(u.Children[0] is UsingDeclaration);
UsingDeclaration ud = (UsingDeclaration)u.Children[0];
Assert.AreEqual(1, ud.Usings.Count);
Assert.IsTrue(((Using)ud.Usings[0]).IsAlias);
Assert.AreEqual("TESTME", ud.Usings[0].Name);
Assert.AreEqual("System", ud.Usings[0].Alias.Type);
Assert.IsTrue(u.Children[1] is UsingDeclaration);
ud = (UsingDeclaration)u.Children[1];
Assert.AreEqual(1, ud.Usings.Count);
Assert.IsTrue(((Using)ud.Usings[0]).IsAlias);
Assert.AreEqual("myAlias", ud.Usings[0].Name);
Assert.AreEqual("My.Name.Space", ud.Usings[0].Alias.Type);
Assert.IsTrue(u.Children[2] is UsingDeclaration);
ud = (UsingDeclaration)u.Children[2];
Assert.AreEqual(1, ud.Usings.Count);
Assert.IsTrue(((Using)ud.Usings[0]).IsAlias);
Assert.AreEqual("StringCollection", ud.Usings[0].Name);
Assert.AreEqual("System.Collections.Generic.List", ud.Usings[0].Alias.Type);
Assert.AreEqual("System.String", ud.Usings[0].Alias.GenericTypes[0].Type);
}
#region VB.NET
[Test]
public void VBNetWrongUsingTest()
{
string program = "Imports\n";
VBParser parser = ParserFactory.CreateParser(new StringReader(program));
parser.Parse();
Assert.IsTrue(parser.Errors.Count > 0);
UsingDeclaration u = (UsingDeclaration)parser.CompilationUnit.Children[0];
foreach (Using us in u.Usings) {
Assert.IsNotNull(us);
}
}
[Test]
public void VBNetWrongUsing2Test()
{
string program = "Imports ,\n";
VBParser parser = ParserFactory.CreateParser(new StringReader(program));
parser.Parse();
Assert.IsTrue(parser.Errors.Count > 0);
UsingDeclaration u = (UsingDeclaration)parser.CompilationUnit.Children[0];
foreach (Using us in u.Usings) {
Assert.IsNotNull(us);
}
}
[Test]
public void VBNetDeclarationTest()
{
string program = "Imports System\n" +
"Imports My.Name.Space\n";
VBParser parser = ParserFactory.CreateParser(new StringReader(program));
parser.Parse();
Assert.AreEqual("", parser.Errors.ErrorOutput);
CheckTwoSimpleUsings(parser.CompilationUnit);
}
[Test]
public void VBNetUsingAliasDeclarationTest()
{
string program = "Imports TESTME=System\n" +
"Imports myAlias=My.Name.Space\n" +
"Imports StringCollection = System.Collections.Generic.List(Of string)\n";
VBParser parser = ParserFactory.CreateParser(new StringReader(program));
parser.Parse();
Assert.AreEqual("", parser.Errors.ErrorOutput);
CheckAliases(parser.CompilationUnit);
}
[Test]
public void VBNetComplexUsingAliasDeclarationTest()
{
string program = "Imports NS1, AL=NS2, NS3, AL2=NS4, NS5\n";
VBParser parser = ParserFactory.CreateParser(new StringReader(program));
parser.Parse();
Assert.AreEqual("", parser.Errors.ErrorOutput);
// TODO : Extend test ...
}
[Test]
public void VBNetXmlNamespaceUsingTest()
{
string program = "Imports <xmlns=\"http://icsharpcode.net/sharpdevelop/avalonedit\">";
VBParser parser = ParserFactory.CreateParser(new StringReader(program));
parser.Parse();
Assert.AreEqual("", parser.Errors.ErrorOutput);
CompilationUnit unit = parser.CompilationUnit;
Assert.AreEqual(1, unit.Children.Count);
Assert.IsTrue(unit.Children[0] is UsingDeclaration);
UsingDeclaration ud = (UsingDeclaration)unit.Children[0];
Assert.AreEqual(1, ud.Usings.Count);
Assert.IsFalse(ud.Usings[0].IsAlias);
Assert.IsTrue(ud.Usings[0].IsXml);
Assert.AreEqual("xmlns", ud.Usings[0].XmlPrefix);
Assert.AreEqual("http://icsharpcode.net/sharpdevelop/avalonedit", ud.Usings[0].Name);
}
[Test]
public void VBNetXmlNamespaceWithPrefixUsingTest()
{
string program = "Imports <xmlns:avalonedit=\"http://icsharpcode.net/sharpdevelop/avalonedit\">";
VBParser parser = ParserFactory.CreateParser(new StringReader(program));
parser.Parse();
Assert.AreEqual("", parser.Errors.ErrorOutput);
CompilationUnit unit = parser.CompilationUnit;
Assert.AreEqual(1, unit.Children.Count);
Assert.IsTrue(unit.Children[0] is UsingDeclaration);
UsingDeclaration ud = (UsingDeclaration)unit.Children[0];
Assert.AreEqual(1, ud.Usings.Count);
Assert.IsFalse(ud.Usings[0].IsAlias);
Assert.IsTrue(ud.Usings[0].IsXml);
Assert.AreEqual("xmlns:avalonedit", ud.Usings[0].XmlPrefix);
Assert.AreEqual("http://icsharpcode.net/sharpdevelop/avalonedit", ud.Usings[0].Name);
}
[Test]
public void VBNetXmlNamespaceSingleQuotedUsingTest()
{
string program = "Imports <xmlns='http://icsharpcode.net/sharpdevelop/avalonedit'>";
VBParser parser = ParserFactory.CreateParser(new StringReader(program));
parser.Parse();
Assert.AreEqual("", parser.Errors.ErrorOutput);
CompilationUnit unit = parser.CompilationUnit;
Assert.AreEqual(1, unit.Children.Count);
Assert.IsTrue(unit.Children[0] is UsingDeclaration);
UsingDeclaration ud = (UsingDeclaration)unit.Children[0];
Assert.AreEqual(1, ud.Usings.Count);
Assert.IsFalse(ud.Usings[0].IsAlias);
Assert.IsTrue(ud.Usings[0].IsXml);
Assert.AreEqual("xmlns", ud.Usings[0].XmlPrefix);
Assert.AreEqual("http://icsharpcode.net/sharpdevelop/avalonedit", ud.Usings[0].Name);
}
[Test]
public void VBNetXmlNamespaceSingleQuotedWithPrefixUsingTest()
{
string program = "Imports <xmlns:avalonedit='http://icsharpcode.net/sharpdevelop/avalonedit'>";
VBParser parser = ParserFactory.CreateParser(new StringReader(program));
parser.Parse();
Assert.AreEqual("", parser.Errors.ErrorOutput);
CompilationUnit unit = parser.CompilationUnit;
Assert.AreEqual(1, unit.Children.Count);
Assert.IsTrue(unit.Children[0] is UsingDeclaration);
UsingDeclaration ud = (UsingDeclaration)unit.Children[0];
Assert.AreEqual(1, ud.Usings.Count);
Assert.IsFalse(ud.Usings[0].IsAlias);
Assert.IsTrue(ud.Usings[0].IsXml);
Assert.AreEqual("xmlns:avalonedit", ud.Usings[0].XmlPrefix);
Assert.AreEqual("http://icsharpcode.net/sharpdevelop/avalonedit", ud.Usings[0].Name);
}
#endregion
}
}

26
NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/LocationAssignmentCheckVisitor.cs

@ -1,26 +0,0 @@ @@ -1,26 +0,0 @@
// 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 ICSharpCode.NRefactory.VB.Ast;
using ICSharpCode.NRefactory.VB.Visitors;
using NUnit.Framework;
namespace ICSharpCode.NRefactory.VB.Tests.Ast
{
public class LocationAssignmentCheckVisitor : NodeTrackingAstVisitor
{
protected override void BeginVisit(INode node)
{
if (node is CompilationUnit)
return;
if (node is INullable && ((INullable)node).IsNull)
return;
if (node is TypeReference)
return;
Assert.IsFalse(node.StartLocation.IsEmpty, "StartLocation of {0}", node);
Assert.IsFalse(node.EndLocation.IsEmpty, "EndLocation of {0}", node);
}
}
}

148
NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/ParseUtil.cs

@ -3,90 +3,106 @@ @@ -3,90 +3,106 @@
using System;
using System.IO;
using ICSharpCode.NRefactory.VB.Parser;
using System.Linq;
using ICSharpCode.NRefactory.PatternMatching;
using ICSharpCode.NRefactory.VB.Ast;
using ICSharpCode.NRefactory.VB.Parser;
using NUnit.Framework;
namespace ICSharpCode.NRefactory.VB.Tests.Ast
{
public class ParseUtil
{
public static T ParseGlobal<T>(string program) where T : INode
{
return ParseGlobal<T>(program, false);
}
public static T ParseGlobal<T>(string program, bool expectErrors) where T : INode
public static T ParseGlobal<T>(string code, bool expectErrors = false) where T : AstNode
{
VBParser parser = ParserFactory.CreateParser(new StringReader(program));
parser.Parse();
VBParser parser = new VBParser();
CompilationUnit cu = parser.Parse(new StringReader(code));
if (expectErrors)
Assert.IsFalse(parser.Errors.ErrorOutput.Length == 0, "Expected errors, but operation completed successfully");
else
Assert.AreEqual("", parser.Errors.ErrorOutput);
Assert.IsNotNull(parser.CompilationUnit);
Assert.IsNotNull(parser.CompilationUnit.Children);
Assert.IsNotNull(parser.CompilationUnit.Children[0]);
Assert.AreEqual(1, parser.CompilationUnit.Children.Count);
Assert.AreEqual(expectErrors, parser.HasErrors, "HasErrors");
AstNode node = cu.Children.Single();
Type type = typeof(T);
Assert.IsTrue(type.IsAssignableFrom(parser.CompilationUnit.Children[0].GetType()), String.Format("Parsed expression was {0} instead of {1} ({2})", parser.CompilationUnit.Children[0].GetType(), type, parser.CompilationUnit.Children[0]));
parser.CompilationUnit.AcceptVisitor(new CheckParentVisitor(), null);
// TODO fix Locations
// parser.CompilationUnit.AcceptChildren(new LocationAssignmentCheckVisitor(), null);
return (T)parser.CompilationUnit.Children[0];
Assert.IsTrue(type.IsAssignableFrom(node.GetType()), String.Format("Parsed node was {0} instead of {1} ({2})", node.GetType(), type, node));
return (T)node;
}
public static T ParseTypeMember<T>(string typeMember, bool expectErrors) where T : INode
public static void AssertGlobal(string code, AstNode expectedNode)
{
TypeDeclaration td = ParseGlobal<TypeDeclaration>("Class TestClass\n " + typeMember + "\n End Class\n", expectErrors);
Assert.AreEqual(1, td.Children.Count);
Type type = typeof(T);
Assert.IsTrue(type.IsAssignableFrom(td.Children[0].GetType()), String.Format("Parsed expression was {0} instead of {1} ({2})", td.GetType(), type, td));
return (T)td.Children[0];
var node = ParseGlobal<AstNode>(code);
if (!expectedNode.IsMatch(node)) {
Assert.Fail("Expected '{0}' but was '{1}'", ToVB(expectedNode), ToVB(node));
}
}
public static T ParseTypeMember<T>(string typeMember) where T : INode
{
return ParseTypeMember<T>(typeMember, false);
}
// public static T ParseStatement<T>(string stmt, bool expectErrors = false) where T : AstNode
// {
// VBParser parser = new VBParser();
// var statements = parser.ParseStatements(new StringReader(stmt));
//
// Assert.AreEqual(expectErrors, parser.HasErrors, "HasErrors");
//
// AstNode statement = statements.Single();
// Type type = typeof(T);
// Assert.IsTrue(type.IsAssignableFrom(statement.GetType()), String.Format("Parsed statement was {0} instead of {1} ({2})", statement.GetType(), type, statement));
// return (T)statement;
// }
//
// public static void AssertStatement(string code, VB.Ast.Statement expectedStmt)
// {
// var stmt = ParseStatement<VB.Ast.Statement>(code);
// if (!expectedStmt.IsMatch(stmt)) {
// Assert.Fail("Expected '{0}' but was '{1}'", ToCSharp(expectedStmt), ToCSharp(stmt));
// }
// }
//
// public static T ParseExpression<T>(string expr, bool expectErrors = false) where T : AstNode
// {
// VBParser parser = new VBParser();
// AstNode parsedExpression = parser.ParseExpression(new StringReader(expr));
//
// Assert.AreEqual(expectErrors, parser.HasErrors, "HasErrors");
// if (expectErrors && parsedExpression == null)
// return default (T);
// Type type = typeof(T);
// Assert.IsTrue(type.IsAssignableFrom(parsedExpression.GetType()), String.Format("Parsed expression was {0} instead of {1} ({2})", parsedExpression.GetType(), type, parsedExpression));
// return (T)parsedExpression;
// }
//
// public static void AssertExpression(string code, VB.Ast.Expression expectedExpr)
// {
// var expr = ParseExpression<CSharp.Expression>(code);
// if (!expectedExpr.IsMatch(expr)) {
// Assert.Fail("Expected '{0}' but was '{1}'", ToCSharp(expectedExpr), ToCSharp(expr));
// }
// }
//
// public static T ParseTypeMember<T>(string expr, bool expectErrors = false) where T : AttributedNode
// {
// VBParser parser = new VBParser();
// var members = parser.ParseTypeMembers(new StringReader(expr));
//
// Assert.AreEqual(expectErrors, parser.HasErrors, "HasErrors");
//
// AttributedNode m = members.Single();
// Type type = typeof(T);
// Assert.IsTrue(type.IsAssignableFrom(m.GetType()), String.Format("Parsed member was {0} instead of {1} ({2})", m.GetType(), type, m));
// return (T)m;
// }
//
// public static void AssertTypeMember(string code, VB.Ast.AttributedNode expectedMember)
// {
// var member = ParseTypeMember<VB.Ast.AttributedNode>(code);
// if (!expectedMember.IsMatch(member)) {
// Assert.Fail("Expected '{0}' but was '{1}'", ToVB(expectedMember), ToVB(member));
// }
// }
public static T ParseStatement<T>(string statement, bool expectErrors) where T : INode
static string ToVB(AstNode node)
{
MethodDeclaration md = ParseTypeMember<MethodDeclaration>("Sub A()\n " + statement + "\nEnd Sub\n", expectErrors);
Assert.AreEqual(1, md.Body.Children.Count);
Type type = typeof(T);
Assert.IsTrue(type.IsAssignableFrom(md.Body.Children[0].GetType()), String.Format("Parsed expression was {0} instead of {1} ({2})", md.GetType(), type, md));
return (T)md.Body.Children[0];
}
public static T ParseStatement<T>(string statement) where T : INode
{
return ParseStatement<T>(statement, false);
}
public static T ParseExpression<T>(string expr) where T : INode
{
return ParseExpression<T>(expr, false);
}
public static T ParseExpression<T>(string expr, bool expectErrors) where T : INode
{
VBParser parser = ParserFactory.CreateParser(new StringReader(expr));
INode parsedExpression = parser.ParseExpression();
if (expectErrors)
Assert.IsFalse(parser.Errors.ErrorOutput.Length == 0, "Expected errors, but operation completed successfully");
else
Assert.AreEqual("", parser.Errors.ErrorOutput);
// TODO fix Locations
// parsedExpression.AcceptVisitor(new LocationAssignmentCheckVisitor(), null);
Type type = typeof(T);
Assert.IsTrue(type.IsAssignableFrom(parsedExpression.GetType()), String.Format("Parsed expression was {0} instead of {1} ({2})", parsedExpression.GetType(), type, parsedExpression));
return (T)parsedExpression;
StringWriter w = new StringWriter();
node.AcceptVisitor(new OutputVisitor(w, new VBFormattingOptions()), null);
return w.ToString();
}
}
}

16
NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/SnippetParserTests.cs

@ -10,13 +10,13 @@ namespace ICSharpCode.NRefactory.VB.Tests @@ -10,13 +10,13 @@ namespace ICSharpCode.NRefactory.VB.Tests
[TestFixture]
public class SnippetParserTests
{
[Test]
public void InvalidExpressionSyntax()
{
// SD2-1584: ensure we don't crash on this invalid VB code
SnippetParser parser = new SnippetParser();
INode node = parser.Parse("i == 5");
Assert.IsTrue(parser.Errors.Count > 0);
}
// [Test]
// public void InvalidExpressionSyntax()
// {
// // SD2-1584: ensure we don't crash on this invalid VB code
// SnippetParser parser = new SnippetParser();
// INode node = parser.Parse("i == 5");
// Assert.IsTrue(parser.Errors.Count > 0);
// }
}
}

4
NRefactory/ICSharpCode.NRefactory.VB.Tests/Parser/Statements/SwitchStatementTests.cs

@ -17,7 +17,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -17,7 +17,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
public void VBSwitchStatementTest()
{
SwitchStatement switchStmt = ParseUtil.ParseStatement<SwitchStatement>("Select Case a\n Case 4, 5\n Case 6\n Case Else\n End Select");
Assert.AreEqual("a", ((IdentifierExpression)switchStmt.SwitchExpression).Identifier);
Assert.AreEqual("a", ((SimpleNameExpression)switchStmt.SwitchExpression).Identifier);
// TODO: Extend test
}
@ -25,7 +25,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast @@ -25,7 +25,7 @@ namespace ICSharpCode.NRefactory.VB.Tests.Ast
public void InvalidVBSwitchStatementTest()
{
SwitchStatement switchStmt = ParseUtil.ParseStatement<SwitchStatement>("Select Case a\n Case \n End Select", true);
Assert.AreEqual("a", ((IdentifierExpression)switchStmt.SwitchExpression).Identifier);
Assert.AreEqual("a", ((SimpleNameExpression)switchStmt.SwitchExpression).Identifier);
SwitchSection sec = switchStmt.SwitchSections[0];
Assert.AreEqual(0, sec.SwitchLabels.Count);
}

73
NRefactory/ICSharpCode.NRefactory.VB/Ast/AbstractNode.cs

@ -1,73 +0,0 @@ @@ -1,73 +0,0 @@
// 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.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
namespace ICSharpCode.NRefactory.VB.Ast
{
public abstract class AbstractNode : INode
{
List<INode> children = new List<INode>();
public INode Parent { get; set; }
public Location StartLocation { get; set; }
public Location EndLocation { get; set; }
public object UserData { get; set; }
public List<INode> Children {
get {
return children;
}
set {
Debug.Assert(value != null);
children = value;
}
}
public virtual void AddChild(INode childNode)
{
Debug.Assert(childNode != null);
childNode.Parent = this;
children.Add(childNode);
}
public abstract object AcceptVisitor(IAstVisitor visitor, object data);
public virtual object AcceptChildren(IAstVisitor visitor, object data)
{
foreach (INode child in children) {
Debug.Assert(child != null);
child.AcceptVisitor(visitor, data);
}
return data;
}
public static string GetCollectionString(ICollection collection)
{
StringBuilder output = new StringBuilder();
output.Append('{');
if (collection != null) {
IEnumerator en = collection.GetEnumerator();
bool isFirst = true;
while (en.MoveNext()) {
if (!isFirst) {
output.Append(", ");
} else {
isFirst = false;
}
output.Append(en.Current == null ? "<null>" : en.Current.ToString());
}
} else {
return "null";
}
output.Append('}');
return output.ToString();
}
}
}

137
NRefactory/ICSharpCode.NRefactory.VB/Ast/AstLocation.cs

@ -0,0 +1,137 @@ @@ -0,0 +1,137 @@
//
// DomLocation.cs
//
// Author:
// Mike Krüger <mkrueger@novell.com>
//
// Copyright (C) 2008 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
using System;
namespace ICSharpCode.NRefactory.VB
{
[Serializable]
public struct AstLocation : IComparable<AstLocation>, IEquatable<AstLocation>
{
public static readonly AstLocation Empty = new AstLocation(0, 0);
readonly int line, column;
public AstLocation (int line, int column)
{
this.line = line;
this.column = column;
}
public bool IsEmpty {
get {
return line <= 0;
}
}
public int Line {
get { return line; }
}
public int Column {
get { return column; }
}
public override bool Equals (object obj)
{
if (!(obj is AstLocation))
return false;
return (AstLocation)obj == this;
}
public override int GetHashCode ()
{
unchecked {
return line + column * 5000;
}
}
public bool Equals (AstLocation other)
{
return other == this;
}
public int CompareTo (AstLocation other)
{
if (this == other)
return 0;
if (this < other)
return -1;
return 1;
}
public override string ToString ()
{
return String.Format ("(Line {0}, Column {1})", Line, Column);
}
public static AstLocation FromInvariantString (string invariantString)
{
if (string.Equals(invariantString, "EMPTY", StringComparison.OrdinalIgnoreCase))
return AstLocation.Empty;
string[] splits = invariantString.Split (',', '/');
if (splits.Length == 2)
return new AstLocation (Int32.Parse (splits[0]), Int32.Parse (splits[1]));
return AstLocation.Empty;
}
public string ToInvariantString ()
{
if (IsEmpty)
return "Empty";
return String.Format ("{0}/{1}", line, column);
}
public static bool operator==(AstLocation left, AstLocation right)
{
return left.line == right.line && left.column == right.column;
}
public static bool operator!=(AstLocation left, AstLocation right)
{
return left.line != right.line || left.column != right.column;
}
public static bool operator<(AstLocation left, AstLocation right)
{
return left.line < right.line || left.line == right.line && left.column < right.column;
}
public static bool operator>(AstLocation left, AstLocation right)
{
return left.line > right.line || left.line == right.line && left.column > right.column;
}
public static bool operator<=(AstLocation left, AstLocation right)
{
return !(left > right);
}
public static bool operator>=(AstLocation left, AstLocation right)
{
return !(left < right);
}
}
}

730
NRefactory/ICSharpCode.NRefactory.VB/Ast/AstNode.cs

@ -0,0 +1,730 @@ @@ -0,0 +1,730 @@
//
// AstNode.cs
//
// Author:
// Mike Krüger <mkrueger@novell.com>
//
// Copyright (c) 2009 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using ICSharpCode.NRefactory.PatternMatching;
using ICSharpCode.NRefactory.VB.Ast;
namespace ICSharpCode.NRefactory.VB
{
public abstract class AstNode : PatternMatching.INode
{
#region Null
public static readonly AstNode Null = new NullAstNode ();
sealed class NullAstNode : AstNode
{
public override bool IsNull {
get {
return true;
}
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{
return default (S);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return other == null || other.IsNull;
}
}
#endregion
#region PatternPlaceholder
public static implicit operator AstNode(PatternMatching.Pattern pattern)
{
return pattern != null ? new PatternPlaceholder(pattern) : null;
}
sealed class PatternPlaceholder : AstNode, PatternMatching.INode
{
readonly PatternMatching.Pattern child;
public PatternPlaceholder(PatternMatching.Pattern child)
{
this.child = child;
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitPatternPlaceholder(this, child, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return child.DoMatch(other, match);
}
bool PatternMatching.INode.DoMatchCollection(Role role, PatternMatching.INode pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo backtrackingInfo)
{
return child.DoMatchCollection(role, pos, match, backtrackingInfo);
}
}
#endregion
AstNode parent;
AstNode prevSibling;
AstNode nextSibling;
AstNode firstChild;
AstNode lastChild;
Role role = RootRole;
public virtual bool IsNull {
get {
return false;
}
}
public virtual AstLocation StartLocation {
get {
var child = firstChild;
if (child == null)
return AstLocation.Empty;
return child.StartLocation;
}
}
public virtual AstLocation EndLocation {
get {
var child = lastChild;
if (child == null)
return AstLocation.Empty;
return child.EndLocation;
}
}
public AstNode Parent {
get { return parent; }
}
public Role Role {
get { return role; }
}
public AstNode NextSibling {
get { return nextSibling; }
}
public AstNode PrevSibling {
get { return prevSibling; }
}
public AstNode FirstChild {
get { return firstChild; }
}
public AstNode LastChild {
get { return lastChild; }
}
public IEnumerable<AstNode> Children {
get {
AstNode next;
for (AstNode cur = firstChild; cur != null; cur = next) {
Debug.Assert(cur.parent == this);
// Remember next before yielding cur.
// This allows removing/replacing nodes while iterating through the list.
next = cur.nextSibling;
yield return cur;
}
}
}
/// <summary>
/// Gets the ancestors of this node (excluding this node itself)
/// </summary>
public IEnumerable<AstNode> Ancestors {
get {
for (AstNode cur = parent; cur != null; cur = cur.parent) {
yield return cur;
}
}
}
/// <summary>
/// Gets all descendants of this node (excluding this node itself).
/// </summary>
public IEnumerable<AstNode> Descendants {
get {
return Utils.TreeTraversal.PreOrder(this.Children, n => n.Children);
}
}
/// <summary>
/// Gets all descendants of this node (including this node itself).
/// </summary>
public IEnumerable<AstNode> DescendantsAndSelf {
get {
return Utils.TreeTraversal.PreOrder(this, n => n.Children);
}
}
/// <summary>
/// Gets the first child with the specified role.
/// Returns the role's null object if the child is not found.
/// </summary>
public T GetChildByRole<T>(Role<T> role) where T : AstNode
{
if (role == null)
throw new ArgumentNullException("role");
for (var cur = firstChild; cur != null; cur = cur.nextSibling) {
if (cur.role == role)
return (T)cur;
}
return role.NullObject;
}
public AstNodeCollection<T> GetChildrenByRole<T>(Role<T> role) where T : AstNode
{
return new AstNodeCollection<T>(this, role);
}
protected void SetChildByRole<T>(Role<T> role, T newChild) where T : AstNode
{
AstNode oldChild = GetChildByRole(role);
if (oldChild.IsNull)
AddChild(newChild, role);
else
oldChild.ReplaceWith(newChild);
}
public void AddChild<T>(T child, Role<T> role) where T : AstNode
{
if (role == null)
throw new ArgumentNullException("role");
if (child == null || child.IsNull)
return;
if (this.IsNull)
throw new InvalidOperationException("Cannot add children to null nodes");
if (child.parent != null)
throw new ArgumentException ("Node is already used in another tree.", "child");
AddChildUnsafe(child, role);
}
internal void AddChildUntyped(AstNode child, Role role)
{
if (role == null)
throw new ArgumentNullException("role");
if (child == null || child.IsNull)
return;
if (this.IsNull)
throw new InvalidOperationException("Cannot add children to null nodes");
if (child.parent != null)
throw new ArgumentException ("Node is already used in another tree.", "child");
AddChildUnsafe(child, role);
}
/// <summary>
/// Adds a child without performing any safety checks.
/// </summary>
void AddChildUnsafe(AstNode child, Role role)
{
child.parent = this;
child.role = role;
if (firstChild == null) {
lastChild = firstChild = child;
} else {
lastChild.nextSibling = child;
child.prevSibling = lastChild;
lastChild = child;
}
}
public void InsertChildBefore<T>(AstNode nextSibling, T child, Role<T> role) where T : AstNode
{
if (role == null)
throw new ArgumentNullException("role");
if (nextSibling == null || nextSibling.IsNull) {
AddChild(child, role);
return;
}
if (child == null || child.IsNull)
return;
if (child.parent != null)
throw new ArgumentException ("Node is already used in another tree.", "child");
if (nextSibling.parent != this)
throw new ArgumentException ("NextSibling is not a child of this node.", "nextSibling");
// No need to test for "Cannot add children to null nodes",
// as there isn't any valid nextSibling in null nodes.
InsertChildBeforeUnsafe(nextSibling, child, role);
}
void InsertChildBeforeUnsafe(AstNode nextSibling, AstNode child, Role role)
{
child.parent = this;
child.role = role;
child.nextSibling = nextSibling;
child.prevSibling = nextSibling.prevSibling;
if (nextSibling.prevSibling != null) {
Debug.Assert(nextSibling.prevSibling.nextSibling == nextSibling);
nextSibling.prevSibling.nextSibling = child;
} else {
Debug.Assert(firstChild == nextSibling);
firstChild = child;
}
nextSibling.prevSibling = child;
}
public void InsertChildAfter<T>(AstNode prevSibling, T child, Role<T> role) where T : AstNode
{
InsertChildBefore((prevSibling == null || prevSibling.IsNull) ? firstChild : prevSibling.nextSibling, child, role);
}
/// <summary>
/// Removes this node from its parent.
/// </summary>
public void Remove()
{
if (parent != null) {
if (prevSibling != null) {
Debug.Assert(prevSibling.nextSibling == this);
prevSibling.nextSibling = nextSibling;
} else {
Debug.Assert(parent.firstChild == this);
parent.firstChild = nextSibling;
}
if (nextSibling != null) {
Debug.Assert(nextSibling.prevSibling == this);
nextSibling.prevSibling = prevSibling;
} else {
Debug.Assert(parent.lastChild == this);
parent.lastChild = prevSibling;
}
parent = null;
role = Roles.Root;
prevSibling = null;
nextSibling = null;
}
}
/// <summary>
/// Replaces this node with the new node.
/// </summary>
public void ReplaceWith(AstNode newNode)
{
if (newNode == null || newNode.IsNull) {
Remove();
return;
}
if (newNode == this)
return; // nothing to do...
if (parent == null) {
throw new InvalidOperationException(this.IsNull ? "Cannot replace the null nodes" : "Cannot replace the root node");
}
// Because this method doesn't statically check the new node's type with the role,
// we perform a runtime test:
if (!role.IsValid(newNode)) {
throw new ArgumentException (string.Format("The new node '{0}' is not valid in the role {1}", newNode.GetType().Name, role.ToString()), "newNode");
}
if (newNode.parent != null) {
// newNode is used within this tree?
if (newNode.Ancestors.Contains(this)) {
// e.g. "parenthesizedExpr.ReplaceWith(parenthesizedExpr.Expression);"
// enable automatic removal
newNode.Remove();
} else {
throw new ArgumentException ("Node is already used in another tree.", "newNode");
}
}
newNode.parent = parent;
newNode.role = role;
newNode.prevSibling = prevSibling;
newNode.nextSibling = nextSibling;
if (parent != null) {
if (prevSibling != null) {
Debug.Assert(prevSibling.nextSibling == this);
prevSibling.nextSibling = newNode;
} else {
Debug.Assert(parent.firstChild == this);
parent.firstChild = newNode;
}
if (nextSibling != null) {
Debug.Assert(nextSibling.prevSibling == this);
nextSibling.prevSibling = newNode;
} else {
Debug.Assert(parent.lastChild == this);
parent.lastChild = newNode;
}
parent = null;
prevSibling = null;
nextSibling = null;
role = Roles.Root;
}
}
public AstNode ReplaceWith(Func<AstNode, AstNode> replaceFunction)
{
if (replaceFunction == null)
throw new ArgumentNullException("replaceFunction");
if (parent == null) {
throw new InvalidOperationException(this.IsNull ? "Cannot replace the null nodes" : "Cannot replace the root node");
}
AstNode oldParent = parent;
AstNode oldSuccessor = nextSibling;
Role oldRole = role;
Remove();
AstNode replacement = replaceFunction(this);
if (oldSuccessor != null && oldSuccessor.parent != oldParent)
throw new InvalidOperationException("replace function changed nextSibling of node being replaced?");
if (!(replacement == null || replacement.IsNull)) {
if (replacement.parent != null)
throw new InvalidOperationException("replace function must return the root of a tree");
if (!oldRole.IsValid(replacement)) {
throw new InvalidOperationException (string.Format("The new node '{0}' is not valid in the role {1}", replacement.GetType().Name, oldRole.ToString()));
}
if (oldSuccessor != null)
oldParent.InsertChildBeforeUnsafe(oldSuccessor, replacement, oldRole);
else
oldParent.AddChildUnsafe(replacement, oldRole);
}
return replacement;
}
/// <summary>
/// Clones the whole subtree starting at this AST node.
/// </summary>
/// <remarks>Annotations are copied over to the new nodes; and any annotations implementating ICloneable will be cloned.</remarks>
public AstNode Clone()
{
AstNode copy = (AstNode)MemberwiseClone();
// First, reset the shallow pointer copies
copy.parent = null;
copy.role = Roles.Root;
copy.firstChild = null;
copy.lastChild = null;
copy.prevSibling = null;
copy.nextSibling = null;
// Then perform a deep copy:
for (AstNode cur = firstChild; cur != null; cur = cur.nextSibling) {
copy.AddChildUnsafe(cur.Clone(), cur.role);
}
// Finally, clone the annotation, if necessary
ICloneable annotations = copy.annotations as ICloneable; // read from copy (for thread-safety)
if (annotations != null)
copy.annotations = annotations.Clone();
return copy;
}
#region Annotation support
// Annotations: points either null (no annotations), to the single annotation,
// or to an AnnotationList.
// Once it is pointed at an AnnotationList, it will never change (this allows thread-safety support by locking the list)
object annotations;
sealed class AnnotationList : List<object>, ICloneable
{
// There are two uses for this custom list type:
// 1) it's private, and thus (unlike List<object>) cannot be confused with real annotations
// 2) It allows us to simplify the cloning logic by making the list behave the same as a clonable annotation.
public AnnotationList(int initialCapacity) : base(initialCapacity)
{
}
public object Clone()
{
lock (this) {
AnnotationList copy = new AnnotationList(this.Count);
for (int i = 0; i < this.Count; i++) {
object obj = this[i];
ICloneable c = obj as ICloneable;
copy.Add(c != null ? c.Clone() : obj);
}
return copy;
}
}
}
public void AddAnnotation(object annotation)
{
if (annotation == null)
throw new ArgumentNullException("annotation");
if (this.IsNull)
throw new InvalidOperationException("Cannot add annotations to the null node");
retry: // Retry until successful
object oldAnnotation = Interlocked.CompareExchange(ref this.annotations, annotation, null);
if (oldAnnotation == null) {
return; // we successfully added a single annotation
}
AnnotationList list = oldAnnotation as AnnotationList;
if (list == null) {
// we need to transform the old annotation into a list
list = new AnnotationList(4);
list.Add(oldAnnotation);
list.Add(annotation);
if (Interlocked.CompareExchange(ref this.annotations, list, oldAnnotation) != oldAnnotation) {
// the transformation failed (some other thread wrote to this.annotations first)
goto retry;
}
} else {
// once there's a list, use simple locking
lock (list) {
list.Add(annotation);
}
}
}
public void RemoveAnnotations<T>() where T : class
{
retry: // Retry until successful
object oldAnnotations = this.annotations;
AnnotationList list = oldAnnotations as AnnotationList;
if (list != null) {
lock (list)
list.RemoveAll(obj => obj is T);
} else if (oldAnnotations is T) {
if (Interlocked.CompareExchange(ref this.annotations, null, oldAnnotations) != oldAnnotations) {
// Operation failed (some other thread wrote to this.annotations first)
goto retry;
}
}
}
public void RemoveAnnotations(Type type)
{
if (type == null)
throw new ArgumentNullException("type");
retry: // Retry until successful
object oldAnnotations = this.annotations;
AnnotationList list = oldAnnotations as AnnotationList;
if (list != null) {
lock (list)
list.RemoveAll(obj => type.IsInstanceOfType(obj));
} else if (type.IsInstanceOfType(oldAnnotations)) {
if (Interlocked.CompareExchange(ref this.annotations, null, oldAnnotations) != oldAnnotations) {
// Operation failed (some other thread wrote to this.annotations first)
goto retry;
}
}
}
public T Annotation<T>() where T: class
{
object annotations = this.annotations;
AnnotationList list = annotations as AnnotationList;
if (list != null) {
lock (list) {
foreach (object obj in list) {
T t = obj as T;
if (t != null)
return t;
}
return null;
}
} else {
return annotations as T;
}
}
public object Annotation(Type type)
{
if (type == null)
throw new ArgumentNullException("type");
object annotations = this.annotations;
AnnotationList list = annotations as AnnotationList;
if (list != null) {
lock (list) {
foreach (object obj in list) {
if (type.IsInstanceOfType(obj))
return obj;
}
}
} else {
if (type.IsInstanceOfType(annotations))
return annotations;
}
return null;
}
/// <summary>
/// Gets all annotations stored on this AstNode.
/// </summary>
public IEnumerable<object> Annotations {
get {
object annotations = this.annotations;
AnnotationList list = annotations as AnnotationList;
if (list != null) {
lock (list) {
return list.ToArray();
}
} else {
if (annotations != null)
return new object[] { annotations };
else
return Enumerable.Empty<object>();
}
}
}
#endregion
public abstract S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data);
#region Pattern Matching
protected static bool MatchString(string name1, string name2)
{
return string.IsNullOrEmpty(name1) || string.Equals(name1, name2, StringComparison.OrdinalIgnoreCase);
}
protected static bool MatchStringXml(string name1, string name2)
{
return string.IsNullOrEmpty(name1) || string.Equals(name1, name2, StringComparison.Ordinal);
}
protected internal abstract bool DoMatch(AstNode other, PatternMatching.Match match);
bool PatternMatching.INode.DoMatch(PatternMatching.INode other, PatternMatching.Match match)
{
AstNode o = other as AstNode;
// try matching if other is null, or if other is an AstNode
return (other == null || o != null) && DoMatch(o, match);
}
bool PatternMatching.INode.DoMatchCollection(Role role, PatternMatching.INode pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo backtrackingInfo)
{
AstNode o = pos as AstNode;
return (pos == null || o != null) && DoMatch (o, match);
}
PatternMatching.INode PatternMatching.INode.NextSibling {
get { return nextSibling; }
}
PatternMatching.INode PatternMatching.INode.FirstChild {
get { return firstChild; }
}
#endregion
public AstNode GetNextNode ()
{
if (NextSibling != null)
return NextSibling;
if (Parent != null)
return Parent.GetNextNode ();
return null;
}
public AstNode GetPrevNode ()
{
if (PrevSibling != null)
return PrevSibling;
if (Parent != null)
return Parent.GetPrevNode ();
return null;
}
// filters all non VB nodes (comments, white spaces or pre processor directives)
public AstNode GetVBNodeBefore (AstNode node)
{
var n = node.PrevSibling;
while (n != null) {
if (n.Role != Roles.Comment)
return n;
n = n.GetPrevNode ();
}
return null;
}
// the Root role must be available when creating the null nodes, so we can't put it in the Roles class
static readonly Role<AstNode> RootRole = new Role<AstNode>("Root");
public static class Roles
{
/// <summary>
/// Root of an abstract syntax tree.
/// </summary>
public static readonly Role<AstNode> Root = RootRole;
// some pre defined constants for common roles
public static readonly Role<Identifier> Identifier = new Role<Identifier>("Identifier", Ast.Identifier.Null);
public static readonly Role<XmlIdentifier> XmlIdentifier = new Role<XmlIdentifier>("XmlIdentifier", Ast.XmlIdentifier.Null);
public static readonly Role<XmlLiteralString> XmlLiteralString = new Role<XmlLiteralString>("XmlLiteralString", Ast.XmlLiteralString.Null);
// public static readonly Role<BlockStatement> Body = new Role<BlockStatement>("Body", CSharp.BlockStatement.Null);
public static readonly Role<ParameterDeclaration> Parameter = new Role<ParameterDeclaration>("Parameter");
public static readonly Role<Expression> Argument = new Role<Expression>("Argument", Ast.Expression.Null);
public static readonly Role<AstType> Type = new Role<AstType>("Type", AstType.Null);
public static readonly Role<Expression> Expression = new Role<Expression>("Expression", Ast.Expression.Null);
// public static readonly Role<Expression> TargetExpression = new Role<Expression>("Target", CSharp.Expression.Null);
// public readonly static Role<Expression> Condition = new Role<Expression>("Condition", CSharp.Expression.Null);
//
public static readonly Role<TypeParameterDeclaration> TypeParameter = new Role<TypeParameterDeclaration>("TypeParameter");
public static readonly Role<AstType> TypeArgument = new Role<AstType>("TypeArgument", AstType.Null);
// public static readonly Role<VariableInitializer> Variable = new Role<VariableInitializer>("Variable");
// public static readonly Role<Statement> EmbeddedStatement = new Role<Statement>("EmbeddedStatement", CSharp.Statement.Null);
//
public static readonly Role<VBTokenNode> Keyword = new Role<VBTokenNode>("Keyword", VBTokenNode.Null);
// public static readonly Role<VBTokenNode> InKeyword = new Role<VBTokenNode>("InKeyword", VBTokenNode.Null);
// some pre defined constants for most used punctuation
public static readonly Role<VBTokenNode> LPar = new Role<VBTokenNode>("LPar", VBTokenNode.Null);
public static readonly Role<VBTokenNode> RPar = new Role<VBTokenNode>("RPar", VBTokenNode.Null);
public static readonly Role<VBTokenNode> LBracket = new Role<VBTokenNode>("LBracket", VBTokenNode.Null);
public static readonly Role<VBTokenNode> RBracket = new Role<VBTokenNode>("RBracket", VBTokenNode.Null);
public static readonly Role<VBTokenNode> LBrace = new Role<VBTokenNode>("LBrace", VBTokenNode.Null);
public static readonly Role<VBTokenNode> RBrace = new Role<VBTokenNode>("RBrace", VBTokenNode.Null);
public static readonly Role<VBTokenNode> LChevron = new Role<VBTokenNode>("LChevron", VBTokenNode.Null);
public static readonly Role<VBTokenNode> RChevron = new Role<VBTokenNode>("RChevron", VBTokenNode.Null);
public static readonly Role<VBTokenNode> Comma = new Role<VBTokenNode>("Comma", VBTokenNode.Null);
public static readonly Role<VBTokenNode> Dot = new Role<VBTokenNode>("Dot", VBTokenNode.Null);
public static readonly Role<VBTokenNode> Semicolon = new Role<VBTokenNode>("Semicolon", VBTokenNode.Null);
public static readonly Role<VBTokenNode> Assign = new Role<VBTokenNode>("Assign", VBTokenNode.Null);
public static readonly Role<VBTokenNode> Colon = new Role<VBTokenNode>("Colon", VBTokenNode.Null);
public static readonly Role<VBTokenNode> StatementTerminator = new Role<VBTokenNode>("StatementTerminator", VBTokenNode.Null);
// XML
/// <summary>
/// Text: &lt;
/// </summary>
public static readonly Role<VBTokenNode> XmlOpenTag = new Role<VBTokenNode>("XmlOpenTag", VBTokenNode.Null);
/// <summary>
/// Text: &gt;
/// </summary>
public static readonly Role<VBTokenNode> XmlCloseTag = new Role<VBTokenNode>("XmlOpenTag", VBTokenNode.Null);
public static readonly Role<Comment> Comment = new Role<Comment>("Comment");
}
}
public class Comment
{
}
}

209
NRefactory/ICSharpCode.NRefactory.VB/Ast/AstNodeCollection.cs

@ -0,0 +1,209 @@ @@ -0,0 +1,209 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using ICSharpCode.NRefactory.PatternMatching;
namespace ICSharpCode.NRefactory.VB
{
/// <summary>
/// Represents the children of an AstNode that have a specific role.
/// </summary>
public class AstNodeCollection<T> : ICollection<T> where T : AstNode
{
readonly AstNode node;
readonly Role<T> role;
public AstNodeCollection(AstNode node, Role<T> role)
{
if (node == null)
throw new ArgumentNullException("node");
if (role == null)
throw new ArgumentNullException("role");
this.node = node;
this.role = role;
}
public int Count {
get {
int count = 0;
for (AstNode cur = node.FirstChild; cur != null; cur = cur.NextSibling) {
if (cur.Role == role)
count++;
}
return count;
}
}
public void Add(T element)
{
node.AddChild(element, role);
}
public void AddRange(IEnumerable<T> nodes)
{
// Evaluate 'nodes' first, since it might change when we add the new children
// Example: collection.AddRange(collection);
if (nodes != null) {
foreach (T node in nodes.ToList())
Add(node);
}
}
public void AddRange(T[] nodes)
{
// Fast overload for arrays - we don't need to create a copy
if (nodes != null) {
foreach (T node in nodes)
Add(node);
}
}
public void ReplaceWith(IEnumerable<T> nodes)
{
// Evaluate 'nodes' first, since it might change when we call Clear()
// Example: collection.ReplaceWith(collection);
if (nodes != null)
nodes = nodes.ToList();
Clear();
foreach (T node in nodes)
Add(node);
}
public void MoveTo(ICollection<T> targetCollection)
{
foreach (T node in this) {
node.Remove();
targetCollection.Add(node);
}
}
public bool Contains(T element)
{
return element != null && element.Parent == node && element.Role == role;
}
public bool Remove(T element)
{
if (Contains(element)) {
element.Remove();
return true;
} else {
return false;
}
}
public void CopyTo(T[] array, int arrayIndex)
{
foreach (T item in this)
array[arrayIndex++] = item;
}
public void Clear()
{
foreach (T item in this)
item.Remove();
}
bool ICollection<T>.IsReadOnly {
get { return false; }
}
public IEnumerator<T> GetEnumerator()
{
AstNode next;
for (AstNode cur = node.FirstChild; cur != null; cur = next) {
Debug.Assert(cur.Parent == node);
// Remember next before yielding cur.
// This allows removing/replacing nodes while iterating through the list.
next = cur.NextSibling;
if (cur.Role == role)
yield return (T)cur;
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
#region Equals and GetHashCode implementation
public override bool Equals(object obj)
{
if (obj is AstNodeCollection<T>) {
return ((AstNodeCollection<T>)obj) == this;
} else {
return false;
}
}
public override int GetHashCode()
{
return node.GetHashCode() ^ role.GetHashCode();
}
public static bool operator ==(AstNodeCollection<T> left, AstNodeCollection<T> right)
{
return left.role == right.role && left.node == right.node;
}
public static bool operator !=(AstNodeCollection<T> left, AstNodeCollection<T> right)
{
return !(left.role == right.role && left.node == right.node);
}
#endregion
internal bool DoMatch(AstNodeCollection<T> other, Match match)
{
// TODO : does not compile (ask Daniel)!
// Stack<AstNode> patternStack = new Stack<AstNode>();
// Stack<Pattern.PossibleMatch> stack = new Stack<Pattern.PossibleMatch>();
// patternStack.Push(this.node.FirstChild);
// stack.Push(new Pattern.PossibleMatch(other.node.FirstChild, match.CheckPoint()));
// while (stack.Count > 0) {
// AstNode cur1 = patternStack.Pop();
// AstNode cur2 = stack.Peek().NextOther;
// match.RestoreCheckPoint(stack.Pop().Checkpoint);
// bool success = true;
// while (cur1 != null && success) {
// while (cur1 != null && cur1.Role != role)
// cur1 = cur1.NextSibling;
// while (cur2 != null && cur2.Role != role)
// cur2 = cur2.NextSibling;
// if (cur1 == null)
// break;
//
// Debug.Assert(stack.Count == patternStack.Count);
// success = cur1.DoMatchCollection(role, cur2, match, stack);
// Debug.Assert(stack.Count >= patternStack.Count);
// while (stack.Count > patternStack.Count)
// patternStack.Push(cur1.NextSibling);
//
// cur1 = cur1.NextSibling;
// if (cur2 != null)
// cur2 = cur2.NextSibling;
// }
// while (cur2 != null && cur2.Role != role)
// cur2 = cur2.NextSibling;
// if (success && cur2 == null)
// return true;
// }
return false;
}
public void InsertAfter(T existingItem, T newItem)
{
node.InsertChildAfter(existingItem, newItem, role);
}
public void InsertBefore(T existingItem, T newItem)
{
node.InsertChildBefore(existingItem, newItem, role);
}
}
}

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

@ -10,82 +10,45 @@ namespace ICSharpCode.NRefactory.VB.Ast @@ -10,82 +10,45 @@ namespace ICSharpCode.NRefactory.VB.Ast
{
None = 0x0000,
// Access
// Accessibility
Private = 0x0001,
/// <summary>C# 'internal', VB 'Friend'</summary>
Internal = 0x0002,
Friend = 0x0002,
Protected = 0x0004,
Public = 0x0008,
// Scope
Abstract = 0x0010, // == MustOverride/MustInherit
Virtual = 0x0020,
Sealed = 0x0040,
/// <summary>C# 'static', VB 'Shared'</summary>
Static = 0x0080,
Override = 0x0100,
/// <summary>For fields: readonly (c# and vb), for properties: get-only (vb)</summary>
ReadOnly = 0x0200,
Const = 0x0400,
/// <summary>C# 'new', VB 'Shadows'</summary>
New = 0x0800,
Partial = 0x1000,
MustInherit = 0x0010, // Types
MustOverride = 0x0020, // Members
Overridable = 0x0040,
NotInheritable = 0x0080, // Types
NotOverridable = 0x0100, // Members
Const = 0x0200,
Shared = 0x0400,
Static = 0x0800,
Override = 0x1000,
ReadOnly = 0x2000,
Shadows = 0x4000,
Partial = 0x8000,
// Special
Extern = 0x2000,
Volatile = 0x4000,
Unsafe = 0x8000,
Overloads = 0x10000, // VB specific
WithEvents = 0x20000, // VB specific
Default = 0x40000, // VB specific
Fixed = 0x80000, // C# specific (fixed size arrays in unsafe structs)
Dim = 0x100000, // VB.NET SPECIFIC, for fields/local variables only
Dim = 0x80000, // VB.NET SPECIFIC, for fields/local variables only
/// <summary>Generated code, not part of parsed code</summary>
Synthetic = 0x200000,
/// <summary>Only for VB properties.</summary>
WriteOnly = 0x400000, // VB specific
WriteOnly = 0x100000, // VB specific
Visibility = Private | Public | Protected | Internal,
Classes = New | Visibility | Abstract | Sealed | Partial | Static,
VBModules = Visibility,
VBStructures = Visibility | New,
VBEnums = Visibility | New,
VBInterfacs = Visibility | New,
VBDelegates = Visibility | New,
VBMethods = Visibility | New | Static | Virtual | Sealed | Abstract | Override | Overloads,
VBExternalMethods = Visibility | New | Overloads,
VBEvents = Visibility | New | Overloads,
VBProperties = VBMethods | Default | ReadOnly | WriteOnly,
VBCustomEvents = Visibility | New | Overloads,
VBOperators = Public | Static | Overloads | New,
ByVal = 0x200000,
ByRef = 0x400000,
ParamArray = 0x800000,
Optional = 0x1000000,
// this is not documented in the spec
VBInterfaceEvents = New,
VBInterfaceMethods = New | Overloads,
VBInterfaceProperties = New | Overloads | ReadOnly | WriteOnly | Default,
VBInterfaceEnums = New,
Fields = New | Visibility | Static | ReadOnly | Volatile | Fixed,
PropertysEventsMethods = New | Visibility | Static | Virtual | Sealed | Override | Abstract | Extern,
Indexers = New | Visibility | Virtual | Sealed | Override | Abstract | Extern,
Operators = Public | Static | Extern,
Constants = New | Visibility,
StructsInterfacesEnumsDelegates = New | Visibility | Partial,
StaticConstructors = Extern | Static | Unsafe,
Destructors = Extern | Unsafe,
Constructors = Visibility | Extern,
}
public enum ClassType
{
Class,
Module,
Interface,
Struct,
Enum
/// <summary>
/// Special value used to match any modifiers during pattern matching.
/// </summary>
Any = unchecked((int)0x80000000)
}
public enum ParentType
@ -104,18 +67,6 @@ namespace ICSharpCode.NRefactory.VB.Ast @@ -104,18 +67,6 @@ namespace ICSharpCode.NRefactory.VB.Ast
Ref
}
[Flags]
public enum ParameterModifiers
{
// Values must be the same as in SharpDevelop's ParameterModifiers
None = 0,
In = 1,
Out = 2,
Ref = 4,
Params = 8,
Optional = 16
}
public enum VarianceModifier
{
Invariant,
@ -359,20 +310,6 @@ namespace ICSharpCode.NRefactory.VB.Ast @@ -359,20 +310,6 @@ namespace ICSharpCode.NRefactory.VB.Ast
Ansi
}
///<summary>
/// Compare type, used in the <c>Option Compare</c>
/// pragma (VB only).
///</summary>
public enum OptionType
{
None,
Explicit,
Strict,
CompareBinary,
CompareText,
Infer
}
/// <summary>
/// Specifies the ordering direction of a QueryExpressionOrdering node.
/// </summary>

33
NRefactory/ICSharpCode.NRefactory.VB/Ast/Expressions/Expression.cs

@ -0,0 +1,33 @@ @@ -0,0 +1,33 @@
// 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;
namespace ICSharpCode.NRefactory.VB.Ast
{
public abstract class Expression : AstNode
{
#region Null
public new static readonly Expression Null = new NullExpression ();
sealed class NullExpression : Expression
{
public override bool IsNull {
get {
return true;
}
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{
return default (S);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return other == null || other.IsNull;
}
}
#endregion
}
}

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

@ -0,0 +1,75 @@ @@ -0,0 +1,75 @@
// 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 ICSharpCode.NRefactory.VB.PrettyPrinter;
using System;
namespace ICSharpCode.NRefactory.VB.Ast
{
/// <summary>
/// Represents a literal value.
/// </summary>
public class PrimitiveExpression : Expression
{
public static readonly object AnyValue = new object();
AstLocation startLocation;
public override AstLocation StartLocation {
get {
return startLocation;
}
}
int length;
public override AstLocation EndLocation {
get {
return new AstLocation(StartLocation.Line, StartLocation.Column + length);
}
}
public object Value { get; private set; }
string stringValue;
public string StringValue {
get { return stringValue; } // TODO ?? VBNetOutputVisitor.ToVBNetString(this); }
}
public PrimitiveExpression(object value)
{
this.Value = value;
}
public PrimitiveExpression(object value, string stringValue)
{
this.Value = value;
this.stringValue = stringValue;
}
public PrimitiveExpression(object value, AstLocation startLocation, int length)
{
this.Value = value;
this.startLocation = startLocation;
this.length = length;
}
public PrimitiveExpression(object value, string stringValue, AstLocation startLocation, int length)
{
this.Value = value;
this.stringValue = stringValue;
this.startLocation = startLocation;
this.length = length;
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitPrimitiveExpression(this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
PrimitiveExpression o = other as PrimitiveExpression;
return o != null && (this.Value == AnyValue || object.Equals(this.Value, o.Value));
}
}
}

27
NRefactory/ICSharpCode.NRefactory.VB/Ast/Expressions/SimpleNameExpression.cs

@ -0,0 +1,27 @@ @@ -0,0 +1,27 @@
// 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;
namespace ICSharpCode.NRefactory.VB.Ast
{
/// <summary>
/// Description of IdentifierExpression.
/// </summary>
public class SimpleNameExpression : Expression
{
public Identifier Identifier { get; set; }
protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match)
{
var node = other as SimpleNameExpression;
return node != null
&& Identifier.DoMatch(node.Identifier, match);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitSimpleNameExpression(this, data);
}
}
}

72
NRefactory/ICSharpCode.NRefactory.VB/Ast/Expressions/XmlIdentifier.cs

@ -0,0 +1,72 @@ @@ -0,0 +1,72 @@
// 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;
namespace ICSharpCode.NRefactory.VB.Ast
{
/// <summary>
/// Description of XmlIdentifier.
/// </summary>
public class XmlIdentifier : AstNode
{
public static readonly new XmlIdentifier Null = new NullXmlIdentifier();
class NullXmlIdentifier : XmlIdentifier
{
public override bool IsNull {
get {
return true;
}
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{
return default(S);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return other == null || other.IsNull;
}
}
public string Name { get; set; }
AstLocation startLocation;
public override AstLocation StartLocation {
get { return startLocation; }
}
AstLocation endLocation;
public override AstLocation EndLocation {
get { return endLocation; }
}
private XmlIdentifier()
{
this.Name = string.Empty;
}
public XmlIdentifier(string name, AstLocation startLocation, AstLocation endLocation)
{
this.Name = name;
this.startLocation = startLocation;
this.endLocation = endLocation;
}
protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match)
{
var ident = other as XmlIdentifier;
return ident != null
&& MatchStringXml(Name, ident.Name)
&& ident.startLocation == startLocation
&& ident.endLocation == endLocation;
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitXmlIdentifier(this, data);
}
}
}

69
NRefactory/ICSharpCode.NRefactory.VB/Ast/Expressions/XmlLiteralString.cs

@ -0,0 +1,69 @@ @@ -0,0 +1,69 @@
// 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;
namespace ICSharpCode.NRefactory.VB.Ast
{
public class XmlLiteralString : AstNode
{
public static readonly new XmlLiteralString Null = new XmlLiteralString();
class NullXmlLiteralString : XmlLiteralString
{
public override bool IsNull {
get {
return true;
}
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{
return default(S);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return other == null || other.IsNull;
}
}
public string Value { get; set; }
AstLocation startLocation;
public override AstLocation StartLocation {
get { return startLocation; }
}
AstLocation endLocation;
public override AstLocation EndLocation {
get { return endLocation; }
}
private XmlLiteralString()
{
this.Value = string.Empty;
}
public XmlLiteralString(string value, AstLocation startLocation, AstLocation endLocation)
{
this.Value = value;
this.startLocation = startLocation;
this.endLocation = endLocation;
}
protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match)
{
var ident = other as XmlLiteralString;
return ident != null
&& MatchStringXml(Value, ident.Value)
&& ident.startLocation == startLocation
&& ident.endLocation == endLocation;
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitXmlLiteralString(this, data);
}
}
}

93
NRefactory/ICSharpCode.NRefactory.VB/Ast/General/Attribute.cs

@ -0,0 +1,93 @@ @@ -0,0 +1,93 @@
// 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;
namespace ICSharpCode.NRefactory.VB.Ast
{
public class Attribute : AstNode
{
#region PatternPlaceholder
public static implicit operator Attribute(PatternMatching.Pattern pattern)
{
return pattern != null ? new PatternPlaceholder(pattern) : null;
}
sealed class PatternPlaceholder : Attribute, PatternMatching.INode
{
readonly PatternMatching.Pattern child;
public PatternPlaceholder(PatternMatching.Pattern child)
{
this.child = child;
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitPatternPlaceholder(this, child, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return child.DoMatch(other, match);
}
bool PatternMatching.INode.DoMatchCollection(Role role, PatternMatching.INode pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo backtrackingInfo)
{
return child.DoMatchCollection(role, pos, match, backtrackingInfo);
}
}
#endregion
public static readonly Role<Attribute> AttributeRole = new Role<Attribute>("Attribute");
public static readonly Role<VBTokenNode> TargetRole = new Role<VBTokenNode>("Target", VBTokenNode.Null);
public VBTokenNode Target {
get { return GetChildByRole(TargetRole); }
set { SetChildByRole(TargetRole, value); }
}
public VBTokenNode ColonToken {
get { return GetChildByRole(Roles.StatementTerminator); }
}
public AstType Type {
get { return GetChildByRole(Roles.Type); }
set { SetChildByRole(Roles.Type, value); }
}
public VBTokenNode LParToken {
get { return GetChildByRole(Roles.LPar); }
}
public AstNodeCollection<Expression> Arguments {
get { return GetChildrenByRole(Roles.Argument); }
}
public VBTokenNode RParToken {
get { return GetChildByRole(Roles.RPar); }
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitAttribute(this, data);
}
// public override string ToString()
// {
// return string.Format("[Attribute Type={0} Arguments={1}]", Type, GetCollectionString(Arguments));
// }
protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match)
{
var node = other as Attribute;
return node != null && node.Target.DoMatch(this.Target, match) && node.Type.DoMatch(this.Type, match) && node.Arguments.DoMatch(this.Arguments, match);
}
}
public enum AttributeTarget
{
Assembly,
Module
}
}

36
NRefactory/ICSharpCode.NRefactory.VB/Ast/General/AttributeBlock.cs

@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
// 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;
namespace ICSharpCode.NRefactory.VB.Ast
{
public class AttributeBlock : AstNode
{
public readonly static Role<AttributeBlock> AttributeBlockRole = new Role<AttributeBlock>("AttributeBlock");
public readonly static Role<AttributeBlock> ReturnTypeAttributeBlockRole = new Role<AttributeBlock>("ReturnTypeAttributeBlock");
public VBTokenNode LChevron {
get { return GetChildByRole(Roles.LChevron); }
}
public AstNodeCollection<Attribute> Attributes {
get { return GetChildrenByRole(Attribute.AttributeRole); }
}
public VBTokenNode RChevron {
get { return GetChildByRole(Roles.RChevron); }
}
protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match)
{
var node = other as AttributeBlock;
return node != null && Attributes.DoMatch(node.Attributes, match);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitAttributeBlock(this, data);
}
}
}

67
NRefactory/ICSharpCode.NRefactory.VB/Ast/General/AttributedNode.cs

@ -0,0 +1,67 @@ @@ -0,0 +1,67 @@
// 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.Collections.Generic;
using System.Linq;
namespace ICSharpCode.NRefactory.VB.Ast
{
public abstract class AttributedNode : AstNode
{
public AstNodeCollection<AttributeBlock> Attributes {
get { return GetChildrenByRole(AttributeBlock.AttributeBlockRole); }
}
public static readonly Role<VBModifierToken> ModifierRole = new Role<VBModifierToken>("Modifier");
public Modifiers Modifiers {
get { return GetModifiers(this); }
set { SetModifiers(this, value); }
}
public IEnumerable<VBModifierToken> ModifierTokens {
get { return GetChildrenByRole (ModifierRole); }
}
internal static Modifiers GetModifiers(AstNode node)
{
Modifiers m = 0;
foreach (VBModifierToken t in node.GetChildrenByRole (ModifierRole)) {
m |= t.Modifier;
}
return m;
}
internal static void SetModifiers(AstNode node, Modifiers newValue)
{
Modifiers oldValue = GetModifiers(node);
AstNode insertionPos = node.GetChildrenByRole(Attribute.AttributeRole).LastOrDefault();
foreach (Modifiers m in VBModifierToken.AllModifiers) {
if ((m & newValue) != 0) {
if ((m & oldValue) == 0) {
// Modifier was added
var newToken = new VBModifierToken(AstLocation.Empty, m);
node.InsertChildAfter(insertionPos, newToken, ModifierRole);
insertionPos = newToken;
} else {
// Modifier already exists
insertionPos = node.GetChildrenByRole(ModifierRole).First(t => t.Modifier == m);
}
} else {
if ((m & oldValue) != 0) {
// Modifier was removed
node.GetChildrenByRole (ModifierRole).First(t => t.Modifier == m).Remove();
}
}
}
}
protected bool MatchAttributesAndModifiers(AttributedNode o, PatternMatching.Match match)
{
return (this.Modifiers == Modifiers.Any || this.Modifiers == o.Modifiers) && this.Attributes.DoMatch(o.Attributes, match);
}
}
}

58
NRefactory/ICSharpCode.NRefactory.VB/Ast/General/BlockStatement.cs

@ -1,58 +0,0 @@ @@ -1,58 +0,0 @@
// 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;
namespace ICSharpCode.NRefactory.VB.Ast
{
public class BlockStatement : Statement
{
// Children in VB: LabelStatement, EndStatement, Statement
public static new BlockStatement Null {
get {
return NullBlockStatement.Instance;
}
}
public override object AcceptVisitor(IAstVisitor visitor, object data)
{
return visitor.VisitBlockStatement(this, data);
}
public override string ToString()
{
return String.Format("[BlockStatement: Children={0}]",
GetCollectionString(base.Children));
}
}
internal sealed class NullBlockStatement : BlockStatement
{
public static readonly NullBlockStatement Instance = new NullBlockStatement();
public override bool IsNull {
get {
return true;
}
}
public override object AcceptVisitor(IAstVisitor visitor, object data)
{
return data;
}
public override object AcceptChildren(IAstVisitor visitor, object data)
{
return data;
}
public override void AddChild(INode childNode)
{
throw new InvalidOperationException();
}
public override string ToString()
{
return String.Format("[NullBlockStatement]");
}
}
}

73
NRefactory/ICSharpCode.NRefactory.VB/Ast/General/CompilationUnit.cs

@ -2,23 +2,80 @@ @@ -2,23 +2,80 @@
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
using System;
using System.Collections;
using System.Collections.Generic;
namespace ICSharpCode.NRefactory.VB.Ast
{
public class CompilationUnit : AbstractNode
public class CompilationUnit : AstNode
{
// Children in C#: UsingAliasDeclaration, UsingDeclaration, AttributeSection, NamespaceDeclaration
// Children in VB: OptionStatements, ImportsStatement, AttributeSection, NamespaceDeclaration
public static readonly Role<AstNode> MemberRole = new Role<AstNode>("Member", AstNode.Null);
public override object AcceptVisitor(IAstVisitor visitor, object data)
public CompilationUnit ()
{
return visitor.VisitCompilationUnit(this, data);
}
public override string ToString()
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return String.Format("[CompilationUnit]");
CompilationUnit o = other as CompilationUnit;
return o != null && GetChildrenByRole(MemberRole).DoMatch(o.GetChildrenByRole(MemberRole), match);
}
public AstNode GetNodeAt (int line, int column)
{
return GetNodeAt (new AstLocation (line, column));
}
public AstNode GetNodeAt (AstLocation location)
{
AstNode node = this;
while (node.FirstChild != null) {
var child = node.FirstChild;
while (child != null) {
if (child.StartLocation <= location && location < child.EndLocation) {
node = child;
break;
}
child = child.NextSibling;
}
// found no better child node - therefore the parent is the right one.
if (child == null)
break;
}
return node;
}
public IEnumerable<AstNode> GetNodesBetween (int startLine, int startColumn, int endLine, int endColumn)
{
return GetNodesBetween (new AstLocation (startLine, startColumn), new AstLocation (endLine, endColumn));
}
public IEnumerable<AstNode> GetNodesBetween (AstLocation start, AstLocation end)
{
AstNode node = this;
while (node != null) {
AstNode next;
if (start <= node.StartLocation && node.EndLocation <= end) {
// Remember next before yielding node.
// This allows iteration to continue when the caller removes/replaces the node.
next = node.NextSibling;
yield return node;
} else {
if (node.EndLocation < start) {
next = node.NextSibling;
} else {
next = node.FirstChild;
}
}
if (next != null && next.StartLocation > end)
yield break;
node = next;
}
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitCompilationUnit (this, data);
}
}
}

103
NRefactory/ICSharpCode.NRefactory.VB/Ast/General/Expression.cs

@ -1,103 +0,0 @@ @@ -1,103 +0,0 @@
// 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;
namespace ICSharpCode.NRefactory.VB.Ast
{
public abstract class Expression : AbstractNode, INullable
{
public static Expression Null {
get {
return NullExpression.Instance;
}
}
public virtual bool IsNull {
get {
return false;
}
}
public static Expression CheckNull(Expression expression)
{
return expression == null ? NullExpression.Instance : expression;
}
/// <summary>
/// Returns the existing expression plus the specified integer value.
/// The old <paramref name="expr"/> object is not modified, but might be a subobject on the new expression
/// (and thus its parent property is modified).
/// </summary>
public static Expression AddInteger(Expression expr, int value)
{
PrimitiveExpression pe = expr as PrimitiveExpression;
if (pe != null && pe.Value is int) {
int newVal = (int)pe.Value + value;
return new PrimitiveExpression(newVal, newVal.ToString(System.Globalization.NumberFormatInfo.InvariantInfo));
}
BinaryOperatorExpression boe = expr as BinaryOperatorExpression;
if (boe != null && boe.Op == BinaryOperatorType.Add) {
// clone boe:
boe = new BinaryOperatorExpression(boe.Left, boe.Op, boe.Right);
boe.Right = AddInteger(boe.Right, value);
if (boe.Right is PrimitiveExpression && ((PrimitiveExpression)boe.Right).Value is int) {
int newVal = (int)((PrimitiveExpression)boe.Right).Value;
if (newVal == 0) {
return boe.Left;
} else if (newVal < 0) {
((PrimitiveExpression)boe.Right).Value = -newVal;
boe.Op = BinaryOperatorType.Subtract;
}
}
return boe;
}
if (boe != null && boe.Op == BinaryOperatorType.Subtract) {
pe = boe.Right as PrimitiveExpression;
if (pe != null && pe.Value is int) {
int newVal = (int)pe.Value - value;
if (newVal == 0)
return boe.Left;
// clone boe:
boe = new BinaryOperatorExpression(boe.Left, boe.Op, boe.Right);
if (newVal < 0) {
newVal = -newVal;
boe.Op = BinaryOperatorType.Add;
}
boe.Right = new PrimitiveExpression(newVal, newVal.ToString(System.Globalization.NumberFormatInfo.InvariantInfo));
return boe;
}
}
BinaryOperatorType opType = BinaryOperatorType.Add;
if (value < 0) {
value = -value;
opType = BinaryOperatorType.Subtract;
}
return new BinaryOperatorExpression(expr, opType, new PrimitiveExpression(value, value.ToString(System.Globalization.NumberFormatInfo.InvariantInfo)));
}
}
internal sealed class NullExpression : Expression
{
internal static readonly NullExpression Instance = new NullExpression();
public override bool IsNull {
get {
return true;
}
}
public override object AcceptVisitor(IAstVisitor visitor, object data)
{
return null;
}
public override string ToString()
{
return String.Format("[NullExpression]");
}
}
}

99
NRefactory/ICSharpCode.NRefactory.VB/Ast/General/LocalVariableDeclaration.cs

@ -1,99 +0,0 @@ @@ -1,99 +0,0 @@
// 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.Collections.Generic;
namespace ICSharpCode.NRefactory.VB.Ast
{
public class LocalVariableDeclaration : Statement
{
TypeReference typeReference;
Modifiers modifier = Modifiers.None;
List<VariableDeclaration> variables = new List<VariableDeclaration>();
public TypeReference TypeReference {
get {
return typeReference;
}
set {
typeReference = TypeReference.CheckNull(value);
if (!typeReference.IsNull) typeReference.Parent = this;
}
}
public Modifiers Modifier {
get {
return modifier;
}
set {
modifier = value;
}
}
public List<VariableDeclaration> Variables {
get {
return variables;
}
}
public TypeReference GetTypeForVariable(int variableIndex)
{
if (!typeReference.IsNull) {
return typeReference;
}
for (int i = variableIndex; i < Variables.Count;++i) {
if (!((VariableDeclaration)Variables[i]).TypeReference.IsNull) {
return ((VariableDeclaration)Variables[i]).TypeReference;
}
}
return null;
}
public LocalVariableDeclaration(VariableDeclaration declaration) : this(TypeReference.Null)
{
Variables.Add(declaration);
}
public LocalVariableDeclaration(TypeReference typeReference)
{
this.TypeReference = typeReference;
}
public LocalVariableDeclaration(TypeReference typeReference, Modifiers modifier)
{
this.TypeReference = typeReference;
this.modifier = modifier;
}
public LocalVariableDeclaration(Modifiers modifier)
{
this.typeReference = TypeReference.Null;
this.modifier = modifier;
}
public VariableDeclaration GetVariableDeclaration(string variableName)
{
foreach (VariableDeclaration variableDeclaration in variables) {
if (variableDeclaration.Name == variableName) {
return variableDeclaration;
}
}
return null;
}
public override object AcceptVisitor(IAstVisitor visitor, object data)
{
return visitor.VisitLocalVariableDeclaration(this, data);
}
public override string ToString()
{
return String.Format("[LocalVariableDeclaration: Type={0}, Modifier ={1} Variables={2}]",
typeReference,
modifier,
GetCollectionString(variables));
}
}
}

40
NRefactory/ICSharpCode.NRefactory.VB/Ast/General/ParameterDeclaration.cs

@ -0,0 +1,40 @@ @@ -0,0 +1,40 @@
// 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;
namespace ICSharpCode.NRefactory.VB.Ast
{
public class ParameterDeclaration : AttributedNode
{
public Identifier Name {
get { return GetChildByRole(Roles.Identifier); }
set { SetChildByRole(Roles.Identifier, value); }
}
public Expression OptionalValue {
get { return GetChildByRole(Roles.Expression); }
set { SetChildByRole(Roles.Expression, value); }
}
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)
{
var param = other as ParameterDeclaration;
return param != null &&
MatchAttributesAndModifiers(param, match) &&
Name.DoMatch(param.Name, match) &&
OptionalValue.DoMatch(param.OptionalValue, match) &&
ReturnType.DoMatch(param.ReturnType, match);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitParameterDeclaration(this, data);
}
}
}

53
NRefactory/ICSharpCode.NRefactory.VB/Ast/General/PrimitiveExpression.cs

@ -1,53 +0,0 @@ @@ -1,53 +0,0 @@
// 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 ICSharpCode.NRefactory.VB.PrettyPrinter;
using System;
namespace ICSharpCode.NRefactory.VB.Ast
{
public class PrimitiveExpression : Expression
{
string stringValue;
public Parser.LiteralFormat LiteralFormat { get; set; }
public object Value { get; set; }
public string StringValue {
get {
if (stringValue == null)
return VBNetOutputVisitor.ToVBNetString(this);
else
return stringValue;
}
set {
stringValue = value == null ? String.Empty : value;
}
}
public PrimitiveExpression(object val)
{
this.Value = val;
}
public PrimitiveExpression(object val, string stringValue)
{
this.Value = val;
this.StringValue = stringValue;
}
public override object AcceptVisitor(IAstVisitor visitor, object data)
{
return visitor.VisitPrimitiveExpression(this, data);
}
public override string ToString()
{
return String.Format("[PrimitiveExpression: Value={1}, ValueType={2}, StringValue={0}]",
this.StringValue,
this.Value,
this.Value == null ? "null" : this.Value.GetType().FullName
);
}
}
}

62
NRefactory/ICSharpCode.NRefactory.VB/Ast/General/Statement.cs

@ -1,62 +0,0 @@ @@ -1,62 +0,0 @@
// 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;
namespace ICSharpCode.NRefactory.VB.Ast
{
public abstract class Statement : AbstractNode, INullable
{
public static Statement Null {
get {
return NullStatement.Instance;
}
}
public virtual bool IsNull {
get {
return false;
}
}
public static Statement CheckNull(Statement statement)
{
return statement ?? NullStatement.Instance;
}
}
public abstract class StatementWithEmbeddedStatement : Statement
{
Statement embeddedStatement;
public Statement EmbeddedStatement {
get {
return embeddedStatement;
}
set {
embeddedStatement = Statement.CheckNull(value);
if (value != null)
value.Parent = this;
}
}
}
internal sealed class NullStatement : Statement
{
public static readonly NullStatement Instance = new NullStatement();
public override bool IsNull {
get { return true; }
}
public override object AcceptVisitor(IAstVisitor visitor, object data)
{
return data;
}
public override string ToString()
{
return String.Format("[NullStatement]");
}
}
}

44
NRefactory/ICSharpCode.NRefactory.VB/Ast/General/TypeParameterDeclaration.cs

@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
// 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.Collections.Generic;
using System.Linq;
namespace ICSharpCode.NRefactory.VB.Ast
{
/// <summary>
/// [In|Out] Name [As Contraints]
///
/// Represents a type parameter.
/// </summary>
public class TypeParameterDeclaration : AstNode
{
public static readonly Role<AstType> TypeConstraintRole = TypeDeclaration.InheritsTypeRole;
public static readonly Role<VBTokenNode> VarianceRole = new Role<VBTokenNode>("Variance");
public VarianceModifier Variance { get; set; }
public string Name {
get { return GetChildByRole (Roles.Identifier).Name; }
set { SetChildByRole(Roles.Identifier, new Identifier(value, AstLocation.Empty)); }
}
public AstNodeCollection<AstType> Constraints {
get { return GetChildrenByRole(TypeConstraintRole); }
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitTypeParameterDeclaration(this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
TypeParameterDeclaration o = other as TypeParameterDeclaration;
return o != null && this.Variance == o.Variance
&& MatchString(this.Name, o.Name)
&& this.Constraints.DoMatch(o.Constraints, match);
}
}
}

10017
NRefactory/ICSharpCode.NRefactory.VB/Ast/Generated.cs

File diff suppressed because it is too large Load Diff

52
NRefactory/ICSharpCode.NRefactory.VB/Ast/GlobalScope/DelegateDeclaration.cs

@ -0,0 +1,52 @@ @@ -0,0 +1,52 @@
// 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;
namespace ICSharpCode.NRefactory.VB.Ast
{
public class DelegateDeclaration : AttributedNode
{
public bool IsSub { get; set; }
public AstNodeCollection<TypeParameterDeclaration> TypeParameters {
get { return GetChildrenByRole(Roles.TypeParameter); }
}
public Identifier Name {
get { return GetChildByRole(Roles.Identifier); }
set { SetChildByRole(Roles.Identifier, value); }
}
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)
{
var o = other as DelegateDeclaration;
return o != null &&
MatchAttributesAndModifiers(o, match) &&
IsSub == o.IsSub &&
TypeParameters.DoMatch(o.TypeParameters, match) &&
Name.DoMatch(o.Name, match) &&
Parameters.DoMatch(o.Parameters, match) &&
ReturnTypeAttributes.DoMatch(o.ReturnTypeAttributes, match) &&
ReturnType.DoMatch(o.ReturnType, match);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitDelegateDeclaration(this, data);
}
}
}

44
NRefactory/ICSharpCode.NRefactory.VB/Ast/GlobalScope/EnumDeclaration.cs

@ -0,0 +1,44 @@ @@ -0,0 +1,44 @@
// 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.Collections.Generic;
using System.Linq;
namespace ICSharpCode.NRefactory.VB.Ast
{
public class EnumDeclaration : AttributedNode
{
public readonly static Role<EnumMemberDeclaration> MemberRole = new Role<EnumMemberDeclaration>("Member");
public readonly static Role<AstType> UnderlyingTypeRole = new Role<AstType>("UnderlyingType", AstType.Null);
public Identifier Name {
get { return GetChildByRole(Roles.Identifier); }
set { SetChildByRole(Roles.Identifier, value); }
}
public AstType UnderlyingType {
get { return GetChildByRole(UnderlyingTypeRole); }
set { SetChildByRole(UnderlyingTypeRole, value); }
}
public AstNodeCollection<EnumMemberDeclaration> Member {
get { return GetChildrenByRole(MemberRole); }
}
protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match)
{
var decl = other as EnumDeclaration;
return decl != null &&
MatchAttributesAndModifiers(decl, match) &&
Name.DoMatch(decl.Name, match) &&
UnderlyingType.DoMatch(decl.UnderlyingType, match) &&
Member.DoMatch(decl.Member, match);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitEnumDeclaration(this, data);
}
}
}

39
NRefactory/ICSharpCode.NRefactory.VB/Ast/GlobalScope/EnumMemberDeclaration.cs

@ -0,0 +1,39 @@ @@ -0,0 +1,39 @@
// 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.Collections.Generic;
using System.Linq;
namespace ICSharpCode.NRefactory.VB.Ast
{
public class EnumMemberDeclaration : AstNode
{
public AstNodeCollection<AttributeBlock> Attributes {
get { return GetChildrenByRole(AttributeBlock.AttributeBlockRole); }
}
public Identifier Name {
get { return GetChildByRole(Roles.Identifier); }
set { SetChildByRole(Roles.Identifier, value); }
}
public Expression Value {
get { return GetChildByRole(Roles.Expression); }
set { SetChildByRole(Roles.Expression, value); }
}
protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match)
{
var member = other as EnumMemberDeclaration;
return Attributes.DoMatch(member.Attributes, match) &&
Name.DoMatch(member.Name, match) &&
Value.DoMatch(member.Value, match);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitEnumMemberDeclaration(this, data);
}
}
}

113
NRefactory/ICSharpCode.NRefactory.VB/Ast/GlobalScope/ImportsClause.cs

@ -0,0 +1,113 @@ @@ -0,0 +1,113 @@
// 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.Collections.Generic;
namespace ICSharpCode.NRefactory.VB.Ast
{
public abstract class ImportsClause : AstNode
{
public new static readonly ImportsClause Null = new NullImportsClause();
class NullImportsClause : ImportsClause
{
public override bool IsNull {
get { return true; }
}
protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match)
{
return other != null && other.IsNull;
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return default(S);
}
}
}
public class AliasImportsClause : ImportsClause
{
public Identifier Name {
get { return GetChildByRole(Roles.Identifier); }
set { SetChildByRole(Roles.Identifier, value); }
}
public AstType Alias {
get { return GetChildByRole(Roles.Type); }
set { SetChildByRole(Roles.Type, value); }
}
protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match)
{
var clause = other as AliasImportsClause;
return clause != null
&& Name.DoMatch(clause.Name, match)
&& Alias.DoMatch(clause.Alias, match);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitAliasImportsClause(this, data);
}
public override string ToString() {
return string.Format("[AliasImportsClause Name={0} Alias={1}]", Name, Alias);
}
}
public class MemberImportsClause : ImportsClause
{
public AstType Member {
get { return GetChildByRole(Roles.Type); }
set { SetChildByRole(Roles.Type, value); }
}
protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match)
{
var node = other as MemberImportsClause;
return node != null
&& Member.DoMatch(node.Member, match);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitMembersImportsClause(this, data);
}
public override string ToString()
{
return string.Format("[MemberImportsClause Member={0}]", Member);
}
}
public class XmlNamespaceImportsClause : ImportsClause
{
public XmlIdentifier Prefix {
get { return GetChildByRole(Roles.XmlIdentifier); }
set { SetChildByRole(Roles.XmlIdentifier, value); }
}
public XmlLiteralString Namespace {
get { return GetChildByRole(Roles.XmlLiteralString); }
set { SetChildByRole(Roles.XmlLiteralString, value); }
}
protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match)
{
var clause = other as XmlNamespaceImportsClause;
return clause != null && Namespace.DoMatch(clause.Namespace, match) && Prefix.DoMatch(clause.Prefix, match);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitXmlNamespaceImportsClause(this, data);
}
public override string ToString()
{
return string.Format("[XmlNamespaceImportsClause Prefix={0}, Namespace={1}]", Prefix, Namespace);
}
}
}

36
NRefactory/ICSharpCode.NRefactory.VB/Ast/GlobalScope/ImportsStatement.cs

@ -0,0 +1,36 @@ @@ -0,0 +1,36 @@
// 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.Collections.Generic;
using ICSharpCode.NRefactory.PatternMatching;
namespace ICSharpCode.NRefactory.VB.Ast
{
public class ImportsStatement : AstNode
{
public static readonly Role<ImportsClause> ImportsClauseRole = new Role<ImportsClause>("ImportsClause", ImportsClause.Null);
public VBTokenNode Imports {
get { return GetChildByRole(Roles.Keyword); }
}
public AstNodeCollection<ImportsClause> ImportsClauses {
get { return GetChildrenByRole(ImportsClauseRole); }
}
// public override string ToString() {
// return string.Format("[ImportsStatement ImportsClauses={0}]", GetCollectionString(ImportsClauses));
// }
protected internal override bool DoMatch(AstNode other, Match match)
{
ImportsStatement stmt = other as ImportsStatement;
return stmt != null && stmt.ImportsClauses.DoMatch(ImportsClauses, match);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitImportsStatement(this, data);
}
}
}

78
NRefactory/ICSharpCode.NRefactory.VB/Ast/GlobalScope/NamespaceDeclaration.cs

@ -0,0 +1,78 @@ @@ -0,0 +1,78 @@
// 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.Collections.Generic;
using System.Linq;
using System.Text;
using ICSharpCode.NRefactory.PatternMatching;
namespace ICSharpCode.NRefactory.VB.Ast
{
/// <summary>
/// Namespace Name
/// Members
/// End Namespace
/// </summary>
public class NamespaceDeclaration : AstNode
{
public static readonly Role<AstNode> MemberRole = CompilationUnit.MemberRole;
public string Name {
get {
StringBuilder builder = new StringBuilder();
foreach (Identifier identifier in GetChildrenByRole (Roles.Identifier)) {
if (builder.Length > 0)
builder.Append ('.');
builder.Append (identifier.Name);
}
return builder.ToString ();
}
set {
GetChildrenByRole(Roles.Identifier).ReplaceWith(value.Split('.').Select(ident => new Identifier(ident, AstLocation.Empty)));
}
}
public AstNodeCollection<Identifier> Identifiers {
get { return GetChildrenByRole (Roles.Identifier); }
}
/// <summary>
/// Gets the full namespace name (including any parent namespaces)
/// </summary>
public string FullName {
get {
NamespaceDeclaration parentNamespace = Parent as NamespaceDeclaration;
if (parentNamespace != null)
return BuildQualifiedName (parentNamespace.FullName, Name);
return Name;
}
}
public AstNodeCollection<AstNode> Members {
get { return GetChildrenByRole(MemberRole); }
}
public static string BuildQualifiedName (string name1, string name2)
{
if (string.IsNullOrEmpty (name1))
return name2;
if (string.IsNullOrEmpty (name2))
return name1;
return name1 + "." + name2;
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitNamespaceDeclaration(this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
NamespaceDeclaration o = other as NamespaceDeclaration;
return o != null && MatchString(this.Name, o.Name) && this.Members.DoMatch(o.Members, match);
}
}
};

60
NRefactory/ICSharpCode.NRefactory.VB/Ast/GlobalScope/OptionStatement.cs

@ -0,0 +1,60 @@ @@ -0,0 +1,60 @@
// 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.Collections.Generic;
using ICSharpCode.NRefactory.PatternMatching;
namespace ICSharpCode.NRefactory.VB.Ast
{
public class OptionStatement : AstNode
{
public static readonly Role<VBTokenNode> OptionTypeRole = new Role<VBTokenNode>("OptionType");
public static readonly Role<VBTokenNode> OptionValueRole = new Role<VBTokenNode>("OptionValue");
public VBTokenNode OptionKeyword {
get { return GetChildByRole(Roles.Keyword); }
}
public VBTokenNode OptionTypeKeyword {
get { return GetChildByRole(OptionTypeRole); }
}
public VBTokenNode OptionValueKeyword {
get { return GetChildByRole(OptionValueRole); }
}
public OptionType OptionType { get; set; }
public OptionValue OptionValue { get; set; }
protected internal override bool DoMatch(AstNode other, Match match)
{
var stmt = other as OptionStatement;
return stmt != null && stmt.OptionType == this.OptionType
&& stmt.OptionValue == this.OptionValue;
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitOptionStatement(this, data);
}
public override string ToString() {
return string.Format("[OptionStatement OptionType={0} OptionValue={1}]", OptionType, OptionValue);
}
}
public enum OptionType
{
Explicit,
Strict,
Compare,
Infer
}
public enum OptionValue
{
On, Off,
Text, Binary
}
}

58
NRefactory/ICSharpCode.NRefactory.VB/Ast/GlobalScope/TypeDeclaration.cs

@ -0,0 +1,58 @@ @@ -0,0 +1,58 @@
// 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.Collections.Generic;
using System.Linq;
using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.NRefactory.VB.Ast
{
public class TypeDeclaration : AttributedNode
{
public readonly static Role<AttributedNode> MemberRole = new Role<AttributedNode>("Member");
public readonly static Role<AstType> InheritsTypeRole = new Role<AstType>("InheritsType", AstType.Null);
public readonly static Role<AstType> ImplementsTypesRole = new Role<AstType>("ImplementsTypes", AstType.Null);
public AstNodeCollection<AttributedNode> Members {
get { return base.GetChildrenByRole(MemberRole); }
}
public ClassType ClassType { get; set; }
public Identifier Name {
get { return GetChildByRole(Roles.Identifier); }
set { SetChildByRole(Roles.Identifier, value); }
}
public AstNodeCollection<TypeParameterDeclaration> TypeParameters {
get { return GetChildrenByRole(Roles.TypeParameter); }
}
public AstType InheritsType {
get { return GetChildByRole(InheritsTypeRole); }
}
public AstNodeCollection<AstType> ImplementsTypes {
get { return GetChildrenByRole(ImplementsTypesRole); }
}
protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match)
{
TypeDeclaration t = other as TypeDeclaration;
return t != null &&
MatchAttributesAndModifiers(t, match) &&
Members.DoMatch(t.Members, match) &&
ClassType == t.ClassType &&
Name.DoMatch(t.Name, match) &&
TypeParameters.DoMatch(t.TypeParameters, match) &&
InheritsType.DoMatch(t.InheritsType, match) &&
ImplementsTypes.DoMatch(t.ImplementsTypes, match);
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitTypeDeclaration(this, data);
}
}
}

51
NRefactory/ICSharpCode.NRefactory.VB/Ast/INode.cs

@ -1,51 +0,0 @@ @@ -1,51 +0,0 @@
// 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.Collections.Generic;
namespace ICSharpCode.NRefactory.VB.Ast
{
public interface INode
{
INode Parent {
get;
set;
}
List<INode> Children {
get;
}
Location StartLocation {
get;
set;
}
Location EndLocation {
get;
set;
}
object UserData {
get;
set;
}
/// <summary>
/// Visits all children
/// </summary>
/// <param name="visitor">The visitor to accept</param>
/// <param name="data">Additional data for the visitor</param>
/// <returns>The paremeter <paramref name="data"/></returns>
object AcceptChildren(IAstVisitor visitor, object data);
/// <summary>
/// Accept the visitor
/// </summary>
/// <param name="visitor">The visitor to accept</param>
/// <param name="data">Additional data for the visitor</param>
/// <returns>The value the visitor returns after the visit</returns>
object AcceptVisitor(IAstVisitor visitor, object data);
}
}

91
NRefactory/ICSharpCode.NRefactory.VB/Ast/Identifier.cs

@ -0,0 +1,91 @@ @@ -0,0 +1,91 @@
// 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;
namespace ICSharpCode.NRefactory.VB.Ast
{
/// <summary>
/// Represents an identifier in VB.
/// </summary>
public class Identifier : AstNode
{
public static readonly new Identifier Null = new NullIdentifier ();
class NullIdentifier : Identifier
{
public override bool IsNull {
get {
return true;
}
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{
return default (S);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return other == null || other.IsNull;
}
}
string name;
public string Name {
get { return name; }
set {
if (value == null)
throw new ArgumentNullException("value");
name = value;
}
}
public TypeCode TypeCharacter { get; set; }
AstLocation startLocation;
public override AstLocation StartLocation {
get {
return startLocation;
}
}
public override AstLocation EndLocation {
get {
return new AstLocation (StartLocation.Line, StartLocation.Column + Name.Length);
}
}
private Identifier()
{
this.name = string.Empty;
}
public Identifier (string name, AstLocation location)
{
if (name == null)
throw new ArgumentNullException("name");
this.Name = name;
this.startLocation = location;
}
protected internal override bool DoMatch(AstNode other, ICSharpCode.NRefactory.PatternMatching.Match match)
{
var node = other as Identifier;
return node != null
&& MatchString(node.name, name)
&& node.TypeCharacter == TypeCharacter;
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitIdentifier(this, data);
}
public override string ToString()
{
return string.Format("[Identifier Name={0}, StartLocation={1}, TypeCharacter{4}]",
name, startLocation, TypeCharacter);
}
}
}

125
NRefactory/ICSharpCode.NRefactory.VB/Ast/Statements/BlockStatement.cs

@ -0,0 +1,125 @@ @@ -0,0 +1,125 @@
// 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.Collections.Generic;
namespace ICSharpCode.NRefactory.VB.Ast
{
/// <summary>
/// { Statements }
/// </summary>
public class BlockStatement : Statement, IEnumerable<Statement>
{
public static readonly Role<Statement> StatementRole = new Role<Statement>("Statement", Statement.Null);
#region Null
public static readonly new BlockStatement Null = new NullBlockStatement();
sealed class NullBlockStatement : BlockStatement
{
public override bool IsNull {
get {
return true;
}
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{
return default(S);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return other == null || other.IsNull;
}
}
#endregion
#region PatternPlaceholder
public static implicit operator BlockStatement(PatternMatching.Pattern pattern)
{
return pattern != null ? new PatternPlaceholder(pattern) : null;
}
sealed class PatternPlaceholder : BlockStatement, PatternMatching.INode
{
readonly PatternMatching.Pattern child;
public PatternPlaceholder(PatternMatching.Pattern child)
{
this.child = child;
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitPatternPlaceholder(this, child, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return child.DoMatch(other, match);
}
bool PatternMatching.INode.DoMatchCollection(Role role, PatternMatching.INode pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo backtrackingInfo)
{
return child.DoMatchCollection(role, pos, match, backtrackingInfo);
}
}
#endregion
public AstNodeCollection<Statement> Statements {
get { return GetChildrenByRole (StatementRole); }
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitBlockStatement (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
BlockStatement o = other as BlockStatement;
return o != null && !o.IsNull && this.Statements.DoMatch(o.Statements, match);
}
#region Builder methods
public void Add(Statement statement)
{
AddChild(statement, StatementRole);
}
// TODO : uncomment
// public void Add(Expression expression)
// {
// AddChild(new ExpressionStatement { Expression = expression }, StatementRole);
// }
//
public void AddRange(IEnumerable<Statement> statements)
{
foreach (Statement st in statements)
AddChild(st, StatementRole);
}
// public void AddAssignment(Expression left, Expression right)
// {
// Add(new AssignmentExpression { Left = left, Operator = AssignmentOperatorType.Assign, Right = right });
// }
//
// public void AddReturnStatement(Expression expression)
// {
// Add(new ReturnStatement { Expression = expression });
// }
#endregion
IEnumerator<Statement> IEnumerable<Statement>.GetEnumerator()
{
return this.Statements.GetEnumerator();
}
System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
{
return this.Statements.GetEnumerator();
}
}
}

132
NRefactory/ICSharpCode.NRefactory.VB/Ast/Statements/Statement.cs

@ -0,0 +1,132 @@ @@ -0,0 +1,132 @@
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
// This code is distributed under MIT X11 license (for details please see \doc\license.txt)
using System;
using System.IO;
namespace ICSharpCode.NRefactory.VB.Ast
{
/// <summary>
/// Base class for statements.
/// </summary>
/// <remarks>
/// This class is useful even though it doesn't provide any additional functionality:
/// It can be used to communicate more information in APIs, e.g. "this subnode will always be a statement"
/// </remarks>
public abstract class Statement : AstNode
{
#region Null
public new static readonly Statement Null = new NullStatement ();
sealed class NullStatement : Statement
{
public override bool IsNull {
get {
return true;
}
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{
return default (S);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return other == null || other.IsNull;
}
}
#endregion
#region PatternPlaceholder
public static implicit operator Statement(PatternMatching.Pattern pattern)
{
return pattern != null ? new PatternPlaceholder(pattern) : null;
}
sealed class PatternPlaceholder : Statement, PatternMatching.INode
{
readonly PatternMatching.Pattern child;
public PatternPlaceholder(PatternMatching.Pattern child)
{
this.child = child;
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitPatternPlaceholder(this, child, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return child.DoMatch(other, match);
}
bool PatternMatching.INode.DoMatchCollection(Role role, PatternMatching.INode pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo backtrackingInfo)
{
return child.DoMatchCollection(role, pos, match, backtrackingInfo);
}
}
#endregion
/// <summary>
/// Gets the previous statement within the current block.
/// This is usually equivalent to <see cref="PrevSibling"/>, but will skip any non-statements (e.g. comments)
/// </summary>
public Statement PreviousStatement {
get {
AstNode node = this;
while ((node = node.PrevSibling) != null) {
Statement stmt = node as Statement;
if (stmt != null)
return stmt;
}
return null;
}
}
/// <summary>
/// Gets the next statement within the current block.
/// This is usually equivalent to <see cref="NextSibling"/>, but will skip any non-statements (e.g. comments)
/// </summary>
public Statement NextStatement {
get {
AstNode node = this;
while ((node = node.NextSibling) != null) {
Statement stmt = node as Statement;
if (stmt != null)
return stmt;
}
return null;
}
}
public new Statement Clone()
{
return (Statement)base.Clone();
}
public Statement ReplaceWith(Func<Statement, Statement> replaceFunction)
{
if (replaceFunction == null)
throw new ArgumentNullException("replaceFunction");
return (Statement)base.ReplaceWith(node => replaceFunction((Statement)node));
}
// Make debugging easier by giving Statements a ToString() implementation
public override string ToString()
{
// if (IsNull)
// return "Null";
// StringWriter w = new StringWriter();
// AcceptVisitor(new OutputVisitor(w, new CSharpFormattingOptions()), null);
// string text = w.ToString().TrimEnd().Replace("\t", "").Replace(w.NewLine, " ");
// if (text.Length > 100)
// return text.Substring(0, 97) + "...";
// else
// return text;
throw new NotImplementedException();
}
}
}

145
NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeName/AstType.cs

@ -0,0 +1,145 @@ @@ -0,0 +1,145 @@
// 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.Collections.Generic;
namespace ICSharpCode.NRefactory.VB.Ast
{
/// <summary>
/// A type reference in the VB AST.
/// </summary>
public abstract class AstType : AstNode
{
#region Null
public new static readonly AstType Null = new NullAstType();
sealed class NullAstType : AstType
{
public override bool IsNull {
get {
return true;
}
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{
return default (S);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return other == null || other.IsNull;
}
}
#endregion
#region PatternPlaceholder
public static implicit operator AstType(PatternMatching.Pattern pattern)
{
return pattern != null ? new PatternPlaceholder(pattern) : null;
}
sealed class PatternPlaceholder : AstType, PatternMatching.INode
{
readonly PatternMatching.Pattern child;
public PatternPlaceholder(PatternMatching.Pattern child)
{
this.child = child;
}
public override S AcceptVisitor<T, S>(IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitPatternPlaceholder(this, child, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
return child.DoMatch(other, match);
}
bool PatternMatching.INode.DoMatchCollection(Role role, PatternMatching.INode pos, PatternMatching.Match match, PatternMatching.BacktrackingInfo backtrackingInfo)
{
return child.DoMatchCollection(role, pos, match, backtrackingInfo);
}
}
#endregion
public virtual AstType MakeArrayType(int rank = 1)
{
return new ComposedType { BaseType = this }.MakeArrayType(rank);
}
// TODO : reimplement this
// /// <summary>
// /// Builds an expression that can be used to access a static member on this type.
// /// </summary>
// public MemberReferenceExpression Member(string memberName)
// {
// return new TypeReferenceExpression { Type = this }.Member(memberName);
// }
//
// /// <summary>
// /// Builds an invocation expression using this type as target.
// /// </summary>
// public InvocationExpression Invoke(string methodName, IEnumerable<Expression> arguments)
// {
// return new TypeReferenceExpression { Type = this }.Invoke(methodName, arguments);
// }
//
// /// <summary>
// /// Builds an invocation expression using this type as target.
// /// </summary>
// public InvocationExpression Invoke(string methodName, params Expression[] arguments)
// {
// return new TypeReferenceExpression { Type = this }.Invoke(methodName, arguments);
// }
//
// /// <summary>
// /// Builds an invocation expression using this type as target.
// /// </summary>
// public InvocationExpression Invoke(string methodName, IEnumerable<AstType> typeArguments, IEnumerable<Expression> arguments)
// {
// return new TypeReferenceExpression { Type = this }.Invoke(methodName, typeArguments, arguments);
// }
public static AstType Create(Type type)
{
switch (Type.GetTypeCode(type)) {
case TypeCode.Object:
return new PrimitiveType("Object");
case TypeCode.Boolean:
return new PrimitiveType("Boolean");
case TypeCode.Char:
return new PrimitiveType("Char");
case TypeCode.SByte:
return new PrimitiveType("SByte");
case TypeCode.Byte:
return new PrimitiveType("Byte");
case TypeCode.Int16:
return new PrimitiveType("Short");
case TypeCode.UInt16:
return new PrimitiveType("UShort");
case TypeCode.Int32:
return new PrimitiveType("Integer");
case TypeCode.UInt32:
return new PrimitiveType("UInteger");
case TypeCode.Int64:
return new PrimitiveType("Long");
case TypeCode.UInt64:
return new PrimitiveType("ULong");
case TypeCode.Single:
return new PrimitiveType("Single");
case TypeCode.Double:
return new PrimitiveType("Double");
case TypeCode.Decimal:
return new PrimitiveType("Decimal");
case TypeCode.String:
return new PrimitiveType("String");
case TypeCode.DateTime:
return new PrimitiveType("Date");
}
return new SimpleType(type.FullName); // TODO: implement this correctly
}
}
}

119
NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeName/ComposedType.cs

@ -0,0 +1,119 @@ @@ -0,0 +1,119 @@
// 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.Collections.Generic;
using System.Linq;
using System.Text;
namespace ICSharpCode.NRefactory.VB.Ast
{
public class ComposedType : AstType
{
public static readonly Role<VBTokenNode> NullableRole = new Role<VBTokenNode>("Nullable", VBTokenNode.Null);
public static readonly Role<ArraySpecifier> ArraySpecifierRole = new Role<ArraySpecifier>("ArraySpecifier");
public AstType BaseType {
get { return GetChildByRole(Roles.Type); }
set { SetChildByRole(Roles.Type, value); }
}
public bool HasNullableSpecifier {
get {
return !GetChildByRole(NullableRole).IsNull;
}
set {
SetChildByRole(NullableRole, value ? new VBTokenNode(AstLocation.Empty, 1) : null);
}
}
public AstNodeCollection<ArraySpecifier> ArraySpecifiers {
get { return GetChildrenByRole (ArraySpecifierRole); }
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitComposedType (this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ComposedType o = other as ComposedType;
return o != null && this.HasNullableSpecifier == o.HasNullableSpecifier && this.ArraySpecifiers.DoMatch(o.ArraySpecifiers, match);
}
public override string ToString()
{
StringBuilder b = new StringBuilder();
b.Append(this.BaseType.ToString());
if (this.HasNullableSpecifier)
b.Append('?');
foreach (var arraySpecifier in this.ArraySpecifiers) {
b.Append('(');
b.Append(',', arraySpecifier.Dimensions - 1);
b.Append(')');
}
return b.ToString();
}
public override AstType MakeArrayType(int dimensions)
{
InsertChildBefore(this.ArraySpecifiers.FirstOrDefault(), new ArraySpecifier(dimensions), ArraySpecifierRole);
return this;
}
}
/// <summary>
/// [,,,]
/// </summary>
public class ArraySpecifier : AstNode
{
public ArraySpecifier()
{
}
public ArraySpecifier(int dimensions)
{
this.Dimensions = dimensions;
}
public VBTokenNode LParToken {
get { return GetChildByRole (Roles.LPar); }
}
public int Dimensions {
get { return 1 + GetChildrenByRole(Roles.Comma).Count(); }
set {
int d = this.Dimensions;
while (d > value) {
GetChildByRole(Roles.Comma).Remove();
d--;
}
while (d < value) {
InsertChildBefore(GetChildByRole(Roles.Comma), new VBTokenNode(AstLocation.Empty, 1), Roles.Comma);
d++;
}
}
}
public VBTokenNode RParToken {
get { return GetChildByRole (Roles.LPar); }
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitArraySpecifier(this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
ArraySpecifier o = other as ArraySpecifier;
return o != null && this.Dimensions == o.Dimensions;
}
public override string ToString()
{
return "(" + new string(',', this.Dimensions - 1) + ")";
}
}
}

57
NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeName/PrimitiveType.cs

@ -0,0 +1,57 @@ @@ -0,0 +1,57 @@
// 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.Collections.Generic;
using System.Linq;
namespace ICSharpCode.NRefactory.VB.Ast
{
public class PrimitiveType : AstType
{
public string Keyword { get; set; }
public AstLocation Location { get; set; }
public PrimitiveType()
{
}
public PrimitiveType(string keyword)
{
this.Keyword = keyword;
}
public PrimitiveType(string keyword, AstLocation location)
{
this.Keyword = keyword;
this.Location = location;
}
public override AstLocation StartLocation {
get {
return Location;
}
}
public override AstLocation EndLocation {
get {
return new AstLocation (Location.Line, Location.Column + (Keyword != null ? Keyword.Length : 0));
}
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitPrimitiveType(this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
PrimitiveType o = other as PrimitiveType;
return o != null && MatchString(this.Keyword, o.Keyword);
}
public override string ToString()
{
return Keyword ?? base.ToString();
}
}
}

66
NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeName/QualifiedType.cs

@ -0,0 +1,66 @@ @@ -0,0 +1,66 @@
// 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.Linq;
using System.Text;
namespace ICSharpCode.NRefactory.VB.Ast
{
/// <summary>
/// Description of QualifiedType.
/// </summary>
public class QualifiedType : AstType
{
public static readonly Role<AstType> TargetRole = new Role<AstType>("Target", AstType.Null);
public AstType Target {
get { return GetChildByRole(TargetRole); }
set { SetChildByRole(TargetRole, value); }
}
public string Name {
get {
return GetChildByRole (Roles.Identifier).Name;
}
set {
SetChildByRole (Roles.Identifier, new Identifier(value, AstLocation.Empty));
}
}
public QualifiedType(AstType target, Identifier name)
{
Target = target;
SetChildByRole(Roles.Identifier, name);
}
public AstNodeCollection<AstType> TypeArguments {
get { return GetChildrenByRole (Roles.TypeArgument); }
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitQualifiedType(this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
var o = other as QualifiedType;
return o != null && MatchString(this.Name, o.Name) && this.Target.DoMatch(o.Target, match);
}
public override string ToString()
{
StringBuilder b = new StringBuilder();
b.Append(this.Target);
b.Append('.');
b.Append(this.Name);
if (this.TypeArguments.Any()) {
b.Append('(');
b.Append(string.Join(", ", this.TypeArguments));
b.Append(')');
}
return b.ToString();
}
}
}

87
NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeName/SimpleType.cs

@ -0,0 +1,87 @@ @@ -0,0 +1,87 @@
//
// FullTypeName.cs
//
// Author:
// Mike Krüger <mkrueger@novell.com>
//
// Copyright (c) 2010 Novell, Inc (http://www.novell.com)
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ICSharpCode.NRefactory.VB.Ast
{
public class SimpleType : AstType
{
public SimpleType()
{
}
public SimpleType(string identifier)
{
this.Identifier = identifier;
}
public SimpleType(string identifier, AstLocation location)
{
SetChildByRole (Roles.Identifier, new Identifier(identifier, location));
}
public string Identifier {
get {
return GetChildByRole (Roles.Identifier).Name;
}
set {
SetChildByRole (Roles.Identifier, new Identifier(value, AstLocation.Empty));
}
}
public AstNodeCollection<AstType> TypeArguments {
get { return GetChildrenByRole (Roles.TypeArgument); }
}
public override S AcceptVisitor<T, S> (IAstVisitor<T, S> visitor, T data)
{
return visitor.VisitSimpleType(this, data);
}
protected internal override bool DoMatch(AstNode other, PatternMatching.Match match)
{
SimpleType o = other as SimpleType;
return o != null && MatchString(this.Identifier, o.Identifier) && this.TypeArguments.DoMatch(o.TypeArguments, match);
}
public override string ToString()
{
StringBuilder b = new StringBuilder(this.Identifier);
if (this.TypeArguments.Any()) {
b.Append('(');
b.Append("Of ");
b.Append(string.Join(", ", this.TypeArguments));
b.Append(')');
}
return b.ToString();
}
}
}

427
NRefactory/ICSharpCode.NRefactory.VB/Ast/TypeReference.cs

@ -1,427 +0,0 @@ @@ -1,427 +0,0 @@
// 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.Collections.Generic;
using System.Diagnostics;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Text;
namespace ICSharpCode.NRefactory.VB.Ast
{
public class TypeReference : AbstractNode, INullable, ICloneable
{
public static readonly TypeReference StructConstraint = new TypeReference("constraint: struct");
public static readonly TypeReference ClassConstraint = new TypeReference("constraint: class");
public static readonly TypeReference NewConstraint = new TypeReference("constraint: new");
string type = "";
int pointerNestingLevel;
int[] rankSpecifier;
List<TypeReference> genericTypes = new List<TypeReference>();
#region Static primitive type list
static Dictionary<string, string> types = 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()
{
// C# types
types.Add("bool", "System.Boolean");
types.Add("byte", "System.Byte");
types.Add("char", "System.Char");
types.Add("decimal", "System.Decimal");
types.Add("double", "System.Double");
types.Add("float", "System.Single");
types.Add("int", "System.Int32");
types.Add("long", "System.Int64");
types.Add("object", "System.Object");
types.Add("sbyte", "System.SByte");
types.Add("short", "System.Int16");
types.Add("string", "System.String");
types.Add("uint", "System.UInt32");
types.Add("ulong", "System.UInt64");
types.Add("ushort", "System.UInt16");
types.Add("void", "System.Void");
// VB.NET types
vbtypes.Add("Boolean", "System.Boolean");
vbtypes.Add("Byte", "System.Byte");
vbtypes.Add("SByte", "System.SByte");
vbtypes.Add("Date", "System.DateTime");
vbtypes.Add("Char", "System.Char");
vbtypes.Add("Decimal", "System.Decimal");
vbtypes.Add("Double", "System.Double");
vbtypes.Add("Single", "System.Single");
vbtypes.Add("Integer", "System.Int32");
vbtypes.Add("Long", "System.Int64");
vbtypes.Add("UInteger","System.UInt32");
vbtypes.Add("ULong", "System.UInt64");
vbtypes.Add("Object", "System.Object");
vbtypes.Add("Short", "System.Int16");
vbtypes.Add("UShort", "System.UInt16");
vbtypes.Add("String", "System.String");
foreach (KeyValuePair<string, string> pair in types) {
typesReverse.Add(pair.Value, pair.Key);
}
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; }
}
static string GetSystemType(string type)
{
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()
{
return this.Clone();
}
public virtual TypeReference Clone()
{
TypeReference c = new TypeReference(type);
CopyFields(this, c);
return c;
}
/// <summary>
/// Copies the pointerNestingLevel, RankSpecifier, GenericTypes and IsGlobal flag
/// from <paramref name="from"/> to <paramref name="to"/>.
/// </summary>
/// <remarks>
/// If <paramref name="to"/> already contains generics, the new generics are appended to the list.
/// </remarks>
protected static void CopyFields(TypeReference from, TypeReference to)
{
to.pointerNestingLevel = from.pointerNestingLevel;
if (from.rankSpecifier != null) {
to.rankSpecifier = (int[])from.rankSpecifier.Clone();
}
foreach (TypeReference r in from.genericTypes) {
to.genericTypes.Add(r.Clone());
}
to.IsGlobal = from.IsGlobal;
to.IsKeyword = from.IsKeyword;
}
public string Type {
get {
return type;
}
set {
Debug.Assert(value != null);
type = value ?? "?";
}
}
/// <summary>
/// Removes the last identifier from the type.
/// e.g. "System.String.Length" becomes "System.String" or
/// "System.Collections.IEnumerable(of string).Current" becomes "System.Collections.IEnumerable(of string)"
/// This is used for explicit interface implementation in VB.
/// </summary>
public static string StripLastIdentifierFromType(ref TypeReference tr)
{
if (tr is InnerClassTypeReference && ((InnerClassTypeReference)tr).Type.IndexOf('.') < 0) {
string ident = ((InnerClassTypeReference)tr).Type;
tr = ((InnerClassTypeReference)tr).BaseType;
return ident;
} else {
int pos = tr.Type.LastIndexOf('.');
if (pos < 0)
return tr.Type;
string ident = tr.Type.Substring(pos + 1);
tr.Type = tr.Type.Substring(0, pos);
return ident;
}
}
public int PointerNestingLevel {
get {
return pointerNestingLevel;
}
set {
Debug.Assert(this.IsNull == false);
pointerNestingLevel = value;
}
}
/// <summary>
/// The rank of the array type.
/// For "object[]", this is { 0 }; for "object[,]", it is {1}.
/// For "object[,][,,][]", it is {1, 2, 0}.
/// For non-array types, this property is null or {}.
/// </summary>
public int[] RankSpecifier {
get {
return rankSpecifier;
}
set {
Debug.Assert(this.IsNull == false);
rankSpecifier = value;
}
}
public List<TypeReference> GenericTypes {
get {
return genericTypes;
}
}
public bool IsArrayType {
get {
return rankSpecifier != null && rankSpecifier.Length > 0;
}
}
public static TypeReference CheckNull(TypeReference typeReference)
{
return typeReference ?? NullTypeReference.Instance;
}
public static TypeReference Null {
get {
return NullTypeReference.Instance;
}
}
public virtual bool IsNull {
get {
return false;
}
}
/// <summary>
/// Gets/Sets if the type reference had a "global::" prefix.
/// </summary>
public bool IsGlobal {
get; set;
}
/// <summary>
/// Gets/Sets if the type reference was using a language keyword.
/// </summary>
public bool IsKeyword {
get; set;
}
public TypeReference(string type)
{
this.Type = type;
}
public TypeReference(string type, bool isKeyword)
{
this.Type = type;
this.IsKeyword = isKeyword;
}
public TypeReference(string type, List<TypeReference> genericTypes) : this(type)
{
if (genericTypes != null) {
this.genericTypes = genericTypes;
}
}
public TypeReference(string type, int[] rankSpecifier) : this(type, 0, rankSpecifier)
{
}
public TypeReference(string type, int pointerNestingLevel, int[] rankSpecifier) : this(type, pointerNestingLevel, rankSpecifier, null)
{
}
public TypeReference(string type, int pointerNestingLevel, int[] rankSpecifier, List<TypeReference> genericTypes)
{
Debug.Assert(type != null);
this.type = type;
this.pointerNestingLevel = pointerNestingLevel;
this.rankSpecifier = rankSpecifier;
if (genericTypes != null) {
this.genericTypes = genericTypes;
}
}
protected TypeReference()
{}
public override object AcceptVisitor(IAstVisitor visitor, object data)
{
return visitor.VisitTypeReference(this, data);
}
public override string ToString()
{
StringBuilder b = new StringBuilder(type);
if (genericTypes != null && genericTypes.Count > 0) {
b.Append('<');
for (int i = 0; i < genericTypes.Count; i++) {
if (i > 0) b.Append(',');
b.Append(genericTypes[i].ToString());
}
b.Append('>');
}
if (pointerNestingLevel > 0) {
b.Append('*', pointerNestingLevel);
}
if (IsArrayType) {
foreach (int rank in rankSpecifier) {
b.Append('[');
if (rank < 0)
b.Append('`', -rank);
else
b.Append(',', rank);
b.Append(']');
}
}
return b.ToString();
}
public static bool AreEqualReferences(TypeReference a, TypeReference b)
{
if (a == b) return true;
if (a == null || b == null) return false;
if (a is InnerClassTypeReference) a = ((InnerClassTypeReference)a).CombineToNormalTypeReference();
if (b is InnerClassTypeReference) b = ((InnerClassTypeReference)b).CombineToNormalTypeReference();
if (a.type != b.type) return false;
if (a.IsKeyword != b.IsKeyword) return false;
if (a.IsGlobal != b.IsGlobal) return false;
if (a.pointerNestingLevel != b.pointerNestingLevel) return false;
if (a.IsArrayType != b.IsArrayType) return false;
if (a.IsArrayType) {
if (a.rankSpecifier.Length != b.rankSpecifier.Length) return false;
for (int i = 0; i < a.rankSpecifier.Length; i++) {
if (a.rankSpecifier[i] != b.rankSpecifier[i]) return false;
}
}
if (a.genericTypes.Count != b.genericTypes.Count) return false;
for (int i = 0; i < a.genericTypes.Count; i++) {
if (!AreEqualReferences(a.genericTypes[i], b.genericTypes[i]))
return false;
}
return true;
}
}
internal sealed class NullTypeReference : TypeReference
{
public static readonly NullTypeReference Instance = new NullTypeReference();
public override bool IsNull {
get {
return true;
}
}
public override TypeReference Clone()
{
return this;
}
public override object AcceptVisitor(IAstVisitor visitor, object data)
{
return null;
}
public override string ToString()
{
return String.Format("[NullTypeReference]");
}
}
/// <summary>
/// We need this special type reference for cases like
/// OuterClass(Of T1).InnerClass(Of T2) (in expression or type context)
/// or Dictionary(Of String, NamespaceStruct).KeyCollection (in type context, otherwise it's a
/// MemberReferenceExpression)
/// </summary>
public class InnerClassTypeReference: TypeReference
{
TypeReference baseType;
public TypeReference BaseType {
get { return baseType; }
set { baseType = value; }
}
public override TypeReference Clone()
{
InnerClassTypeReference c = new InnerClassTypeReference(baseType.Clone(), Type, new List<TypeReference>());
CopyFields(this, c);
return c;
}
public InnerClassTypeReference(TypeReference outerClass, string innerType, List<TypeReference> innerGenericTypes)
: base(innerType, innerGenericTypes)
{
this.baseType = outerClass;
}
public override object AcceptVisitor(IAstVisitor visitor, object data)
{
return visitor.VisitInnerClassTypeReference(this, data);
}
/// <summary>
/// Creates a type reference where all type parameters are specified for the innermost class.
/// Namespace.OuterClass(of string).InnerClass(of integer).InnerInnerClass
/// becomes Namespace.OuterClass.InnerClass.InnerInnerClass(of string, integer)
/// </summary>
public TypeReference CombineToNormalTypeReference()
{
TypeReference tr = (baseType is InnerClassTypeReference)
? ((InnerClassTypeReference)baseType).CombineToNormalTypeReference()
: baseType.Clone();
CopyFields(this, tr);
tr.Type += "." + Type;
return tr;
}
public override string ToString()
{
return baseType.ToString() + "+" + base.ToString();
}
}
}

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save