Browse Source

Delete files not included in ILSpy.csproj from the repository.

pull/1030/head
Siegfried Pammer 8 years ago
parent
commit
463494e3fa
  1. 65
      ILSpy/Cecil/CecilExtensions.cs
  2. 525
      ILSpy/Cecil/TypesHierarchyHelpers.cs
  3. 176
      ILSpy/VB/ILSpyEnvironmentProvider.cs
  4. 448
      ILSpy/VB/VBLanguage.cs
  5. 254
      ILSpy/VB/VBTextOutputFormatter.cs

65
ILSpy/Cecil/CecilExtensions.cs

@ -1,65 +0,0 @@ @@ -1,65 +0,0 @@
// 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.Collections.Generic;
using System.Linq;
using ICSharpCode.Decompiler.TypeSystem;
using Mono.Cecil;
using Mono.Cecil.Cil;
using ArrayType = Mono.Cecil.ArrayType;
namespace ICSharpCode.ILSpy.Cecil
{
/// <summary>
/// Cecil helper methods.
/// </summary>
public static class CecilExtensions
{
public static HashSet<MethodDefinition> GetAccessorMethods(this TypeDefinition type)
{
HashSet<MethodDefinition> accessorMethods = new HashSet<MethodDefinition>();
foreach (var property in type.Properties) {
accessorMethods.Add(property.GetMethod);
accessorMethods.Add(property.SetMethod);
if (property.HasOtherMethods) {
foreach (var m in property.OtherMethods)
accessorMethods.Add(m);
}
}
foreach (EventDefinition ev in type.Events) {
accessorMethods.Add(ev.AddMethod);
accessorMethods.Add(ev.RemoveMethod);
accessorMethods.Add(ev.InvokeMethod);
if (ev.HasOtherMethods) {
foreach (var m in ev.OtherMethods)
accessorMethods.Add(m);
}
}
return accessorMethods;
}
public static TypeDefinition ResolveWithinSameModule(this TypeReference type)
{
if (type != null && type.GetElementType().Module == type.Module)
return type.Resolve();
else
return null;
}
}
}

525
ILSpy/Cecil/TypesHierarchyHelpers.cs

@ -1,525 +0,0 @@ @@ -1,525 +0,0 @@
// 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.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.Cecil
{
public static class TypesHierarchyHelpers
{
public static bool IsBaseType(TypeDefinition baseType, TypeDefinition derivedType, bool resolveTypeArguments)
{
if (resolveTypeArguments)
return BaseTypes(derivedType).Any(t => t.Item == baseType);
else {
var comparableBaseType = baseType.Resolve();
if (comparableBaseType == null)
return false;
while (derivedType.BaseType != null) {
var resolvedBaseType = derivedType.BaseType.Resolve();
if (resolvedBaseType == null)
return false;
if (comparableBaseType == resolvedBaseType)
return true;
derivedType = resolvedBaseType;
}
return false;
}
}
/// <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)
throw new ArgumentNullException(nameof(parentMethod));
if (childMethod == null)
throw new ArgumentNullException(nameof(childMethod));
if (parentMethod.Name != childMethod.Name)
return false;
if (parentMethod.HasParameters || childMethod.HasParameters)
if (!parentMethod.HasParameters || !childMethod.HasParameters || parentMethod.Parameters.Count != childMethod.Parameters.Count)
return false;
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)
throw new ArgumentNullException(nameof(parentProperty));
if (childProperty == null)
throw new ArgumentNullException(nameof(childProperty));
if (parentProperty.Name != childProperty.Name)
return false;
if (parentProperty.HasParameters || childProperty.HasParameters)
if (!parentProperty.HasParameters || !childProperty.HasParameters || parentProperty.Parameters.Count != childProperty.Parameters.Count)
return false;
return FindBaseProperties(childProperty).Any(m => m == parentProperty);
}
public static bool IsBaseEvent(EventDefinition parentEvent, EventDefinition childEvent)
{
if (parentEvent.Name != childEvent.Name)
return false;
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)
throw new ArgumentNullException(nameof(method));
var typeContext = CreateGenericContext(method.DeclaringType);
var gMethod = typeContext.ApplyTo(method);
foreach (var baseType in BaseTypes(method.DeclaringType))
foreach (var baseMethod in baseType.Item.Methods)
if (MatchMethod(baseType.ApplyTo(baseMethod), gMethod) && IsVisibleFromDerived(baseMethod, method.DeclaringType)) {
yield return baseMethod;
if (baseMethod.IsNewSlot == baseMethod.IsVirtual)
yield break;
}
}
/// <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(nameof(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)
&& IsVisibleFromDerived(baseProperty, property.DeclaringType)) {
if (isIndexer != baseProperty.IsIndexer())
continue;
yield return baseProperty;
var anyPropertyAccessor = baseProperty.GetMethod ?? baseProperty.SetMethod;
if (anyPropertyAccessor.IsNewSlot == anyPropertyAccessor.IsVirtual)
yield break;
}
}
public static IEnumerable<EventDefinition> FindBaseEvents(EventDefinition eventDef)
{
if (eventDef == null)
throw new ArgumentNullException(nameof(eventDef));
var typeContext = CreateGenericContext(eventDef.DeclaringType);
var gEvent = typeContext.ApplyTo(eventDef);
foreach (var baseType in BaseTypes(eventDef.DeclaringType))
foreach (var baseEvent in baseType.Item.Events)
if (MatchEvent(baseType.ApplyTo(baseEvent), gEvent) && IsVisibleFromDerived(baseEvent, eventDef.DeclaringType)) {
yield return baseEvent;
var anyEventAccessor = baseEvent.AddMethod ?? baseEvent.RemoveMethod;
if (anyEventAccessor.IsNewSlot == anyEventAccessor.IsVirtual)
yield break;
}
}
/// <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 (baseMember == null)
throw new ArgumentNullException(nameof(baseMember));
if (derivedType == null)
throw new ArgumentNullException(nameof(derivedType));
MethodAttributes attrs = GetAccessAttributes(baseMember) & MethodAttributes.MemberAccessMask;
if (attrs == MethodAttributes.Private)
return false;
if (baseMember.DeclaringType.Module == derivedType.Module)
return true;
if (attrs == MethodAttributes.Assembly || attrs == MethodAttributes.FamANDAssem) {
var derivedTypeAsm = derivedType.Module.Assembly;
var asm = baseMember.DeclaringType.Module.Assembly;
if (asm.HasCustomAttributes) {
var attributes = asm.CustomAttributes
.Where(attr => attr.AttributeType.FullName == "System.Runtime.CompilerServices.InternalsVisibleToAttribute");
foreach (var attribute in attributes) {
string assemblyName = attribute.ConstructorArguments[0].Value as string;
assemblyName = assemblyName.Split(',')[0]; // strip off any public key info
if (assemblyName == derivedTypeAsm.Name.Name)
return true;
}
}
return false;
}
return true;
}
private static MethodAttributes GetAccessAttributes(IMemberDefinition member)
{
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)
{
var mCandidate = candidate.Item;
var mMethod = method.Item;
if (mCandidate.Name != mMethod.Name)
return false;
if (mCandidate.HasOverrides)
return false;
if (mCandidate.IsSpecialName != method.Item.IsSpecialName)
return false;
if (mCandidate.HasGenericParameters || mMethod.HasGenericParameters) {
if (!mCandidate.HasGenericParameters || !mMethod.HasGenericParameters || mCandidate.GenericParameters.Count != mMethod.GenericParameters.Count)
return false;
}
if (mCandidate.HasParameters || mMethod.HasParameters) {
if (!mCandidate.HasParameters || !mMethod.HasParameters || mCandidate.Parameters.Count != mMethod.Parameters.Count)
return false;
for (int index = 0; index < mCandidate.Parameters.Count; index++) {
if (!MatchParameters(candidate.ApplyTo(mCandidate.Parameters[index]), method.ApplyTo(mMethod.Parameters[index])))
return false;
}
}
return true;
}
public static bool MatchInterfaceMethod(MethodDefinition candidate, MethodDefinition method, TypeReference interfaceContextType)
{
var candidateContext = CreateGenericContext(candidate.DeclaringType);
var gCandidate = candidateContext.ApplyTo(candidate);
if (interfaceContextType is GenericInstanceType) {
var methodContext = new GenericContext<TypeDefinition>(interfaceContextType.Resolve(), ((GenericInstanceType)interfaceContextType).GenericArguments);
var gMethod = methodContext.ApplyTo(method);
return MatchMethod(gCandidate, gMethod);
} else {
var methodContext = CreateGenericContext(interfaceContextType.Resolve());
var gMethod = candidateContext.ApplyTo(method);
return MatchMethod(gCandidate, gMethod);
}
}
private static bool MatchProperty(GenericContext<PropertyDefinition> candidate, GenericContext<PropertyDefinition> property)
{
var mCandidate = candidate.Item;
var mProperty = property.Item;
if (mCandidate.Name != mProperty.Name)
return false;
if ((mCandidate.GetMethod ?? mCandidate.SetMethod).HasOverrides)
return false;
if (mCandidate.HasParameters || mProperty.HasParameters) {
if (!mCandidate.HasParameters || !mProperty.HasParameters || mCandidate.Parameters.Count != mProperty.Parameters.Count)
return false;
for (int index = 0; index < mCandidate.Parameters.Count; index++) {
if (!MatchParameters(candidate.ApplyTo(mCandidate.Parameters[index]), property.ApplyTo(mProperty.Parameters[index])))
return false;
}
}
return true;
}
private static bool MatchEvent(GenericContext<EventDefinition> candidate, GenericContext<EventDefinition> ev)
{
var mCandidate = candidate.Item;
var mEvent = ev.Item;
if (mCandidate.Name != mEvent.Name)
return false;
if ((mCandidate.AddMethod ?? mCandidate.RemoveMethod).HasOverrides)
return false;
if (!IsSameType(candidate.ResolveWithContext(mCandidate.EventType), ev.ResolveWithContext(mEvent.EventType)))
return false;
return true;
}
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);
}
private static bool IsSameType(TypeReference tr1, TypeReference tr2)
{
if (tr1 == tr2)
return true;
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;
}
private static IEnumerable<GenericContext<TypeDefinition>> BaseTypes(TypeDefinition type)
{
return BaseTypes(CreateGenericContext(type));
}
private static IEnumerable<GenericContext<TypeDefinition>> BaseTypes(GenericContext<TypeDefinition> type)
{
while (type.Item.BaseType != null) {
var baseType = type.Item.BaseType;
var genericBaseType = baseType as GenericInstanceType;
if (genericBaseType != null) {
type = new GenericContext<TypeDefinition>(genericBaseType.ResolveOrThrow(),
genericBaseType.GenericArguments.Select(t => type.ResolveWithContext(t)));
} else
type = new GenericContext<TypeDefinition>(baseType.ResolveOrThrow());
yield return type;
}
}
private static GenericContext<TypeDefinition> CreateGenericContext(TypeDefinition type)
{
return type.HasGenericParameters
? new GenericContext<TypeDefinition>(type, type.GenericParameters)
: new GenericContext<TypeDefinition>(type);
}
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;
public GenericContext(T item)
{
if (item == null)
throw new ArgumentNullException(nameof(item));
Item = item;
TypeArguments = Empty;
}
public GenericContext(T item, IEnumerable<TypeReference> typeArguments)
{
if (item == null)
throw new ArgumentNullException(nameof(item));
Item = item;
var list = new List<TypeReference>();
foreach (var arg in typeArguments) {
var resolved = arg != null ? arg.Resolve() : arg;
list.Add(resolved != null ? resolved : arg);
}
TypeArguments = new ReadOnlyCollection<TypeReference>(list);
}
private GenericContext(T item, ReadOnlyCollection<TypeReference> typeArguments)
{
Item = item;
TypeArguments = typeArguments;
}
public TypeReference ResolveWithContext(TypeReference type)
{
var genericParameter = type as GenericParameter;
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);
}
return type.ResolveOrThrow();
}
private TypeReference ReplaceElementType(TypeSpecification ts, TypeReference newElementType)
{
var arrayType = ts as Mono.Cecil.ArrayType;
if (arrayType != null) {
if (newElementType == arrayType.ElementType)
return arrayType;
var newArrayType = new Mono.Cecil.ArrayType(newElementType, arrayType.Rank);
for (int dimension = 0; dimension < arrayType.Rank; dimension++)
newArrayType.Dimensions[dimension] = arrayType.Dimensions[dimension];
return newArrayType;
}
var byReferenceType = ts as Mono.Cecil.ByReferenceType;
if (byReferenceType != null) {
return new Mono.Cecil.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();
}
}
}
}
}
}

