From 3bbc3f6b6d2e9ca343c931a8d446855e25a98268 Mon Sep 17 00:00:00 2001 From: Daniel Grunwald Date: Thu, 25 Aug 2011 18:47:05 +0200 Subject: [PATCH] Fixed NullReferenceException in MethodGroupResolveResult.ResolveInvocation(). Implemented resolving local variables that are declared as 'const'. --- .../CSharp/Parser/ParsedFile.cs | 11 +++-- .../CSharp/Parser/TypeSystemConvertVisitor.cs | 46 +++++++++++++------ .../Resolver/MethodGroupResolveResult.cs | 4 +- .../CSharp/Resolver/ResolveVisitor.cs | 5 +- .../TypeSystem/IParsedFile.cs | 4 +- 5 files changed, 46 insertions(+), 24 deletions(-) diff --git a/ICSharpCode.NRefactory/CSharp/Parser/ParsedFile.cs b/ICSharpCode.NRefactory/CSharp/Parser/ParsedFile.cs index 12902b4afa..36b9d1c305 100644 --- a/ICSharpCode.NRefactory/CSharp/Parser/ParsedFile.cs +++ b/ICSharpCode.NRefactory/CSharp/Parser/ParsedFile.cs @@ -62,10 +62,13 @@ namespace ICSharpCode.NRefactory.CSharp get { return fileName; } } - DateTime parseTime = DateTime.Now; - public DateTime ParseTime { - get { - return parseTime; + DateTime lastWriteTime = DateTime.UtcNow; + + public DateTime LastWriteTime { + get { return lastWriteTime; } + set { + CheckBeforeMutation(); + lastWriteTime = value; } } diff --git a/ICSharpCode.NRefactory/CSharp/Parser/TypeSystemConvertVisitor.cs b/ICSharpCode.NRefactory/CSharp/Parser/TypeSystemConvertVisitor.cs index 4474d8838f..00a75b0373 100644 --- a/ICSharpCode.NRefactory/CSharp/Parser/TypeSystemConvertVisitor.cs +++ b/ICSharpCode.NRefactory/CSharp/Parser/TypeSystemConvertVisitor.cs @@ -837,8 +837,13 @@ namespace ICSharpCode.NRefactory.CSharp #region Constant Values IConstantValue ConvertConstantValue(ITypeReference targetType, AstNode expression) { - ConstantValueBuilder b = new ConstantValueBuilder(); - b.convertVisitor = this; + return ConvertConstantValue(targetType, expression, currentTypeDefinition, currentMethod, usingScope); + } + + internal static IConstantValue ConvertConstantValue(ITypeReference targetType, AstNode expression, + ITypeDefinition parentTypeDefinition, IMethod parentMethodDefinition, UsingScope parentUsingScope) + { + ConstantValueBuilder b = new ConstantValueBuilder(parentTypeDefinition, parentMethodDefinition, parentUsingScope, false); ConstantExpression c = expression.AcceptVisitor(b, null); if (c == null) return null; @@ -848,14 +853,12 @@ namespace ICSharpCode.NRefactory.CSharp return new SimpleConstantValue(targetType, pc.Value); } // cast to the desired type - return new CSharpConstantValue(new ConstantCast(targetType, c), usingScope, currentTypeDefinition); + return new CSharpConstantValue(new ConstantCast(targetType, c), parentUsingScope, parentTypeDefinition); } IConstantValue ConvertAttributeArgument(Expression expression) { - ConstantValueBuilder b = new ConstantValueBuilder(); - b.convertVisitor = this; - b.isAttributeArgument = true; + ConstantValueBuilder b = new ConstantValueBuilder(currentTypeDefinition, currentMethod, usingScope, true); ConstantExpression c = expression.AcceptVisitor(b, null); if (c == null) return null; @@ -870,8 +873,23 @@ namespace ICSharpCode.NRefactory.CSharp sealed class ConstantValueBuilder : DepthFirstAstVisitor { - internal TypeSystemConvertVisitor convertVisitor; - internal bool isAttributeArgument; + readonly ITypeDefinition currentTypeDefinition; + readonly IMethod currentMethod; + readonly UsingScope usingScope; + readonly bool isAttributeArgument; + + public ConstantValueBuilder(ITypeDefinition currentTypeDefinition, IMethod currentMethod, UsingScope usingScope, bool isAttributeArgument) + { + this.currentTypeDefinition = currentTypeDefinition; + this.currentMethod = currentMethod; + this.usingScope = usingScope; + this.isAttributeArgument = isAttributeArgument; + } + + ITypeReference ConvertType(AstType type) + { + return TypeSystemConvertVisitor.ConvertType(type, currentTypeDefinition, currentMethod, usingScope, SimpleNameLookupMode.Type); + } protected override ConstantExpression VisitChildren(AstNode node, object data) { @@ -897,7 +915,7 @@ namespace ICSharpCode.NRefactory.CSharp ITypeReference[] result = new ITypeReference[count]; int pos = 0; foreach (AstType type in types) { - result[pos++] = convertVisitor.ConvertType(type); + result[pos++] = ConvertType(type); } return result; } @@ -913,7 +931,7 @@ namespace ICSharpCode.NRefactory.CSharp if (tre != null) { // handle "int.MaxValue" return new ConstantMemberReference( - convertVisitor.ConvertType(tre.Type), + ConvertType(tre.Type), memberReferenceExpression.MemberName, ConvertTypeArguments(memberReferenceExpression.TypeArguments)); } @@ -935,7 +953,7 @@ namespace ICSharpCode.NRefactory.CSharp ConstantExpression v = castExpression.Expression.AcceptVisitor(this, data); if (v == null) return null; - return new ConstantCast(convertVisitor.ConvertType(castExpression.Type), v); + return new ConstantCast(ConvertType(castExpression.Type), v); } public override ConstantExpression VisitCheckedExpression(CheckedExpression checkedExpression, object data) @@ -958,7 +976,7 @@ namespace ICSharpCode.NRefactory.CSharp public override ConstantExpression VisitDefaultValueExpression(DefaultValueExpression defaultValueExpression, object data) { - return new ConstantDefaultValue(convertVisitor.ConvertType(defaultValueExpression.Type)); + return new ConstantDefaultValue(ConvertType(defaultValueExpression.Type)); } public override ConstantExpression VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression, object data) @@ -989,7 +1007,7 @@ namespace ICSharpCode.NRefactory.CSharp public override ConstantExpression VisitTypeOfExpression(TypeOfExpression typeOfExpression, object data) { if (isAttributeArgument) { - return new PrimitiveConstantExpression(KnownTypeReference.Type, convertVisitor.ConvertType(typeOfExpression.Type)); + return new PrimitiveConstantExpression(KnownTypeReference.Type, ConvertType(typeOfExpression.Type)); } else { return null; } @@ -1004,7 +1022,7 @@ namespace ICSharpCode.NRefactory.CSharp if (arrayCreateExpression.Type.IsNull) { type = null; } else { - type = convertVisitor.ConvertType(arrayCreateExpression.Type); + type = ConvertType(arrayCreateExpression.Type); foreach (var spec in arrayCreateExpression.AdditionalArraySpecifiers.Reverse()) { type = ArrayTypeReference.Create(type, spec.Dimensions); } diff --git a/ICSharpCode.NRefactory/CSharp/Resolver/MethodGroupResolveResult.cs b/ICSharpCode.NRefactory/CSharp/Resolver/MethodGroupResolveResult.cs index 865f1858e1..a34830d91d 100644 --- a/ICSharpCode.NRefactory/CSharp/Resolver/MethodGroupResolveResult.cs +++ b/ICSharpCode.NRefactory/CSharp/Resolver/MethodGroupResolveResult.cs @@ -134,7 +134,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver /// new List { all extensions from SomeExtensions } /// } /// - public List> GetExtensionMethods() + public IList> GetExtensionMethods() { if (resolver != null) { Debug.Assert(extensionMethods == null); @@ -148,7 +148,7 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver usingScope = null; } } - return extensionMethods; + return extensionMethods ?? EmptyList>.Instance; } public override string ToString() diff --git a/ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs b/ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs index d69b6b1c28..7f7d3d58ee 100644 --- a/ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs +++ b/ICSharpCode.NRefactory/CSharp/Resolver/ResolveVisitor.cs @@ -2085,8 +2085,9 @@ namespace ICSharpCode.NRefactory.CSharp.Resolver VariableInitializer vi = (VariableInitializer)node; IConstantValue cv = null; - if (isConst) - throw new NotImplementedException(); + if (isConst) { + cv = TypeSystemConvertVisitor.ConvertConstantValue(type, vi.Initializer, resolver.CurrentTypeDefinition, resolver.CurrentMember as IMethod, resolver.UsingScope); + } resolver.AddVariable(type, MakeRegion(vi), vi.Name, cv); if (resolverEnabled && initializerCount == 1) { diff --git a/ICSharpCode.NRefactory/TypeSystem/IParsedFile.cs b/ICSharpCode.NRefactory/TypeSystem/IParsedFile.cs index 3e459257ae..86e6586e39 100644 --- a/ICSharpCode.NRefactory/TypeSystem/IParsedFile.cs +++ b/ICSharpCode.NRefactory/TypeSystem/IParsedFile.cs @@ -38,9 +38,9 @@ namespace ICSharpCode.NRefactory.TypeSystem string FileName { get; } /// - /// Gets the time of object creation. + /// Gets the time when the file was last written. /// - DateTime ParseTime { get; } + DateTime LastWriteTime { get; } /// /// Gets all top-level type definitions.