From 7ed3af27fcc2224fe7f27e5b7ad3989ade9f9606 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mike=20Kr=C3=BCger?= Date: Tue, 6 Sep 2011 16:40:39 +0200 Subject: [PATCH] Updated mcs (fixed char posititions). --- .../Parser/mcs/class.cs | 6 ++ .../Parser/mcs/cs-tokenizer.cs | 22 +++-- .../Parser/mcs/ecore.cs | 11 +++ .../Parser/mcs/expression.cs | 44 ++++++++-- .../Parser/mcs/flowanalysis.cs | 7 +- .../Parser/mcs/method.cs | 81 ++++++++++--------- .../Parser/mcs/pending.cs | 11 +-- .../Parser/mcs/property.cs | 6 +- 8 files changed, 127 insertions(+), 61 deletions(-) diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/class.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/class.cs index de0d0f5bb4..3959f351bb 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/class.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/class.cs @@ -319,6 +319,12 @@ namespace Mono.CSharp } } + public TypeSpec[] Interfaces { + get { + return iface_exprs; + } + } + #endregion public override void Accept (StructuralVisitor visitor) diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs index 7c9c599d83..db2d176c5d 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-tokenizer.cs @@ -3188,7 +3188,6 @@ namespace Mono.CSharp } // Handle double-slash comments. if (d == '/') { - Console.WriteLine (line + "/" + col); get_char (); if (doc_processing) { if (peek_char () == '/') { @@ -3432,16 +3431,20 @@ namespace Mono.CSharp int TokenizeBackslash () { +#if FULL_AST + int read_start = reader.Position; +#endif + Location start_location = Location; int c = get_char (); tokens_seen = true; if (c == '\'') { - val = new CharLiteral (context.BuiltinTypes, (char) c, Location); - Report.Error (1011, Location, "Empty character literal"); + val = new CharLiteral (context.BuiltinTypes, (char) c, start_location); + Report.Error (1011, start_location, "Empty character literal"); return Token.LITERAL; } - if (c == '\n') { - Report.Error (1010, Location, "Newline in constant"); + if (c == '\r') { + Report.Error (1010, start_location, "Newline in constant"); return Token.ERROR; } @@ -3452,11 +3455,12 @@ namespace Mono.CSharp if (d != 0) throw new NotImplementedException (); - val = new CharLiteral (context.BuiltinTypes, (char) c, Location); + ILiteralConstant res = new CharLiteral (context.BuiltinTypes, (char) c, start_location); + val = res; c = get_char (); if (c != '\'') { - Report.Error (1012, Location, "Too many characters in character literal"); + Report.Error (1012, start_location, "Too many characters in character literal"); // Try to recover, read until newline or next "'" while ((c = get_char ()) != -1) { @@ -3465,6 +3469,10 @@ namespace Mono.CSharp } } +#if FULL_AST + res.ParsedValue = reader.ReadChars (read_start - 1, reader.Position); +#endif + return Token.LITERAL; } diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/ecore.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/ecore.cs index 8ea57ed36d..d7e357c012 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/ecore.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/ecore.cs @@ -1862,6 +1862,17 @@ namespace Mono.CSharp { c = new ReducedConstantExpression (c, orig_expr); return c; } + + public override void EncodeAttributeValue (IMemberContext rc, AttributeEncoder enc, TypeSpec targetType) + { + // + // LAMESPEC: Reduced conditional expression is allowed as an attribute argument + // + if (orig_expr is Conditional) + child.EncodeAttributeValue (rc, enc, targetType); + else + base.EncodeAttributeValue (rc, enc, targetType); + } } sealed class ReducedExpressionStatement : ExpressionStatement diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/expression.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/expression.cs index bd2d50c921..f440ab7c62 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/expression.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/expression.cs @@ -4563,8 +4563,32 @@ namespace Mono.CSharp protected override Expression DoResolve (ResolveContext ec) { expr = expr.Resolve (ec); - true_expr = true_expr.Resolve (ec); - false_expr = false_expr.Resolve (ec); + + // + // Unreachable code needs different resolve path. For instance for await + // expression to not generate unreachable resumable statement + // + Constant c = expr as Constant; + if (c != null && ec.CurrentBranching != null) { + bool unreachable = ec.CurrentBranching.CurrentUsageVector.IsUnreachable; + + if (c.IsDefaultValue) { + ec.CurrentBranching.CurrentUsageVector.IsUnreachable = true; + true_expr = true_expr.Resolve (ec); + ec.CurrentBranching.CurrentUsageVector.IsUnreachable = unreachable; + + false_expr = false_expr.Resolve (ec); + } else { + true_expr = true_expr.Resolve (ec); + + ec.CurrentBranching.CurrentUsageVector.IsUnreachable = true; + false_expr = false_expr.Resolve (ec); + ec.CurrentBranching.CurrentUsageVector.IsUnreachable = unreachable; + } + } else { + true_expr = true_expr.Resolve (ec); + false_expr = false_expr.Resolve (ec); + } if (true_expr == null || false_expr == null || expr == null) return null; @@ -4604,11 +4628,17 @@ namespace Mono.CSharp } } - // Dead code optimalization - Constant c = expr as Constant; - if (c != null){ + if (c != null) { bool is_false = c.IsDefaultValue; - ec.Report.Warning (429, 4, is_false ? true_expr.Location : false_expr.Location, "Unreachable expression code detected"); + + // + // Don't issue the warning for constant expressions + // + if (!(is_false ? true_expr is Constant : false_expr is Constant)) { + ec.Report.Warning (429, 4, is_false ? true_expr.Location : false_expr.Location, + "Unreachable expression code detected"); + } + return ReducedExpression.Create ( is_false ? false_expr : true_expr, this, false_expr is Constant && true_expr is Constant).Resolve (ec); @@ -5965,7 +5995,7 @@ namespace Mono.CSharp { var current_field = rc.CurrentMemberDefinition as FieldBase; TypeExpression type; - if (current_field != null) { + if (current_field != null && rc.CurrentAnonymousMethod == null) { type = new TypeExpression (current_field.MemberType, current_field.Location); } else if (variable != null) { if (variable.TypeExpression is VarExpr) { diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/flowanalysis.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/flowanalysis.cs index 1becb532d4..f54f6f1790 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/flowanalysis.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/flowanalysis.cs @@ -251,7 +251,12 @@ namespace Mono.CSharp } public bool IsUnreachable { - get { return is_unreachable; } + get { + return is_unreachable; + } + set { + is_unreachable = value; + } } public void ResetBarrier () diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/method.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/method.cs index ec453172ff..c69c1d766f 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/method.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/method.cs @@ -613,7 +613,7 @@ namespace Mono.CSharp { MethodData = new MethodData ( this, ModFlags, flags, this, MethodBuilder, GenericMethod, base_method); - if (!MethodData.Define (Parent.PartialContainer, GetFullName (MemberName), Report)) + if (!MethodData.Define (Parent.PartialContainer, GetFullName (MemberName))) return false; MethodBuilder = MethodData.MethodBuilder; @@ -1819,32 +1819,34 @@ namespace Mono.CSharp { this.parent_method = parent_method; } - public bool Define (DeclSpace parent, string method_full_name, Report Report) + public bool Define (TypeContainer container, string method_full_name) { - TypeContainer container = parent.PartialContainer; - PendingImplementation pending = container.PendingImplementations; MethodSpec ambig_iface_method; + bool optional = false; + if (pending != null) { - implementing = pending.IsInterfaceMethod (method.MethodName, member.InterfaceType, this, out ambig_iface_method); + implementing = pending.IsInterfaceMethod (method.MethodName, member.InterfaceType, this, out ambig_iface_method, ref optional); if (member.InterfaceType != null) { if (implementing == null) { if (member is PropertyBase) { - Report.Error (550, method.Location, "`{0}' is an accessor not found in interface member `{1}{2}'", + container.Compiler.Report.Error (550, method.Location, + "`{0}' is an accessor not found in interface member `{1}{2}'", method.GetSignatureForError (), TypeManager.CSharpName (member.InterfaceType), member.GetSignatureForError ().Substring (member.GetSignatureForError ().LastIndexOf ('.'))); } else { - Report.Error (539, method.Location, + container.Compiler.Report.Error (539, method.Location, "`{0}.{1}' in explicit interface declaration is not a member of interface", TypeManager.CSharpName (member.InterfaceType), member.ShortName); } return false; } if (implementing.IsAccessor && !method.IsAccessor) { - Report.SymbolRelatedToPreviousError (implementing); - Report.Error (683, method.Location, "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor", + container.Compiler.Report.SymbolRelatedToPreviousError (implementing); + container.Compiler.Report.Error (683, method.Location, + "`{0}' explicit method implementation cannot implement `{1}' because it is an accessor", member.GetSignatureForError (), TypeManager.CSharpSignature (implementing)); return false; } @@ -1852,20 +1854,23 @@ namespace Mono.CSharp { if (implementing != null) { if (!method.IsAccessor) { if (implementing.IsAccessor) { - Report.SymbolRelatedToPreviousError (implementing); - Report.Error (470, method.Location, "Method `{0}' cannot implement interface accessor `{1}'", + container.Compiler.Report.SymbolRelatedToPreviousError (implementing); + container.Compiler.Report.Error (470, method.Location, + "Method `{0}' cannot implement interface accessor `{1}'", method.GetSignatureForError (), TypeManager.CSharpSignature (implementing)); } } else if (implementing.DeclaringType.IsInterface) { if (!implementing.IsAccessor) { - Report.SymbolRelatedToPreviousError (implementing); - Report.Error (686, method.Location, "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation", + container.Compiler.Report.SymbolRelatedToPreviousError (implementing); + container.Compiler.Report.Error (686, method.Location, + "Accessor `{0}' cannot implement interface member `{1}' for type `{2}'. Use an explicit interface implementation", method.GetSignatureForError (), TypeManager.CSharpSignature (implementing), container.GetSignatureForError ()); } else { PropertyBase.PropertyMethod pm = method as PropertyBase.PropertyMethod; if (pm != null && pm.HasCustomAccessModifier && (pm.ModFlags & Modifiers.PUBLIC) == 0) { - Report.SymbolRelatedToPreviousError (implementing); - Report.Error (277, method.Location, "Accessor `{0}' must be declared public to implement interface member `{1}'", + container.Compiler.Report.SymbolRelatedToPreviousError (implementing); + container.Compiler.Report.Error (277, method.Location, + "Accessor `{0}' must be declared public to implement interface member `{1}'", method.GetSignatureForError (), implementing.GetSignatureForError ()); } } @@ -1881,43 +1886,44 @@ namespace Mono.CSharp { // explicit implementations, make sure we are private. // if (implementing != null){ - // - // Setting null inside this block will trigger a more - // verbose error reporting for missing interface implementations - // - // The "candidate" function has been flagged already - // but it wont get cleared - // - if (member.IsExplicitImpl){ + if (member.IsExplicitImpl) { if (method.ParameterInfo.HasParams && !implementing.Parameters.HasParams) { - Report.SymbolRelatedToPreviousError (implementing); - Report.Error (466, method.Location, "`{0}': the explicit interface implementation cannot introduce the params modifier", + container.Compiler.Report.SymbolRelatedToPreviousError (implementing); + container.Compiler.Report.Error (466, method.Location, + "`{0}': the explicit interface implementation cannot introduce the params modifier", method.GetSignatureForError ()); } if (ambig_iface_method != null) { - Report.SymbolRelatedToPreviousError (ambig_iface_method); - Report.SymbolRelatedToPreviousError (implementing); - Report.Warning (473, 2, method.Location, + container.Compiler.Report.SymbolRelatedToPreviousError (ambig_iface_method); + container.Compiler.Report.SymbolRelatedToPreviousError (implementing); + container.Compiler.Report.Warning (473, 2, method.Location, "Explicit interface implementation `{0}' matches more than one interface member. Consider using a non-explicit implementation instead", method.GetSignatureForError ()); } - } else { + // + // Setting implementin to null inside this block will trigger a more + // verbose error reporting for missing interface implementations + // if (implementing.DeclaringType.IsInterface) { // // If this is an interface method implementation, // check for public accessibility // - if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public) - { + if ((flags & MethodAttributes.MemberAccessMask) != MethodAttributes.Public) { + implementing = null; + } else if (optional && (container.Interfaces == null || Array.IndexOf (container.Interfaces, implementing.DeclaringType) < 0)) { + // + // We are not implementing interface when base class already implemented it + // implementing = null; } - } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private){ + } else if ((flags & MethodAttributes.MemberAccessMask) == MethodAttributes.Private) { // We may never be private. implementing = null; - } else if ((modifiers & Modifiers.OVERRIDE) == 0){ + } else if ((modifiers & Modifiers.OVERRIDE) == 0) { // // We may be protected if we're overriding something. // @@ -1941,9 +1947,8 @@ namespace Mono.CSharp { // When implementing interface methods, set NewSlot // unless, we are overwriting a method. // - if (implementing.DeclaringType.IsInterface){ - if ((modifiers & Modifiers.OVERRIDE) == 0) - flags |= MethodAttributes.NewSlot; + if ((modifiers & Modifiers.OVERRIDE) == 0 && implementing.DeclaringType.IsInterface) { + flags |= MethodAttributes.NewSlot; } flags |= MethodAttributes.Virtual | MethodAttributes.HideBySig; @@ -1955,8 +1960,8 @@ namespace Mono.CSharp { // // clear the pending implementation flag (requires explicit methods to be defined first) // - parent.PartialContainer.PendingImplementations.ImplementMethod (method.MethodName, - member.InterfaceType, this, member.IsExplicitImpl, out ambig_iface_method); + pending.ImplementMethod (method.MethodName, + member.InterfaceType, this, member.IsExplicitImpl, out ambig_iface_method, ref optional); // // Update indexer accessor name to match implementing abstract accessor diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/pending.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/pending.cs index b9f9da18fd..0852b0f826 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/pending.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/pending.cs @@ -345,14 +345,14 @@ namespace Mono.CSharp { /// /// Whether the specified method is an interface method implementation /// - public MethodSpec IsInterfaceMethod (MemberName name, TypeSpec ifaceType, MethodData method, out MethodSpec ambiguousCandidate) + public MethodSpec IsInterfaceMethod (MemberName name, TypeSpec ifaceType, MethodData method, out MethodSpec ambiguousCandidate, ref bool optional) { - return InterfaceMethod (name, ifaceType, method, Operation.Lookup, out ambiguousCandidate); + return InterfaceMethod (name, ifaceType, method, Operation.Lookup, out ambiguousCandidate, ref optional); } - public void ImplementMethod (MemberName name, TypeSpec ifaceType, MethodData method, bool clear_one, out MethodSpec ambiguousCandidate) + public void ImplementMethod (MemberName name, TypeSpec ifaceType, MethodData method, bool clear_one, out MethodSpec ambiguousCandidate, ref bool optional) { - InterfaceMethod (name, ifaceType, method, clear_one ? Operation.ClearOne : Operation.ClearAll, out ambiguousCandidate); + InterfaceMethod (name, ifaceType, method, clear_one ? Operation.ClearOne : Operation.ClearAll, out ambiguousCandidate, ref optional); } /// @@ -372,7 +372,7 @@ namespace Mono.CSharp { /// that was used in the interface, then we always need to create a proxy for it. /// /// - public MethodSpec InterfaceMethod (MemberName name, TypeSpec iType, MethodData method, Operation op, out MethodSpec ambiguousCandidate) + public MethodSpec InterfaceMethod (MemberName name, TypeSpec iType, MethodData method, Operation op, out MethodSpec ambiguousCandidate, ref bool optional) { ambiguousCandidate = null; @@ -439,6 +439,7 @@ namespace Mono.CSharp { } } else { tm.found [i] = method; + optional = tm.optional; } if (op == Operation.Lookup && name.Left != null && ambiguousCandidate == null) { diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/property.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/property.cs index d5adfccad9..db013e307f 100644 --- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/property.cs +++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/property.cs @@ -205,7 +205,7 @@ namespace Mono.CSharp method_data = new MethodData (method, ModFlags, flags, this); - if (!method_data.Define (parent, method.GetFullName (MemberName), Report)) + if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName))) return null; Spec.SetMetaInfo (method_data.MethodBuilder); @@ -272,7 +272,7 @@ namespace Mono.CSharp method_data = new MethodData (method, ModFlags, flags, this); - if (!method_data.Define (parent, method.GetFullName (MemberName), Report)) + if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName))) return null; Spec.SetMetaInfo (method_data.MethodBuilder); @@ -1165,7 +1165,7 @@ namespace Mono.CSharp method_data = new MethodData (method, method.ModFlags, method.flags | MethodAttributes.HideBySig | MethodAttributes.SpecialName, this); - if (!method_data.Define (parent, method.GetFullName (MemberName), Report)) + if (!method_data.Define (parent.PartialContainer, method.GetFullName (MemberName))) return null; MethodBuilder mb = method_data.MethodBuilder;