diff --git a/ICSharpCode.Decompiler/Ast/AstBuilder.cs b/ICSharpCode.Decompiler/Ast/AstBuilder.cs
index 86b62ced5..21c5d73a4 100644
--- a/ICSharpCode.Decompiler/Ast/AstBuilder.cs
+++ b/ICSharpCode.Decompiler/Ast/AstBuilder.cs
@@ -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
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
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
return op;
}
}
- astMethod.WithAnnotation(methodMapping);
return astMethod;
}
@@ -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
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
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
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
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
return type.CustomAttributes.Any(attr => attr.AttributeType.FullName == "System.FlagsAttribute");
}
+
+ ///
+ /// Sets new modifier if the member hides some other member from a base type.
+ ///
+ /// The node of the member which new modifier state should be determined.
+ static void SetNewModifier(AttributedNode member)
+ {
+ try {
+ bool addNewModifier = false;
+ if (member is IndexerDeclaration) {
+ var propertyDef = member.Annotation();
+ 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();
+ 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;
+ }
+
+ ///
+ /// Determines whether any base class member has the same name as the given member.
+ ///
+ /// The derived type's member.
+ /// true if names of methods declared in base types should also be checked.
+ /// true if any base member has the same name as given member, otherwise false.
+ 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(IEnumerable members, IMemberDefinition derived, Predicate condition = null)
+ where T : IMemberDefinition
+ {
+ return members.Any(m => m.Name == derived.Name
+ && (condition == null || condition(m))
+ && TypesHierarchyHelpers.IsVisibleFromDerived(m, derived.DeclaringType));
+ }
///
/// Gets the local variables for the current decompiled type, method, etc.
diff --git a/ICSharpCode.Decompiler/Ast/TypesHierarchyHelpers.cs b/ICSharpCode.Decompiler/Ast/TypesHierarchyHelpers.cs
index ca1d72f8f..a7cd35a30 100644
--- a/ICSharpCode.Decompiler/Ast/TypesHierarchyHelpers.cs
+++ b/ICSharpCode.Decompiler/Ast/TypesHierarchyHelpers.cs
@@ -27,6 +27,13 @@ namespace ICSharpCode.Decompiler.Ast
}
}
+ ///
+ /// Determines whether one method overrides or hides another method.
+ ///
+ /// The method declared in a base type.
+ /// The method declared in a derived type.
+ /// true if hides or overrides ,
+ /// otherwise false.
public static bool IsBaseMethod(MethodDefinition parentMethod, MethodDefinition childMethod)
{
if (parentMethod == null)
@@ -44,6 +51,13 @@ namespace ICSharpCode.Decompiler.Ast
return FindBaseMethods(childMethod).Any(m => m == parentMethod);// || (parentMethod.HasGenericParameters && m.);
}
+ ///
+ /// Determines whether a property overrides or hides another property.
+ ///
+ /// The property declared in a base type.
+ /// The property declared in a derived type.
+ /// true if the hides or overrides ,
+ /// otherwise false.
public static bool IsBaseProperty(PropertyDefinition parentProperty, PropertyDefinition childProperty)
{
if (parentProperty == null)
@@ -69,6 +83,11 @@ namespace ICSharpCode.Decompiler.Ast
return FindBaseEvents(childEvent).Any(m => m == parentEvent);
}
+ ///
+ /// Finds all methods from base types overridden or hidden by the specified method.
+ ///
+ /// The method which overrides or hides methods from base types.
+ /// Methods overriden or hidden by the specified method.
public static IEnumerable FindBaseMethods(MethodDefinition method)
{
if (method == null)
@@ -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 FindBaseProperties(PropertyDefinition property, bool ignoreResolveExceptions = false)
+ ///
+ /// Finds all properties from base types overridden or hidden by the specified property.
+ ///
+ /// The property which overrides or hides properties from base types.
+ /// Properties overriden or hidden by the specified property.
+ public static IEnumerable 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 FindBaseEvents(EventDefinition eventDef)
@@ -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)
+ ///
+ /// Determinates whether member of the base type is visible from a derived type.
+ ///
+ /// The member which visibility is checked.
+ /// The derived type.
+ /// true if the member is visible from derived type, othewise false.
+ 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 candidate, GenericContext method)
@@ -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
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
private static bool MatchParameters(GenericContext baseParameterType, GenericContext 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
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
struct GenericContext where T : class
{
private static readonly ReadOnlyCollection Empty = new ReadOnlyCollection(new List());
+ 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 TypeArguments;
@@ -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 ApplyTo(T2 item) where T2 : class
{
return new GenericContext(item, this.TypeArguments);
}
+
+ private class DummyGenericParameterProvider : IGenericParameterProvider
+ {
+ readonly Mono.Cecil.GenericParameterType type;
+ readonly Mono.Collections.Generic.Collection parameters;
+
+ public DummyGenericParameterProvider(bool methodTypeParameter)
+ {
+ type = methodTypeParameter ? Mono.Cecil.GenericParameterType.Method :
+ Mono.Cecil.GenericParameterType.Type;
+ parameters = new Mono.Collections.Generic.Collection(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 IGenericParameterProvider.GenericParameters
+ {
+ get { return parameters; }
+ }
+
+ GenericParameterType IGenericParameterProvider.GenericParameterType
+ {
+ get { return type; }
+ }
+
+ MetadataToken IMetadataTokenProvider.MetadataToken
+ {
+ get
+ {
+ throw new NotImplementedException();
+ }
+ set
+ {
+ throw new NotImplementedException();
+ }
+ }
+ }
}
}
}
diff --git a/ICSharpCode.Decompiler/DecompilerSettings.cs b/ICSharpCode.Decompiler/DecompilerSettings.cs
index 32b257eda..4d5d62d76 100644
--- a/ICSharpCode.Decompiler/DecompilerSettings.cs
+++ b/ICSharpCode.Decompiler/DecompilerSettings.cs
@@ -209,6 +209,21 @@ namespace ICSharpCode.Decompiler
}
}
+ bool showXmlDocumentation = true;
+
+ ///
+ /// Gets/Sets whether to include XML documentation comments in the decompiled code
+ ///
+ public bool ShowXmlDocumentation {
+ get { return showXmlDocumentation; }
+ set {
+ if (showXmlDocumentation != value) {
+ showXmlDocumentation = value;
+ OnPropertyChanged("ShowXmlDocumentation");
+ }
+ }
+ }
+
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string propertyName)
diff --git a/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj b/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj
index 90a2db494..b4906c60f 100644
--- a/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj
+++ b/ICSharpCode.Decompiler/Tests/ICSharpCode.Decompiler.Tests.csproj
@@ -69,7 +69,7 @@
-
+
@@ -107,4 +107,4 @@
-
+
\ No newline at end of file
diff --git a/ICSharpCode.Decompiler/Tests/Types/S_TypeMemberDeclarations.cs b/ICSharpCode.Decompiler/Tests/Types/S_TypeMemberDeclarations.cs
index 401bfab61..22458bcfc 100644
--- a/ICSharpCode.Decompiler/Tests/Types/S_TypeMemberDeclarations.cs
+++ b/ICSharpCode.Decompiler/Tests/Types/S_TypeMemberDeclarations.cs
@@ -428,8 +428,8 @@ namespace IndexerOverrideRestrictedAccessorOnly
}
}
}
-//$$ PropertyHiding
-namespace PropertyHiding
+//$$ HideProperty
+namespace HideProperty
{
public class A
{
@@ -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
+ {
+ public void M1(T p)
+ {
+ }
+ public int M2(int t)
+ {
+ return 3;
+ }
+ }
+ public class G1 : G
+ {
+ public new int M1(int i)
+ {
+ return 0;
+ }
+ public int M2(T i)
+ {
+ return 2;
+ }
+ }
+ public class G2 : G
+ {
+ 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)
+ {
+ }
+ }
+ public class A1 : A
+ {
+ public new void M(K t)
+ {
+ }
+ public void M(int t)
+ {
+ }
+ }
+ public class B
+ {
+ public void M()
+ {
+ }
+ public void M1()
+ {
+ }
+ public void M2(T t)
+ {
+ }
+ }
+ public class B1 : B
+ {
+ public void M()
+ {
+ }
+ public new void M1()
+ {
+ }
+ public new void M2(R r)
+ {
+ }
+ }
+ public class C
+ {
+ public void M(T t)
+ {
+ }
+ }
+ public class C1 : C
+ {
+ public void M(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
{
@@ -515,8 +904,8 @@ namespace IndexerHidingGeneric
}
}
}
-//$$ MethodHiding
-namespace MethodHiding
+//$$ HideMethod
+namespace HideMethod
{
public class A
{
@@ -539,8 +928,8 @@ namespace MethodHiding
}
}
}
-//$$ MethodHideGeneric
-namespace MethodHideGeneric
+//$$ HideMethodGeneric
+namespace HideMethodGeneric
{
public class A
{
@@ -583,8 +972,8 @@ namespace MethodHideGeneric
}
}
}
-//$$ MethodHideGenericSkipPrivate
-namespace MethodHideGenericSkipPrivate
+//$$ HideMethodGenericSkipPrivate
+namespace HideMethodGenericSkipPrivate
{
public class A
{
@@ -617,8 +1006,8 @@ namespace MethodHideGenericSkipPrivate
}
}
}
-//$$ MethodHideGeneric2
-namespace MethodHideGeneric2
+//$$ HideMethodGeneric2
+namespace HideMethodGeneric2
{
public class A
{
@@ -669,8 +1058,51 @@ namespace MethodHideGeneric2
}
}
}
-//$$ EventHiding
-namespace EventHiding
+//$$ HideMethodDiffSignatures
+namespace HideMethodDiffSignatures
+{
+ public class C1
+ {
+ public virtual void M(T arg)
+ {
+ }
+ }
+ public class C2 : C1
+ {
+ public new virtual void M(T2 arg)
+ {
+ }
+ }
+ public class C3 : C2
+ {
+ 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
{
diff --git a/ILSpy/AboutPage.cs b/ILSpy/AboutPage.cs
index 9116d0e6a..c80286d55 100644
--- a/ILSpy/AboutPage.cs
+++ b/ILSpy/AboutPage.cs
@@ -178,7 +178,7 @@ namespace ICSharpCode.ILSpy
{
var tcs = new TaskCompletionSource();
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);
diff --git a/ILSpy/CSharpLanguage.cs b/ILSpy/CSharpLanguage.cs
index 0f1cc6e19..865d9c2e0 100644
--- a/ILSpy/CSharpLanguage.cs
+++ b/ILSpy/CSharpLanguage.cs
@@ -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
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
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
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
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
{
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) {
diff --git a/ILSpy/ILSpy.csproj b/ILSpy/ILSpy.csproj
index dbe8416ca..baadb3c3d 100644
--- a/ILSpy/ILSpy.csproj
+++ b/ILSpy/ILSpy.csproj
@@ -162,6 +162,7 @@
+
diff --git a/ILSpy/LoadedAssembly.cs b/ILSpy/LoadedAssembly.cs
index 29cc0c59e..8285be9ae 100644
--- a/ILSpy/LoadedAssembly.cs
+++ b/ILSpy/LoadedAssembly.cs
@@ -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
diff --git a/ILSpy/Options/DecompilerSettingsPanel.xaml b/ILSpy/Options/DecompilerSettingsPanel.xaml
index d9f0e938e..ae1a96404 100644
--- a/ILSpy/Options/DecompilerSettingsPanel.xaml
+++ b/ILSpy/Options/DecompilerSettingsPanel.xaml
@@ -7,5 +7,6 @@
Decompile enumerators (yield return)
Decompile query expressions
Use variable names from debug symbols, if available
+ Show XML documentation in decompiled code
\ No newline at end of file
diff --git a/ILSpy/Options/DecompilerSettingsPanel.xaml.cs b/ILSpy/Options/DecompilerSettingsPanel.xaml.cs
index 99e8474ae..50564416a 100644
--- a/ILSpy/Options/DecompilerSettingsPanel.xaml.cs
+++ b/ILSpy/Options/DecompilerSettingsPanel.xaml.cs
@@ -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
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)
diff --git a/ILSpy/TextView/DecompilerTextView.cs b/ILSpy/TextView/DecompilerTextView.cs
index 2118568b4..4d938aded 100644
--- a/ILSpy/TextView/DecompilerTextView.cs
+++ b/ILSpy/TextView/DecompilerTextView.cs
@@ -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;
}
diff --git a/ILSpy/XmlDoc/AddXmlDocTransform.cs b/ILSpy/XmlDoc/AddXmlDocTransform.cs
new file mode 100644
index 000000000..dd0fb3311
--- /dev/null
+++ b/ILSpy/XmlDoc/AddXmlDocTransform.cs
@@ -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
+{
+ ///
+ /// Adds XML documentation for member definitions.
+ ///
+ static class AddXmlDocTransform
+ {
+ public static void Run(AstNode node)
+ {
+ if (node is AttributedNode) {
+ MemberReference mr = node.Annotation();
+ 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();
+ }
+ }
+ }
+}
diff --git a/NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.Designer.cs b/NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.Designer.cs
new file mode 100644
index 000000000..998cee6fe
--- /dev/null
+++ b/NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.Designer.cs
@@ -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
+ {
+ ///
+ /// Designer variable used to keep track of non-visual components.
+ ///
+ private System.ComponentModel.IContainer components = null;
+
+ ///
+ /// Disposes resources used by the control.
+ ///
+ /// true if managed resources should be disposed; otherwise, false.
+ protected override void Dispose(bool disposing)
+ {
+ if (disposing) {
+ if (components != null) {
+ components.Dispose();
+ }
+ }
+ base.Dispose(disposing);
+ }
+
+ ///
+ /// 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.
+ ///
+ 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;
+ }
+}
diff --git a/NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.cs b/NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.cs
new file mode 100644
index 000000000..d667596de
--- /dev/null
+++ b/NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.cs
@@ -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
+{
+ ///
+ /// Description of CSDemo.
+ ///
+ 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> builtInLibs = new Lazy>(
+ 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 projects = new List();
+ 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;
+ }
+ }
+}
diff --git a/NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.resx b/NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.resx
new file mode 100644
index 000000000..1af7de150
--- /dev/null
+++ b/NRefactory/ICSharpCode.NRefactory.Demo/CSDemo.resx
@@ -0,0 +1,120 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ text/microsoft-resx
+
+
+ 2.0
+
+
+ System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
\ No newline at end of file
diff --git a/NRefactory/ICSharpCode.NRefactory.Demo/ICSharpCode.NRefactory.Demo.csproj b/NRefactory/ICSharpCode.NRefactory.Demo/ICSharpCode.NRefactory.Demo.csproj
index 169dd2a0d..841474f59 100644
--- a/NRefactory/ICSharpCode.NRefactory.Demo/ICSharpCode.NRefactory.Demo.csproj
+++ b/NRefactory/ICSharpCode.NRefactory.Demo/ICSharpCode.NRefactory.Demo.csproj
@@ -40,17 +40,9 @@
-
- Form
-
-
- VBEditDialog.cs
-
-
- UserControl
-
-
- VBAstView.cs
+
+
+ CSDemo.cs
Form
@@ -60,9 +52,7 @@
-
- UserControl
-
+
VBDemo.cs
@@ -78,11 +68,8 @@
-
- VBEditDialog.cs
-
-
- VBAstView.cs
+
+ CSDemo.cs
MainForm.cs
diff --git a/NRefactory/ICSharpCode.NRefactory.Demo/MainForm.Designer.cs b/NRefactory/ICSharpCode.NRefactory.Demo/MainForm.Designer.cs
index c24f304ab..12c38ffb6 100644
--- a/NRefactory/ICSharpCode.NRefactory.Demo/MainForm.Designer.cs
+++ b/NRefactory/ICSharpCode.NRefactory.Demo/MainForm.Designer.cs
@@ -30,40 +30,32 @@ namespace ICSharpCode.NRefactory.Demo
///
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
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
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
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;
}
diff --git a/NRefactory/ICSharpCode.NRefactory.Demo/MainForm.cs b/NRefactory/ICSharpCode.NRefactory.Demo/MainForm.cs
index 285428d8f..9633a00f1 100644
--- a/NRefactory/ICSharpCode.NRefactory.Demo/MainForm.cs
+++ b/NRefactory/ICSharpCode.NRefactory.Demo/MainForm.cs
@@ -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> builtInLibs = new Lazy>(
- 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 projects = new List();
- 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;
}
}
}
diff --git a/NRefactory/ICSharpCode.NRefactory.Demo/VBAstView.cs b/NRefactory/ICSharpCode.NRefactory.Demo/VBAstView.cs
index 42be32e73..a6e6f58aa 100644
--- a/NRefactory/ICSharpCode.NRefactory.Demo/VBAstView.cs
+++ b/NRefactory/ICSharpCode.NRefactory.Demo/VBAstView.cs
@@ -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
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
}
}
- void AddProperties(Type type, INode node)
+ void AddProperties(Type type, AstNode node)
{
if (type == typeof(AbstractNode))
return;
diff --git a/NRefactory/ICSharpCode.NRefactory.Demo/VBDemo.Designer.cs b/NRefactory/ICSharpCode.NRefactory.Demo/VBDemo.Designer.cs
index f4cba1760..48641c669 100644
--- a/NRefactory/ICSharpCode.NRefactory.Demo/VBDemo.Designer.cs
+++ b/NRefactory/ICSharpCode.NRefactory.Demo/VBDemo.Designer.cs
@@ -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
//
// 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
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
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;
diff --git a/NRefactory/ICSharpCode.NRefactory.Demo/VBDemo.cs b/NRefactory/ICSharpCode.NRefactory.Demo/VBDemo.cs
index 387921259..beb3308c1 100644
--- a/NRefactory/ICSharpCode.NRefactory.Demo/VBDemo.cs
+++ b/NRefactory/ICSharpCode.NRefactory.Demo/VBDemo.cs
@@ -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
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
- ParseButtonClick(null, null);
}
- IList 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 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);
+ }
}
}
}
diff --git a/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ConditionalOperatorTests.cs b/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ConditionalOperatorTests.cs
new file mode 100644
index 000000000..d1178757e
--- /dev/null
+++ b/NRefactory/ICSharpCode.NRefactory.Tests/CSharp/Resolver/ConditionalOperatorTests.cs
@@ -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), resolver.ResolveConditional(
+ MakeResult(typeof(bool)), MakeResult(typeof(List