176
ILSpy/VB/ILSpyEnvironmentProvider.cs

@ -1,176 +0,0 @@ @@ -1,176 +0,0 @@
// 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.Collections.Generic;
using System.Linq;
using ICSharpCode.Decompiler;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.VB.Visitors;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.VB
{
public class ILSpyEnvironmentProvider : IEnvironmentProvider
{
public string RootNamespace {
get {
return "";
}
}
//readonly CecilLoader loader = new CecilLoader();
public string GetTypeNameForAttribute(NRefactory.CSharp.Attribute attribute)
{
return attribute.Type.Annotations
.OfType<Mono.Cecil.MemberReference>()
.First()
.FullName;
}
public IType ResolveType(NRefactory.VB.Ast.AstType type, NRefactory.VB.Ast.TypeDeclaration entity = null)
{
/*
var annotation = type.Annotation<TypeReference>();
if (annotation == null )
return null;
IEntity current = null;
if (entity != null) {
var typeInfo = entity.Annotation<TypeReference>();
current = loader.ReadTypeReference(typeInfo).Resolve(context).GetDefinition();
}
return loader.ReadTypeReference(annotation, entity: current).Resolve(context);*/
return SpecialType.UnknownType;
}
public TypeKind GetTypeKindForAstType(NRefactory.CSharp.AstType type)
{
var annotation = type.Annotation<TypeReference>();
if (annotation == null)
return TypeKind.Unknown;
var definition = annotation.ResolveOrThrow();
if (definition.IsClass)
return TypeKind.Class;
if (definition.IsInterface)
return TypeKind.Interface;
if (definition.IsEnum)
return TypeKind.Enum;
if (definition.IsFunctionPointer)
return TypeKind.Delegate;
if (definition.IsValueType)
return TypeKind.Struct;
return TypeKind.Unknown;
}
public TypeCode ResolveExpression(NRefactory.CSharp.Expression expression)
{
var annotation = expression.Annotations.OfType<TypeInformation>().FirstOrDefault();
if (annotation == null || annotation.InferredType == null)
return TypeCode.Object;
var definition = annotation.InferredType.Resolve();
if (definition == null)
return TypeCode.Object;
switch (definition.FullName) {
case "System.String":
return TypeCode.String;
default:
break;
}
return TypeCode.Object;
}
public bool? IsReferenceType(NRefactory.CSharp.Expression expression)
{
if (expression is NRefactory.CSharp.NullReferenceExpression)
return true;
var annotation = expression.Annotations.OfType<TypeInformation>().FirstOrDefault();
if (annotation == null || annotation.InferredType == null)
return null;
var definition = annotation.InferredType.Resolve();
if (definition == null)
return null;
return !definition.IsValueType;
}
public IEnumerable<NRefactory.VB.Ast.InterfaceMemberSpecifier> CreateMemberSpecifiersForInterfaces(IEnumerable<NRefactory.VB.Ast.AstType> interfaces)
{
foreach (var type in interfaces) {
var def = type.Annotation<TypeReference>().Resolve();
if (def == null) continue;
foreach (var method in def.Methods.Where(m => !m.Name.StartsWith("get_", StringComparison.Ordinal) && !m.Name.StartsWith("set_", StringComparison.Ordinal))) {
yield return new NRefactory.VB.Ast.InterfaceMemberSpecifier((NRefactory.VB.Ast.AstType)type.Clone(), method.Name);
}
foreach (var property in def.Properties) {
yield return new NRefactory.VB.Ast.InterfaceMemberSpecifier((NRefactory.VB.Ast.AstType)type.Clone(), property.Name);
}
}
}
public bool HasEvent(NRefactory.VB.Ast.Expression expression)
{
return expression.Annotation<EventDefinition>() != null;
}
public bool IsMethodGroup(NRefactory.CSharp.Expression expression)
{
var methodInfo = expression.Annotation<MethodReference>()?.Resolve();
if (methodInfo != null) {
return !methodInfo.IsGetter && !methodInfo.IsSetter && !methodInfo.IsAddOn && !methodInfo.IsRemoveOn;
}
return false;
}
public NRefactory.CSharp.ParameterDeclaration[] GetParametersForProperty(NRefactory.CSharp.PropertyDeclaration property)
{
var propInfo = property.Annotation<PropertyReference>();
if (propInfo == null)
return new NRefactory.CSharp.ParameterDeclaration[0];
return propInfo.Parameters.Select(p => new NRefactory.CSharp.ParameterDeclaration(AstBuilder.ConvertType(p.ParameterType), p.Name, GetModifiers(p))).ToArray();
}
NRefactory.CSharp.ParameterModifier GetModifiers(ParameterDefinition p)
{
if (p.IsOut && p.IsIn)
return NRefactory.CSharp.ParameterModifier.Ref;
if (p.IsOut)
return NRefactory.CSharp.ParameterModifier.Out;
return NRefactory.CSharp.ParameterModifier.None;
}
}
}

448
ILSpy/VB/VBLanguage.cs

@ -1,448 +0,0 @@ @@ -1,448 +0,0 @@
// 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.Collections.Generic;
using System.ComponentModel.Composition;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Xml;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.Ast.Transforms;
using ICSharpCode.ILSpy.XmlDoc;
using ICSharpCode.NRefactory.VB;
using ICSharpCode.NRefactory.VB.Visitors;
using Mono.Cecil;
using CSharp = ICSharpCode.NRefactory.CSharp;
namespace ICSharpCode.ILSpy.VB
{
/// <summary>
/// Decompiler logic for VB.
/// </summary>
[Export(typeof(Language))]
public class VBLanguage : Language
{
readonly Predicate<IAstTransform> transformAbortCondition = null;
bool showAllMembers = false;
public VBLanguage()
{
}
public override string Name {
get { return "VB"; }
}
public override string FileExtension {
get { return ".vb"; }
}
public override string ProjectFileExtension {
get { return ".vbproj"; }
}
public override void WriteCommentLine(ITextOutput output, string comment)
{
output.WriteLine("' " + comment);
}
public override void DecompileAssembly(LoadedAssembly assembly, ITextOutput output, DecompilationOptions options)
{
if (options.FullDecompilation && options.SaveAsProjectDirectory != null) {
HashSet<string> directories = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
var files = WriteCodeFilesInProject(assembly.ModuleDefinition, options, directories).ToList();
files.AddRange(WriteResourceFilesInProject(assembly, options, directories));
WriteProjectFile(new TextOutputWriter(output), files, assembly.ModuleDefinition);
} else {
base.DecompileAssembly(assembly, output, options);
output.WriteLine();
ModuleDefinition mainModule = assembly.ModuleDefinition;
if (mainModule.Types.Count > 0) {
output.Write("' Global type: ");
output.WriteReference(mainModule.Types[0].FullName, mainModule.Types[0]);
output.WriteLine();
}
if (mainModule.EntryPoint != null) {
output.Write("' Entry point: ");
output.WriteReference(mainModule.EntryPoint.DeclaringType.FullName + "." + mainModule.EntryPoint.Name, mainModule.EntryPoint);
output.WriteLine();
}
WriteCommentLine(output, "Architecture: " + CSharpLanguage.GetPlatformDisplayName(mainModule));
if ((mainModule.Attributes & ModuleAttributes.ILOnly) == 0) {
WriteCommentLine(output, "This assembly contains unmanaged code.");
}
switch (mainModule.Runtime) {
case TargetRuntime.Net_1_0:
WriteCommentLine(output, "Runtime: .NET 1.0");
break;
case TargetRuntime.Net_1_1:
WriteCommentLine(output, "Runtime: .NET 1.1");
break;
case TargetRuntime.Net_2_0:
WriteCommentLine(output, "Runtime: .NET 2.0");
break;
case TargetRuntime.Net_4_0:
WriteCommentLine(output, "Runtime: .NET 4.0");
break;
}
output.WriteLine();
// don't automatically load additional assemblies when an assembly node is selected in the tree view
using (options.FullDecompilation ? null : LoadedAssembly.DisableAssemblyLoad()) {
AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: assembly.ModuleDefinition);
codeDomBuilder.AddAssembly(assembly.ModuleDefinition, onlyAssemblyLevel: !options.FullDecompilation);
RunTransformsAndGenerateCode(codeDomBuilder, output, options, assembly.ModuleDefinition);
}
}
}
static readonly string[] projectImports = new[] {
"System.Diagnostics",
"Microsoft.VisualBasic",
"System",
"System.Collections",
"System.Collections.Generic"
};
#region WriteProjectFile
void WriteProjectFile(TextWriter writer, IEnumerable<Tuple<string, string>> files, ModuleDefinition module)
{
const string ns = "http://schemas.microsoft.com/developer/msbuild/2003";
string platformName = CSharpLanguage.GetPlatformName(module);
Guid guid = App.CommandLineArguments.FixedGuid ?? Guid.NewGuid();
using (XmlTextWriter w = new XmlTextWriter(writer)) {
w.Formatting = Formatting.Indented;
w.WriteStartDocument();
w.WriteStartElement("Project", ns);
w.WriteAttributeString("ToolsVersion", "4.0");
w.WriteAttributeString("DefaultTargets", "Build");
w.WriteStartElement("PropertyGroup");
w.WriteElementString("ProjectGuid", guid.ToString("B").ToUpperInvariant());
w.WriteStartElement("Configuration");
w.WriteAttributeString("Condition", " '$(Configuration)' == '' ");
w.WriteValue("Debug");
w.WriteEndElement(); // </Configuration>
w.WriteStartElement("Platform");
w.WriteAttributeString("Condition", " '$(Platform)' == '' ");
w.WriteValue(platformName);
w.WriteEndElement(); // </Platform>
switch (module.Kind) {
case ModuleKind.Windows:
w.WriteElementString("OutputType", "WinExe");
break;
case ModuleKind.Console:
w.WriteElementString("OutputType", "Exe");
break;
default:
w.WriteElementString("OutputType", "Library");
break;
}
w.WriteElementString("AssemblyName", module.Assembly.Name.Name);
bool useTargetFrameworkAttribute = false;
var targetFrameworkAttribute = module.Assembly.CustomAttributes.FirstOrDefault(a => a.AttributeType.FullName == "System.Runtime.Versioning.TargetFrameworkAttribute");
if (targetFrameworkAttribute != null && targetFrameworkAttribute.ConstructorArguments.Any()) {
string frameworkName = (string)targetFrameworkAttribute.ConstructorArguments[0].Value;
string[] frameworkParts = frameworkName.Split(',');
string frameworkVersion = frameworkParts.FirstOrDefault(a => a.StartsWith("Version="));
if (frameworkVersion != null) {
w.WriteElementString("TargetFrameworkVersion", frameworkVersion.Substring("Version=".Length));
useTargetFrameworkAttribute = true;
}
string frameworkProfile = frameworkParts.FirstOrDefault(a => a.StartsWith("Profile="));
if (frameworkProfile != null)
w.WriteElementString("TargetFrameworkProfile", frameworkProfile.Substring("Profile=".Length));
}
if (!useTargetFrameworkAttribute) {
switch (module.Runtime) {
case TargetRuntime.Net_1_0:
w.WriteElementString("TargetFrameworkVersion", "v1.0");
break;
case TargetRuntime.Net_1_1:
w.WriteElementString("TargetFrameworkVersion", "v1.1");
break;
case TargetRuntime.Net_2_0:
w.WriteElementString("TargetFrameworkVersion", "v2.0");
// TODO: Detect when .NET 3.0/3.5 is required
break;
default:
w.WriteElementString("TargetFrameworkVersion", "v4.0");
break;
}
}
w.WriteElementString("WarningLevel", "4");
w.WriteEndElement(); // </PropertyGroup>
w.WriteStartElement("PropertyGroup"); // platform-specific
w.WriteAttributeString("Condition", " '$(Platform)' == '" + platformName + "' ");
w.WriteElementString("PlatformTarget", platformName);
w.WriteEndElement(); // </PropertyGroup> (platform-specific)
w.WriteStartElement("PropertyGroup"); // Debug
w.WriteAttributeString("Condition", " '$(Configuration)' == 'Debug' ");
w.WriteElementString("OutputPath", "bin\\Debug\\");
w.WriteElementString("DebugSymbols", "true");
w.WriteElementString("DebugType", "full");
w.WriteElementString("Optimize", "false");
w.WriteEndElement(); // </PropertyGroup> (Debug)
w.WriteStartElement("PropertyGroup"); // Release
w.WriteAttributeString("Condition", " '$(Configuration)' == 'Release' ");
w.WriteElementString("OutputPath", "bin\\Release\\");
w.WriteElementString("DebugSymbols", "true");
w.WriteElementString("DebugType", "pdbonly");
w.WriteElementString("Optimize", "true");
w.WriteEndElement(); // </PropertyGroup> (Release)
w.WriteStartElement("ItemGroup"); // References
foreach (AssemblyNameReference r in module.AssemblyReferences) {
if (r.Name != "mscorlib") {
w.WriteStartElement("Reference");
w.WriteAttributeString("Include", r.Name);
w.WriteEndElement();
}
}
w.WriteEndElement(); // </ItemGroup> (References)
foreach (IGrouping<string, string> gr in (from f in files group f.Item2 by f.Item1 into g orderby g.Key select g)) {
w.WriteStartElement("ItemGroup");
foreach (string file in gr.OrderBy(f => f, StringComparer.OrdinalIgnoreCase)) {
w.WriteStartElement(gr.Key);
w.WriteAttributeString("Include", file);
w.WriteEndElement();
}
w.WriteEndElement();
}
w.WriteStartElement("ItemGroup"); // Imports
foreach (var import in projectImports.OrderBy(x => x)) {
w.WriteStartElement("Import");
w.WriteAttributeString("Include", import);
w.WriteEndElement();
}
w.WriteEndElement(); // </ItemGroup> (Imports)
w.WriteStartElement("Import");
w.WriteAttributeString("Project", "$(MSBuildToolsPath)\\Microsoft.VisualBasic.targets");
w.WriteEndElement();
w.WriteEndDocument();
}
}
#endregion
#region WriteCodeFilesInProject
bool IncludeTypeWhenDecompilingProject(TypeDefinition type, DecompilationOptions options)
{
if (type.Name == "<Module>" || AstBuilder.MemberIsHidden(type, options.DecompilerSettings))
return false;
if (type.Namespace == "XamlGeneratedNamespace" && type.Name == "GeneratedInternalTypeHelper")
return false;
return true;
}
IEnumerable<Tuple<string, string>> WriteAssemblyInfo(ModuleDefinition module, DecompilationOptions options, HashSet<string> directories)
{
// don't automatically load additional assemblies when an assembly node is selected in the tree view
using (LoadedAssembly.DisableAssemblyLoad())
{
AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: module);
codeDomBuilder.AddAssembly(module, onlyAssemblyLevel: true);
codeDomBuilder.RunTransformations(transformAbortCondition);
string prop = "Properties";
if (directories.Add("Properties"))
Directory.CreateDirectory(Path.Combine(options.SaveAsProjectDirectory, prop));
string assemblyInfo = Path.Combine(prop, "AssemblyInfo" + this.FileExtension);
using (StreamWriter w = new StreamWriter(Path.Combine(options.SaveAsProjectDirectory, assemblyInfo)))
codeDomBuilder.GenerateCode(new PlainTextOutput(w));
return new Tuple<string, string>[] { Tuple.Create("Compile", assemblyInfo) };
}
}
IEnumerable<Tuple<string, string>> WriteCodeFilesInProject(ModuleDefinition module, DecompilationOptions options, HashSet<string> directories)
{
var files = module.Types.Where(t => IncludeTypeWhenDecompilingProject(t, options)).GroupBy(
delegate(TypeDefinition type) {
string file = TextView.DecompilerTextView.CleanUpName(type.Name) + this.FileExtension;
if (string.IsNullOrEmpty(type.Namespace)) {
return file;
} else {
string dir = TextView.DecompilerTextView.CleanUpName(type.Namespace);
if (directories.Add(dir))
Directory.CreateDirectory(Path.Combine(options.SaveAsProjectDirectory, dir));
return Path.Combine(dir, file);
}
}, StringComparer.OrdinalIgnoreCase).ToList();
AstMethodBodyBuilder.ClearUnhandledOpcodes();
Parallel.ForEach(
files,
new ParallelOptions { MaxDegreeOfParallelism = Environment.ProcessorCount },
delegate(IGrouping<string, TypeDefinition> file) {
using (StreamWriter w = new StreamWriter(Path.Combine(options.SaveAsProjectDirectory, file.Key))) {
AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: module);
foreach (TypeDefinition type in file) {
codeDomBuilder.AddType(type);
}
RunTransformsAndGenerateCode(codeDomBuilder, new PlainTextOutput(w), options, module);
}
});
AstMethodBodyBuilder.PrintNumberOfUnhandledOpcodes();
return files.Select(f => Tuple.Create("Compile", f.Key)).Concat(WriteAssemblyInfo(module, options, directories));
}
#endregion
public override void DecompileMethod(MethodDefinition method, ITextOutput output, DecompilationOptions options)
{
WriteCommentLine(output, TypeToString(method.DeclaringType, includeNamespace: true));
AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: method.DeclaringType, isSingleMember: true);
codeDomBuilder.AddMethod(method);
RunTransformsAndGenerateCode(codeDomBuilder, output, options, method.Module);
}
public override void DecompileProperty(PropertyDefinition property, ITextOutput output, DecompilationOptions options)
{
WriteCommentLine(output, TypeToString(property.DeclaringType, includeNamespace: true));
AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: property.DeclaringType, isSingleMember: true);
codeDomBuilder.AddProperty(property);
RunTransformsAndGenerateCode(codeDomBuilder, output, options, property.Module);
}
public override void DecompileField(FieldDefinition field, ITextOutput output, DecompilationOptions options)
{
WriteCommentLine(output, TypeToString(field.DeclaringType, includeNamespace: true));
AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: field.DeclaringType, isSingleMember: true);
codeDomBuilder.AddField(field);
RunTransformsAndGenerateCode(codeDomBuilder, output, options, field.Module);
}
public override void DecompileEvent(EventDefinition ev, ITextOutput output, DecompilationOptions options)
{
WriteCommentLine(output, TypeToString(ev.DeclaringType, includeNamespace: true));
AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: ev.DeclaringType, isSingleMember: true);
codeDomBuilder.AddEvent(ev);
RunTransformsAndGenerateCode(codeDomBuilder, output, options, ev.Module);
}
public override void DecompileType(TypeDefinition type, ITextOutput output, DecompilationOptions options)
{
AstBuilder codeDomBuilder = CreateAstBuilder(options, currentModule: type.Module);
codeDomBuilder.AddType(type);
RunTransformsAndGenerateCode(codeDomBuilder, output, options, type.Module);
}
public override bool ShowMember(MemberReference member)
{
return showAllMembers || !AstBuilder.MemberIsHidden(member, new DecompilationOptions().DecompilerSettings);
}
void RunTransformsAndGenerateCode(AstBuilder astBuilder, ITextOutput output, DecompilationOptions options, ModuleDefinition module)
{
astBuilder.RunTransformations(transformAbortCondition);
if (options.DecompilerSettings.ShowXmlDocumentation) {
try {
AddXmlDocTransform.Run(astBuilder.SyntaxTree);
} catch (XmlException ex) {
string[] msg = (" Exception while reading XmlDoc: " + ex.ToString()).Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
var insertionPoint = astBuilder.SyntaxTree.FirstChild;
for (int i = 0; i < msg.Length; i++)
astBuilder.SyntaxTree.InsertChildBefore(insertionPoint, new CSharp.Comment(msg[i], CSharp.CommentType.Documentation), CSharp.Roles.Comment);
}
}
var csharpUnit = astBuilder.SyntaxTree;
csharpUnit.AcceptVisitor(new NRefactory.CSharp.InsertParenthesesVisitor() { InsertParenthesesForReadability = true });
var unit = csharpUnit.AcceptVisitor(new CSharpToVBConverterVisitor(new ILSpyEnvironmentProvider()), null);
var outputFormatter = new VBTextOutputFormatter(output);
var formattingPolicy = new VBFormattingOptions();
unit.AcceptVisitor(new OutputVisitor(outputFormatter, formattingPolicy), null);
}
AstBuilder CreateAstBuilder(DecompilationOptions options, ModuleDefinition currentModule = null, TypeDefinition currentType = null, bool isSingleMember = false)
{
if (currentModule == null)
currentModule = currentType.Module;
DecompilerSettings settings = options.DecompilerSettings;
settings = settings.Clone();
if (isSingleMember)
settings.UsingDeclarations = false;
settings.IntroduceIncrementAndDecrement = false;
settings.MakeAssignmentExpressions = false;
settings.QueryExpressions = false;
settings.AlwaysGenerateExceptionVariableForCatchBlocks = true;
return new AstBuilder(
new DecompilerContext(currentModule) {
CancellationToken = options.CancellationToken,
CurrentType = currentType,
Settings = settings
});
}
public override string FormatMethodName(MethodDefinition method)
{
if (method == null)
throw new ArgumentNullException("method");
return (method.IsConstructor) ? method.DeclaringType.Name : method.Name;
}
public override string FormatTypeName(TypeDefinition type)
{
if (type == null)
throw new ArgumentNullException("type");
return TypeToString(ConvertTypeOptions.DoNotUsePrimitiveTypeNames | ConvertTypeOptions.IncludeTypeParameterDefinitions, type);
}
public override string TypeToString(TypeReference type, bool includeNamespace, ICustomAttributeProvider typeAttributes = null)
{
ConvertTypeOptions options = ConvertTypeOptions.IncludeTypeParameterDefinitions;
if (includeNamespace)
options |= ConvertTypeOptions.IncludeNamespace;
return TypeToString(options, type, typeAttributes);
}
string TypeToString(ConvertTypeOptions options, TypeReference type, ICustomAttributeProvider typeAttributes = null)
{
var envProvider = new ILSpyEnvironmentProvider();
var converter = new CSharpToVBConverterVisitor(envProvider);
var astType = AstBuilder.ConvertType(type, typeAttributes, options);
StringWriter w = new StringWriter();
if (type.IsByReference) {
w.Write("ByRef ");
if (astType is NRefactory.CSharp.ComposedType && ((NRefactory.CSharp.ComposedType)astType).PointerRank > 0)
((NRefactory.CSharp.ComposedType)astType).PointerRank--;
}
var vbAstType = astType.AcceptVisitor(converter, null);
vbAstType.AcceptVisitor(new OutputVisitor(w, new VBFormattingOptions()), null);
return w.ToString();
}
}
}

