diff --git a/ICSharpCode.NRefactory.CSharp.AstVerifier/ICSharpCode.NRefactory.CSharp.AstVerifier.csproj b/ICSharpCode.NRefactory.CSharp.AstVerifier/ICSharpCode.NRefactory.CSharp.AstVerifier.csproj
index bd6e1e8230..b75da9acdb 100644
--- a/ICSharpCode.NRefactory.CSharp.AstVerifier/ICSharpCode.NRefactory.CSharp.AstVerifier.csproj
+++ b/ICSharpCode.NRefactory.CSharp.AstVerifier/ICSharpCode.NRefactory.CSharp.AstVerifier.csproj
@@ -1,49 +1,69 @@
-
-
-
- Debug
- AnyCPU
- 10.0.0
- 2.0
- {961DADFA-7CE6-429F-BC22-47630D6DB826}
- Exe
- ICSharpCode.NRefactory.CSharp.AstVerifier
- AstVerifier
-
-
- true
- full
- false
- bin\Debug
- DEBUG;
- prompt
- 4
- true
-
-
- none
- false
- bin\Release
- prompt
- 4
- true
-
-
-
-
-
-
-
-
-
-
-
- {53DCA265-3C3C-42F9-B647-F72BA678122B}
- ICSharpCode.NRefactory.CSharp
-
-
- {3B2A5653-EC97-4001-BB9B-D90F1AF2C371}
- ICSharpCode.NRefactory
-
-
+
+
+
+ Debug
+ AnyCPU
+ 10.0.0
+ 2.0
+ {961DADFA-7CE6-429F-BC22-47630D6DB826}
+ Exe
+ ICSharpCode.NRefactory.CSharp.AstVerifier
+ AstVerifier
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+ true
+
+
+ none
+ false
+ bin\Release
+ prompt
+ 4
+ true
+
+
+ true
+ full
+ false
+ bin\Debug
+ DEBUG;
+ prompt
+ 4
+ true
+ v4.5
+
+
+ none
+ false
+ bin\Release
+ prompt
+ 4
+ true
+ v4.5
+
+
+
+
+
+
+
+
+
+
+
+ {53DCA265-3C3C-42F9-B647-F72BA678122B}
+ ICSharpCode.NRefactory.CSharp
+
+
+ {3B2A5653-EC97-4001-BB9B-D90F1AF2C371}
+ ICSharpCode.NRefactory
+
+
\ No newline at end of file
diff --git a/ICSharpCode.NRefactory.CSharp/Ast/AstNodeCollection.cs b/ICSharpCode.NRefactory.CSharp/Ast/AstNodeCollection.cs
index 4e28849be4..b727dc2112 100644
--- a/ICSharpCode.NRefactory.CSharp/Ast/AstNodeCollection.cs
+++ b/ICSharpCode.NRefactory.CSharp/Ast/AstNodeCollection.cs
@@ -204,5 +204,21 @@ namespace ICSharpCode.NRefactory.CSharp
{
node.InsertChildBefore(existingItem, newItem, role);
}
+
+ ///
+ /// Applies the to all nodes in this collection.
+ ///
+ public void AcceptVisitor(IAstVisitor visitor)
+ {
+ AstNode next;
+ for (AstNode cur = node.FirstChild; cur != null; cur = next) {
+ Debug.Assert(cur.Parent == node);
+ // Remember next before yielding cur.
+ // This allows removing/replacing nodes while iterating through the list.
+ next = cur.NextSibling;
+ if (cur.Role == role)
+ cur.AcceptVisitor(visitor);
+ }
+ }
}
}
diff --git a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs
index 71fdde7687..b07dc7983b 100644
--- a/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs
+++ b/ICSharpCode.NRefactory.CSharp/Completion/CSharpCompletionEngine.cs
@@ -1,4 +1,4 @@
-//
+//
// CSharpCompletionEngine.cs
//
// Author:
@@ -48,7 +48,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
public string EolMarker { get; set; }
public string IndentString { get; set; }
-#endregion
+ #endregion
#region Result properties
public bool AutoCompleteEmptyMatch;
@@ -262,7 +262,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return contextList.Result;
}
- foreach (var m in initializerResult.Item1.Type.GetMembers (m => !m.IsSynthetic && m.IsPublic && (m.EntityType == EntityType.Property || m.EntityType == EntityType.Field))) {
+ foreach (var m in initializerResult.Item1.Type.GetMembers (m => m.IsPublic && (m.EntityType == EntityType.Property || m.EntityType == EntityType.Field))) {
contextList.AddMember(m);
}
@@ -543,7 +543,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
var wrapper = new CompletionDataWrapper(this);
if (currentType != null) {
// bool includeProtected = DomType.IncludeProtected (dom, typeFromDatabase, resolver.CallingType);
- foreach (var method in currentType.Methods) {
+ foreach (var method in ctx.CurrentTypeDefinition.Methods) {
if (MatchDelegate(delegateType, method) /*&& method.IsAccessibleFrom (dom, resolver.CallingType, resolver.CallingMember, includeProtected) &&*/) {
wrapper.AddMember(method);
// data.SetText (data.CompletionText + ";");
@@ -1200,16 +1200,16 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
wrapper.AddVariable(variable);
}
}
-
- if (currentMember is IUnresolvedParameterizedMember && !(node is AstType)) {
- var param = (IParameterizedMember)currentMember.CreateResolved(ctx);
+
+ if (state.CurrentMember is IParameterizedMember && !(node is AstType)) {
+ var param = (IParameterizedMember)state.CurrentMember;
foreach (var p in param.Parameters) {
wrapper.AddVariable(p);
}
}
- if (currentMember is IUnresolvedMethod) {
- var method = (IUnresolvedMethod)currentMember;
+ if (state.CurrentMember is IMethod) {
+ var method = (IMethod)state.CurrentMember;
foreach (var p in method.TypeParameters) {
wrapper.AddTypeParameter(p);
}
@@ -1319,10 +1319,8 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
{
var lookup = new MemberLookup(ctx.CurrentTypeDefinition, Compilation.MainAssembly);
if (currentType != null) {
- for (var ct = currentType; ct != null; ct = ct.DeclaringTypeDefinition) {
+ for (var ct = ctx.CurrentTypeDefinition; ct != null; ct = ct.DeclaringTypeDefinition) {
foreach (var nestedType in ct.NestedTypes) {
- if (nestedType.IsSynthetic)
- continue;
string name = nestedType.Name;
if (IsAttributeContext(node) && name.EndsWith("Attribute") && name.Length > "Attribute".Length) {
name = name.Substring(0, name.Length - "Attribute".Length);
@@ -1333,7 +1331,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
continue;
}
- var type = typePred(nestedType.Resolve(ctx));
+ var type = typePred(nestedType);
if (type != null) {
var a2 = wrapper.AddType(type, name);
if (a2 != null && callback != null) {
@@ -1351,8 +1349,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
if (member is IMethod && ((IMethod)member).FullName == "System.Object.Finalize") {
continue;
}
- if (member.IsSynthetic)
- continue;
if (member.EntityType == EntityType.Operator) {
continue;
}
@@ -1369,7 +1365,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
var declaring = def.DeclaringTypeDefinition;
while (declaring != null) {
- foreach (var member in declaring.GetMembers (m => m.IsStatic && !m.IsSynthetic)) {
+ foreach (var member in declaring.GetMembers (m => m.IsStatic)) {
if (memberPred == null || memberPred(member)) {
wrapper.AddMember(member);
}
@@ -1378,8 +1374,10 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
}
}
- foreach (var p in currentType.TypeParameters) {
- wrapper.AddTypeParameter(p);
+ if (ctx.CurrentTypeDefinition != null) {
+ foreach (var p in ctx.CurrentTypeDefinition.TypeParameters) {
+ wrapper.AddTypeParameter(p);
+ }
}
}
var scope = ctx.CurrentUsingScope;
@@ -1916,7 +1914,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return;
}
foreach (var m in curType.GetMembers ().Reverse ()) {
- if (m.IsSynthetic || curType.Kind != TypeKind.Interface && !m.IsOverridable) {
+ if (curType.Kind != TypeKind.Interface && !m.IsOverridable) {
continue;
}
// filter out the "Finalize" methods, because finalizers should be done with destructors.
@@ -1987,7 +1985,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return result;
}
- bool MatchDelegate(IType delegateType, IUnresolvedMethod method)
+ bool MatchDelegate(IType delegateType, IMethod method)
{
var delegateMethod = delegateType.GetDelegateInvokeMethod();
if (delegateMethod == null || delegateMethod.Parameters.Count != method.Parameters.Count) {
@@ -1995,7 +1993,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
for (int i = 0; i < delegateMethod.Parameters.Count; i++) {
- if (!delegateMethod.Parameters [i].Type.Equals(method.Parameters [i].Type.Resolve(ctx))) {
+ if (!delegateMethod.Parameters [i].Type.Equals(method.Parameters [i].Type)) {
return false;
}
}
@@ -2016,34 +2014,47 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
"delegate",
"Creates anonymous delegate.",
"delegate {" + EolMarker + thisLineIndent + IndentString + "|" + delegateEndString
- );
+ );
}
var sb = new StringBuilder("(");
var sbWithoutTypes = new StringBuilder("(");
+ var state = GetState();
+ var builder = new TypeSystemAstBuilder(state);
+
for (int k = 0; k < delegateMethod.Parameters.Count; k++) {
if (k > 0) {
sb.Append(", ");
sbWithoutTypes.Append(", ");
}
- var parameterType = delegateMethod.Parameters [k].Type;
- sb.Append(GetShortType(parameterType, GetState()));
- sb.Append(" ");
- sb.Append(delegateMethod.Parameters [k].Name);
+ var convertedParameter = builder.ConvertParameter (delegateMethod.Parameters [k]);
+ if (convertedParameter.ParameterModifier == ParameterModifier.Params)
+ convertedParameter.ParameterModifier = ParameterModifier.None;
+ sb.Append(convertedParameter.GetText (FormattingPolicy));
sbWithoutTypes.Append(delegateMethod.Parameters [k].Name);
}
+
sb.Append(")");
sbWithoutTypes.Append(")");
completionList.AddCustom(
"delegate" + sb,
"Creates anonymous delegate.",
"delegate" + sb + " {" + EolMarker + thisLineIndent + IndentString + "|" + delegateEndString
- );
- if (!completionList.Result.Any(data => data.DisplayText == sbWithoutTypes.ToString())) {
+ );
+
+ if (!completionList.Result.Any(data => data.DisplayText == sb.ToString())) {
+ completionList.AddCustom(
+ sb.ToString(),
+ "Creates typed lambda expression.",
+ sb + " => |" + (addSemicolon ? ";" : "")
+ );
+ }
+
+ if (!delegateMethod.Parameters.Any (p => p.IsOut || p.IsRef) && !completionList.Result.Any(data => data.DisplayText == sbWithoutTypes.ToString())) {
completionList.AddCustom(
sbWithoutTypes.ToString(),
"Creates lambda expression.",
sbWithoutTypes + " => |" + (addSemicolon ? ";" : "")
- );
+ );
}
/* TODO:Make factory method out of it.
// It's needed to temporarly disable inserting auto matching bracket because the anonymous delegates are selectable with '('
@@ -2057,7 +2068,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}*/
return sb.ToString();
}
-
+
bool IsAccessibleFrom(IEntity member, ITypeDefinition calledType, IMember currentMember, bool includeProtected)
{
if (currentMember == null) {
@@ -2151,8 +2162,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
var nr = (NamespaceResolveResult)resolveResult;
if (!(resolvedNode.Parent is UsingDeclaration || resolvedNode.Parent != null && resolvedNode.Parent.Parent is UsingDeclaration)) {
foreach (var cl in nr.Namespace.Types) {
- if (cl.IsSynthetic)
- continue;
string name = cl.Name;
if (hintType != null && hintType.Kind != TypeKind.Array && cl.Kind == TypeKind.Interface) {
continue;
@@ -2291,8 +2300,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
var namespaceContents = new CompletionDataWrapper(this);
foreach (var cl in nr.Namespace.Types) {
- if (cl.IsSynthetic)
- continue;
IType addType = typePred != null ? typePred(cl) : cl;
if (addType != null)
namespaceContents.AddType(addType, addType.Name);
@@ -2393,8 +2400,6 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
var filteredList = new List();
foreach (var member in type.GetMembers ()) {
- if (member.IsSynthetic)
- continue;
if (member.EntityType == EntityType.Indexer || member.EntityType == EntityType.Operator || member.EntityType == EntityType.Constructor || member.EntityType == EntityType.Destructor) {
continue;
}
@@ -2445,7 +2450,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
if (resolveResult is TypeResolveResult || includeStaticMembers) {
- foreach (var nested in type.GetNestedTypes (t => !t.IsSynthetic)) {
+ foreach (var nested in type.GetNestedTypes ()) {
if (!lookup.IsAccessible(nested.GetDefinition(), isProtectedAllowed))
continue;
IType addType = typePred != null ? typePred(nested) : nested;
diff --git a/ICSharpCode.NRefactory.CSharp/Completion/CompletionDataWrapper.cs b/ICSharpCode.NRefactory.CSharp/Completion/CompletionDataWrapper.cs
index 68f20c593a..ea8352ab67 100644
--- a/ICSharpCode.NRefactory.CSharp/Completion/CompletionDataWrapper.cs
+++ b/ICSharpCode.NRefactory.CSharp/Completion/CompletionDataWrapper.cs
@@ -75,31 +75,24 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
}
HashSet usedTypes = new HashSet ();
-
+
public ICompletionData AddType(IType type, string shortType)
{
if (type == null || string.IsNullOrEmpty(shortType) || usedTypes.Contains(shortType))
return null;
if (type.Name == "Void" && type.Namespace == "System")
return null;
- usedTypes.Add(shortType);
- var iCompletionData = Factory.CreateTypeCompletionData(type, shortType);
- result.Add(iCompletionData);
- return iCompletionData;
- }
-
- public ICompletionData AddType(IUnresolvedTypeDefinition type, string shortType)
- {
- if (type == null || string.IsNullOrEmpty(shortType) || usedTypes.Contains(shortType))
- return null;
- if (type.Name == "Void" && type.Namespace == "System")
+
+ var def = type.GetDefinition ();
+ if (def != null && def.ParentAssembly != completion.ctx.CurrentAssembly && !def.IsBrowsable ())
return null;
+
usedTypes.Add(shortType);
var iCompletionData = Factory.CreateTypeCompletionData(type, shortType);
result.Add(iCompletionData);
return iCompletionData;
}
-
+
Dictionary> data = new Dictionary> ();
public ICompletionData AddVariable(IVariable variable)
@@ -126,59 +119,25 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
return cd;
}
- public void AddTypeParameter (IUnresolvedTypeParameter variable)
+ public void AddTypeParameter (ITypeParameter variable)
{
if (data.ContainsKey (variable.Name))
return;
data [variable.Name] = new List ();
result.Add (Factory.CreateVariableCompletionData (variable));
}
-
- public ICompletionData AddMember (IUnresolvedMember member)
- {
- var newData = Factory.CreateEntityCompletionData (member);
-
- // newData.HideExtensionParameter = HideExtensionParameter;
- string memberKey = newData.DisplayText;
- if (memberKey == null)
- return null;
- if (member is IMember) {
- newData.CompletionCategory = GetCompletionCategory (member.DeclaringTypeDefinition.Resolve (completion.ctx));
- }
- List existingData;
- data.TryGetValue (memberKey, out existingData);
-
- if (existingData != null) {
- var a = member as IEntity;
- foreach (var d in existingData) {
- if (!(d is IEntityCompletionData))
- continue;
- var b = ((IEntityCompletionData)d).Entity;
- if (a == null || b == null || a.EntityType == b.EntityType) {
- d.AddOverload (newData);
- return d;
- }
- }
- if (newData != null) {
- result.Add (newData);
- data [memberKey].Add (newData);
- }
- } else {
- result.Add (newData);
- data [memberKey] = new List ();
- data [memberKey].Add (newData);
- }
- return newData;
- }
-
+
public ICompletionData AddMember (IMember member)
{
var newData = Factory.CreateEntityCompletionData (member);
- // newData.HideExtensionParameter = HideExtensionParameter;
+ if (member.ParentAssembly != completion.ctx.CurrentAssembly && !member.IsBrowsable ())
+ return null;
+
string memberKey = newData.DisplayText;
if (memberKey == null)
return null;
+
if (member is IMember) {
newData.CompletionCategory = GetCompletionCategory (member.DeclaringTypeDefinition);
}
diff --git a/ICSharpCode.NRefactory.CSharp/Completion/ICompletionDataFactory.cs b/ICSharpCode.NRefactory.CSharp/Completion/ICompletionDataFactory.cs
index fe367f4eb0..a258dff812 100644
--- a/ICSharpCode.NRefactory.CSharp/Completion/ICompletionDataFactory.cs
+++ b/ICSharpCode.NRefactory.CSharp/Completion/ICompletionDataFactory.cs
@@ -32,14 +32,11 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
{
public interface ICompletionDataFactory
{
- ICompletionData CreateEntityCompletionData (IUnresolvedEntity entity);
- ICompletionData CreateEntityCompletionData (IUnresolvedEntity entity, string text);
ICompletionData CreateEntityCompletionData (IEntity entity);
ICompletionData CreateEntityCompletionData (IEntity entity, string text);
ICompletionData CreateTypeCompletionData (IType type, string shortType);
- ICompletionData CreateTypeCompletionData (IUnresolvedTypeDefinition type, string shortType);
-
+
///
/// Creates a generic completion data.
///
@@ -58,7 +55,7 @@ namespace ICSharpCode.NRefactory.CSharp.Completion
ICompletionData CreateVariableCompletionData (IVariable variable);
- ICompletionData CreateVariableCompletionData (IUnresolvedTypeParameter parameter);
+ ICompletionData CreateVariableCompletionData (ITypeParameter parameter);
ICompletionData CreateEventCreationCompletionData (string varName, IType delegateType, IEvent evt, string parameterDefinition, IUnresolvedMember currentMember, IUnresolvedTypeDefinition currentType);
diff --git a/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj b/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj
index a0871f1848..353b9ef022 100644
--- a/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj
+++ b/ICSharpCode.NRefactory.CSharp/ICSharpCode.NRefactory.CSharp.csproj
@@ -47,6 +47,27 @@
full
True
+
+ ..\ICSharpCode.NRefactory\bin\Debug\
+ False
+ False
+ DEBUG;TRACE;FULL_AST;NET45
+ v4.5
+
+
+ full
+ True
+
+
+ ..\ICSharpCode.NRefactory\bin\Release\
+ True
+ False
+ TRACE;FULL_AST;NET45
+ v4.5
+
+
+ PdbOnly
+
diff --git a/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs b/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs
index 23932e802c..7c7900b451 100644
--- a/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs
+++ b/ICSharpCode.NRefactory.CSharp/OutputVisitor/CSharpOutputVisitor.cs
@@ -2172,6 +2172,7 @@ namespace ICSharpCode.NRefactory.CSharp
WriteAttributes(indexerDeclaration.Attributes);
WriteModifiers(indexerDeclaration.ModifierTokens);
indexerDeclaration.ReturnType.AcceptVisitor(this);
+ Space();
WritePrivateImplementationType(indexerDeclaration.PrivateImplementationType);
WriteKeyword(IndexerDeclaration.ThisKeywordRole);
Space(policy.SpaceBeforeMethodDeclarationParentheses);
diff --git a/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs b/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs
index 78bf756126..8c1810bff2 100644
--- a/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs
+++ b/ICSharpCode.NRefactory.CSharp/Parser/CSharpParser.cs
@@ -2390,7 +2390,9 @@ namespace ICSharpCode.NRefactory.CSharp
if (binaryExpression.Left != null)
result.AddChild ((Expression)binaryExpression.Left.Accept (this), BinaryOperatorExpression.LeftRole);
- result.AddChild (new CSharpTokenNode (Convert (binaryExpression.Location)), BinaryOperatorExpression.GetOperatorRole (result.Operator));
+ var location = LocationsBag.GetLocations (binaryExpression);
+ if (location != null)
+ result.AddChild (new CSharpTokenNode (Convert (location[0])), BinaryOperatorExpression.GetOperatorRole (result.Operator));
if (binaryExpression.Right != null)
result.AddChild ((Expression)binaryExpression.Right.Accept (this), BinaryOperatorExpression.RightRole);
return result;
@@ -2402,7 +2404,9 @@ namespace ICSharpCode.NRefactory.CSharp
result.Operator = BinaryOperatorType.NullCoalescing;
if (nullCoalescingOperator.LeftExpression != null)
result.AddChild ((Expression)nullCoalescingOperator.LeftExpression.Accept (this), BinaryOperatorExpression.LeftRole);
- result.AddChild (new CSharpTokenNode (Convert (nullCoalescingOperator.Location)), BinaryOperatorExpression.NullCoalescingRole);
+ var location = LocationsBag.GetLocations (nullCoalescingOperator);
+ if (location != null)
+ result.AddChild (new CSharpTokenNode (Convert (location[0])), BinaryOperatorExpression.NullCoalescingRole);
if (nullCoalescingOperator.RightExpression != null)
result.AddChild ((Expression)nullCoalescingOperator.RightExpression.Accept (this), BinaryOperatorExpression.RightRole);
return result;
@@ -3076,7 +3080,9 @@ namespace ICSharpCode.NRefactory.CSharp
result.Operator = AssignmentOperatorType.Assign;
if (simpleAssign.Target != null)
result.AddChild ((Expression)simpleAssign.Target.Accept (this), AssignmentExpression.LeftRole);
- result.AddChild (new CSharpTokenNode (Convert (simpleAssign.Location)), AssignmentExpression.AssignRole);
+ var location = LocationsBag.GetLocations (simpleAssign);
+ if (location != null)
+ result.AddChild (new CSharpTokenNode (Convert (location[0])), AssignmentExpression.AssignRole);
if (simpleAssign.Source != null) {
result.AddChild ((Expression)simpleAssign.Source.Accept (this), AssignmentExpression.RightRole);
}
@@ -3121,7 +3127,9 @@ namespace ICSharpCode.NRefactory.CSharp
if (compoundAssign.Target != null)
result.AddChild ((Expression)compoundAssign.Target.Accept (this), AssignmentExpression.LeftRole);
- result.AddChild (new CSharpTokenNode (Convert (compoundAssign.Location)), AssignmentExpression.GetOperatorRole (result.Operator));
+ var location = LocationsBag.GetLocations (compoundAssign);
+ if (location != null)
+ result.AddChild (new CSharpTokenNode (Convert (location[0])), AssignmentExpression.GetOperatorRole (result.Operator));
if (compoundAssign.Source != null)
result.AddChild ((Expression)compoundAssign.Source.Accept (this), AssignmentExpression.RightRole);
return result;
@@ -3781,11 +3789,13 @@ namespace ICSharpCode.NRefactory.CSharp
var file = new SourceFile (fileName, fileName, 0);
Location.Initialize (new List (new [] { file }));
var module = new ModuleContainer (ctx);
- var parser = Driver.Parse (reader, file, module, lineModifier);
-
+ var session = new ParserSession ();
+ session.LocationsBag = new LocationsBag ();
+ var report = new Report (ctx, errorReportPrinter);
+ var parser = Driver.Parse (reader, file, module, session, report, lineModifier);
var top = new CompilerCompilationUnit () {
ModuleCompiled = module,
- LocationsBag = parser.LocationsBag,
+ LocationsBag = session.LocationsBag,
SpecialsBag = parser.Lexer.sbag,
Conditionals = parser.Lexer.SourceFile.Conditionals
};
@@ -3882,10 +3892,12 @@ namespace ICSharpCode.NRefactory.CSharp
var file = new SourceFile("", "", 0);
Location.Initialize(new List (new [] { file }));
var module = new ModuleContainer(ctx);
- module.DocumentationBuilder = new DocumentationBuilder();
+ module.DocumentationBuilder = new DocumentationBuilder(module);
var source_file = new CompilationSourceFile (module);
var report = new Report (ctx, errorReportPrinter);
- var parser = new Mono.CSharp.CSharpParser (reader, source_file, report);
+ ParserSession session = new ParserSession ();
+ session.LocationsBag = new LocationsBag ();
+ var parser = new Mono.CSharp.CSharpParser (reader, source_file, report, session);
parser.Lexer.putback_char = Tokenizer.DocumentationXref;
parser.Lexer.parsing_generic_declaration_doc = true;
parser.parse ();
@@ -3894,7 +3906,7 @@ namespace ICSharpCode.NRefactory.CSharp
// mc.GetSignatureForError (), cref);
}
- ConversionVisitor conversionVisitor = new ConversionVisitor (false, parser.LocationsBag);
+ ConversionVisitor conversionVisitor = new ConversionVisitor (false, session.LocationsBag);
DocumentationReference docRef = conversionVisitor.ConvertXmlDoc(module.DocumentationBuilder);
CompilerCallableEntryPoint.Reset();
return docRef;
diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolFile.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolFile.cs
index 664cdf0cf8..9b83bf3bed 100644
--- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolFile.cs
+++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolFile.cs
@@ -53,7 +53,7 @@ namespace Mono.CompilerServices.SymbolWriter
}
}
- internal class MyBinaryWriter : BinaryWriter
+ sealed class MyBinaryWriter : BinaryWriter
{
public MyBinaryWriter (Stream stream)
: base (stream)
diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolTable.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolTable.cs
index c9beaa0d43..88d604f2e3 100644
--- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolTable.cs
+++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/MonoSymbolTable.cs
@@ -183,6 +183,7 @@ namespace Mono.CompilerServices.SymbolWriter
{
#region This is actually written to the symbol file
public readonly int Row;
+ public int Column;
public readonly int File;
public readonly int Offset;
public readonly bool IsHidden; // Obsolete is never used
@@ -195,28 +196,35 @@ namespace Mono.CompilerServices.SymbolWriter
public int Compare (LineNumberEntry l1, LineNumberEntry l2)
{
return l1.Row == l2.Row ?
- l1.Offset.CompareTo (l2.Offset) :
+ l1.Column.CompareTo (l2.Column) :
l1.Row.CompareTo (l2.Row);
}
}
- public static readonly LineNumberEntry Null = new LineNumberEntry (0, 0, 0);
+ public static readonly LineNumberEntry Null = new LineNumberEntry (0, 0, 0, 0);
+
+ public LineNumberEntry (int file, int row, int column, int offset)
+ : this (file, row, offset, column, false)
+ {
+ }
public LineNumberEntry (int file, int row, int offset)
- : this (file, row, offset, false)
- { }
+ : this (file, row, -1, offset, false)
+ {
+ }
- public LineNumberEntry (int file, int row, int offset, bool is_hidden)
+ public LineNumberEntry (int file, int row, int column, int offset, bool is_hidden)
{
this.File = file;
this.Row = row;
+ this.Column = column;
this.Offset = offset;
this.IsHidden = is_hidden;
}
public override string ToString ()
{
- return String.Format ("[Line {0}:{1}:{2}]", File, Row, Offset);
+ return String.Format ("[Line {0}:{1,2}:{3}]", File, Row, Column, Offset);
}
}
@@ -675,8 +683,7 @@ namespace Mono.CompilerServices.SymbolWriter
creating = true;
}
- public SourceFileEntry (MonoSymbolFile file, string file_name,
- byte[] guid, byte[] checksum)
+ public SourceFileEntry (MonoSymbolFile file, string file_name, byte[] guid, byte[] checksum)
: this (file, file_name)
{
this.guid = guid;
@@ -694,13 +701,15 @@ namespace Mono.CompilerServices.SymbolWriter
DataOffset = (int) bw.BaseStream.Position;
bw.Write (file_name);
- if (guid == null) {
- guid = Guid.NewGuid ().ToByteArray ();
+ if (guid == null)
+ guid = new byte[16];
+
+ if (hash == null) {
try {
- using (FileStream fs = new FileStream (file_name, FileMode.Open, FileAccess.Read)) {
- MD5 md5 = MD5.Create ();
- hash = md5.ComputeHash (fs);
- }
+ using (FileStream fs = new FileStream (file_name, FileMode.Open, FileAccess.Read)) {
+ MD5 md5 = MD5.Create ();
+ hash = md5.ComputeHash (fs);
+ }
} catch {
hash = new byte [16];
}
@@ -791,7 +800,6 @@ namespace Mono.CompilerServices.SymbolWriter
public const int Default_LineRange = 8;
public const byte Default_OpcodeBase = 9;
- public const bool SuppressDuplicates = true;
#endregion
public const byte DW_LNS_copy = 1;
@@ -822,7 +830,7 @@ namespace Mono.CompilerServices.SymbolWriter
this._line_numbers = lines;
}
- internal void Write (MonoSymbolFile file, MyBinaryWriter bw)
+ internal void Write (MonoSymbolFile file, MyBinaryWriter bw, bool readColumnsInfo)
{
int start = (int) bw.BaseStream.Position;
@@ -832,11 +840,6 @@ namespace Mono.CompilerServices.SymbolWriter
int line_inc = LineNumbers [i].Row - last_line;
int offset_inc = LineNumbers [i].Offset - last_offset;
- if (SuppressDuplicates && (i+1 < LineNumbers.Length)) {
- if (LineNumbers [i+1].Equals (LineNumbers [i]))
- continue;
- }
-
if (LineNumbers [i].File != last_file) {
bw.Write (DW_LNS_set_file);
bw.WriteLeb128 (LineNumbers [i].File);
@@ -884,17 +887,23 @@ namespace Mono.CompilerServices.SymbolWriter
bw.Write ((byte) 1);
bw.Write (DW_LNE_end_sequence);
+ for (int i = 0; i < LineNumbers.Length; i++) {
+ var ln = LineNumbers [i];
+ if (ln.Row >= 0)
+ bw.WriteLeb128 (ln.Column);
+ }
+
file.ExtendedLineNumberSize += (int) bw.BaseStream.Position - start;
}
- internal static LineNumberTable Read (MonoSymbolFile file, MyBinaryReader br)
+ internal static LineNumberTable Read (MonoSymbolFile file, MyBinaryReader br, bool readColumnsInfo)
{
LineNumberTable lnt = new LineNumberTable (file);
- lnt.DoRead (file, br);
+ lnt.DoRead (file, br, readColumnsInfo);
return lnt;
}
- void DoRead (MonoSymbolFile file, MyBinaryReader br)
+ void DoRead (MonoSymbolFile file, MyBinaryReader br, bool includesColumns)
{
var lines = new List ();
@@ -911,7 +920,7 @@ namespace Mono.CompilerServices.SymbolWriter
if (opcode == DW_LNE_end_sequence) {
if (modified)
lines.Add (new LineNumberEntry (
- stm_file, stm_line, stm_offset, is_hidden));
+ stm_file, stm_line, -1, stm_offset, is_hidden));
break;
} else if (opcode == DW_LNE_MONO_negate_is_hidden) {
is_hidden = !is_hidden;
@@ -929,7 +938,7 @@ namespace Mono.CompilerServices.SymbolWriter
switch (opcode) {
case DW_LNS_copy:
lines.Add (new LineNumberEntry (
- stm_file, stm_line, stm_offset, is_hidden));
+ stm_file, stm_line, -1, stm_offset, is_hidden));
modified = false;
break;
case DW_LNS_advance_pc:
@@ -959,13 +968,20 @@ namespace Mono.CompilerServices.SymbolWriter
stm_offset += opcode / LineRange;
stm_line += LineBase + (opcode % LineRange);
lines.Add (new LineNumberEntry (
- stm_file, stm_line, stm_offset, is_hidden));
+ stm_file, stm_line, -1, stm_offset, is_hidden));
modified = false;
}
}
- _line_numbers = new LineNumberEntry [lines.Count];
- lines.CopyTo (_line_numbers, 0);
+ _line_numbers = lines.ToArray ();
+
+ if (includesColumns) {
+ for (int i = 0; i < _line_numbers.Length; ++i) {
+ var ln = _line_numbers[i];
+ if (ln.Row >= 0)
+ ln.Column = br.ReadLeb128 ();
+ }
+ }
}
public bool GetMethodBounds (out LineNumberEntry start, out LineNumberEntry end)
@@ -1022,7 +1038,8 @@ namespace Mono.CompilerServices.SymbolWriter
[Flags]
public enum Flags
{
- LocalNamesAmbiguous = 1
+ LocalNamesAmbiguous = 1,
+ ColumnsInfoIncluded = 1 << 1
}
public const int Size = 12;
@@ -1176,7 +1193,7 @@ namespace Mono.CompilerServices.SymbolWriter
}
LineNumberTableOffset = (int) bw.BaseStream.Position;
- lnt.Write (file, bw);
+ lnt.Write (file, bw, (flags & Flags.ColumnsInfoIncluded) != 0);
DataOffset = (int) bw.BaseStream.Position;
@@ -1204,7 +1221,7 @@ namespace Mono.CompilerServices.SymbolWriter
long old_pos = reader.BaseStream.Position;
reader.BaseStream.Position = LineNumberTableOffset;
- lnt = LineNumberTable.Read (SymbolFile, reader);
+ lnt = LineNumberTable.Read (SymbolFile, reader, (flags & Flags.ColumnsInfoIncluded) != 0);
reader.BaseStream.Position = old_pos;
return lnt;
diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/SourceMethodBuilder.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/SourceMethodBuilder.cs
index 1ff399cdcd..b45bf8a1fb 100644
--- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/SourceMethodBuilder.cs
+++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/SourceMethodBuilder.cs
@@ -64,7 +64,7 @@ namespace Mono.CompilerServices.SymbolWriter
public void MarkSequencePoint (int offset, SourceFileEntry file, int line, int column, bool is_hidden)
{
int file_idx = file != null ? file.Index : 0;
- var lne = new LineNumberEntry (file_idx, line, offset, is_hidden);
+ var lne = new LineNumberEntry (file_idx, line, column, offset, is_hidden);
if (method_lines.Count > 0) {
var prev = method_lines[method_lines.Count - 1];
@@ -185,7 +185,7 @@ namespace Mono.CompilerServices.SymbolWriter
{
MethodEntry entry = new MethodEntry (
file, _comp_unit.Entry, token, ScopeVariables,
- Locals, method_lines.ToArray (), Blocks, null, 0, ns_id);
+ Locals, method_lines.ToArray (), Blocks, null, MethodEntry.Flags.ColumnsInfoIncluded, ns_id);
file.AddMethod (entry);
}
diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/anonymous.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/anonymous.cs
index 87a472af79..9a2c4a334a 100644
--- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/anonymous.cs
+++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/anonymous.cs
@@ -816,7 +816,7 @@ namespace Mono.CSharp {
sealed class HoistedFieldAssign : CompilerAssign
{
public HoistedFieldAssign (Expression target, Expression source)
- : base (target, source, source.Location)
+ : base (target, source, target.Location)
{
}
@@ -1503,6 +1503,10 @@ namespace Mono.CSharp {
aec.Set (flags);
+ var bc = ec as BlockContext;
+ if (bc != null)
+ aec.FlowOffset = bc.FlowOffset;
+
var errors = ec.Report.Errors;
bool res = Block.Resolve (ec.CurrentBranching, aec, null);
@@ -2013,11 +2017,11 @@ namespace Mono.CSharp {
IntConstant FNV_prime = new IntConstant (Compiler.BuiltinTypes, 16777619, loc);
rs_hashcode = new Binary (Binary.Operator.Multiply,
- new Binary (Binary.Operator.ExclusiveOr, rs_hashcode, field_hashcode, loc),
- FNV_prime, loc);
+ new Binary (Binary.Operator.ExclusiveOr, rs_hashcode, field_hashcode),
+ FNV_prime);
Expression field_to_string = new Conditional (new BooleanExpression (new Binary (Binary.Operator.Inequality,
- new MemberAccess (new This (f.Location), f.Name), new NullLiteral (loc), loc)),
+ new MemberAccess (new This (f.Location), f.Name), new NullLiteral (loc))),
new Invocation (new MemberAccess (
new MemberAccess (new This (f.Location), f.Name), "ToString"), null),
new StringConstant (Compiler.BuiltinTypes, string.Empty, loc), loc);
@@ -2028,9 +2032,7 @@ namespace Mono.CSharp {
string_concat,
new Binary (Binary.Operator.Addition,
new StringConstant (Compiler.BuiltinTypes, " " + p.Name + " = ", loc),
- field_to_string,
- loc),
- loc);
+ field_to_string));
continue;
}
@@ -2040,18 +2042,15 @@ namespace Mono.CSharp {
string_concat = new Binary (Binary.Operator.Addition,
new Binary (Binary.Operator.Addition,
string_concat,
- new StringConstant (Compiler.BuiltinTypes, ", " + p.Name + " = ", loc),
- loc),
- field_to_string,
- loc);
+ new StringConstant (Compiler.BuiltinTypes, ", " + p.Name + " = ", loc)),
+ field_to_string);
- rs_equals = new Binary (Binary.Operator.LogicalAnd, rs_equals, field_equal, loc);
+ rs_equals = new Binary (Binary.Operator.LogicalAnd, rs_equals, field_equal);
}
string_concat = new Binary (Binary.Operator.Addition,
string_concat,
- new StringConstant (Compiler.BuiltinTypes, " }", loc),
- loc);
+ new StringConstant (Compiler.BuiltinTypes, " }", loc));
//
// Equals (object obj) override
@@ -2062,9 +2061,9 @@ namespace Mono.CSharp {
new As (equals_block.GetParameterReference (0, loc),
current_type, loc), loc)));
- Expression equals_test = new Binary (Binary.Operator.Inequality, other_variable, new NullLiteral (loc), loc);
+ Expression equals_test = new Binary (Binary.Operator.Inequality, other_variable, new NullLiteral (loc));
if (rs_equals != null)
- equals_test = new Binary (Binary.Operator.LogicalAnd, equals_test, rs_equals, loc);
+ equals_test = new Binary (Binary.Operator.LogicalAnd, equals_test, rs_equals);
equals_block.AddStatement (new Return (equals_test, loc));
equals.Block = equals_block;
@@ -2106,19 +2105,19 @@ namespace Mono.CSharp {
var hash_variable = new LocalVariableReference (li_hash, loc);
hashcode_block.AddStatement (new StatementExpression (
new CompoundAssign (Binary.Operator.Addition, hash_variable,
- new Binary (Binary.Operator.LeftShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 13, loc), loc), loc)));
+ new Binary (Binary.Operator.LeftShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 13, loc)))));
hashcode_block.AddStatement (new StatementExpression (
new CompoundAssign (Binary.Operator.ExclusiveOr, hash_variable,
- new Binary (Binary.Operator.RightShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 7, loc), loc), loc)));
+ new Binary (Binary.Operator.RightShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 7, loc)))));
hashcode_block.AddStatement (new StatementExpression (
new CompoundAssign (Binary.Operator.Addition, hash_variable,
- new Binary (Binary.Operator.LeftShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 3, loc), loc), loc)));
+ new Binary (Binary.Operator.LeftShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 3, loc)))));
hashcode_block.AddStatement (new StatementExpression (
new CompoundAssign (Binary.Operator.ExclusiveOr, hash_variable,
- new Binary (Binary.Operator.RightShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 17, loc), loc), loc)));
+ new Binary (Binary.Operator.RightShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 17, loc)))));
hashcode_block.AddStatement (new StatementExpression (
new CompoundAssign (Binary.Operator.Addition, hash_variable,
- new Binary (Binary.Operator.LeftShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 5, loc), loc), loc)));
+ new Binary (Binary.Operator.LeftShift, hash_variable, new IntConstant (Compiler.BuiltinTypes, 5, loc)))));
hashcode_block.AddStatement (new Return (hash_variable, loc));
hashcode.Block = hashcode_top;
diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/argument.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/argument.cs
index 9da98b8a80..22e28eaf72 100644
--- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/argument.cs
+++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/argument.cs
@@ -320,20 +320,20 @@ namespace Mono.CSharp
if (a.Expr is Constant) {
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags,
- new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "Constant", loc), loc);
+ new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "Constant", loc));
} else if (a.ArgType == Argument.AType.Ref) {
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags,
- new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "IsRef", loc), loc);
+ new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "IsRef", loc));
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags,
- new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "UseCompileTimeType", loc), loc);
+ new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "UseCompileTimeType", loc));
} else if (a.ArgType == Argument.AType.Out) {
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags,
- new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "IsOut", loc), loc);
+ new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "IsOut", loc));
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags,
- new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "UseCompileTimeType", loc), loc);
+ new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "UseCompileTimeType", loc));
} else if (a.ArgType == Argument.AType.DynamicTypeName) {
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags,
- new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "IsStaticType", loc), loc);
+ new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "IsStaticType", loc));
}
var arg_type = a.Expr.Type;
@@ -354,14 +354,14 @@ namespace Mono.CSharp
}
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags,
- new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "UseCompileTimeType", loc), loc);
+ new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "UseCompileTimeType", loc));
}
string named_value;
NamedArgument na = a as NamedArgument;
if (na != null) {
info_flags = new Binary (Binary.Operator.BitwiseOr, info_flags,
- new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "NamedArgument", loc), loc);
+ new MemberAccess (new MemberAccess (binder, info_flags_enum, loc), "NamedArgument", loc));
named_value = na.Name;
} else {
diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/assign.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/assign.cs
index 673d586d10..ce8e254308 100644
--- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/assign.cs
+++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/assign.cs
@@ -543,11 +543,11 @@ namespace Mono.CSharp {
ExpressionStatement resolved;
IMemberContext mc;
- public FieldInitializer (FieldSpec spec, Expression expression, IMemberContext mc)
- : base (new FieldExpr (spec, expression.Location), expression, expression.Location)
+ public FieldInitializer (FieldBase mc, Expression expression, Location loc)
+ : base (new FieldExpr (mc.Spec, expression.Location), expression, loc)
{
this.mc = mc;
- if (!spec.IsStatic)
+ if (!mc.IsStatic)
((FieldExpr)target).InstanceExpression = new CompilerGeneratedThis (mc.CurrentType, expression.Location);
}
@@ -660,15 +660,15 @@ namespace Mono.CSharp {
}
}
- public CompoundAssign (Binary.Operator op, Expression target, Expression source, Location loc)
- : base (target, source, loc)
+ public CompoundAssign (Binary.Operator op, Expression target, Expression source)
+ : base (target, source, target.Location)
{
right = source;
this.op = op;
}
- public CompoundAssign (Binary.Operator op, Expression target, Expression source, Expression left, Location loc)
- : this (op, target, source, loc)
+ public CompoundAssign (Binary.Operator op, Expression target, Expression source, Expression left)
+ : this (op, target, source)
{
this.left = left;
}
@@ -731,7 +731,7 @@ namespace Mono.CSharp {
if (left == null)
left = new TargetExpression (target);
- source = new Binary (op, left, right, true, loc);
+ source = new Binary (op, left, right, true);
if (target is DynamicMemberAssignable) {
Arguments targs = ((DynamicMemberAssignable) target).Arguments;
diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/async.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/async.cs
index 4c0cce6127..e962e7d623 100644
--- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/async.cs
+++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/async.cs
@@ -227,7 +227,9 @@ namespace Mono.CSharp
//
// awaiter = expr.GetAwaiter ();
//
- fe_awaiter.EmitAssign (ec, expr, false, false);
+ using (ec.With (BuilderContext.Options.OmitDebugInfo, true)) {
+ fe_awaiter.EmitAssign (ec, expr, false, false);
+ }
Label skip_continuation = ec.DefineLabel ();
@@ -284,14 +286,8 @@ namespace Mono.CSharp
awaiter.IsAvailableForReuse = true;
- if (ResultType.Kind != MemberKind.Void) {
- var storey = (AsyncTaskStorey) machine_initializer.Storey;
-
- if (storey.HoistedReturn != null)
- storey.HoistedReturn.EmitAssign (ec);
- else
- ec.Emit (OpCodes.Pop);
- }
+ if (ResultType.Kind != MemberKind.Void)
+ ec.Emit (OpCodes.Pop);
}
void Error_WrongAwaiterPattern (ResolveContext rc, TypeSpec awaiter)
diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/attribute.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/attribute.cs
index 47eaad62e0..eff7a5231d 100644
--- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/attribute.cs
+++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/attribute.cs
@@ -1016,7 +1016,7 @@ namespace Mono.CSharp {
if (pos_args.Count == 1 && pos_args[0].Expr is Constant) {
var value = ((Constant) pos_args[0].Expr).GetValue () as string;
if (string.IsNullOrEmpty (value))
- Error_AttributeEmitError ("DllName cannot be empty");
+ Error_AttributeEmitError ("DllName cannot be empty or null");
}
} else if (Type == predefined.MethodImpl && pt.BuiltinType == BuiltinTypeSpec.Type.Short &&
!System.Enum.IsDefined (typeof (MethodImplOptions), ((Constant) arg_expr).GetValue ().ToString ())) {
@@ -1476,6 +1476,12 @@ namespace Mono.CSharp {
Encode (type.MemberDefinition.IsImported ? old_type.AssemblyQualifiedName : old_type.FullName);
}
+ public void EncodeTypeName (TypeContainer type)
+ {
+ Encode (type.GetSignatureForMetadata ());
+ }
+
+
//
// Encodes single property named argument per call
//
@@ -1629,6 +1635,10 @@ namespace Mono.CSharp {
// New in .NET 4.0
public readonly PredefinedDynamicAttribute Dynamic;
+ // New in .NET 4.5
+ public readonly PredefinedStateMachineAttribute AsyncStateMachine;
+ public readonly PredefinedStateMachineAttribute IteratorStateMachine;
+
//
// Optional types which are used as types and for member lookup
//
@@ -1690,6 +1700,11 @@ namespace Mono.CSharp {
StructLayout = new PredefinedAttribute (module, "System.Runtime.InteropServices", "StructLayoutAttribute");
FieldOffset = new PredefinedAttribute (module, "System.Runtime.InteropServices", "FieldOffsetAttribute");
+ AsyncStateMachine = new PredefinedStateMachineAttribute (module, "System.Runtime.CompilerServices", "AsyncStateMachineAttribute");
+ IteratorStateMachine = new PredefinedStateMachineAttribute (module, "System.Runtime.CompilerServices", "IteratorStateMachineAttribute") {
+ IsIterator = true
+ };
+
CallerMemberNameAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerMemberNameAttribute");
CallerLineNumberAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerLineNumberAttribute");
CallerFilePathAttribute = new PredefinedAttribute (module, "System.Runtime.CompilerServices", "CallerFilePathAttribute");
@@ -1877,6 +1892,34 @@ namespace Mono.CSharp {
}
}
+ public class PredefinedStateMachineAttribute : PredefinedAttribute
+ {
+ public PredefinedStateMachineAttribute (ModuleContainer module, string ns, string name)
+ : base (module, ns, name)
+ {
+ }
+
+ public bool IsIterator { get; set; }
+
+ public void EmitAttribute (MethodBuilder builder, StateMachine type)
+ {
+ var predefined_ctor = IsIterator ?
+ module.PredefinedMembers.IteratorStateMachineAttributeCtor :
+ module.PredefinedMembers.AsyncStateMachineAttributeCtor;
+
+ var ctor = predefined_ctor.Get ();
+
+ if (ctor == null)
+ return;
+
+ AttributeEncoder encoder = new AttributeEncoder ();
+ encoder.EncodeTypeName (type);
+ encoder.EncodeEmptyNamedArguments ();
+
+ builder.SetCustomAttribute ((ConstructorInfo) ctor.GetMetaInfo (), encoder.ToArray ());
+ }
+ }
+
public class PredefinedDynamicAttribute : PredefinedAttribute
{
MethodSpec tctor;
diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/cfold.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/cfold.cs
index 9e2cfc8b96..8724e48b52 100644
--- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/cfold.cs
+++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/cfold.cs
@@ -187,7 +187,7 @@ namespace Mono.CSharp {
//
if ((lt.BuiltinType == BuiltinTypeSpec.Type.Bool && right is NullLiteral) ||
(rt.BuiltinType == BuiltinTypeSpec.Type.Bool && left is NullLiteral)) {
- var b = new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
+ var b = new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec);
// false | null => null
// null | false => null
@@ -231,7 +231,7 @@ namespace Mono.CSharp {
//
if ((lt.BuiltinType == BuiltinTypeSpec.Type.Bool && right is NullLiteral) ||
(rt.BuiltinType == BuiltinTypeSpec.Type.Bool && left is NullLiteral)) {
- var b = new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
+ var b = new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec);
// false & null => false
// null & false => false
@@ -469,7 +469,7 @@ namespace Mono.CSharp {
if (left is NullLiteral && right is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec);
- return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
+ return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
}
if (!DoBinaryNumericPromotions (ec, ref left, ref right))
@@ -566,7 +566,7 @@ namespace Mono.CSharp {
if (left is NullLiteral && right is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec);
- return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
+ return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
}
if (!DoBinaryNumericPromotions (ec, ref left, ref right))
@@ -662,7 +662,7 @@ namespace Mono.CSharp {
if (left is NullLiteral && right is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec);
- return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
+ return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
}
if (!DoBinaryNumericPromotions (ec, ref left, ref right))
@@ -762,7 +762,7 @@ namespace Mono.CSharp {
if (left is NullLiteral && right is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec);
- return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
+ return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
}
if (!DoBinaryNumericPromotions (ec, ref left, ref right))
@@ -852,7 +852,7 @@ namespace Mono.CSharp {
if (left is NullLiteral && right is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec);
- return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
+ return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
}
IntConstant ic = right.ConvertImplicitly (ec.BuiltinTypes.Int) as IntConstant;
@@ -873,7 +873,7 @@ namespace Mono.CSharp {
// null << value => null
if (left is NullLiteral)
- return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
+ return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec);
left = left.ConvertImplicitly (ec.BuiltinTypes.Int);
if (left.Type.BuiltinType == BuiltinTypeSpec.Type.Int)
@@ -889,7 +889,7 @@ namespace Mono.CSharp {
if (left is NullLiteral && right is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec);
- return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
+ return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
}
IntConstant sic = right.ConvertImplicitly (ec.BuiltinTypes.Int) as IntConstant;
@@ -909,7 +909,7 @@ namespace Mono.CSharp {
// null >> value => null
if (left is NullLiteral)
- return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
+ return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec);
left = left.ConvertImplicitly (ec.BuiltinTypes.Int);
if (left.Type.BuiltinType == BuiltinTypeSpec.Type.Int)
@@ -925,7 +925,7 @@ namespace Mono.CSharp {
if (left.IsNull || right.IsNull) {
return ReducedExpression.Create (
new BoolConstant (ec.BuiltinTypes, left.IsNull == right.IsNull, left.Location),
- new Binary (oper, left, right, loc));
+ new Binary (oper, left, right));
}
if (left is StringConstant && right is StringConstant)
@@ -969,7 +969,7 @@ namespace Mono.CSharp {
if (left.IsNull || right.IsNull) {
return ReducedExpression.Create (
new BoolConstant (ec.BuiltinTypes, left.IsNull != right.IsNull, left.Location),
- new Binary (oper, left, right, loc));
+ new Binary (oper, left, right));
}
if (left is StringConstant && right is StringConstant)
@@ -1011,11 +1011,11 @@ namespace Mono.CSharp {
if (left is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec);
- return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
+ return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
}
if (left is Nullable.LiftedNull) {
- return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
+ return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec);
}
}
@@ -1051,11 +1051,11 @@ namespace Mono.CSharp {
if (left is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec);
- return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
+ return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
}
if (left is Nullable.LiftedNull) {
- return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
+ return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec);
}
}
@@ -1091,11 +1091,11 @@ namespace Mono.CSharp {
if (left is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec);
- return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
+ return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
}
if (left is Nullable.LiftedNull) {
- return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
+ return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec);
}
}
@@ -1131,11 +1131,11 @@ namespace Mono.CSharp {
if (left is NullLiteral) {
var lifted_int = new Nullable.NullableType (ec.BuiltinTypes.Int, loc);
lifted_int.ResolveAsType (ec);
- return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right, loc).Resolve (ec);
+ return (Constant) new Nullable.LiftedBinaryOperator (oper, lifted_int, right).Resolve (ec);
}
if (left is Nullable.LiftedNull) {
- return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right, loc).Resolve (ec);
+ return (Constant) new Nullable.LiftedBinaryOperator (oper, left, right).Resolve (ec);
}
}
diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/class.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/class.cs
index c776c47b08..645f53245c 100644
--- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/class.cs
+++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/class.cs
@@ -346,6 +346,24 @@ namespace Mono.CSharp
return MemberName.GetSignatureForError ();
}
+ public string GetSignatureForMetadata ()
+ {
+#if STATIC
+ var name = TypeNameParser.Escape (MemberName.Basename);
+
+ if (Parent is TypeDefinition) {
+ return Parent.GetSignatureForMetadata () + "+" + name;
+ }
+
+ if (Parent != null && Parent.MemberName != null)
+ return Parent.GetSignatureForMetadata () + "." + name;
+
+ return name;
+#else
+ throw new NotImplementedException ();
+#endif
+ }
+
public virtual void RemoveContainer (TypeContainer cont)
{
if (containers != null)
@@ -1845,13 +1863,20 @@ namespace Mono.CSharp
return;
string class_indexer_name = null;
- has_normal_indexers = true;
//
// Check normal indexers for consistent name, explicit interface implementation
// indexers are ignored
//
foreach (var indexer in indexers) {
+ //
+ // FindMembers can return unfiltered full hierarchy names
+ //
+ if (indexer.DeclaringType != spec)
+ continue;
+
+ has_normal_indexers = true;
+
if (class_indexer_name == null) {
indexer_name = class_indexer_name = indexer.Name;
continue;
diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/codegen.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/codegen.cs
index 026d410698..9bb7066758 100644
--- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/codegen.cs
+++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/codegen.cs
@@ -944,10 +944,10 @@ namespace Mono.CSharp
if (method.ReturnType.Kind == MemberKind.Void && method.IsConditionallyExcluded (ec.MemberContext, loc))
return;
- EmitPredefined (ec, method, Arguments);
+ EmitPredefined (ec, method, Arguments, loc);
}
- public void EmitPredefined (EmitContext ec, MethodSpec method, Arguments Arguments)
+ public void EmitPredefined (EmitContext ec, MethodSpec method, Arguments Arguments, Location? loc = null)
{
Expression instance_copy = null;
@@ -1006,6 +1006,18 @@ namespace Mono.CSharp
ec.Emit (OpCodes.Constrained, InstanceExpression.Type);
}
+ if (loc != null) {
+ //
+ // Emit explicit sequence point for expressions like Foo.Bar () to help debugger to
+ // break at right place when LHS expression can be stepped-into
+ //
+ // TODO: The list is probably not comprehensive, need to do more testing
+ //
+ if (InstanceExpression is PropertyExpr || InstanceExpression is Invocation || InstanceExpression is IndexerExpr ||
+ InstanceExpression is New || InstanceExpression is DelegateInvocation)
+ ec.Mark (loc.Value);
+ }
+
//
// Set instance expression to actual result expression. When it contains await it can be
// picked up by caller
diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/const.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/const.cs
index 5eb93d129a..31cba91fe0 100644
--- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/const.cs
+++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/const.cs
@@ -59,7 +59,7 @@ namespace Mono.CSharp {
if ((field_attr & FieldAttributes.InitOnly) != 0)
Parent.PartialContainer.RegisterFieldForInitialization (this,
- new FieldInitializer (spec, initializer, this));
+ new FieldInitializer (this, initializer, Location));
if (declarators != null) {
var t = new TypeExpression (MemberType, TypeExpression.Location);
diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/context.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/context.cs
index 5f309854bd..0e45bd5deb 100644
--- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/context.cs
+++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/context.cs
@@ -13,6 +13,7 @@
using System;
using System.Collections.Generic;
using System.IO;
+using System.Security.Cryptography;
namespace Mono.CSharp
{
@@ -730,4 +731,28 @@ namespace Mono.CSharp
return new FlagsHandle (this, options, enable ? options : 0);
}
}
+
+ //
+ // Parser session objects. We could recreate all these objects for each parser
+ // instance but the best parser performance the session object can be reused
+ //
+ public class ParserSession
+ {
+ MD5 md5;
+
+ public readonly char[] StreamReaderBuffer = new char[SeekableStreamReader.DefaultReadAheadSize * 2];
+ public readonly Dictionary[] Identifiers = new Dictionary[Tokenizer.MaxIdentifierLength + 1];
+ public readonly List ParametersStack = new List (4);
+ public readonly char[] IDBuilder = new char[Tokenizer.MaxIdentifierLength];
+ public readonly char[] NumberBuilder = new char[Tokenizer.MaxNumberLength];
+
+ public LocationsBag LocationsBag { get; set; }
+ public bool UseJayGlobalArrays { get; set; }
+ public Tokenizer.LocatedToken[] LocatedTokens { get; set; }
+
+ public MD5 GetChecksumAlgorithm ()
+ {
+ return md5 ?? (md5 = MD5.Create ());
+ }
+ }
}
diff --git a/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.cs b/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.cs
index 32eafa832d..b9491273a1 100644
--- a/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.cs
+++ b/ICSharpCode.NRefactory.CSharp/Parser/mcs/cs-parser.cs
@@ -78,7 +78,7 @@ namespace Mono.CSharp
///
/// An out-of-band stack.
///
- static Stack
diff --git a/ICSharpCode.NRefactory/Semantics/NamedArgumentResolveResult.cs b/ICSharpCode.NRefactory/Semantics/NamedArgumentResolveResult.cs
new file mode 100644
index 0000000000..7a69afebf8
--- /dev/null
+++ b/ICSharpCode.NRefactory/Semantics/NamedArgumentResolveResult.cs
@@ -0,0 +1,81 @@
+// Copyright (c) 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.NRefactory.TypeSystem;
+
+namespace ICSharpCode.NRefactory.Semantics
+{
+ ///
+ /// Represents a named argument.
+ ///
+ public class NamedArgumentResolveResult : ResolveResult
+ {
+ ///
+ /// Gets the member to which the parameter belongs.
+ /// This field can be null.
+ ///
+ public readonly IParameterizedMember Member;
+
+ ///
+ /// Gets the parameter.
+ /// This field can be null.
+ ///
+ public readonly IParameter Parameter;
+
+ ///
+ /// Gets the parameter name.
+ ///
+ public readonly string ParameterName;
+
+ ///
+ /// Gets the argument passed to the parameter.
+ ///
+ public readonly ResolveResult Argument;
+
+ public NamedArgumentResolveResult(IParameter parameter, ResolveResult argument, IParameterizedMember member = null)
+ : base(argument.Type)
+ {
+ if (parameter == null)
+ throw new ArgumentNullException("parameter");
+ if (argument == null)
+ throw new ArgumentNullException("argument");
+ this.Member = member;
+ this.Parameter = parameter;
+ this.ParameterName = parameter.Name;
+ this.Argument = argument;
+ }
+
+ public NamedArgumentResolveResult(string parameterName, ResolveResult argument)
+ : base(argument.Type)
+ {
+ if (parameterName == null)
+ throw new ArgumentNullException("parameterName");
+ if (argument == null)
+ throw new ArgumentNullException("argument");
+ this.ParameterName = parameterName;
+ this.Argument = argument;
+ }
+
+ public override IEnumerable GetChildResults()
+ {
+ return new [] { Argument };
+ }
+ }
+}
diff --git a/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs b/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs
index e4322822f9..0f6c6d6741 100644
--- a/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/CecilLoader.cs
@@ -55,6 +55,12 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// the Cecil objects to stay in memory (which can significantly increase memory usage).
/// It also prevents serialization of the Cecil-loaded type system.
///
+ ///
+ /// Because the type system can be used on multiple threads, but Cecil is not
+ /// thread-safe for concurrent read access, the CecilLoader will lock on the instance
+ /// for every delay-loading operation.
+ /// If you access the Cecil objects directly in your application, you may need to take the same lock.
+ ///
public bool LazyLoad { get; set; }
///
@@ -72,6 +78,17 @@ namespace ICSharpCode.NRefactory.TypeSystem
///
public CancellationToken CancellationToken { get; set; }
+ ///
+ /// This delegate gets executed whenever an entity was loaded.
+ ///
+ ///
+ /// This callback may be to build a dictionary that maps between
+ /// entities and cecil objects.
+ /// Warning: if delay-loading is used and the type system is accessed by multiple threads,
+ /// the callback may be invoked concurrently on multiple threads.
+ ///
+ public Action OnEntityLoaded { get; set; }
+
///
/// Gets a value indicating whether this instance stores references to the cecil objects.
///
@@ -84,19 +101,26 @@ namespace ICSharpCode.NRefactory.TypeSystem
ModuleDefinition currentModule;
CecilUnresolvedAssembly currentAssembly;
+ ///
+ /// Initializes a new instance of the class.
+ ///
+ public CecilLoader()
+ {
+ // Enable interning by default.
+ this.InterningProvider = new SimpleInterningProvider();
+ }
+
///
/// Initializes a new instance of the class.
///
///
/// If true references to the cecil objects are hold. In this case the cecil loader can do a type system -> cecil mapping.
///
- public CecilLoader (bool createCecilReferences = false)
+ [Obsolete("The built-in entity<->cecil mapping is obsolete. Use the OnEntityLoaded callback instead!")]
+ public CecilLoader(bool createCecilReferences) : this()
{
if (createCecilReferences)
typeSystemTranslationTable = new Dictionary ();
-
- // Enable interning by default.
- this.InterningProvider = new SimpleInterningProvider();
}
///
@@ -108,6 +132,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
this.typeSystemTranslationTable = loader.typeSystemTranslationTable;
this.IncludeInternalMembers = loader.IncludeInternalMembers;
this.LazyLoad = loader.LazyLoad;
+ this.OnEntityLoaded = loader.OnEntityLoaded;
this.currentModule = loader.currentModule;
this.currentAssembly = loader.currentAssembly;
// don't use interning - the interning provider is most likely not thread-safe
@@ -169,12 +194,15 @@ namespace ICSharpCode.NRefactory.TypeSystem
continue;
if (this.LazyLoad) {
- currentAssembly.AddTypeDefinition(new LazyCecilTypeDefinition(cecilLoaderCloneForLazyLoading, td));
+ var t = new LazyCecilTypeDefinition(cecilLoaderCloneForLazyLoading, td);
+ currentAssembly.AddTypeDefinition(t);
+ RegisterCecilObject(t, td);
} else {
var t = CreateTopLevelTypeDefinition(td);
cecilTypeDefs.Add(td);
typeDefs.Add(t);
currentAssembly.AddTypeDefinition(t);
+ // The registration will happen after the members are initialized
}
}
}
@@ -184,7 +212,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
InitTypeDefinition(cecilTypeDefs[i], typeDefs[i]);
}
- RegisterCecilObject(this.currentAssembly, assemblyDefinition);
+ AddToTypeSystemTranslationTable(this.currentAssembly, assemblyDefinition);
var result = this.currentAssembly;
this.currentAssembly = null;
@@ -249,9 +277,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
throw new ArgumentNullException("fileName");
var param = new ReaderParameters { AssemblyResolver = new DummyAssemblyResolver() };
AssemblyDefinition asm = AssemblyDefinition.ReadAssembly(fileName, param);
- var result = LoadAssembly(asm);
- RegisterCecilObject(result, asm);
- return result;
+ return LoadAssembly(asm);
}
// used to prevent Cecil from loading referenced assemblies
@@ -941,7 +967,16 @@ namespace ICSharpCode.NRefactory.TypeSystem
return;
}
foreach (var ctorParameter in ctorParameterTypes.Resolve(context)) {
- positionalArguments.Add(reader.ReadFixedArg(ctorParameter));
+ ResolveResult arg = reader.ReadFixedArg(ctorParameter);
+ positionalArguments.Add(arg);
+ if (arg.IsError) {
+ // After a decoding error, we must stop decoding the blob because
+ // we might have read too few bytes due to the error.
+ // Just fill up the remaining arguments with ErrorResolveResult:
+ while (positionalArguments.Count < ctorParameterTypes.Count)
+ positionalArguments.Add(ErrorResolveResult.UnknownError);
+ return;
+ }
}
ushort numNamed = reader.ReadUInt16();
for (int i = 0; i < numNamed; i++) {
@@ -1105,6 +1140,9 @@ namespace ICSharpCode.NRefactory.TypeSystem
ResolveResult[] elements = new ResolveResult[numElem];
for (int i = 0; i < elements.Length; i++) {
elements[i] = ReadElem(elementType);
+ // Stop decoding when encountering an error:
+ if (elements[i].IsError)
+ return ErrorResolveResult.UnknownError;
}
return new ArrayCreateResolveResult(argType, null, elements);
}
@@ -1395,11 +1433,10 @@ namespace ICSharpCode.NRefactory.TypeSystem
namedArgs.Add(namedArg);
}
- attributes[i] = new ResolvedSecurityAttribute {
- AttributeType = attributeType,
- NamedArguments = namedArgs,
- PositionalArguments = new ResolveResult[] { securityActionRR }
- };
+ attributes[i] = new DefaultAttribute(
+ attributeType,
+ positionalArguments: new ResolveResult[] { securityActionRR },
+ namedArguments: namedArgs);
}
}
@@ -1442,37 +1479,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
return secDecl.Resolve(context.CurrentAssembly)[index];
}
}
-
- sealed class ResolvedSecurityAttribute : IAttribute
- {
- public IType AttributeType { get; internal set; }
-
- DomRegion IAttribute.Region {
- get { return DomRegion.Empty; }
- }
-
- volatile IMethod constructor;
-
- public IMethod Constructor {
- get {
- IMethod ctor = this.constructor;
- if (ctor == null) {
- foreach (IMethod candidate in this.AttributeType.GetConstructors(m => m.Parameters.Count == 1)) {
- if (candidate.Parameters[0].Type.Equals(this.PositionalArguments[0].Type)) {
- ctor = candidate;
- break;
- }
- }
- this.constructor = ctor;
- }
- return ctor;
- }
- }
-
- public IList PositionalArguments { get; internal set; }
-
- public IList> NamedArguments { get; internal set; }
- }
#endregion
#endregion
@@ -1742,7 +1748,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
this.ApplyInterningProvider(loader.InterningProvider);
}
this.Freeze();
- loader.RegisterCecilObject(this, typeDefinition);
}
public override string Namespace {
@@ -1772,7 +1777,8 @@ namespace ICSharpCode.NRefactory.TypeSystem
var result = LazyInit.VolatileRead(ref this.baseTypes);
if (result != null) {
return result;
- } else {
+ }
+ lock (loader.currentModule) {
result = new List();
loader.InitBaseTypes(cecilTypeDef, result);
return LazyInit.GetOrSet(ref this.baseTypes, FreezableHelper.FreezeList(result));
@@ -1785,7 +1791,10 @@ namespace ICSharpCode.NRefactory.TypeSystem
var result = LazyInit.VolatileRead(ref this.nestedTypes);
if (result != null) {
return result;
- } else {
+ }
+ lock (loader.currentModule) {
+ if (this.nestedTypes != null)
+ return this.nestedTypes;
result = new List();
loader.InitNestedTypes(cecilTypeDef, this, result);
return LazyInit.GetOrSet(ref this.nestedTypes, FreezableHelper.FreezeList(result));
@@ -1798,7 +1807,10 @@ namespace ICSharpCode.NRefactory.TypeSystem
var result = LazyInit.VolatileRead(ref this.members);
if (result != null) {
return result;
- } else {
+ }
+ lock (loader.currentModule) {
+ if (this.members != null)
+ return this.members;
result = new List();
loader.InitMembers(cecilTypeDef, this, result);
return LazyInit.GetOrSet(ref this.members, FreezableHelper.FreezeList(result));
@@ -2160,7 +2172,7 @@ namespace ICSharpCode.NRefactory.TypeSystem
}
#endregion
- void FinishReadMember(AbstractUnresolvedMember member, object cecilDefinition)
+ void FinishReadMember(AbstractUnresolvedMember member, MemberReference cecilDefinition)
{
if (this.InterningProvider != null)
member.ApplyInterningProvider(this.InterningProvider);
@@ -2171,7 +2183,15 @@ namespace ICSharpCode.NRefactory.TypeSystem
#region Type system translation table
readonly Dictionary typeSystemTranslationTable;
- void RegisterCecilObject(object typeSystemObject, object cecilObject)
+ void RegisterCecilObject(IUnresolvedEntity typeSystemObject, MemberReference cecilObject)
+ {
+ if (OnEntityLoaded != null)
+ OnEntityLoaded(typeSystemObject, cecilObject);
+
+ AddToTypeSystemTranslationTable(typeSystemObject, cecilObject);
+ }
+
+ void AddToTypeSystemTranslationTable(object typeSystemObject, object cecilObject)
{
if (typeSystemTranslationTable != null) {
// When lazy-loading, the dictionary might be shared between multiple cecil-loaders that are used concurrently
diff --git a/ICSharpCode.NRefactory/TypeSystem/IAttribute.cs b/ICSharpCode.NRefactory/TypeSystem/IAttribute.cs
index ef9adf7f48..184de64784 100644
--- a/ICSharpCode.NRefactory/TypeSystem/IAttribute.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/IAttribute.cs
@@ -18,7 +18,6 @@
using System;
using System.Collections.Generic;
-using System.Diagnostics.Contracts;
using ICSharpCode.NRefactory.Semantics;
@@ -27,9 +26,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
///
/// Represents an unresolved attribute.
///
- #if WITH_CONTRACTS
- [ContractClass(typeof(IUnresolvedAttributeContract))]
- #endif
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix")]
public interface IUnresolvedAttribute
{
@@ -38,8 +34,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
///
DomRegion Region { get; }
- //ITypeReference AttributeType { get; }
-
///
/// Resolves the attribute.
///
@@ -49,9 +43,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
///
/// Represents an attribute.
///
- #if WITH_CONTRACTS
- [ContractClass(typeof(IAttributeContract))]
- #endif
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1711:IdentifiersShouldNotHaveIncorrectSuffix")]
public interface IAttribute
{
@@ -81,41 +72,4 @@ namespace ICSharpCode.NRefactory.TypeSystem
///
IList> NamedArguments { get; }
}
-
- #if WITH_CONTRACTS
- [ContractClassFor(typeof(IAttribute))]
- abstract class IAttributeContract : IFreezableContract, IAttribute
- {
- DomRegion IAttribute.Region {
- get { return DomRegion.Empty; }
- }
-
- ITypeReference IAttribute.AttributeType {
- get {
- Contract.Ensures(Contract.Result() != null);
- return null;
- }
- }
-
- IList IAttribute.GetPositionalArguments(ITypeResolveContext context)
- {
- Contract.Requires(context != null);
- Contract.Ensures(Contract.Result>() != null);
- return null;
- }
-
- IList> IAttribute.GetNamedArguments(ITypeResolveContext context)
- {
- Contract.Requires(context != null);
- Contract.Ensures(Contract.Result>>() != null);
- return null;
- }
-
- IMethod IAttribute.ResolveConstructor(ITypeResolveContext context)
- {
- Contract.Requires(context != null);
- return null;
- }
- }
- #endif
}
diff --git a/ICSharpCode.NRefactory/TypeSystem/IFreezable.cs b/ICSharpCode.NRefactory/TypeSystem/IFreezable.cs
index e0b63a28ad..050d09e099 100644
--- a/ICSharpCode.NRefactory/TypeSystem/IFreezable.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/IFreezable.cs
@@ -17,13 +17,9 @@
// DEALINGS IN THE SOFTWARE.
using System;
-using System.Diagnostics.Contracts;
namespace ICSharpCode.NRefactory.TypeSystem
{
- #if WITH_CONTRACTS
- [ContractClass(typeof(IFreezableContract))]
- #endif
public interface IFreezable
{
///
@@ -36,20 +32,4 @@ namespace ICSharpCode.NRefactory.TypeSystem
///
void Freeze();
}
-
- #if WITH_CONTRACTS
- [ContractClassFor(typeof(IFreezable))]
- abstract class IFreezableContract : IFreezable
- {
- bool IFreezable.IsFrozen {
- get { return default(bool); }
- }
-
- void IFreezable.Freeze()
- {
- IFreezable self = this;
- Contract.Ensures(self.IsFrozen);
- }
- }
- #endif
}
diff --git a/ICSharpCode.NRefactory/TypeSystem/IInterningProvider.cs b/ICSharpCode.NRefactory/TypeSystem/IInterningProvider.cs
index dc20e18ef8..89edd7f9f4 100644
--- a/ICSharpCode.NRefactory/TypeSystem/IInterningProvider.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/IInterningProvider.cs
@@ -18,7 +18,6 @@
using System;
using System.Collections.Generic;
-using System.Diagnostics.Contracts;
namespace ICSharpCode.NRefactory.TypeSystem
{
@@ -40,9 +39,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// and which are used only within a single type definition. Then a persistent file format could be organized so
/// that shared objects are loaded only once, yet non-shared objects get loaded lazily together with the class.
///
- #if WITH_CONTRACTS
- [ContractClass(typeof(IInterningProviderContract))]
- #endif
public interface IInterningProvider
{
///
@@ -55,22 +51,4 @@ namespace ICSharpCode.NRefactory.TypeSystem
IList InternList(IList list) where T : class;
}
-
- #if WITH_CONTRACTS
- [ContractClassFor(typeof(IInterningProvider))]
- abstract class IInterningProviderContract : IInterningProvider
- {
- T IInterningProvider.Intern(T obj)
- {
- Contract.Ensures((Contract.Result() == null) == (obj == null));
- return obj;
- }
-
- IList IInterningProvider.InternList(IList list)
- {
- Contract.Ensures((Contract.Result>() == null) == (list == null));
- return list;
- }
- }
- #endif
}
diff --git a/ICSharpCode.NRefactory/TypeSystem/ISupportsInterning.cs b/ICSharpCode.NRefactory/TypeSystem/ISupportsInterning.cs
index 43573ade47..0832e33e90 100644
--- a/ICSharpCode.NRefactory/TypeSystem/ISupportsInterning.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/ISupportsInterning.cs
@@ -17,8 +17,6 @@
// DEALINGS IN THE SOFTWARE.
using System;
-using System.Collections.Generic;
-using System.Diagnostics.Contracts;
namespace ICSharpCode.NRefactory.TypeSystem
{
@@ -26,9 +24,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// Interface for TypeSystem objects that support interning.
/// See for more information.
///
- #if WITH_CONTRACTS
- [ContractClass(typeof(ISupportsInterningContract))]
- #endif
public interface ISupportsInterning
{
///
@@ -46,25 +41,4 @@ namespace ICSharpCode.NRefactory.TypeSystem
///
bool EqualsForInterning(ISupportsInterning other);
}
-
- #if WITH_CONTRACTS
- [ContractClassFor(typeof(ISupportsInterning))]
- abstract class ISupportsInterningContract : ISupportsInterning
- {
- void ISupportsInterning.PrepareForInterning(IInterningProvider provider)
- {
- Contract.Requires(provider != null);
- }
-
- int ISupportsInterning.GetHashCodeForInterning()
- {
- return 0;
- }
-
- bool ISupportsInterning.EqualsForInterning(ISupportsInterning other)
- {
- return false;
- }
- }
- #endif
}
diff --git a/ICSharpCode.NRefactory/TypeSystem/IType.cs b/ICSharpCode.NRefactory/TypeSystem/IType.cs
index a6a4892f4c..2d010e22b9 100644
--- a/ICSharpCode.NRefactory/TypeSystem/IType.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/IType.cs
@@ -18,7 +18,6 @@
using System;
using System.Collections.Generic;
-using System.Diagnostics.Contracts;
namespace ICSharpCode.NRefactory.TypeSystem
{
diff --git a/ICSharpCode.NRefactory/TypeSystem/ITypeDefinition.cs b/ICSharpCode.NRefactory/TypeSystem/ITypeDefinition.cs
index 1438505d8b..7cd98c8d23 100644
--- a/ICSharpCode.NRefactory/TypeSystem/ITypeDefinition.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/ITypeDefinition.cs
@@ -130,5 +130,25 @@ namespace ICSharpCode.NRefactory.TypeSystem
///
/// This property is used to speed up the search for extension methods.
bool HasExtensionMethods { get; }
+
+ ///
+ /// Determines how this type is implementing the specified interface member.
+ ///
+ ///
+ /// The method on this type that implements the interface member;
+ /// or null if the type does not implement the interface.
+ ///
+ IMember GetInterfaceImplementation(IMember interfaceMember);
+
+ ///
+ /// Determines how this type is implementing the specified interface members.
+ ///
+ ///
+ /// For each interface member, this method returns the class member
+ /// that implements the interface member.
+ /// For interface members that are missing an implementation, the
+ /// result collection will contain a null element.
+ ///
+ IList GetInterfaceImplementation(IList interfaceMembers);
}
}
diff --git a/ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs b/ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs
index efad8e983c..fc22826c37 100644
--- a/ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/ITypeReference.cs
@@ -17,8 +17,6 @@
// DEALINGS IN THE SOFTWARE.
using System;
-using System.Collections.Generic;
-using System.Diagnostics.Contracts;
namespace ICSharpCode.NRefactory.TypeSystem
{
@@ -26,9 +24,6 @@ namespace ICSharpCode.NRefactory.TypeSystem
/// Represents a reference to a type.
/// Must be resolved before it can be used as type.
///
- #if WITH_CONTRACTS
- [ContractClass(typeof(ITypeReferenceContract))]
- #endif
public interface ITypeReference
{
// Keep this interface simple: I decided against having GetMethods/GetEvents etc. here,
@@ -81,17 +76,4 @@ namespace ICSharpCode.NRefactory.TypeSystem
ITypeResolveContext WithCurrentTypeDefinition(ITypeDefinition typeDefinition);
ITypeResolveContext WithCurrentMember(IMember member);
}
-
- #if WITH_CONTRACTS
- [ContractClassFor(typeof(ITypeReference))]
- abstract class ITypeReferenceContract : ITypeReference
- {
- IType ITypeReference.Resolve(ITypeResolveContext context)
- {
- Contract.Requires(context != null);
- Contract.Ensures(Contract.Result() != null);
- return null;
- }
- }
- #endif
}
\ No newline at end of file
diff --git a/ICSharpCode.NRefactory/TypeSystem/IVariable.cs b/ICSharpCode.NRefactory/TypeSystem/IVariable.cs
index e185247707..9e4d45835e 100644
--- a/ICSharpCode.NRefactory/TypeSystem/IVariable.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/IVariable.cs
@@ -17,16 +17,12 @@
// DEALINGS IN THE SOFTWARE.
using System;
-using System.Diagnostics.Contracts;
namespace ICSharpCode.NRefactory.TypeSystem
{
///
/// Represents a variable (name/type pair).
///
- #if WITH_CONTRACTS
- [ContractClass(typeof(IVariableContract))]
- #endif
public interface IVariable
{
///
@@ -55,36 +51,4 @@ namespace ICSharpCode.NRefactory.TypeSystem
///
object ConstantValue { get; }
}
-
- #if WITH_CONTRACTS
- [ContractClassFor(typeof(IVariable))]
- abstract class IVariableContract : IVariable
- {
- string IVariable.Name {
- get {
- Contract.Ensures(Contract.Result() != null);
- return null;
- }
- }
-
- ITypeReference IVariable.Type {
- get {
- Contract.Ensures(Contract.Result() != null);
- return null;
- }
- }
-
- bool IVariable.IsConst {
- get {
- IVariable @this = this;
- Contract.Ensures(Contract.Result() == (@this.ConstantValue != null));
- return false;
- }
- }
-
- object IVariable.ConstantValue {
- get { return null; }
- }
- }
- #endif
}
diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAttribute.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAttribute.cs
new file mode 100644
index 0000000000..79df0167a6
--- /dev/null
+++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultAttribute.cs
@@ -0,0 +1,97 @@
+// Copyright (c) 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.NRefactory.Semantics;
+
+namespace ICSharpCode.NRefactory.TypeSystem.Implementation
+{
+ ///
+ /// IAttribute implementation for already-resolved attributes.
+ ///
+ public class DefaultAttribute : IAttribute
+ {
+ readonly IType attributeType;
+ readonly IList positionalArguments;
+ readonly IList> namedArguments;
+ readonly DomRegion region;
+ volatile IMethod constructor;
+
+ public DefaultAttribute(IType attributeType, IList positionalArguments = null,
+ IList> namedArguments = null,
+ DomRegion region = default(DomRegion))
+ {
+ if (attributeType == null)
+ throw new ArgumentNullException("attributeType");
+ this.attributeType = attributeType;
+ this.positionalArguments = positionalArguments ?? EmptyList.Instance;
+ this.namedArguments = namedArguments ?? EmptyList>.Instance;
+ this.region = region;
+ }
+
+ public DefaultAttribute(IMethod constructor, IList positionalArguments = null,
+ IList> namedArguments = null,
+ DomRegion region = default(DomRegion))
+ {
+ if (constructor == null)
+ throw new ArgumentNullException("constructor");
+ this.constructor = constructor;
+ this.attributeType = constructor.DeclaringType;
+ this.positionalArguments = positionalArguments ?? EmptyList.Instance;
+ this.namedArguments = namedArguments ?? EmptyList>.Instance;
+ this.region = region;
+ if (this.positionalArguments.Count != constructor.Parameters.Count) {
+ throw new ArgumentException("Positional argument count must match the constructor's parameter count");
+ }
+ }
+
+ public IType AttributeType {
+ get { return attributeType; }
+ }
+
+ public DomRegion Region {
+ get { return region; }
+ }
+
+ public IMethod Constructor {
+ get {
+ IMethod ctor = this.constructor;
+ if (ctor == null) {
+ foreach (IMethod candidate in this.AttributeType.GetConstructors(m => m.Parameters.Count == positionalArguments.Count)) {
+ if (candidate.Parameters.Select(p => p.Type).SequenceEqual(this.PositionalArguments.Select(a => a.Type))) {
+ ctor = candidate;
+ break;
+ }
+ }
+ this.constructor = ctor;
+ }
+ return ctor;
+ }
+ }
+
+ public IList PositionalArguments {
+ get { return positionalArguments; }
+ }
+
+ public IList> NamedArguments {
+ get { return namedArguments; }
+ }
+ }
+}
diff --git a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs
index 4ea28dbe69..902d1c9094 100644
--- a/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs
+++ b/ICSharpCode.NRefactory/TypeSystem/Implementation/DefaultResolvedTypeDefinition.cs
@@ -18,7 +18,6 @@
using System;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
using System.Linq;
using ICSharpCode.NRefactory.Documentation;
using ICSharpCode.NRefactory.Utils;
@@ -861,6 +860,46 @@ namespace ICSharpCode.NRefactory.TypeSystem.Implementation
}
#endregion
+ #region GetInterfaceImplementation
+ public IMember GetInterfaceImplementation(IMember interfaceMember)
+ {
+ return GetInterfaceImplementation(new[] { interfaceMember })[0];
+ }
+
+ public IList GetInterfaceImplementation(IList interfaceMembers)
+ {
+ // TODO: review the subtle rules for interface reimplementation,
+ // write tests and fix this method.
+ // Also virtual/override is going to be tricky -
+ // I think we'll need to consider the 'virtual' method first for
+ // reimplemenatation purposes, but then actually return the 'override'
+ // (as that's the method that ends up getting called)
+
+ interfaceMembers = interfaceMembers.ToList(); // avoid evaluating more than once
+
+ var result = new IMember[interfaceMembers.Count];
+ var signatureToIndexDict = new MultiDictionary(SignatureComparer.Ordinal);
+ for (int i = 0; i < interfaceMembers.Count; i++) {
+ signatureToIndexDict.Add(interfaceMembers[i], i);
+ }
+ foreach (var member in GetMembers(m => !m.IsExplicitInterfaceImplementation)) {
+ foreach (int interfaceMemberIndex in signatureToIndexDict[member]) {
+ result[interfaceMemberIndex] = member;
+ }
+ }
+ foreach (var explicitImpl in GetMembers(m => m.IsExplicitInterfaceImplementation)) {
+ foreach (var interfaceMember in explicitImpl.ImplementedInterfaceMembers) {
+ foreach (int potentialMatchingIndex in signatureToIndexDict[interfaceMember]) {
+ if (interfaceMember.Equals(interfaceMembers[potentialMatchingIndex])) {
+ result[potentialMatchingIndex] = explicitImpl;
+ }
+ }
+ }
+ }
+ return result;
+ }
+ #endregion
+
public bool Equals(IType other)
{
return this == other;
diff --git a/ICSharpCode.NRefactory/Utils/LazyInit.cs b/ICSharpCode.NRefactory/Utils/LazyInit.cs
index 94c08bbea4..467a8daa35 100644
--- a/ICSharpCode.NRefactory/Utils/LazyInit.cs
+++ b/ICSharpCode.NRefactory/Utils/LazyInit.cs
@@ -17,10 +17,7 @@
// DEALINGS IN THE SOFTWARE.
using System;
-using System.Collections.Generic;
-using System.Diagnostics;
using System.Threading;
-using ICSharpCode.NRefactory.TypeSystem;
namespace ICSharpCode.NRefactory.Utils
{
diff --git a/ICSharpCode.NRefactory/Utils/MultiDictionary.cs b/ICSharpCode.NRefactory/Utils/MultiDictionary.cs
new file mode 100644
index 0000000000..496b66ba9e
--- /dev/null
+++ b/ICSharpCode.NRefactory/Utils/MultiDictionary.cs
@@ -0,0 +1,134 @@
+// Copyright (c) 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;
+
+namespace ICSharpCode.NRefactory.Utils
+{
+ ///
+ /// A dictionary that allows multiple pairs with the same key.
+ ///
+ public class MultiDictionary : ILookup
+ {
+ readonly Dictionary> dict;
+
+ public MultiDictionary()
+ {
+ dict = new Dictionary>();
+ }
+
+ public MultiDictionary(IEqualityComparer comparer)
+ {
+ dict = new Dictionary>(comparer);
+ }
+
+ public void Add(TKey key, TValue value)
+ {
+ List valueList;
+ if (!dict.TryGetValue(key, out valueList)) {
+ valueList = new List();
+ dict.Add(key, valueList);
+ }
+ valueList.Add(value);
+ }
+
+ public bool Remove(TKey key, TValue value)
+ {
+ List valueList;
+ if (dict.TryGetValue(key, out valueList)) {
+ if (valueList.Remove(value)) {
+ if (valueList.Count == 0)
+ dict.Remove(key);
+ return true;
+ }
+ }
+ return false;
+ }
+
+ public void Clear()
+ {
+ dict.Clear();
+ }
+
+ #if NET45
+ public IReadOnlyList this[TKey key] {
+ #else
+ public IList this[TKey key] {
+ #endif
+ get {
+ List list;
+ if (dict.TryGetValue(key, out list))
+ return list;
+ else
+ return EmptyList.Instance;
+ }
+ }
+
+ public int Count {
+ get { return dict.Count; }
+ }
+
+ IEnumerable ILookup.this[TKey key] {
+ get { return this[key]; }
+ }
+
+ bool ILookup.Contains(TKey key)
+ {
+ return dict.ContainsKey(key);
+ }
+
+ public IEnumerator> GetEnumerator()
+ {
+ foreach (var pair in dict)
+ yield return new Grouping(pair.Key, pair.Value);
+ }
+
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
+ return GetEnumerator();
+ }
+
+ sealed class Grouping : IGrouping
+ {
+ readonly TKey key;
+ readonly List values;
+
+ public Grouping(TKey key, List values)
+ {
+ this.key = key;
+ this.values = values;
+ }
+
+ public TKey Key {
+ get { return key; }
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return values.GetEnumerator();
+ }
+
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
+ {
+ return values.GetEnumerator();
+ }
+ }
+ }
+}
diff --git a/NRefactory.sln b/NRefactory.sln
index 94451e3646..cc76ba1a42 100644
--- a/NRefactory.sln
+++ b/NRefactory.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 11.00
# Visual Studio 2010
-# SharpDevelop 4.2.0.8783
+# SharpDevelop 4.3
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{DC98210E-1646-483B-819A-2BB8272461E4}"
ProjectSection(SolutionItems) = preProject
Packages\ICSharpCode.NRefactory.nuspec = Packages\ICSharpCode.NRefactory.nuspec
@@ -34,6 +34,10 @@ Global
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|x86 = Release|x86
+ net_4_5_Debug|Any CPU = net_4_5_Debug|Any CPU
+ net_4_5_Debug|x86 = net_4_5_Debug|x86
+ net_4_5_Release|Any CPU = net_4_5_Release|Any CPU
+ net_4_5_Release|x86 = net_4_5_Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
@@ -108,6 +112,78 @@ Global
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.Release|x86.Build.0 = Release|x86
{9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.Release|x86.ActiveCfg = Release|x86
+ {9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.net_4_5_Debug|Any CPU.Build.0 = net_4_5_Debug|Any CPU
+ {9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.net_4_5_Debug|Any CPU.ActiveCfg = net_4_5_Debug|Any CPU
+ {961DADFA-7CE6-429F-BC22-47630D6DB826}.net_4_5_Debug|Any CPU.Build.0 = net_4_5_Debug|Any CPU
+ {961DADFA-7CE6-429F-BC22-47630D6DB826}.net_4_5_Debug|Any CPU.ActiveCfg = net_4_5_Debug|Any CPU
+ {DC393B66-92ED-4CAD-AB25-CFEF23F3D7C6}.net_4_5_Debug|Any CPU.Build.0 = net_4_5_Debug|Any CPU
+ {DC393B66-92ED-4CAD-AB25-CFEF23F3D7C6}.net_4_5_Debug|Any CPU.ActiveCfg = net_4_5_Debug|Any CPU
+ {D81206EF-3DCA-4A30-897B-E262A2AD9EE3}.net_4_5_Debug|Any CPU.Build.0 = net_4_5_Debug|Any CPU
+ {D81206EF-3DCA-4A30-897B-E262A2AD9EE3}.net_4_5_Debug|Any CPU.ActiveCfg = net_4_5_Debug|Any CPU
+ {A7EEF7F8-238F-459D-95A9-96467539641D}.net_4_5_Debug|Any CPU.Build.0 = net_4_5_Debug|Any CPU
+ {A7EEF7F8-238F-459D-95A9-96467539641D}.net_4_5_Debug|Any CPU.ActiveCfg = net_4_5_Debug|Any CPU
+ {53DCA265-3C3C-42F9-B647-F72BA678122B}.net_4_5_Debug|Any CPU.Build.0 = net_4_5_Debug|Any CPU
+ {53DCA265-3C3C-42F9-B647-F72BA678122B}.net_4_5_Debug|Any CPU.ActiveCfg = net_4_5_Debug|Any CPU
+ {D68133BD-1E63-496E-9EDE-4FBDBF77B486}.net_4_5_Debug|Any CPU.Build.0 = winphone_Release|Any CPU
+ {D68133BD-1E63-496E-9EDE-4FBDBF77B486}.net_4_5_Debug|Any CPU.ActiveCfg = net_4_0_Debug|Any CPU
+ {63D3B27A-D966-4902-90B3-30290E1692F1}.net_4_5_Debug|Any CPU.Build.0 = net_4_5_Debug|Any CPU
+ {63D3B27A-D966-4902-90B3-30290E1692F1}.net_4_5_Debug|Any CPU.ActiveCfg = net_4_5_Debug|Any CPU
+ {3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.net_4_5_Debug|Any CPU.Build.0 = net_4_5_Debug|Any CPU
+ {3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.net_4_5_Debug|Any CPU.ActiveCfg = net_4_5_Debug|Any CPU
+ {9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.net_4_5_Debug|x86.Build.0 = net_4_5_Debug|x86
+ {9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.net_4_5_Debug|x86.ActiveCfg = net_4_5_Debug|x86
+ {961DADFA-7CE6-429F-BC22-47630D6DB826}.net_4_5_Debug|x86.Build.0 = net_4_5_Debug|Any CPU
+ {961DADFA-7CE6-429F-BC22-47630D6DB826}.net_4_5_Debug|x86.ActiveCfg = net_4_5_Debug|Any CPU
+ {DC393B66-92ED-4CAD-AB25-CFEF23F3D7C6}.net_4_5_Debug|x86.Build.0 = net_4_5_Debug|Any CPU
+ {DC393B66-92ED-4CAD-AB25-CFEF23F3D7C6}.net_4_5_Debug|x86.ActiveCfg = net_4_5_Debug|Any CPU
+ {D81206EF-3DCA-4A30-897B-E262A2AD9EE3}.net_4_5_Debug|x86.Build.0 = net_4_5_Debug|x86
+ {D81206EF-3DCA-4A30-897B-E262A2AD9EE3}.net_4_5_Debug|x86.ActiveCfg = net_4_5_Debug|x86
+ {A7EEF7F8-238F-459D-95A9-96467539641D}.net_4_5_Debug|x86.Build.0 = net_4_5_Debug|Any CPU
+ {A7EEF7F8-238F-459D-95A9-96467539641D}.net_4_5_Debug|x86.ActiveCfg = net_4_5_Debug|Any CPU
+ {53DCA265-3C3C-42F9-B647-F72BA678122B}.net_4_5_Debug|x86.Build.0 = net_4_5_Debug|Any CPU
+ {53DCA265-3C3C-42F9-B647-F72BA678122B}.net_4_5_Debug|x86.ActiveCfg = net_4_5_Debug|Any CPU
+ {D68133BD-1E63-496E-9EDE-4FBDBF77B486}.net_4_5_Debug|x86.Build.0 = winphone_Release|Any CPU
+ {D68133BD-1E63-496E-9EDE-4FBDBF77B486}.net_4_5_Debug|x86.ActiveCfg = net_4_0_Debug|Any CPU
+ {63D3B27A-D966-4902-90B3-30290E1692F1}.net_4_5_Debug|x86.Build.0 = net_4_5_Debug|x86
+ {63D3B27A-D966-4902-90B3-30290E1692F1}.net_4_5_Debug|x86.ActiveCfg = net_4_5_Debug|x86
+ {3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.net_4_5_Debug|x86.Build.0 = net_4_5_Debug|Any CPU
+ {3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.net_4_5_Debug|x86.ActiveCfg = net_4_5_Debug|Any CPU
+ {9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.net_4_5_Release|Any CPU.Build.0 = net_4_5_Release|Any CPU
+ {9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.net_4_5_Release|Any CPU.ActiveCfg = net_4_5_Release|Any CPU
+ {961DADFA-7CE6-429F-BC22-47630D6DB826}.net_4_5_Release|Any CPU.Build.0 = net_4_5_Release|Any CPU
+ {961DADFA-7CE6-429F-BC22-47630D6DB826}.net_4_5_Release|Any CPU.ActiveCfg = net_4_5_Release|Any CPU
+ {DC393B66-92ED-4CAD-AB25-CFEF23F3D7C6}.net_4_5_Release|Any CPU.Build.0 = net_4_5_Release|Any CPU
+ {DC393B66-92ED-4CAD-AB25-CFEF23F3D7C6}.net_4_5_Release|Any CPU.ActiveCfg = net_4_5_Release|Any CPU
+ {D81206EF-3DCA-4A30-897B-E262A2AD9EE3}.net_4_5_Release|Any CPU.Build.0 = net_4_5_Release|Any CPU
+ {D81206EF-3DCA-4A30-897B-E262A2AD9EE3}.net_4_5_Release|Any CPU.ActiveCfg = net_4_5_Release|Any CPU
+ {A7EEF7F8-238F-459D-95A9-96467539641D}.net_4_5_Release|Any CPU.Build.0 = net_4_5_Release|Any CPU
+ {A7EEF7F8-238F-459D-95A9-96467539641D}.net_4_5_Release|Any CPU.ActiveCfg = net_4_5_Release|Any CPU
+ {53DCA265-3C3C-42F9-B647-F72BA678122B}.net_4_5_Release|Any CPU.Build.0 = net_4_5_Release|Any CPU
+ {53DCA265-3C3C-42F9-B647-F72BA678122B}.net_4_5_Release|Any CPU.ActiveCfg = net_4_5_Release|Any CPU
+ {D68133BD-1E63-496E-9EDE-4FBDBF77B486}.net_4_5_Release|Any CPU.Build.0 = winphone_Release|Any CPU
+ {D68133BD-1E63-496E-9EDE-4FBDBF77B486}.net_4_5_Release|Any CPU.ActiveCfg = net_4_0_Release|Any CPU
+ {63D3B27A-D966-4902-90B3-30290E1692F1}.net_4_5_Release|Any CPU.Build.0 = net_4_5_Release|Any CPU
+ {63D3B27A-D966-4902-90B3-30290E1692F1}.net_4_5_Release|Any CPU.ActiveCfg = net_4_5_Release|Any CPU
+ {3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.net_4_5_Release|Any CPU.Build.0 = net_4_5_Release|Any CPU
+ {3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.net_4_5_Release|Any CPU.ActiveCfg = net_4_5_Release|Any CPU
+ {9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.net_4_5_Release|x86.Build.0 = net_4_5_Release|x86
+ {9C19E629-C93E-4ACB-9A4B-13072B5AEF9D}.net_4_5_Release|x86.ActiveCfg = net_4_5_Release|x86
+ {961DADFA-7CE6-429F-BC22-47630D6DB826}.net_4_5_Release|x86.Build.0 = net_4_5_Release|Any CPU
+ {961DADFA-7CE6-429F-BC22-47630D6DB826}.net_4_5_Release|x86.ActiveCfg = net_4_5_Release|Any CPU
+ {DC393B66-92ED-4CAD-AB25-CFEF23F3D7C6}.net_4_5_Release|x86.Build.0 = net_4_5_Release|Any CPU
+ {DC393B66-92ED-4CAD-AB25-CFEF23F3D7C6}.net_4_5_Release|x86.ActiveCfg = net_4_5_Release|Any CPU
+ {D81206EF-3DCA-4A30-897B-E262A2AD9EE3}.net_4_5_Release|x86.Build.0 = net_4_5_Release|x86
+ {D81206EF-3DCA-4A30-897B-E262A2AD9EE3}.net_4_5_Release|x86.ActiveCfg = net_4_5_Release|x86
+ {A7EEF7F8-238F-459D-95A9-96467539641D}.net_4_5_Release|x86.Build.0 = net_4_5_Release|Any CPU
+ {A7EEF7F8-238F-459D-95A9-96467539641D}.net_4_5_Release|x86.ActiveCfg = net_4_5_Release|Any CPU
+ {53DCA265-3C3C-42F9-B647-F72BA678122B}.net_4_5_Release|x86.Build.0 = net_4_5_Release|Any CPU
+ {53DCA265-3C3C-42F9-B647-F72BA678122B}.net_4_5_Release|x86.ActiveCfg = net_4_5_Release|Any CPU
+ {D68133BD-1E63-496E-9EDE-4FBDBF77B486}.net_4_5_Release|x86.Build.0 = winphone_Release|Any CPU
+ {D68133BD-1E63-496E-9EDE-4FBDBF77B486}.net_4_5_Release|x86.ActiveCfg = net_4_0_Release|Any CPU
+ {63D3B27A-D966-4902-90B3-30290E1692F1}.net_4_5_Release|x86.Build.0 = net_4_5_Release|x86
+ {63D3B27A-D966-4902-90B3-30290E1692F1}.net_4_5_Release|x86.ActiveCfg = net_4_5_Release|x86
+ {3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.net_4_5_Release|x86.Build.0 = net_4_5_Release|Any CPU
+ {3B2A5653-EC97-4001-BB9B-D90F1AF2C371}.net_4_5_Release|x86.ActiveCfg = net_4_5_Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE