Browse Source

TypeSystemConvertVisitor: added support for fields and methods

newNRvisualizers
Daniel Grunwald 15 years ago
parent
commit
c0b28c03e3
  1. 10
      ICSharpCode.NRefactory/CSharp/Dom/TypeMembers/ConstructorDeclaration.cs
  2. 8
      ICSharpCode.NRefactory/CSharp/Dom/TypeMembers/ParameterDeclaration.cs
  3. 206
      ICSharpCode.NRefactory/CSharp/Parser/TypeSystemConvertVisitor.cs
  4. 11
      ICSharpCode.NRefactory/CSharp/Resolver/CSharpResolver.cs
  5. 98
      ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs
  6. 37
      ICSharpCode.NRefactory/CSharp/Resolver/VariableResolveResult.cs
  7. 3
      ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj
  8. 6
      ICSharpCode.NRefactory/TypeSystem/DomRegion.cs

10
ICSharpCode.NRefactory/CSharp/Dom/TypeMembers/ConstructorDeclaration.cs

@ -49,6 +49,12 @@ namespace ICSharpCode.NRefactory.CSharp @@ -49,6 +49,12 @@ namespace ICSharpCode.NRefactory.CSharp
{
return visitor.VisitConstructorDeclaration (this, data);
}
public IEnumerable<ParameterDeclaration> Parameters {
get {
return GetChildrenByRole (Roles.Argument).Cast<ParameterDeclaration>();
}
}
}
public enum ConstructorInitializerType {
@ -63,9 +69,9 @@ namespace ICSharpCode.NRefactory.CSharp @@ -63,9 +69,9 @@ namespace ICSharpCode.NRefactory.CSharp
set;
}
public IEnumerable<ParameterDeclaration> Arguments {
public IEnumerable<INode> Arguments {
get {
return base.GetChildrenByRole (Roles.Argument).Cast <ParameterDeclaration>();
return base.GetChildrenByRole (Roles.Argument);
}
}

8
ICSharpCode.NRefactory/CSharp/Dom/TypeMembers/ParameterDeclarationExpression.cs → ICSharpCode.NRefactory/CSharp/Dom/TypeMembers/ParameterDeclaration.cs

@ -24,6 +24,8 @@ @@ -24,6 +24,8 @@
// 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;
namespace ICSharpCode.NRefactory.CSharp
{
@ -66,6 +68,12 @@ namespace ICSharpCode.NRefactory.CSharp @@ -66,6 +68,12 @@ namespace ICSharpCode.NRefactory.CSharp
get { return GetChildByRole (Roles.ReturnType); }
}
public IEnumerable<AttributeSection> Attributes {
get {
return base.GetChildrenByRole (Roles.Attribute).Cast <AttributeSection>();
}
}
public override S AcceptVisitor<T, S> (IDomVisitor<T, S> visitor, T data)
{
return visitor.VisitParameterDeclaration (this, data);

206
ICSharpCode.NRefactory/CSharp/Parser/TypeSystemConvertVisitor.cs

@ -3,6 +3,8 @@ @@ -3,6 +3,8 @@
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using ICSharpCode.NRefactory.CSharp.Resolver;
using ICSharpCode.NRefactory.TypeSystem;
using ICSharpCode.NRefactory.TypeSystem.Implementation;
@ -18,6 +20,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -18,6 +20,7 @@ namespace ICSharpCode.NRefactory.CSharp
readonly ParsedFile parsedFile;
UsingScope usingScope;
DefaultTypeDefinition currentTypeDefinition;
DefaultMethod currentMethod;
public TypeSystemConvertVisitor(IProjectContent pc, string fileName)
{
@ -34,6 +37,14 @@ namespace ICSharpCode.NRefactory.CSharp @@ -34,6 +37,14 @@ namespace ICSharpCode.NRefactory.CSharp
return new DomRegion(parsedFile.FileName, start.Line, start.Column, end.Line, end.Column);
}
DomRegion MakeRegion(INode node)
{
if (node == null)
return DomRegion.Empty;
else
return MakeRegion(node.StartLocation, node.EndLocation);
}
#region Using Declarations
// TODO: extern aliases
@ -62,7 +73,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -62,7 +73,7 @@ namespace ICSharpCode.NRefactory.CSharp
#region Namespace Declaration
public override IEntity VisitNamespaceDeclaration(NamespaceDeclaration namespaceDeclaration, object data)
{
DomRegion region = MakeRegion(namespaceDeclaration.StartLocation, namespaceDeclaration.EndLocation);
DomRegion region = MakeRegion(namespaceDeclaration);
UsingScope previousUsingScope = usingScope;
foreach (Identifier ident in namespaceDeclaration.NameIdentifier.NameParts) {
usingScope = new UsingScope(usingScope, NamespaceDeclaration.BuildQualifiedName(usingScope.NamespaceName, ident.Name));
@ -95,7 +106,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -95,7 +106,7 @@ namespace ICSharpCode.NRefactory.CSharp
{
var td = currentTypeDefinition = CreateTypeDefinition(typeDeclaration.Name);
td.ClassType = typeDeclaration.ClassType;
td.Region = MakeRegion(typeDeclaration.StartLocation, typeDeclaration.EndLocation);
td.Region = MakeRegion(typeDeclaration);
td.BodyRegion = MakeRegion(typeDeclaration.LBrace.StartLocation, typeDeclaration.RBrace.EndLocation);
td.AddDefaultConstructorIfRequired = true;
@ -106,7 +117,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -106,7 +117,7 @@ namespace ICSharpCode.NRefactory.CSharp
else if (td.ClassType == ClassType.Enum || td.ClassType == ClassType.Struct)
td.IsSealed = true; // enums/structs are implicitly sealed
//TODO ConvertTypeParameters(td.TypeParameters, typeDeclaration.TypeArguments, typeDeclaration.Constraints, td);
//TODO ConvertTypeParameters(td.TypeParameters, typeDeclaration.TypeParameters, typeDeclaration.Constraints);
// TODO: base type references?
@ -122,7 +133,7 @@ namespace ICSharpCode.NRefactory.CSharp @@ -122,7 +133,7 @@ namespace ICSharpCode.NRefactory.CSharp
{
var td = CreateTypeDefinition(delegateDeclaration.Name);
td.ClassType = ClassType.Delegate;
td.Region = MakeRegion(delegateDeclaration.StartLocation, delegateDeclaration.EndLocation);
td.Region = MakeRegion(delegateDeclaration);
td.BaseTypes.Add(multicastDelegateReference);
ConvertAttributes(td.Attributes, delegateDeclaration.Attributes);
@ -200,6 +211,141 @@ namespace ICSharpCode.NRefactory.CSharp @@ -200,6 +211,141 @@ namespace ICSharpCode.NRefactory.CSharp
}
#endregion
#region Fields
public override IEntity VisitFieldDeclaration(FieldDeclaration fieldDeclaration, object data)
{
bool isSingleField = fieldDeclaration.Variables.Count() == 1;
Modifiers modifiers = fieldDeclaration.Modifiers;
DefaultField field = null;
foreach (VariableInitializer vi in fieldDeclaration.Variables) {
field = new DefaultField(currentTypeDefinition, vi.Name);
field.Region = isSingleField ? MakeRegion(fieldDeclaration) : MakeRegion(vi);
field.BodyRegion = MakeRegion(vi);
ConvertAttributes(field.Attributes, fieldDeclaration.Attributes);
ApplyModifiers(field, modifiers);
field.IsVolatile = (modifiers & Modifiers.Volatile) != 0;
field.IsReadOnly = (modifiers & Modifiers.Readonly) != 0;
field.ReturnType = ConvertType(fieldDeclaration.ReturnType);
if ((modifiers & Modifiers.Fixed) != 0) {
field.ReturnType = PointerTypeReference.Create(field.ReturnType);
}
if ((modifiers & Modifiers.Const) != 0) {
field.ConstantValue = ConvertConstantValue(field.ReturnType, vi.Initializer);
}
currentTypeDefinition.Fields.Add(field);
}
return isSingleField ? field : null;
}
#endregion
#region Methods
public override IEntity VisitMethodDeclaration(MethodDeclaration methodDeclaration, object data)
{
DefaultMethod m = new DefaultMethod(currentTypeDefinition, methodDeclaration.Name);
currentMethod = m; // required for resolving type parameters
m.Region = MakeRegion(methodDeclaration);
m.BodyRegion = MakeRegion(methodDeclaration.Body);
//TODO ConvertTypeParameters(m.TypeParameters, methodDeclaration.TypeParameters, methodDeclaration.Constraints);
m.ReturnType = ConvertType(methodDeclaration.ReturnType);
ConvertAttributes(m.Attributes, methodDeclaration.Attributes.Where(s => s.AttributeTarget != AttributeTarget.Return));
ConvertAttributes(m.ReturnTypeAttributes, methodDeclaration.Attributes.Where(s => s.AttributeTarget == AttributeTarget.Return));
ApplyModifiers(m, methodDeclaration.Modifiers);
m.IsExtensionMethod = methodDeclaration.IsExtensionMethod;
ConvertParameters(m.Parameters, methodDeclaration.Parameters);
if (methodDeclaration.PrivateImplementationType != null) {
m.Accessibility = Accessibility.None;
m.InterfaceImplementations.Add(ConvertInterfaceImplementation(methodDeclaration.PrivateImplementationType, m.Name));
}
currentTypeDefinition.Methods.Add(m);
currentMethod = null;
return m;
}
DefaultExplicitInterfaceImplementation ConvertInterfaceImplementation(INode interfaceType, string memberName)
{
return new DefaultExplicitInterfaceImplementation(ConvertType(interfaceType), memberName);
}
#endregion
#region Operators
public override IEntity VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration, object data)
{
DefaultMethod m = new DefaultMethod(currentTypeDefinition, operatorDeclaration.Name);
m.EntityType = EntityType.Operator;
m.Region = MakeRegion(operatorDeclaration);
m.BodyRegion = MakeRegion(operatorDeclaration.Body);
m.ReturnType = ConvertType(operatorDeclaration.ReturnType);
ConvertAttributes(m.Attributes, operatorDeclaration.Attributes.Where(s => s.AttributeTarget != AttributeTarget.Return));
ConvertAttributes(m.ReturnTypeAttributes, operatorDeclaration.Attributes.Where(s => s.AttributeTarget == AttributeTarget.Return));
ApplyModifiers(m, operatorDeclaration.Modifiers);
ConvertParameters(m.Parameters, operatorDeclaration.Parameters);
currentTypeDefinition.Methods.Add(m);
return m;
}
#endregion
#region Constructors
public override IEntity VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration, object data)
{
Modifiers modifiers = constructorDeclaration.Modifiers;
bool isStatic = (modifiers & Modifiers.Static) != 0;
DefaultMethod ctor = new DefaultMethod(currentTypeDefinition, isStatic ? ".cctor" : ".ctor");
ctor.EntityType = EntityType.Constructor;
ctor.Region = MakeRegion(constructorDeclaration);
if (constructorDeclaration.Initializer != null) {
ctor.BodyRegion = MakeRegion(constructorDeclaration.Initializer.StartLocation, constructorDeclaration.EndLocation);
} else {
ctor.BodyRegion = MakeRegion(constructorDeclaration.Body);
}
ctor.ReturnType = currentTypeDefinition;
ConvertAttributes(ctor.Attributes, constructorDeclaration.Attributes);
ConvertParameters(ctor.Parameters, constructorDeclaration.Parameters);
if (isStatic)
ctor.IsStatic = true;
else
ApplyModifiers(ctor, modifiers);
currentTypeDefinition.Methods.Add(ctor);
return ctor;
}
#endregion
#region Destructors
static readonly GetClassTypeReference voidReference = new GetClassTypeReference("System.Void", 0);
public override IEntity VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration, object data)
{
DefaultMethod dtor = new DefaultMethod(currentTypeDefinition, "Finalize");
dtor.EntityType = EntityType.Destructor;
dtor.Region = MakeRegion(destructorDeclaration);
dtor.BodyRegion = MakeRegion(destructorDeclaration.Body);
dtor.Accessibility = Accessibility.Protected;
dtor.IsOverride = true;
dtor.ReturnType = voidReference;
ConvertAttributes(dtor.Attributes, destructorDeclaration.Attributes);
currentTypeDefinition.Methods.Add(dtor);
return dtor;
}
#endregion
#region Modifiers
static void ApplyModifiers(DefaultTypeDefinition td, Modifiers modifiers)
{
@ -209,6 +355,17 @@ namespace ICSharpCode.NRefactory.CSharp @@ -209,6 +355,17 @@ namespace ICSharpCode.NRefactory.CSharp
td.IsShadowing = (modifiers & Modifiers.New) != 0;
}
static void ApplyModifiers(TypeSystem.Implementation.AbstractMember m, Modifiers modifiers)
{
m.Accessibility = GetAccessibility(modifiers) ?? Accessibility.Private;
m.IsAbstract = (modifiers & Modifiers.Abstract) != 0;
m.IsOverride = (modifiers & Modifiers.Override) != 0;
m.IsSealed = (modifiers & Modifiers.Sealed) != 0;
m.IsShadowing = (modifiers & Modifiers.New) != 0;
m.IsStatic = (modifiers & Modifiers.Static) != 0;
m.IsVirtual = (modifiers & Modifiers.Virtual) != 0;
}
static Accessibility? GetAccessibility(Modifiers modifiers)
{
switch (modifiers & Modifiers.VisibilityMask) {
@ -236,5 +393,46 @@ namespace ICSharpCode.NRefactory.CSharp @@ -236,5 +393,46 @@ namespace ICSharpCode.NRefactory.CSharp
}
}
#endregion
#region Types
ITypeReference ConvertType(INode node)
{
return SharedTypes.UnknownType;
}
#endregion
#region Constant Values
IConstantValue ConvertConstantValue(ITypeReference targetType, INode expression)
{
return new SimpleConstantValue(targetType, null);
}
#endregion
#region Parameters
void ConvertParameters(IList<IParameter> outputList, IEnumerable<ParameterDeclaration> parameters)
{
foreach (ParameterDeclaration pd in parameters) {
DefaultParameter p = new DefaultParameter(ConvertType(pd.Type), pd.Name);
p.Region = MakeRegion(pd);
ConvertAttributes(p.Attributes, pd.Attributes);
switch (pd.ParameterModifier) {
case ParameterModifier.Ref:
p.IsRef = true;
p.Type = ByReferenceTypeReference.Create(p.Type);
break;
case ParameterModifier.Out:
p.IsOut = true;
p.Type = ByReferenceTypeReference.Create(p.Type);
break;
case ParameterModifier.Params:
p.IsParams = true;
break;
}
if (pd.DefaultExpression != null)
p.DefaultValue = ConvertConstantValue(p.Type, pd.DefaultExpression);
outputList.Add(p);
}
}
#endregion
}
}

11
ICSharpCode.NRefactory/CSharp/Resolver/CSharpResolver.cs

@ -1383,7 +1383,16 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -1383,7 +1383,16 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
if (typeArguments == null)
throw new ArgumentNullException("typeArguments");
// TODO: lookup in local variables, in parameters, etc.
IParameterizedMember parameterizedMember = this.CurrentMember as IParameterizedMember;
if (parameterizedMember != null && typeArguments.Count == 0) {
foreach (IParameter p in parameterizedMember.Parameters) {
if (p.Name == identifier) {
return new VariableResolveResult(p, p.Type.Resolve(context));
}
}
}
// TODO: lookup in local variables, etc.
return LookupSimpleNameOrTypeName(identifier, typeArguments,
isInvocationTarget ? SimpleNameLookupMode.InvocationTarget : SimpleNameLookupMode.Expression);

98
ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs

@ -35,6 +35,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -35,6 +35,8 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
public ResolveResult Resolve(INode node)
{
if (node == null)
return errorResult;
ResolveResult result;
if (!cache.TryGetValue(node, out result)) {
result = cache[node] = node.AcceptVisitor(this, null) ?? errorResult;
@ -105,6 +107,85 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -105,6 +107,85 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
}
#endregion
#region Track CurrentMember
public override ResolveResult VisitFieldDeclaration(FieldDeclaration fieldDeclaration, object data)
{
if (FullyResolveSubExpressions) {
ResolveType(fieldDeclaration.ReturnType);
foreach (AttributeSection attr in fieldDeclaration.Attributes)
Resolve(attr);
}
if (fieldDeclaration.Variables.Count() == 1) {
return Resolve(fieldDeclaration.Variables.Single());
} else {
foreach (VariableInitializer vi in fieldDeclaration.Variables)
Resolve(vi);
return null;
}
}
public override ResolveResult VisitVariableInitializer(VariableInitializer variableInitializer, object data)
{
if (variableInitializer.Parent is FieldDeclaration) {
try {
if (resolver.CurrentTypeDefinition != null) {
resolver.CurrentMember = resolver.CurrentTypeDefinition.Fields.FirstOrDefault(f => f.Region.IsInside(variableInitializer.StartLocation));
}
if (FullyResolveSubExpressions)
Resolve(variableInitializer.Initializer);
if (resolver.CurrentMember != null)
return new MemberResolveResult(resolver.CurrentMember, resolver.CurrentMember.ReturnType.Resolve(resolver.Context));
else
return errorResult;
} finally{
resolver.CurrentMember = null;
}
} else {
return base.VisitVariableInitializer(variableInitializer, data);
}
}
ResolveResult VisitMethodMember(AbstractMemberBase member, object data)
{
try {
if (resolver.CurrentTypeDefinition != null) {
resolver.CurrentMember = resolver.CurrentTypeDefinition.Methods.FirstOrDefault(m => m.Region.IsInside(member.StartLocation));
}
VisitChildren(member, data);
if (resolver.CurrentMember != null)
return new MemberResolveResult(resolver.CurrentMember, resolver.CurrentMember.ReturnType.Resolve(resolver.Context));
else
return errorResult;
} finally {
resolver.CurrentMember = null;
}
}
public override ResolveResult VisitMethodDeclaration(MethodDeclaration methodDeclaration, object data)
{
return VisitMethodMember(methodDeclaration, data);
}
public override ResolveResult VisitOperatorDeclaration(OperatorDeclaration operatorDeclaration, object data)
{
return VisitMethodMember(operatorDeclaration, data);
}
public override ResolveResult VisitConstructorDeclaration(ConstructorDeclaration constructorDeclaration, object data)
{
return VisitMethodMember(constructorDeclaration, data);
}
public override ResolveResult VisitDestructorDeclaration(DestructorDeclaration destructorDeclaration, object data)
{
return VisitMethodMember(destructorDeclaration, data);
}
#endregion
#region Track CheckForOverflow
public override ResolveResult VisitCheckedExpression(CheckedExpression checkedExpression, object data)
{
@ -365,5 +446,22 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver @@ -365,5 +446,22 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver
return resolver.ResolveUnaryOperator(unaryOperatorExpression.UnaryOperatorType, expr);
}
#endregion
public override ResolveResult VisitParameterDeclaration(ParameterDeclaration parameterDeclaration, object data)
{
if (FullyResolveSubExpressions) {
ResolveType(parameterDeclaration.Type);
Resolve(parameterDeclaration.DefaultExpression);
}
IParameterizedMember pm = resolver.CurrentMember as IParameterizedMember;
if (pm != null) {
foreach (IParameter p in pm.Parameters) {
if (p.Name == parameterDeclaration.Name) {
return new VariableResolveResult(p, p.Type.Resolve(resolver.Context));
}
}
}
return errorResult;
}
}
}

37
ICSharpCode.NRefactory/CSharp/Resolver/VariableResolveResult.cs

@ -0,0 +1,37 @@ @@ -0,0 +1,37 @@
// 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 ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.NRefactory.CSharp.Resolver
{
/// <summary>
/// Represents a local variable.
/// </summary>
public class VariableResolveResult : ResolveResult
{
readonly IVariable variable;
public VariableResolveResult(IVariable variable, IType type)
: base(type)
{
if (variable == null)
throw new ArgumentNullException("variable");
this.variable = variable;
}
public IVariable Variable {
get { return variable; }
}
public bool IsParameter {
get { return variable is IParameter; }
}
public override string ToString()
{
return string.Format("[VariableResolveResult {0}]", variable);
}
}
}

3
ICSharpCode.NRefactory/ICSharpCode.NRefactory.csproj

@ -142,7 +142,7 @@ @@ -142,7 +142,7 @@
<Compile Include="CSharp\Dom\TypeMembers\IndexerDeclaration.cs" />
<Compile Include="CSharp\Dom\TypeMembers\MethodDeclaration.cs" />
<Compile Include="CSharp\Dom\TypeMembers\OperatorDeclaration.cs" />
<Compile Include="CSharp\Dom\TypeMembers\ParameterDeclarationExpression.cs" />
<Compile Include="CSharp\Dom\TypeMembers\ParameterDeclaration.cs" />
<Compile Include="CSharp\Dom\TypeMembers\PropertyDeclaration.cs" />
<Compile Include="CSharp\Dom\TypeMembers\VariableInitializer.cs" />
<Compile Include="CSharp\Formatter\CSharpFormattingPolicy.cs" />
@ -180,6 +180,7 @@ @@ -180,6 +180,7 @@
<Compile Include="CSharp\Resolver\TypeResolveResult.cs" />
<Compile Include="CSharp\Resolver\UnknownMemberResolveResult.cs" />
<Compile Include="CSharp\Resolver\UsingScope.cs" />
<Compile Include="CSharp\Resolver\VariableResolveResult.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TypeSystem\Accessibility.cs" />
<Compile Include="TypeSystem\ArrayType.cs" />

6
ICSharpCode.NRefactory/TypeSystem/DomRegion.cs

@ -3,6 +3,7 @@ @@ -3,6 +3,7 @@
using System;
using System.Globalization;
using ICSharpCode.NRefactory.CSharp;
namespace ICSharpCode.NRefactory.TypeSystem
{
@ -91,6 +92,11 @@ namespace ICSharpCode.NRefactory.TypeSystem @@ -91,6 +92,11 @@ namespace ICSharpCode.NRefactory.TypeSystem
(line != EndLine || column <= EndColumn);
}
public bool IsInside(DomLocation location)
{
return IsInside(location.Line, location.Column);
}
public override string ToString()
{
return string.Format(

Loading…
Cancel
Save