254
ILSpy/VB/VBTextOutputFormatter.cs

@ -1,254 +0,0 @@ @@ -1,254 +0,0 @@
// 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.Collections.Generic;
using ICSharpCode.Decompiler;
using ICSharpCode.Decompiler.ILAst;
using ICSharpCode.NRefactory.VB;
using ICSharpCode.NRefactory.VB.Ast;
using Mono.Cecil;
namespace ICSharpCode.ILSpy.VB
{
/// <summary>
/// Description of VBTextOutputFormatter.
/// </summary>
public class VBTextOutputFormatter : IOutputFormatter
{
readonly ITextOutput output;
readonly Stack<AstNode> nodeStack = new Stack<AstNode>();
bool firstImport, lastImport;
public VBTextOutputFormatter(ITextOutput output)
{
if (output == null)
throw new ArgumentNullException("output");
this.output = output;
}
public void StartNode(AstNode node)
{
// var ranges = node.Annotation<List<ILRange>>();
// if (ranges != null && ranges.Count > 0)
// {
// // find the ancestor that has method mapping as annotation
// if (node.Ancestors != null && node.Ancestors.Count() > 0)
// {
// var n = node.Ancestors.FirstOrDefault(a => a.Annotation<MemberMapping>() != null);
// if (n != null) {
// MemberMapping mapping = n.Annotation<MemberMapping>();
//
// // add all ranges
// foreach (var range in ranges) {
// mapping.MemberCodeMappings.Add(new SourceCodeMapping {
// ILInstructionOffset = range,
// SourceCodeLine = output.CurrentLine,
// MemberMapping = mapping
// });
// }
// }
// }
// }
if (nodeStack.Count == 0) {
if (node is ImportsStatement) {
firstImport = !(node.PrevSibling is ImportsStatement);
lastImport = !(node.NextSibling is ImportsStatement);
} else {
firstImport = false;
lastImport = false;
}
}
nodeStack.Push(node);
}
public void EndNode(AstNode node)
{
if (nodeStack.Pop() != node)
throw new InvalidOperationException();
}
public void WriteIdentifier(string identifier)
{
var definition = GetCurrentDefinition();
if (definition != null) {
output.WriteDefinition(identifier, definition);
return;
}
object memberRef = GetCurrentMemberReference();
if (memberRef != null) {
output.WriteReference(identifier, memberRef);
return;
}
definition = GetCurrentLocalDefinition();
if (definition != null) {
output.WriteDefinition(identifier, definition);
return;
}
memberRef = GetCurrentLocalReference();
if (memberRef != null) {
output.WriteReference(identifier, memberRef, true);
return;
}
if (firstImport) {
output.MarkFoldStart(defaultCollapsed: true);
firstImport = false;
}
output.Write(identifier);
}
MemberReference GetCurrentMemberReference()
{
AstNode node = nodeStack.Peek();
MemberReference memberRef = node.Annotation<MemberReference>();
if (memberRef == null && node.Role == AstNode.Roles.TargetExpression && (node.Parent is InvocationExpression || node.Parent is ObjectCreationExpression)) {
memberRef = node.Parent.Annotation<MemberReference>();
}
return memberRef;
}
object GetCurrentLocalReference()
{
AstNode node = nodeStack.Peek();
ILVariable variable = node.Annotation<ILVariable>();
if (variable != null) {
if (variable.OriginalParameter != null)
return variable.OriginalParameter;
//if (variable.OriginalVariable != null)
// return variable.OriginalVariable;
return variable;
}
return null;
}
object GetCurrentLocalDefinition()
{
AstNode node = nodeStack.Peek();
var parameterDef = node.Annotation<ParameterDefinition>();
if (parameterDef != null)
return parameterDef;
if (node is VariableInitializer || node is CatchBlock || node is ForEachStatement) {
var variable = node.Annotation<ILVariable>();
if (variable != null) {
if (variable.OriginalParameter != null)
return variable.OriginalParameter;
//if (variable.OriginalVariable != null)
// return variable.OriginalVariable;
return variable;
} else {
}
}
return null;
}
object GetCurrentDefinition()
{
if (nodeStack == null || nodeStack.Count == 0)
return null;
var node = nodeStack.Peek();
if (IsDefinition(node))
return node.Annotation<MemberReference>();
node = node.Parent;
if (IsDefinition(node))
return node.Annotation<MemberReference>();
return null;
}
public void WriteKeyword(string keyword)
{
output.Write(keyword);
}
public void WriteToken(string token)
{
// Attach member reference to token only if there's no identifier in the current node.
MemberReference memberRef = GetCurrentMemberReference();
if (memberRef != null && nodeStack.Peek().GetChildByRole(AstNode.Roles.Identifier).IsNull)
output.WriteReference(token, memberRef);
else
output.Write(token);
}
public void Space()
{
output.Write(' ');
}
public void Indent()
{
output.Indent();
}
public void Unindent()
{
output.Unindent();
}
public void NewLine()
{
if (lastImport) {
output.MarkFoldEnd();
lastImport = false;
}
output.WriteLine();
}
public void WriteComment(bool isDocumentation, string content)
{
if (isDocumentation)
output.Write("'''");
else
output.Write("'");
output.WriteLine(content);
}
public void MarkFoldStart()
{
output.MarkFoldStart();
}
public void MarkFoldEnd()
{
output.MarkFoldEnd();
}
private static bool IsDefinition(AstNode node)
{
return
node is FieldDeclaration ||
node is ConstructorDeclaration ||
node is EventDeclaration ||
node is DelegateDeclaration ||
node is OperatorDeclaration||
node is MemberDeclaration ||
node is TypeDeclaration;
}
}
}
Loading…
Cancel
Save